1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /* Copyright (c) 2019-2020 Marvell International Ltd. */
4 #include <linux/types.h>
5 #include <asm/byteorder.h>
7 #include <linux/errno.h>
8 #include <linux/kernel.h>
9 #include <linux/slab.h>
10 #include <linux/string.h>
11 #include <linux/vmalloc.h>
15 #include "qed_reg_addr.h"
17 #define TLV_TYPE(p) (p[0])
18 #define TLV_LENGTH(p) (p[1])
19 #define TLV_FLAGS(p) (p[3])
21 #define QED_TLV_DATA_MAX (14)
22 struct qed_tlv_parsed_buf
{
23 /* To be filled with the address to set in Value field */
26 /* To be used internally in case the value has to be modified */
27 u8 data
[QED_TLV_DATA_MAX
];
30 static int qed_mfw_get_tlv_group(u8 tlv_type
, u8
*tlv_group
)
33 case DRV_TLV_FEATURE_FLAGS
:
34 case DRV_TLV_LOCAL_ADMIN_ADDR
:
35 case DRV_TLV_ADDITIONAL_MAC_ADDR_1
:
36 case DRV_TLV_ADDITIONAL_MAC_ADDR_2
:
37 case DRV_TLV_OS_DRIVER_STATES
:
38 case DRV_TLV_PXE_BOOT_PROGRESS
:
39 case DRV_TLV_RX_FRAMES_RECEIVED
:
40 case DRV_TLV_RX_BYTES_RECEIVED
:
41 case DRV_TLV_TX_FRAMES_SENT
:
42 case DRV_TLV_TX_BYTES_SENT
:
43 case DRV_TLV_NPIV_ENABLED
:
44 case DRV_TLV_PCIE_BUS_RX_UTILIZATION
:
45 case DRV_TLV_PCIE_BUS_TX_UTILIZATION
:
46 case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION
:
47 case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED
:
48 case DRV_TLV_NCSI_RX_BYTES_RECEIVED
:
49 case DRV_TLV_NCSI_TX_BYTES_SENT
:
50 *tlv_group
|= QED_MFW_TLV_GENERIC
;
52 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE
:
53 case DRV_TLV_LSO_MIN_SEGMENT_COUNT
:
54 case DRV_TLV_PROMISCUOUS_MODE
:
55 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE
:
56 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE
:
57 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG
:
58 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4
:
59 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6
:
60 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
61 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
62 case DRV_TLV_IOV_OFFLOAD
:
63 case DRV_TLV_TX_QUEUES_EMPTY
:
64 case DRV_TLV_RX_QUEUES_EMPTY
:
65 case DRV_TLV_TX_QUEUES_FULL
:
66 case DRV_TLV_RX_QUEUES_FULL
:
67 *tlv_group
|= QED_MFW_TLV_ETH
;
74 case DRV_TLV_BOOT_TYPE
:
75 case DRV_TLV_NPIV_STATE
:
76 case DRV_TLV_NUM_OF_NPIV_IDS
:
77 case DRV_TLV_SWITCH_NAME
:
78 case DRV_TLV_SWITCH_PORT_NUM
:
79 case DRV_TLV_SWITCH_PORT_ID
:
80 case DRV_TLV_VENDOR_NAME
:
81 case DRV_TLV_SWITCH_MODEL
:
82 case DRV_TLV_SWITCH_FW_VER
:
83 case DRV_TLV_QOS_PRIORITY_PER_802_1P
:
84 case DRV_TLV_PORT_ALIAS
:
85 case DRV_TLV_PORT_STATE
:
86 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE
:
87 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE
:
88 case DRV_TLV_LINK_FAILURE_COUNT
:
89 case DRV_TLV_FCOE_BOOT_PROGRESS
:
90 case DRV_TLV_RX_BROADCAST_PACKETS
:
91 case DRV_TLV_TX_BROADCAST_PACKETS
:
92 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
93 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
94 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED
:
95 case DRV_TLV_FCOE_RX_BYTES_RECEIVED
:
96 case DRV_TLV_FCOE_TX_FRAMES_SENT
:
97 case DRV_TLV_FCOE_TX_BYTES_SENT
:
98 case DRV_TLV_CRC_ERROR_COUNT
:
99 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID
:
100 case DRV_TLV_CRC_ERROR_1_TIMESTAMP
:
101 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID
:
102 case DRV_TLV_CRC_ERROR_2_TIMESTAMP
:
103 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID
:
104 case DRV_TLV_CRC_ERROR_3_TIMESTAMP
:
105 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID
:
106 case DRV_TLV_CRC_ERROR_4_TIMESTAMP
:
107 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID
:
108 case DRV_TLV_CRC_ERROR_5_TIMESTAMP
:
109 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT
:
110 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS
:
111 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT
:
112 case DRV_TLV_DISPARITY_ERROR_COUNT
:
113 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT
:
114 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1
:
115 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2
:
116 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3
:
117 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4
:
118 case DRV_TLV_LAST_FLOGI_TIMESTAMP
:
119 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1
:
120 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2
:
121 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3
:
122 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4
:
123 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP
:
124 case DRV_TLV_LAST_FLOGI_RJT
:
125 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP
:
126 case DRV_TLV_FDISCS_SENT_COUNT
:
127 case DRV_TLV_FDISC_ACCS_RECEIVED
:
128 case DRV_TLV_FDISC_RJTS_RECEIVED
:
129 case DRV_TLV_PLOGI_SENT_COUNT
:
130 case DRV_TLV_PLOGI_ACCS_RECEIVED
:
131 case DRV_TLV_PLOGI_RJTS_RECEIVED
:
132 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID
:
133 case DRV_TLV_PLOGI_1_TIMESTAMP
:
134 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID
:
135 case DRV_TLV_PLOGI_2_TIMESTAMP
:
136 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID
:
137 case DRV_TLV_PLOGI_3_TIMESTAMP
:
138 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID
:
139 case DRV_TLV_PLOGI_4_TIMESTAMP
:
140 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID
:
141 case DRV_TLV_PLOGI_5_TIMESTAMP
:
142 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID
:
143 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP
:
144 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID
:
145 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP
:
146 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID
:
147 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP
:
148 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID
:
149 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP
:
150 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID
:
151 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP
:
152 case DRV_TLV_LOGOS_ISSUED
:
153 case DRV_TLV_LOGO_ACCS_RECEIVED
:
154 case DRV_TLV_LOGO_RJTS_RECEIVED
:
155 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID
:
156 case DRV_TLV_LOGO_1_TIMESTAMP
:
157 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID
:
158 case DRV_TLV_LOGO_2_TIMESTAMP
:
159 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID
:
160 case DRV_TLV_LOGO_3_TIMESTAMP
:
161 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID
:
162 case DRV_TLV_LOGO_4_TIMESTAMP
:
163 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID
:
164 case DRV_TLV_LOGO_5_TIMESTAMP
:
165 case DRV_TLV_LOGOS_RECEIVED
:
166 case DRV_TLV_ACCS_ISSUED
:
167 case DRV_TLV_PRLIS_ISSUED
:
168 case DRV_TLV_ACCS_RECEIVED
:
169 case DRV_TLV_ABTS_SENT_COUNT
:
170 case DRV_TLV_ABTS_ACCS_RECEIVED
:
171 case DRV_TLV_ABTS_RJTS_RECEIVED
:
172 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID
:
173 case DRV_TLV_ABTS_1_TIMESTAMP
:
174 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID
:
175 case DRV_TLV_ABTS_2_TIMESTAMP
:
176 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID
:
177 case DRV_TLV_ABTS_3_TIMESTAMP
:
178 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID
:
179 case DRV_TLV_ABTS_4_TIMESTAMP
:
180 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID
:
181 case DRV_TLV_ABTS_5_TIMESTAMP
:
182 case DRV_TLV_RSCNS_RECEIVED
:
183 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1
:
184 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2
:
185 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3
:
186 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4
:
187 case DRV_TLV_LUN_RESETS_ISSUED
:
188 case DRV_TLV_ABORT_TASK_SETS_ISSUED
:
189 case DRV_TLV_TPRLOS_SENT
:
190 case DRV_TLV_NOS_SENT_COUNT
:
191 case DRV_TLV_NOS_RECEIVED_COUNT
:
192 case DRV_TLV_OLS_COUNT
:
193 case DRV_TLV_LR_COUNT
:
194 case DRV_TLV_LRR_COUNT
:
195 case DRV_TLV_LIP_SENT_COUNT
:
196 case DRV_TLV_LIP_RECEIVED_COUNT
:
197 case DRV_TLV_EOFA_COUNT
:
198 case DRV_TLV_EOFNI_COUNT
:
199 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT
:
200 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT
:
201 case DRV_TLV_SCSI_STATUS_BUSY_COUNT
:
202 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT
:
203 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT
:
204 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT
:
205 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT
:
206 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT
:
207 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT
:
208 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ
:
209 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP
:
210 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ
:
211 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP
:
212 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ
:
213 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP
:
214 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ
:
215 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP
:
216 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ
:
217 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP
:
218 *tlv_group
= QED_MFW_TLV_FCOE
;
220 case DRV_TLV_TARGET_LLMNR_ENABLED
:
221 case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED
:
222 case DRV_TLV_DATA_DIGEST_FLAG_ENABLED
:
223 case DRV_TLV_AUTHENTICATION_METHOD
:
224 case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL
:
225 case DRV_TLV_MAX_FRAME_SIZE
:
226 case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE
:
227 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE
:
228 case DRV_TLV_ISCSI_BOOT_PROGRESS
:
229 case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
230 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
231 case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED
:
232 case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED
:
233 case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT
:
234 case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT
:
235 *tlv_group
|= QED_MFW_TLV_ISCSI
;
244 /* Returns size of the data buffer or, -1 in case TLV data is not available. */
246 qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr
*p_tlv
,
247 struct qed_mfw_tlv_generic
*p_drv_buf
,
248 struct qed_tlv_parsed_buf
*p_buf
)
250 switch (p_tlv
->tlv_type
) {
251 case DRV_TLV_FEATURE_FLAGS
:
252 if (p_drv_buf
->flags
.b_set
) {
253 memset(p_buf
->data
, 0, sizeof(u8
) * QED_TLV_DATA_MAX
);
254 p_buf
->data
[0] = p_drv_buf
->flags
.ipv4_csum_offload
?
256 p_buf
->data
[0] |= (p_drv_buf
->flags
.lso_supported
?
258 p_buf
->p_val
= p_buf
->data
;
259 return QED_MFW_TLV_FLAGS_SIZE
;
263 case DRV_TLV_LOCAL_ADMIN_ADDR
:
264 case DRV_TLV_ADDITIONAL_MAC_ADDR_1
:
265 case DRV_TLV_ADDITIONAL_MAC_ADDR_2
:
267 int idx
= p_tlv
->tlv_type
- DRV_TLV_LOCAL_ADMIN_ADDR
;
269 if (p_drv_buf
->mac_set
[idx
]) {
270 p_buf
->p_val
= p_drv_buf
->mac
[idx
];
276 case DRV_TLV_RX_FRAMES_RECEIVED
:
277 if (p_drv_buf
->rx_frames_set
) {
278 p_buf
->p_val
= &p_drv_buf
->rx_frames
;
279 return sizeof(p_drv_buf
->rx_frames
);
282 case DRV_TLV_RX_BYTES_RECEIVED
:
283 if (p_drv_buf
->rx_bytes_set
) {
284 p_buf
->p_val
= &p_drv_buf
->rx_bytes
;
285 return sizeof(p_drv_buf
->rx_bytes
);
288 case DRV_TLV_TX_FRAMES_SENT
:
289 if (p_drv_buf
->tx_frames_set
) {
290 p_buf
->p_val
= &p_drv_buf
->tx_frames
;
291 return sizeof(p_drv_buf
->tx_frames
);
294 case DRV_TLV_TX_BYTES_SENT
:
295 if (p_drv_buf
->tx_bytes_set
) {
296 p_buf
->p_val
= &p_drv_buf
->tx_bytes
;
297 return sizeof(p_drv_buf
->tx_bytes
);
308 qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr
*p_tlv
,
309 struct qed_mfw_tlv_eth
*p_drv_buf
,
310 struct qed_tlv_parsed_buf
*p_buf
)
312 switch (p_tlv
->tlv_type
) {
313 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE
:
314 if (p_drv_buf
->lso_maxoff_size_set
) {
315 p_buf
->p_val
= &p_drv_buf
->lso_maxoff_size
;
316 return sizeof(p_drv_buf
->lso_maxoff_size
);
319 case DRV_TLV_LSO_MIN_SEGMENT_COUNT
:
320 if (p_drv_buf
->lso_minseg_size_set
) {
321 p_buf
->p_val
= &p_drv_buf
->lso_minseg_size
;
322 return sizeof(p_drv_buf
->lso_minseg_size
);
325 case DRV_TLV_PROMISCUOUS_MODE
:
326 if (p_drv_buf
->prom_mode_set
) {
327 p_buf
->p_val
= &p_drv_buf
->prom_mode
;
328 return sizeof(p_drv_buf
->prom_mode
);
331 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE
:
332 if (p_drv_buf
->tx_descr_size_set
) {
333 p_buf
->p_val
= &p_drv_buf
->tx_descr_size
;
334 return sizeof(p_drv_buf
->tx_descr_size
);
337 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE
:
338 if (p_drv_buf
->rx_descr_size_set
) {
339 p_buf
->p_val
= &p_drv_buf
->rx_descr_size
;
340 return sizeof(p_drv_buf
->rx_descr_size
);
343 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG
:
344 if (p_drv_buf
->netq_count_set
) {
345 p_buf
->p_val
= &p_drv_buf
->netq_count
;
346 return sizeof(p_drv_buf
->netq_count
);
349 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4
:
350 if (p_drv_buf
->tcp4_offloads_set
) {
351 p_buf
->p_val
= &p_drv_buf
->tcp4_offloads
;
352 return sizeof(p_drv_buf
->tcp4_offloads
);
355 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6
:
356 if (p_drv_buf
->tcp6_offloads_set
) {
357 p_buf
->p_val
= &p_drv_buf
->tcp6_offloads
;
358 return sizeof(p_drv_buf
->tcp6_offloads
);
361 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
362 if (p_drv_buf
->tx_descr_qdepth_set
) {
363 p_buf
->p_val
= &p_drv_buf
->tx_descr_qdepth
;
364 return sizeof(p_drv_buf
->tx_descr_qdepth
);
367 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
368 if (p_drv_buf
->rx_descr_qdepth_set
) {
369 p_buf
->p_val
= &p_drv_buf
->rx_descr_qdepth
;
370 return sizeof(p_drv_buf
->rx_descr_qdepth
);
373 case DRV_TLV_IOV_OFFLOAD
:
374 if (p_drv_buf
->iov_offload_set
) {
375 p_buf
->p_val
= &p_drv_buf
->iov_offload
;
376 return sizeof(p_drv_buf
->iov_offload
);
379 case DRV_TLV_TX_QUEUES_EMPTY
:
380 if (p_drv_buf
->txqs_empty_set
) {
381 p_buf
->p_val
= &p_drv_buf
->txqs_empty
;
382 return sizeof(p_drv_buf
->txqs_empty
);
385 case DRV_TLV_RX_QUEUES_EMPTY
:
386 if (p_drv_buf
->rxqs_empty_set
) {
387 p_buf
->p_val
= &p_drv_buf
->rxqs_empty
;
388 return sizeof(p_drv_buf
->rxqs_empty
);
391 case DRV_TLV_TX_QUEUES_FULL
:
392 if (p_drv_buf
->num_txqs_full_set
) {
393 p_buf
->p_val
= &p_drv_buf
->num_txqs_full
;
394 return sizeof(p_drv_buf
->num_txqs_full
);
397 case DRV_TLV_RX_QUEUES_FULL
:
398 if (p_drv_buf
->num_rxqs_full_set
) {
399 p_buf
->p_val
= &p_drv_buf
->num_rxqs_full
;
400 return sizeof(p_drv_buf
->num_rxqs_full
);
411 qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time
*p_time
,
412 struct qed_tlv_parsed_buf
*p_buf
)
417 /* Validate numbers */
418 if (p_time
->month
> 12)
420 if (p_time
->day
> 31)
422 if (p_time
->hour
> 23)
424 if (p_time
->min
> 59)
426 if (p_time
->msec
> 999)
428 if (p_time
->usec
> 999)
431 memset(p_buf
->data
, 0, sizeof(u8
) * QED_TLV_DATA_MAX
);
432 snprintf(p_buf
->data
, 14, "%d%d%d%d%d%d",
433 p_time
->month
, p_time
->day
,
434 p_time
->hour
, p_time
->min
, p_time
->msec
, p_time
->usec
);
436 p_buf
->p_val
= p_buf
->data
;
438 return QED_MFW_TLV_TIME_SIZE
;
442 qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr
*p_tlv
,
443 struct qed_mfw_tlv_fcoe
*p_drv_buf
,
444 struct qed_tlv_parsed_buf
*p_buf
)
446 struct qed_mfw_tlv_time
*p_time
;
449 switch (p_tlv
->tlv_type
) {
450 case DRV_TLV_SCSI_TO
:
451 if (p_drv_buf
->scsi_timeout_set
) {
452 p_buf
->p_val
= &p_drv_buf
->scsi_timeout
;
453 return sizeof(p_drv_buf
->scsi_timeout
);
456 case DRV_TLV_R_T_TOV
:
457 if (p_drv_buf
->rt_tov_set
) {
458 p_buf
->p_val
= &p_drv_buf
->rt_tov
;
459 return sizeof(p_drv_buf
->rt_tov
);
462 case DRV_TLV_R_A_TOV
:
463 if (p_drv_buf
->ra_tov_set
) {
464 p_buf
->p_val
= &p_drv_buf
->ra_tov
;
465 return sizeof(p_drv_buf
->ra_tov
);
468 case DRV_TLV_E_D_TOV
:
469 if (p_drv_buf
->ed_tov_set
) {
470 p_buf
->p_val
= &p_drv_buf
->ed_tov
;
471 return sizeof(p_drv_buf
->ed_tov
);
475 if (p_drv_buf
->cr_tov_set
) {
476 p_buf
->p_val
= &p_drv_buf
->cr_tov
;
477 return sizeof(p_drv_buf
->cr_tov
);
480 case DRV_TLV_BOOT_TYPE
:
481 if (p_drv_buf
->boot_type_set
) {
482 p_buf
->p_val
= &p_drv_buf
->boot_type
;
483 return sizeof(p_drv_buf
->boot_type
);
486 case DRV_TLV_NPIV_STATE
:
487 if (p_drv_buf
->npiv_state_set
) {
488 p_buf
->p_val
= &p_drv_buf
->npiv_state
;
489 return sizeof(p_drv_buf
->npiv_state
);
492 case DRV_TLV_NUM_OF_NPIV_IDS
:
493 if (p_drv_buf
->num_npiv_ids_set
) {
494 p_buf
->p_val
= &p_drv_buf
->num_npiv_ids
;
495 return sizeof(p_drv_buf
->num_npiv_ids
);
498 case DRV_TLV_SWITCH_NAME
:
499 if (p_drv_buf
->switch_name_set
) {
500 p_buf
->p_val
= &p_drv_buf
->switch_name
;
501 return sizeof(p_drv_buf
->switch_name
);
504 case DRV_TLV_SWITCH_PORT_NUM
:
505 if (p_drv_buf
->switch_portnum_set
) {
506 p_buf
->p_val
= &p_drv_buf
->switch_portnum
;
507 return sizeof(p_drv_buf
->switch_portnum
);
510 case DRV_TLV_SWITCH_PORT_ID
:
511 if (p_drv_buf
->switch_portid_set
) {
512 p_buf
->p_val
= &p_drv_buf
->switch_portid
;
513 return sizeof(p_drv_buf
->switch_portid
);
516 case DRV_TLV_VENDOR_NAME
:
517 if (p_drv_buf
->vendor_name_set
) {
518 p_buf
->p_val
= &p_drv_buf
->vendor_name
;
519 return sizeof(p_drv_buf
->vendor_name
);
522 case DRV_TLV_SWITCH_MODEL
:
523 if (p_drv_buf
->switch_model_set
) {
524 p_buf
->p_val
= &p_drv_buf
->switch_model
;
525 return sizeof(p_drv_buf
->switch_model
);
528 case DRV_TLV_SWITCH_FW_VER
:
529 if (p_drv_buf
->switch_fw_version_set
) {
530 p_buf
->p_val
= &p_drv_buf
->switch_fw_version
;
531 return sizeof(p_drv_buf
->switch_fw_version
);
534 case DRV_TLV_QOS_PRIORITY_PER_802_1P
:
535 if (p_drv_buf
->qos_pri_set
) {
536 p_buf
->p_val
= &p_drv_buf
->qos_pri
;
537 return sizeof(p_drv_buf
->qos_pri
);
540 case DRV_TLV_PORT_ALIAS
:
541 if (p_drv_buf
->port_alias_set
) {
542 p_buf
->p_val
= &p_drv_buf
->port_alias
;
543 return sizeof(p_drv_buf
->port_alias
);
546 case DRV_TLV_PORT_STATE
:
547 if (p_drv_buf
->port_state_set
) {
548 p_buf
->p_val
= &p_drv_buf
->port_state
;
549 return sizeof(p_drv_buf
->port_state
);
552 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE
:
553 if (p_drv_buf
->fip_tx_descr_size_set
) {
554 p_buf
->p_val
= &p_drv_buf
->fip_tx_descr_size
;
555 return sizeof(p_drv_buf
->fip_tx_descr_size
);
558 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE
:
559 if (p_drv_buf
->fip_rx_descr_size_set
) {
560 p_buf
->p_val
= &p_drv_buf
->fip_rx_descr_size
;
561 return sizeof(p_drv_buf
->fip_rx_descr_size
);
564 case DRV_TLV_LINK_FAILURE_COUNT
:
565 if (p_drv_buf
->link_failures_set
) {
566 p_buf
->p_val
= &p_drv_buf
->link_failures
;
567 return sizeof(p_drv_buf
->link_failures
);
570 case DRV_TLV_FCOE_BOOT_PROGRESS
:
571 if (p_drv_buf
->fcoe_boot_progress_set
) {
572 p_buf
->p_val
= &p_drv_buf
->fcoe_boot_progress
;
573 return sizeof(p_drv_buf
->fcoe_boot_progress
);
576 case DRV_TLV_RX_BROADCAST_PACKETS
:
577 if (p_drv_buf
->rx_bcast_set
) {
578 p_buf
->p_val
= &p_drv_buf
->rx_bcast
;
579 return sizeof(p_drv_buf
->rx_bcast
);
582 case DRV_TLV_TX_BROADCAST_PACKETS
:
583 if (p_drv_buf
->tx_bcast_set
) {
584 p_buf
->p_val
= &p_drv_buf
->tx_bcast
;
585 return sizeof(p_drv_buf
->tx_bcast
);
588 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
589 if (p_drv_buf
->fcoe_txq_depth_set
) {
590 p_buf
->p_val
= &p_drv_buf
->fcoe_txq_depth
;
591 return sizeof(p_drv_buf
->fcoe_txq_depth
);
594 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
595 if (p_drv_buf
->fcoe_rxq_depth_set
) {
596 p_buf
->p_val
= &p_drv_buf
->fcoe_rxq_depth
;
597 return sizeof(p_drv_buf
->fcoe_rxq_depth
);
600 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED
:
601 if (p_drv_buf
->fcoe_rx_frames_set
) {
602 p_buf
->p_val
= &p_drv_buf
->fcoe_rx_frames
;
603 return sizeof(p_drv_buf
->fcoe_rx_frames
);
606 case DRV_TLV_FCOE_RX_BYTES_RECEIVED
:
607 if (p_drv_buf
->fcoe_rx_bytes_set
) {
608 p_buf
->p_val
= &p_drv_buf
->fcoe_rx_bytes
;
609 return sizeof(p_drv_buf
->fcoe_rx_bytes
);
612 case DRV_TLV_FCOE_TX_FRAMES_SENT
:
613 if (p_drv_buf
->fcoe_tx_frames_set
) {
614 p_buf
->p_val
= &p_drv_buf
->fcoe_tx_frames
;
615 return sizeof(p_drv_buf
->fcoe_tx_frames
);
618 case DRV_TLV_FCOE_TX_BYTES_SENT
:
619 if (p_drv_buf
->fcoe_tx_bytes_set
) {
620 p_buf
->p_val
= &p_drv_buf
->fcoe_tx_bytes
;
621 return sizeof(p_drv_buf
->fcoe_tx_bytes
);
624 case DRV_TLV_CRC_ERROR_COUNT
:
625 if (p_drv_buf
->crc_count_set
) {
626 p_buf
->p_val
= &p_drv_buf
->crc_count
;
627 return sizeof(p_drv_buf
->crc_count
);
630 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID
:
631 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID
:
632 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID
:
633 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID
:
634 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID
:
635 idx
= (p_tlv
->tlv_type
-
636 DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID
) / 2;
638 if (p_drv_buf
->crc_err_src_fcid_set
[idx
]) {
639 p_buf
->p_val
= &p_drv_buf
->crc_err_src_fcid
[idx
];
640 return sizeof(p_drv_buf
->crc_err_src_fcid
[idx
]);
643 case DRV_TLV_CRC_ERROR_1_TIMESTAMP
:
644 case DRV_TLV_CRC_ERROR_2_TIMESTAMP
:
645 case DRV_TLV_CRC_ERROR_3_TIMESTAMP
:
646 case DRV_TLV_CRC_ERROR_4_TIMESTAMP
:
647 case DRV_TLV_CRC_ERROR_5_TIMESTAMP
:
648 idx
= (p_tlv
->tlv_type
- DRV_TLV_CRC_ERROR_1_TIMESTAMP
) / 2;
650 return qed_mfw_get_tlv_time_value(&p_drv_buf
->crc_err
[idx
],
652 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT
:
653 if (p_drv_buf
->losync_err_set
) {
654 p_buf
->p_val
= &p_drv_buf
->losync_err
;
655 return sizeof(p_drv_buf
->losync_err
);
658 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS
:
659 if (p_drv_buf
->losig_err_set
) {
660 p_buf
->p_val
= &p_drv_buf
->losig_err
;
661 return sizeof(p_drv_buf
->losig_err
);
664 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT
:
665 if (p_drv_buf
->primtive_err_set
) {
666 p_buf
->p_val
= &p_drv_buf
->primtive_err
;
667 return sizeof(p_drv_buf
->primtive_err
);
670 case DRV_TLV_DISPARITY_ERROR_COUNT
:
671 if (p_drv_buf
->disparity_err_set
) {
672 p_buf
->p_val
= &p_drv_buf
->disparity_err
;
673 return sizeof(p_drv_buf
->disparity_err
);
676 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT
:
677 if (p_drv_buf
->code_violation_err_set
) {
678 p_buf
->p_val
= &p_drv_buf
->code_violation_err
;
679 return sizeof(p_drv_buf
->code_violation_err
);
682 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1
:
683 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2
:
684 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3
:
685 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4
:
686 idx
= p_tlv
->tlv_type
-
687 DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1
;
688 if (p_drv_buf
->flogi_param_set
[idx
]) {
689 p_buf
->p_val
= &p_drv_buf
->flogi_param
[idx
];
690 return sizeof(p_drv_buf
->flogi_param
[idx
]);
693 case DRV_TLV_LAST_FLOGI_TIMESTAMP
:
694 return qed_mfw_get_tlv_time_value(&p_drv_buf
->flogi_tstamp
,
696 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1
:
697 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2
:
698 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3
:
699 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4
:
700 idx
= p_tlv
->tlv_type
-
701 DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1
;
703 if (p_drv_buf
->flogi_acc_param_set
[idx
]) {
704 p_buf
->p_val
= &p_drv_buf
->flogi_acc_param
[idx
];
705 return sizeof(p_drv_buf
->flogi_acc_param
[idx
]);
708 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP
:
709 return qed_mfw_get_tlv_time_value(&p_drv_buf
->flogi_acc_tstamp
,
711 case DRV_TLV_LAST_FLOGI_RJT
:
712 if (p_drv_buf
->flogi_rjt_set
) {
713 p_buf
->p_val
= &p_drv_buf
->flogi_rjt
;
714 return sizeof(p_drv_buf
->flogi_rjt
);
717 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP
:
718 return qed_mfw_get_tlv_time_value(&p_drv_buf
->flogi_rjt_tstamp
,
720 case DRV_TLV_FDISCS_SENT_COUNT
:
721 if (p_drv_buf
->fdiscs_set
) {
722 p_buf
->p_val
= &p_drv_buf
->fdiscs
;
723 return sizeof(p_drv_buf
->fdiscs
);
726 case DRV_TLV_FDISC_ACCS_RECEIVED
:
727 if (p_drv_buf
->fdisc_acc_set
) {
728 p_buf
->p_val
= &p_drv_buf
->fdisc_acc
;
729 return sizeof(p_drv_buf
->fdisc_acc
);
732 case DRV_TLV_FDISC_RJTS_RECEIVED
:
733 if (p_drv_buf
->fdisc_rjt_set
) {
734 p_buf
->p_val
= &p_drv_buf
->fdisc_rjt
;
735 return sizeof(p_drv_buf
->fdisc_rjt
);
738 case DRV_TLV_PLOGI_SENT_COUNT
:
739 if (p_drv_buf
->plogi_set
) {
740 p_buf
->p_val
= &p_drv_buf
->plogi
;
741 return sizeof(p_drv_buf
->plogi
);
744 case DRV_TLV_PLOGI_ACCS_RECEIVED
:
745 if (p_drv_buf
->plogi_acc_set
) {
746 p_buf
->p_val
= &p_drv_buf
->plogi_acc
;
747 return sizeof(p_drv_buf
->plogi_acc
);
750 case DRV_TLV_PLOGI_RJTS_RECEIVED
:
751 if (p_drv_buf
->plogi_rjt_set
) {
752 p_buf
->p_val
= &p_drv_buf
->plogi_rjt
;
753 return sizeof(p_drv_buf
->plogi_rjt
);
756 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID
:
757 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID
:
758 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID
:
759 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID
:
760 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID
:
761 idx
= (p_tlv
->tlv_type
-
762 DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID
) / 2;
764 if (p_drv_buf
->plogi_dst_fcid_set
[idx
]) {
765 p_buf
->p_val
= &p_drv_buf
->plogi_dst_fcid
[idx
];
766 return sizeof(p_drv_buf
->plogi_dst_fcid
[idx
]);
769 case DRV_TLV_PLOGI_1_TIMESTAMP
:
770 case DRV_TLV_PLOGI_2_TIMESTAMP
:
771 case DRV_TLV_PLOGI_3_TIMESTAMP
:
772 case DRV_TLV_PLOGI_4_TIMESTAMP
:
773 case DRV_TLV_PLOGI_5_TIMESTAMP
:
774 idx
= (p_tlv
->tlv_type
- DRV_TLV_PLOGI_1_TIMESTAMP
) / 2;
776 return qed_mfw_get_tlv_time_value(&p_drv_buf
->plogi_tstamp
[idx
],
778 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID
:
779 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID
:
780 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID
:
781 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID
:
782 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID
:
783 idx
= (p_tlv
->tlv_type
-
784 DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID
) / 2;
786 if (p_drv_buf
->plogi_acc_src_fcid_set
[idx
]) {
787 p_buf
->p_val
= &p_drv_buf
->plogi_acc_src_fcid
[idx
];
788 return sizeof(p_drv_buf
->plogi_acc_src_fcid
[idx
]);
791 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP
:
792 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP
:
793 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP
:
794 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP
:
795 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP
:
796 idx
= (p_tlv
->tlv_type
- DRV_TLV_PLOGI_1_ACC_TIMESTAMP
) / 2;
797 p_time
= &p_drv_buf
->plogi_acc_tstamp
[idx
];
799 return qed_mfw_get_tlv_time_value(p_time
, p_buf
);
800 case DRV_TLV_LOGOS_ISSUED
:
801 if (p_drv_buf
->tx_plogos_set
) {
802 p_buf
->p_val
= &p_drv_buf
->tx_plogos
;
803 return sizeof(p_drv_buf
->tx_plogos
);
806 case DRV_TLV_LOGO_ACCS_RECEIVED
:
807 if (p_drv_buf
->plogo_acc_set
) {
808 p_buf
->p_val
= &p_drv_buf
->plogo_acc
;
809 return sizeof(p_drv_buf
->plogo_acc
);
812 case DRV_TLV_LOGO_RJTS_RECEIVED
:
813 if (p_drv_buf
->plogo_rjt_set
) {
814 p_buf
->p_val
= &p_drv_buf
->plogo_rjt
;
815 return sizeof(p_drv_buf
->plogo_rjt
);
818 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID
:
819 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID
:
820 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID
:
821 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID
:
822 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID
:
823 idx
= (p_tlv
->tlv_type
- DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID
) /
826 if (p_drv_buf
->plogo_src_fcid_set
[idx
]) {
827 p_buf
->p_val
= &p_drv_buf
->plogo_src_fcid
[idx
];
828 return sizeof(p_drv_buf
->plogo_src_fcid
[idx
]);
831 case DRV_TLV_LOGO_1_TIMESTAMP
:
832 case DRV_TLV_LOGO_2_TIMESTAMP
:
833 case DRV_TLV_LOGO_3_TIMESTAMP
:
834 case DRV_TLV_LOGO_4_TIMESTAMP
:
835 case DRV_TLV_LOGO_5_TIMESTAMP
:
836 idx
= (p_tlv
->tlv_type
- DRV_TLV_LOGO_1_TIMESTAMP
) / 2;
838 return qed_mfw_get_tlv_time_value(&p_drv_buf
->plogo_tstamp
[idx
],
840 case DRV_TLV_LOGOS_RECEIVED
:
841 if (p_drv_buf
->rx_logos_set
) {
842 p_buf
->p_val
= &p_drv_buf
->rx_logos
;
843 return sizeof(p_drv_buf
->rx_logos
);
846 case DRV_TLV_ACCS_ISSUED
:
847 if (p_drv_buf
->tx_accs_set
) {
848 p_buf
->p_val
= &p_drv_buf
->tx_accs
;
849 return sizeof(p_drv_buf
->tx_accs
);
852 case DRV_TLV_PRLIS_ISSUED
:
853 if (p_drv_buf
->tx_prlis_set
) {
854 p_buf
->p_val
= &p_drv_buf
->tx_prlis
;
855 return sizeof(p_drv_buf
->tx_prlis
);
858 case DRV_TLV_ACCS_RECEIVED
:
859 if (p_drv_buf
->rx_accs_set
) {
860 p_buf
->p_val
= &p_drv_buf
->rx_accs
;
861 return sizeof(p_drv_buf
->rx_accs
);
864 case DRV_TLV_ABTS_SENT_COUNT
:
865 if (p_drv_buf
->tx_abts_set
) {
866 p_buf
->p_val
= &p_drv_buf
->tx_abts
;
867 return sizeof(p_drv_buf
->tx_abts
);
870 case DRV_TLV_ABTS_ACCS_RECEIVED
:
871 if (p_drv_buf
->rx_abts_acc_set
) {
872 p_buf
->p_val
= &p_drv_buf
->rx_abts_acc
;
873 return sizeof(p_drv_buf
->rx_abts_acc
);
876 case DRV_TLV_ABTS_RJTS_RECEIVED
:
877 if (p_drv_buf
->rx_abts_rjt_set
) {
878 p_buf
->p_val
= &p_drv_buf
->rx_abts_rjt
;
879 return sizeof(p_drv_buf
->rx_abts_rjt
);
882 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID
:
883 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID
:
884 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID
:
885 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID
:
886 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID
:
887 idx
= (p_tlv
->tlv_type
-
888 DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID
) / 2;
890 if (p_drv_buf
->abts_dst_fcid_set
[idx
]) {
891 p_buf
->p_val
= &p_drv_buf
->abts_dst_fcid
[idx
];
892 return sizeof(p_drv_buf
->abts_dst_fcid
[idx
]);
895 case DRV_TLV_ABTS_1_TIMESTAMP
:
896 case DRV_TLV_ABTS_2_TIMESTAMP
:
897 case DRV_TLV_ABTS_3_TIMESTAMP
:
898 case DRV_TLV_ABTS_4_TIMESTAMP
:
899 case DRV_TLV_ABTS_5_TIMESTAMP
:
900 idx
= (p_tlv
->tlv_type
- DRV_TLV_ABTS_1_TIMESTAMP
) / 2;
902 return qed_mfw_get_tlv_time_value(&p_drv_buf
->abts_tstamp
[idx
],
904 case DRV_TLV_RSCNS_RECEIVED
:
905 if (p_drv_buf
->rx_rscn_set
) {
906 p_buf
->p_val
= &p_drv_buf
->rx_rscn
;
907 return sizeof(p_drv_buf
->rx_rscn
);
910 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1
:
911 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2
:
912 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3
:
913 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4
:
914 idx
= p_tlv
->tlv_type
- DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1
;
916 if (p_drv_buf
->rx_rscn_nport_set
[idx
]) {
917 p_buf
->p_val
= &p_drv_buf
->rx_rscn_nport
[idx
];
918 return sizeof(p_drv_buf
->rx_rscn_nport
[idx
]);
921 case DRV_TLV_LUN_RESETS_ISSUED
:
922 if (p_drv_buf
->tx_lun_rst_set
) {
923 p_buf
->p_val
= &p_drv_buf
->tx_lun_rst
;
924 return sizeof(p_drv_buf
->tx_lun_rst
);
927 case DRV_TLV_ABORT_TASK_SETS_ISSUED
:
928 if (p_drv_buf
->abort_task_sets_set
) {
929 p_buf
->p_val
= &p_drv_buf
->abort_task_sets
;
930 return sizeof(p_drv_buf
->abort_task_sets
);
933 case DRV_TLV_TPRLOS_SENT
:
934 if (p_drv_buf
->tx_tprlos_set
) {
935 p_buf
->p_val
= &p_drv_buf
->tx_tprlos
;
936 return sizeof(p_drv_buf
->tx_tprlos
);
939 case DRV_TLV_NOS_SENT_COUNT
:
940 if (p_drv_buf
->tx_nos_set
) {
941 p_buf
->p_val
= &p_drv_buf
->tx_nos
;
942 return sizeof(p_drv_buf
->tx_nos
);
945 case DRV_TLV_NOS_RECEIVED_COUNT
:
946 if (p_drv_buf
->rx_nos_set
) {
947 p_buf
->p_val
= &p_drv_buf
->rx_nos
;
948 return sizeof(p_drv_buf
->rx_nos
);
951 case DRV_TLV_OLS_COUNT
:
952 if (p_drv_buf
->ols_set
) {
953 p_buf
->p_val
= &p_drv_buf
->ols
;
954 return sizeof(p_drv_buf
->ols
);
957 case DRV_TLV_LR_COUNT
:
958 if (p_drv_buf
->lr_set
) {
959 p_buf
->p_val
= &p_drv_buf
->lr
;
960 return sizeof(p_drv_buf
->lr
);
963 case DRV_TLV_LRR_COUNT
:
964 if (p_drv_buf
->lrr_set
) {
965 p_buf
->p_val
= &p_drv_buf
->lrr
;
966 return sizeof(p_drv_buf
->lrr
);
969 case DRV_TLV_LIP_SENT_COUNT
:
970 if (p_drv_buf
->tx_lip_set
) {
971 p_buf
->p_val
= &p_drv_buf
->tx_lip
;
972 return sizeof(p_drv_buf
->tx_lip
);
975 case DRV_TLV_LIP_RECEIVED_COUNT
:
976 if (p_drv_buf
->rx_lip_set
) {
977 p_buf
->p_val
= &p_drv_buf
->rx_lip
;
978 return sizeof(p_drv_buf
->rx_lip
);
981 case DRV_TLV_EOFA_COUNT
:
982 if (p_drv_buf
->eofa_set
) {
983 p_buf
->p_val
= &p_drv_buf
->eofa
;
984 return sizeof(p_drv_buf
->eofa
);
987 case DRV_TLV_EOFNI_COUNT
:
988 if (p_drv_buf
->eofni_set
) {
989 p_buf
->p_val
= &p_drv_buf
->eofni
;
990 return sizeof(p_drv_buf
->eofni
);
993 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT
:
994 if (p_drv_buf
->scsi_chks_set
) {
995 p_buf
->p_val
= &p_drv_buf
->scsi_chks
;
996 return sizeof(p_drv_buf
->scsi_chks
);
999 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT
:
1000 if (p_drv_buf
->scsi_cond_met_set
) {
1001 p_buf
->p_val
= &p_drv_buf
->scsi_cond_met
;
1002 return sizeof(p_drv_buf
->scsi_cond_met
);
1005 case DRV_TLV_SCSI_STATUS_BUSY_COUNT
:
1006 if (p_drv_buf
->scsi_busy_set
) {
1007 p_buf
->p_val
= &p_drv_buf
->scsi_busy
;
1008 return sizeof(p_drv_buf
->scsi_busy
);
1011 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT
:
1012 if (p_drv_buf
->scsi_inter_set
) {
1013 p_buf
->p_val
= &p_drv_buf
->scsi_inter
;
1014 return sizeof(p_drv_buf
->scsi_inter
);
1017 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT
:
1018 if (p_drv_buf
->scsi_inter_cond_met_set
) {
1019 p_buf
->p_val
= &p_drv_buf
->scsi_inter_cond_met
;
1020 return sizeof(p_drv_buf
->scsi_inter_cond_met
);
1023 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT
:
1024 if (p_drv_buf
->scsi_rsv_conflicts_set
) {
1025 p_buf
->p_val
= &p_drv_buf
->scsi_rsv_conflicts
;
1026 return sizeof(p_drv_buf
->scsi_rsv_conflicts
);
1029 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT
:
1030 if (p_drv_buf
->scsi_tsk_full_set
) {
1031 p_buf
->p_val
= &p_drv_buf
->scsi_tsk_full
;
1032 return sizeof(p_drv_buf
->scsi_tsk_full
);
1035 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT
:
1036 if (p_drv_buf
->scsi_aca_active_set
) {
1037 p_buf
->p_val
= &p_drv_buf
->scsi_aca_active
;
1038 return sizeof(p_drv_buf
->scsi_aca_active
);
1041 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT
:
1042 if (p_drv_buf
->scsi_tsk_abort_set
) {
1043 p_buf
->p_val
= &p_drv_buf
->scsi_tsk_abort
;
1044 return sizeof(p_drv_buf
->scsi_tsk_abort
);
1047 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ
:
1048 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ
:
1049 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ
:
1050 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ
:
1051 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ
:
1052 idx
= (p_tlv
->tlv_type
-
1053 DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ
) / 2;
1055 if (p_drv_buf
->scsi_rx_chk_set
[idx
]) {
1056 p_buf
->p_val
= &p_drv_buf
->scsi_rx_chk
[idx
];
1057 return sizeof(p_drv_buf
->scsi_rx_chk
[idx
]);
1060 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP
:
1061 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP
:
1062 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP
:
1063 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP
:
1064 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP
:
1065 idx
= (p_tlv
->tlv_type
- DRV_TLV_SCSI_CHECK_1_TIMESTAMP
) / 2;
1066 p_time
= &p_drv_buf
->scsi_chk_tstamp
[idx
];
1068 return qed_mfw_get_tlv_time_value(p_time
, p_buf
);
1077 qed_mfw_get_iscsi_tlv_value(struct qed_drv_tlv_hdr
*p_tlv
,
1078 struct qed_mfw_tlv_iscsi
*p_drv_buf
,
1079 struct qed_tlv_parsed_buf
*p_buf
)
1081 switch (p_tlv
->tlv_type
) {
1082 case DRV_TLV_TARGET_LLMNR_ENABLED
:
1083 if (p_drv_buf
->target_llmnr_set
) {
1084 p_buf
->p_val
= &p_drv_buf
->target_llmnr
;
1085 return sizeof(p_drv_buf
->target_llmnr
);
1088 case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED
:
1089 if (p_drv_buf
->header_digest_set
) {
1090 p_buf
->p_val
= &p_drv_buf
->header_digest
;
1091 return sizeof(p_drv_buf
->header_digest
);
1094 case DRV_TLV_DATA_DIGEST_FLAG_ENABLED
:
1095 if (p_drv_buf
->data_digest_set
) {
1096 p_buf
->p_val
= &p_drv_buf
->data_digest
;
1097 return sizeof(p_drv_buf
->data_digest
);
1100 case DRV_TLV_AUTHENTICATION_METHOD
:
1101 if (p_drv_buf
->auth_method_set
) {
1102 p_buf
->p_val
= &p_drv_buf
->auth_method
;
1103 return sizeof(p_drv_buf
->auth_method
);
1106 case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL
:
1107 if (p_drv_buf
->boot_taget_portal_set
) {
1108 p_buf
->p_val
= &p_drv_buf
->boot_taget_portal
;
1109 return sizeof(p_drv_buf
->boot_taget_portal
);
1112 case DRV_TLV_MAX_FRAME_SIZE
:
1113 if (p_drv_buf
->frame_size_set
) {
1114 p_buf
->p_val
= &p_drv_buf
->frame_size
;
1115 return sizeof(p_drv_buf
->frame_size
);
1118 case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE
:
1119 if (p_drv_buf
->tx_desc_size_set
) {
1120 p_buf
->p_val
= &p_drv_buf
->tx_desc_size
;
1121 return sizeof(p_drv_buf
->tx_desc_size
);
1124 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE
:
1125 if (p_drv_buf
->rx_desc_size_set
) {
1126 p_buf
->p_val
= &p_drv_buf
->rx_desc_size
;
1127 return sizeof(p_drv_buf
->rx_desc_size
);
1130 case DRV_TLV_ISCSI_BOOT_PROGRESS
:
1131 if (p_drv_buf
->boot_progress_set
) {
1132 p_buf
->p_val
= &p_drv_buf
->boot_progress
;
1133 return sizeof(p_drv_buf
->boot_progress
);
1136 case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH
:
1137 if (p_drv_buf
->tx_desc_qdepth_set
) {
1138 p_buf
->p_val
= &p_drv_buf
->tx_desc_qdepth
;
1139 return sizeof(p_drv_buf
->tx_desc_qdepth
);
1142 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH
:
1143 if (p_drv_buf
->rx_desc_qdepth_set
) {
1144 p_buf
->p_val
= &p_drv_buf
->rx_desc_qdepth
;
1145 return sizeof(p_drv_buf
->rx_desc_qdepth
);
1148 case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED
:
1149 if (p_drv_buf
->rx_frames_set
) {
1150 p_buf
->p_val
= &p_drv_buf
->rx_frames
;
1151 return sizeof(p_drv_buf
->rx_frames
);
1154 case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED
:
1155 if (p_drv_buf
->rx_bytes_set
) {
1156 p_buf
->p_val
= &p_drv_buf
->rx_bytes
;
1157 return sizeof(p_drv_buf
->rx_bytes
);
1160 case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT
:
1161 if (p_drv_buf
->tx_frames_set
) {
1162 p_buf
->p_val
= &p_drv_buf
->tx_frames
;
1163 return sizeof(p_drv_buf
->tx_frames
);
1166 case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT
:
1167 if (p_drv_buf
->tx_bytes_set
) {
1168 p_buf
->p_val
= &p_drv_buf
->tx_bytes
;
1169 return sizeof(p_drv_buf
->tx_bytes
);
1179 static int qed_mfw_update_tlvs(struct qed_hwfn
*p_hwfn
,
1180 u8 tlv_group
, u8
*p_mfw_buf
, u32 size
)
1182 union qed_mfw_tlv_data
*p_tlv_data
;
1183 struct qed_tlv_parsed_buf buffer
;
1184 struct qed_drv_tlv_hdr tlv
;
1189 p_tlv_data
= vzalloc(sizeof(*p_tlv_data
));
1193 if (qed_mfw_fill_tlv_data(p_hwfn
, tlv_group
, p_tlv_data
)) {
1198 memset(&tlv
, 0, sizeof(tlv
));
1199 for (offset
= 0; offset
< size
;
1200 offset
+= sizeof(tlv
) + sizeof(u32
) * tlv
.tlv_length
) {
1201 p_tlv
= &p_mfw_buf
[offset
];
1202 tlv
.tlv_type
= TLV_TYPE(p_tlv
);
1203 tlv
.tlv_length
= TLV_LENGTH(p_tlv
);
1204 tlv
.tlv_flags
= TLV_FLAGS(p_tlv
);
1206 DP_VERBOSE(p_hwfn
, QED_MSG_SP
,
1207 "Type %d length = %d flags = 0x%x\n", tlv
.tlv_type
,
1208 tlv
.tlv_length
, tlv
.tlv_flags
);
1210 if (tlv_group
== QED_MFW_TLV_GENERIC
)
1211 len
= qed_mfw_get_gen_tlv_value(&tlv
,
1212 &p_tlv_data
->generic
,
1214 else if (tlv_group
== QED_MFW_TLV_ETH
)
1215 len
= qed_mfw_get_eth_tlv_value(&tlv
,
1218 else if (tlv_group
== QED_MFW_TLV_FCOE
)
1219 len
= qed_mfw_get_fcoe_tlv_value(&tlv
,
1223 len
= qed_mfw_get_iscsi_tlv_value(&tlv
,
1228 WARN(len
> 4 * tlv
.tlv_length
,
1229 "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
1230 len
, 4 * tlv
.tlv_length
);
1231 len
= min_t(int, len
, 4 * tlv
.tlv_length
);
1232 tlv
.tlv_flags
|= QED_DRV_TLV_FLAGS_CHANGED
;
1233 TLV_FLAGS(p_tlv
) = tlv
.tlv_flags
;
1234 memcpy(p_mfw_buf
+ offset
+ sizeof(tlv
),
1244 int qed_mfw_process_tlv_req(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
1246 u32 addr
, size
, offset
, resp
, param
, val
, global_offsize
, global_addr
;
1247 u8 tlv_group
= 0, id
, *p_mfw_buf
= NULL
, *p_temp
;
1248 struct qed_drv_tlv_hdr tlv
;
1251 addr
= SECTION_OFFSIZE_ADDR(p_hwfn
->mcp_info
->public_base
,
1253 global_offsize
= qed_rd(p_hwfn
, p_ptt
, addr
);
1254 global_addr
= SECTION_ADDR(global_offsize
, 0);
1255 addr
= global_addr
+ offsetof(struct public_global
, data_ptr
);
1256 addr
= qed_rd(p_hwfn
, p_ptt
, addr
);
1257 size
= qed_rd(p_hwfn
, p_ptt
, global_addr
+
1258 offsetof(struct public_global
, data_size
));
1261 DP_NOTICE(p_hwfn
, "Invalid TLV req size = %d\n", size
);
1265 p_mfw_buf
= vzalloc(size
);
1267 DP_NOTICE(p_hwfn
, "Failed allocate memory for p_mfw_buf\n");
1271 /* Read the TLV request to local buffer. MFW represents the TLV in
1272 * little endian format and mcp returns it bigendian format. Hence
1273 * driver need to convert data to little endian first and then do the
1274 * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
1277 for (offset
= 0; offset
< size
; offset
+= sizeof(u32
)) {
1278 val
= qed_rd(p_hwfn
, p_ptt
, addr
+ offset
);
1279 val
= be32_to_cpu((__force __be32
)val
);
1280 memcpy(&p_mfw_buf
[offset
], &val
, sizeof(u32
));
1283 /* Parse the headers to enumerate the requested TLV groups */
1284 for (offset
= 0; offset
< size
;
1285 offset
+= sizeof(tlv
) + sizeof(u32
) * tlv
.tlv_length
) {
1286 p_temp
= &p_mfw_buf
[offset
];
1287 tlv
.tlv_type
= TLV_TYPE(p_temp
);
1288 tlv
.tlv_length
= TLV_LENGTH(p_temp
);
1289 if (qed_mfw_get_tlv_group(tlv
.tlv_type
, &tlv_group
))
1290 DP_VERBOSE(p_hwfn
, NETIF_MSG_DRV
,
1291 "Un recognized TLV %d\n", tlv
.tlv_type
);
1294 /* Sanitize the TLV groups according to personality */
1295 if ((tlv_group
& QED_MFW_TLV_ETH
) && !QED_IS_L2_PERSONALITY(p_hwfn
)) {
1296 DP_VERBOSE(p_hwfn
, QED_MSG_SP
,
1297 "Skipping L2 TLVs for non-L2 function\n");
1298 tlv_group
&= ~QED_MFW_TLV_ETH
;
1301 if ((tlv_group
& QED_MFW_TLV_FCOE
) &&
1302 p_hwfn
->hw_info
.personality
!= QED_PCI_FCOE
) {
1303 DP_VERBOSE(p_hwfn
, QED_MSG_SP
,
1304 "Skipping FCoE TLVs for non-FCoE function\n");
1305 tlv_group
&= ~QED_MFW_TLV_FCOE
;
1308 if ((tlv_group
& QED_MFW_TLV_ISCSI
) &&
1309 p_hwfn
->hw_info
.personality
!= QED_PCI_ISCSI
&&
1310 p_hwfn
->hw_info
.personality
!= QED_PCI_NVMETCP
) {
1311 DP_VERBOSE(p_hwfn
, QED_MSG_SP
,
1312 "Skipping iSCSI TLVs for non-iSCSI function\n");
1313 tlv_group
&= ~QED_MFW_TLV_ISCSI
;
1316 /* Update the TLV values in the local buffer */
1317 for (id
= QED_MFW_TLV_GENERIC
; id
< QED_MFW_TLV_MAX
; id
<<= 1) {
1319 if (qed_mfw_update_tlvs(p_hwfn
, id
, p_mfw_buf
, size
))
1323 /* Write the TLV data to shared memory. The stream of 4 bytes first need
1324 * to be mem-copied to u32 element to make it as LSB format. And then
1325 * converted to big endian as required by mcp-write.
1327 for (offset
= 0; offset
< size
; offset
+= sizeof(u32
)) {
1328 memcpy(&val
, &p_mfw_buf
[offset
], sizeof(u32
));
1329 val
= (__force u32
)cpu_to_be32(val
);
1330 qed_wr(p_hwfn
, p_ptt
, addr
+ offset
, val
);
1334 rc
= qed_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_GET_TLV_DONE
, 0, &resp
,