1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/types.h>
3 #include <asm/byteorder.h>
5 #include <linux/errno.h>
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/string.h>
9 #include <linux/vmalloc.h>
13 #include "qed_reg_addr.h"
15 #define TLV_TYPE(p) (p[0])
16 #define TLV_LENGTH(p) (p[1])
17 #define TLV_FLAGS(p) (p[3])
19 #define QED_TLV_DATA_MAX (14)
20 struct qed_tlv_parsed_buf {
21 /* To be filled with the address to set in Value field */
24 /* To be used internally in case the value has to be modified */
25 u8 data[QED_TLV_DATA_MAX];
28 static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
31 case DRV_TLV_FEATURE_FLAGS:
32 case DRV_TLV_LOCAL_ADMIN_ADDR:
33 case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
34 case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
35 case DRV_TLV_OS_DRIVER_STATES:
36 case DRV_TLV_PXE_BOOT_PROGRESS:
37 case DRV_TLV_RX_FRAMES_RECEIVED:
38 case DRV_TLV_RX_BYTES_RECEIVED:
39 case DRV_TLV_TX_FRAMES_SENT:
40 case DRV_TLV_TX_BYTES_SENT:
41 case DRV_TLV_NPIV_ENABLED:
42 case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
43 case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
44 case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
45 case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
46 case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
47 case DRV_TLV_NCSI_TX_BYTES_SENT:
48 *tlv_group |= QED_MFW_TLV_GENERIC;
50 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
51 case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
52 case DRV_TLV_PROMISCUOUS_MODE:
53 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
54 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
55 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
56 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
57 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
58 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
59 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
60 case DRV_TLV_IOV_OFFLOAD:
61 case DRV_TLV_TX_QUEUES_EMPTY:
62 case DRV_TLV_RX_QUEUES_EMPTY:
63 case DRV_TLV_TX_QUEUES_FULL:
64 case DRV_TLV_RX_QUEUES_FULL:
65 *tlv_group |= QED_MFW_TLV_ETH;
72 case DRV_TLV_BOOT_TYPE:
73 case DRV_TLV_NPIV_STATE:
74 case DRV_TLV_NUM_OF_NPIV_IDS:
75 case DRV_TLV_SWITCH_NAME:
76 case DRV_TLV_SWITCH_PORT_NUM:
77 case DRV_TLV_SWITCH_PORT_ID:
78 case DRV_TLV_VENDOR_NAME:
79 case DRV_TLV_SWITCH_MODEL:
80 case DRV_TLV_SWITCH_FW_VER:
81 case DRV_TLV_QOS_PRIORITY_PER_802_1P:
82 case DRV_TLV_PORT_ALIAS:
83 case DRV_TLV_PORT_STATE:
84 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
85 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
86 case DRV_TLV_LINK_FAILURE_COUNT:
87 case DRV_TLV_FCOE_BOOT_PROGRESS:
88 case DRV_TLV_RX_BROADCAST_PACKETS:
89 case DRV_TLV_TX_BROADCAST_PACKETS:
90 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
91 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
92 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
93 case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
94 case DRV_TLV_FCOE_TX_FRAMES_SENT:
95 case DRV_TLV_FCOE_TX_BYTES_SENT:
96 case DRV_TLV_CRC_ERROR_COUNT:
97 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
98 case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
99 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
100 case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
101 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
102 case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
103 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
104 case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
105 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
106 case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
107 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
108 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
109 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
110 case DRV_TLV_DISPARITY_ERROR_COUNT:
111 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
112 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
113 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
114 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
115 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
116 case DRV_TLV_LAST_FLOGI_TIMESTAMP:
117 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
118 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
119 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
120 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
121 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
122 case DRV_TLV_LAST_FLOGI_RJT:
123 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
124 case DRV_TLV_FDISCS_SENT_COUNT:
125 case DRV_TLV_FDISC_ACCS_RECEIVED:
126 case DRV_TLV_FDISC_RJTS_RECEIVED:
127 case DRV_TLV_PLOGI_SENT_COUNT:
128 case DRV_TLV_PLOGI_ACCS_RECEIVED:
129 case DRV_TLV_PLOGI_RJTS_RECEIVED:
130 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
131 case DRV_TLV_PLOGI_1_TIMESTAMP:
132 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
133 case DRV_TLV_PLOGI_2_TIMESTAMP:
134 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
135 case DRV_TLV_PLOGI_3_TIMESTAMP:
136 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
137 case DRV_TLV_PLOGI_4_TIMESTAMP:
138 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
139 case DRV_TLV_PLOGI_5_TIMESTAMP:
140 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
141 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
142 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
143 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
144 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
145 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
146 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
147 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
148 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
149 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
150 case DRV_TLV_LOGOS_ISSUED:
151 case DRV_TLV_LOGO_ACCS_RECEIVED:
152 case DRV_TLV_LOGO_RJTS_RECEIVED:
153 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
154 case DRV_TLV_LOGO_1_TIMESTAMP:
155 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
156 case DRV_TLV_LOGO_2_TIMESTAMP:
157 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
158 case DRV_TLV_LOGO_3_TIMESTAMP:
159 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
160 case DRV_TLV_LOGO_4_TIMESTAMP:
161 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
162 case DRV_TLV_LOGO_5_TIMESTAMP:
163 case DRV_TLV_LOGOS_RECEIVED:
164 case DRV_TLV_ACCS_ISSUED:
165 case DRV_TLV_PRLIS_ISSUED:
166 case DRV_TLV_ACCS_RECEIVED:
167 case DRV_TLV_ABTS_SENT_COUNT:
168 case DRV_TLV_ABTS_ACCS_RECEIVED:
169 case DRV_TLV_ABTS_RJTS_RECEIVED:
170 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
171 case DRV_TLV_ABTS_1_TIMESTAMP:
172 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
173 case DRV_TLV_ABTS_2_TIMESTAMP:
174 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
175 case DRV_TLV_ABTS_3_TIMESTAMP:
176 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
177 case DRV_TLV_ABTS_4_TIMESTAMP:
178 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
179 case DRV_TLV_ABTS_5_TIMESTAMP:
180 case DRV_TLV_RSCNS_RECEIVED:
181 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
182 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
183 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
184 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
185 case DRV_TLV_LUN_RESETS_ISSUED:
186 case DRV_TLV_ABORT_TASK_SETS_ISSUED:
187 case DRV_TLV_TPRLOS_SENT:
188 case DRV_TLV_NOS_SENT_COUNT:
189 case DRV_TLV_NOS_RECEIVED_COUNT:
190 case DRV_TLV_OLS_COUNT:
191 case DRV_TLV_LR_COUNT:
192 case DRV_TLV_LRR_COUNT:
193 case DRV_TLV_LIP_SENT_COUNT:
194 case DRV_TLV_LIP_RECEIVED_COUNT:
195 case DRV_TLV_EOFA_COUNT:
196 case DRV_TLV_EOFNI_COUNT:
197 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
198 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
199 case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
200 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
201 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
202 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
203 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
204 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
205 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
206 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
207 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
208 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
209 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
210 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
211 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
212 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
213 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
214 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
215 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
216 *tlv_group = QED_MFW_TLV_FCOE;
225 /* Returns size of the data buffer or, -1 in case TLV data is not available. */
227 qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
228 struct qed_mfw_tlv_generic *p_drv_buf,
229 struct qed_tlv_parsed_buf *p_buf)
231 switch (p_tlv->tlv_type) {
232 case DRV_TLV_FEATURE_FLAGS:
233 if (p_drv_buf->flags.b_set) {
234 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
235 p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
237 p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
239 p_buf->p_val = p_buf->data;
240 return QED_MFW_TLV_FLAGS_SIZE;
244 case DRV_TLV_LOCAL_ADMIN_ADDR:
245 case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
246 case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
248 int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
250 if (p_drv_buf->mac_set[idx]) {
251 p_buf->p_val = p_drv_buf->mac[idx];
257 case DRV_TLV_RX_FRAMES_RECEIVED:
258 if (p_drv_buf->rx_frames_set) {
259 p_buf->p_val = &p_drv_buf->rx_frames;
260 return sizeof(p_drv_buf->rx_frames);
263 case DRV_TLV_RX_BYTES_RECEIVED:
264 if (p_drv_buf->rx_bytes_set) {
265 p_buf->p_val = &p_drv_buf->rx_bytes;
266 return sizeof(p_drv_buf->rx_bytes);
269 case DRV_TLV_TX_FRAMES_SENT:
270 if (p_drv_buf->tx_frames_set) {
271 p_buf->p_val = &p_drv_buf->tx_frames;
272 return sizeof(p_drv_buf->tx_frames);
275 case DRV_TLV_TX_BYTES_SENT:
276 if (p_drv_buf->tx_bytes_set) {
277 p_buf->p_val = &p_drv_buf->tx_bytes;
278 return sizeof(p_drv_buf->tx_bytes);
289 qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
290 struct qed_mfw_tlv_eth *p_drv_buf,
291 struct qed_tlv_parsed_buf *p_buf)
293 switch (p_tlv->tlv_type) {
294 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
295 if (p_drv_buf->lso_maxoff_size_set) {
296 p_buf->p_val = &p_drv_buf->lso_maxoff_size;
297 return sizeof(p_drv_buf->lso_maxoff_size);
300 case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
301 if (p_drv_buf->lso_minseg_size_set) {
302 p_buf->p_val = &p_drv_buf->lso_minseg_size;
303 return sizeof(p_drv_buf->lso_minseg_size);
306 case DRV_TLV_PROMISCUOUS_MODE:
307 if (p_drv_buf->prom_mode_set) {
308 p_buf->p_val = &p_drv_buf->prom_mode;
309 return sizeof(p_drv_buf->prom_mode);
312 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
313 if (p_drv_buf->tx_descr_size_set) {
314 p_buf->p_val = &p_drv_buf->tx_descr_size;
315 return sizeof(p_drv_buf->tx_descr_size);
318 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
319 if (p_drv_buf->rx_descr_size_set) {
320 p_buf->p_val = &p_drv_buf->rx_descr_size;
321 return sizeof(p_drv_buf->rx_descr_size);
324 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
325 if (p_drv_buf->netq_count_set) {
326 p_buf->p_val = &p_drv_buf->netq_count;
327 return sizeof(p_drv_buf->netq_count);
330 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
331 if (p_drv_buf->tcp4_offloads_set) {
332 p_buf->p_val = &p_drv_buf->tcp4_offloads;
333 return sizeof(p_drv_buf->tcp4_offloads);
336 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
337 if (p_drv_buf->tcp6_offloads_set) {
338 p_buf->p_val = &p_drv_buf->tcp6_offloads;
339 return sizeof(p_drv_buf->tcp6_offloads);
342 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
343 if (p_drv_buf->tx_descr_qdepth_set) {
344 p_buf->p_val = &p_drv_buf->tx_descr_qdepth;
345 return sizeof(p_drv_buf->tx_descr_qdepth);
348 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
349 if (p_drv_buf->rx_descr_qdepth_set) {
350 p_buf->p_val = &p_drv_buf->rx_descr_qdepth;
351 return sizeof(p_drv_buf->rx_descr_qdepth);
354 case DRV_TLV_IOV_OFFLOAD:
355 if (p_drv_buf->iov_offload_set) {
356 p_buf->p_val = &p_drv_buf->iov_offload;
357 return sizeof(p_drv_buf->iov_offload);
360 case DRV_TLV_TX_QUEUES_EMPTY:
361 if (p_drv_buf->txqs_empty_set) {
362 p_buf->p_val = &p_drv_buf->txqs_empty;
363 return sizeof(p_drv_buf->txqs_empty);
366 case DRV_TLV_RX_QUEUES_EMPTY:
367 if (p_drv_buf->rxqs_empty_set) {
368 p_buf->p_val = &p_drv_buf->rxqs_empty;
369 return sizeof(p_drv_buf->rxqs_empty);
372 case DRV_TLV_TX_QUEUES_FULL:
373 if (p_drv_buf->num_txqs_full_set) {
374 p_buf->p_val = &p_drv_buf->num_txqs_full;
375 return sizeof(p_drv_buf->num_txqs_full);
378 case DRV_TLV_RX_QUEUES_FULL:
379 if (p_drv_buf->num_rxqs_full_set) {
380 p_buf->p_val = &p_drv_buf->num_rxqs_full;
381 return sizeof(p_drv_buf->num_rxqs_full);
392 qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
393 struct qed_tlv_parsed_buf *p_buf)
398 /* Validate numbers */
399 if (p_time->month > 12)
401 if (p_time->day > 31)
403 if (p_time->hour > 23)
405 if (p_time->min > 59)
407 if (p_time->msec > 999)
409 if (p_time->usec > 999)
412 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
413 snprintf(p_buf->data, 14, "%d%d%d%d%d%d",
414 p_time->month, p_time->day,
415 p_time->hour, p_time->min, p_time->msec, p_time->usec);
417 p_buf->p_val = p_buf->data;
419 return QED_MFW_TLV_TIME_SIZE;
423 qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
424 struct qed_mfw_tlv_fcoe *p_drv_buf,
425 struct qed_tlv_parsed_buf *p_buf)
427 struct qed_mfw_tlv_time *p_time;
430 switch (p_tlv->tlv_type) {
431 case DRV_TLV_SCSI_TO:
432 if (p_drv_buf->scsi_timeout_set) {
433 p_buf->p_val = &p_drv_buf->scsi_timeout;
434 return sizeof(p_drv_buf->scsi_timeout);
437 case DRV_TLV_R_T_TOV:
438 if (p_drv_buf->rt_tov_set) {
439 p_buf->p_val = &p_drv_buf->rt_tov;
440 return sizeof(p_drv_buf->rt_tov);
443 case DRV_TLV_R_A_TOV:
444 if (p_drv_buf->ra_tov_set) {
445 p_buf->p_val = &p_drv_buf->ra_tov;
446 return sizeof(p_drv_buf->ra_tov);
449 case DRV_TLV_E_D_TOV:
450 if (p_drv_buf->ed_tov_set) {
451 p_buf->p_val = &p_drv_buf->ed_tov;
452 return sizeof(p_drv_buf->ed_tov);
456 if (p_drv_buf->cr_tov_set) {
457 p_buf->p_val = &p_drv_buf->cr_tov;
458 return sizeof(p_drv_buf->cr_tov);
461 case DRV_TLV_BOOT_TYPE:
462 if (p_drv_buf->boot_type_set) {
463 p_buf->p_val = &p_drv_buf->boot_type;
464 return sizeof(p_drv_buf->boot_type);
467 case DRV_TLV_NPIV_STATE:
468 if (p_drv_buf->npiv_state_set) {
469 p_buf->p_val = &p_drv_buf->npiv_state;
470 return sizeof(p_drv_buf->npiv_state);
473 case DRV_TLV_NUM_OF_NPIV_IDS:
474 if (p_drv_buf->num_npiv_ids_set) {
475 p_buf->p_val = &p_drv_buf->num_npiv_ids;
476 return sizeof(p_drv_buf->num_npiv_ids);
479 case DRV_TLV_SWITCH_NAME:
480 if (p_drv_buf->switch_name_set) {
481 p_buf->p_val = &p_drv_buf->switch_name;
482 return sizeof(p_drv_buf->switch_name);
485 case DRV_TLV_SWITCH_PORT_NUM:
486 if (p_drv_buf->switch_portnum_set) {
487 p_buf->p_val = &p_drv_buf->switch_portnum;
488 return sizeof(p_drv_buf->switch_portnum);
491 case DRV_TLV_SWITCH_PORT_ID:
492 if (p_drv_buf->switch_portid_set) {
493 p_buf->p_val = &p_drv_buf->switch_portid;
494 return sizeof(p_drv_buf->switch_portid);
497 case DRV_TLV_VENDOR_NAME:
498 if (p_drv_buf->vendor_name_set) {
499 p_buf->p_val = &p_drv_buf->vendor_name;
500 return sizeof(p_drv_buf->vendor_name);
503 case DRV_TLV_SWITCH_MODEL:
504 if (p_drv_buf->switch_model_set) {
505 p_buf->p_val = &p_drv_buf->switch_model;
506 return sizeof(p_drv_buf->switch_model);
509 case DRV_TLV_SWITCH_FW_VER:
510 if (p_drv_buf->switch_fw_version_set) {
511 p_buf->p_val = &p_drv_buf->switch_fw_version;
512 return sizeof(p_drv_buf->switch_fw_version);
515 case DRV_TLV_QOS_PRIORITY_PER_802_1P:
516 if (p_drv_buf->qos_pri_set) {
517 p_buf->p_val = &p_drv_buf->qos_pri;
518 return sizeof(p_drv_buf->qos_pri);
521 case DRV_TLV_PORT_ALIAS:
522 if (p_drv_buf->port_alias_set) {
523 p_buf->p_val = &p_drv_buf->port_alias;
524 return sizeof(p_drv_buf->port_alias);
527 case DRV_TLV_PORT_STATE:
528 if (p_drv_buf->port_state_set) {
529 p_buf->p_val = &p_drv_buf->port_state;
530 return sizeof(p_drv_buf->port_state);
533 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
534 if (p_drv_buf->fip_tx_descr_size_set) {
535 p_buf->p_val = &p_drv_buf->fip_tx_descr_size;
536 return sizeof(p_drv_buf->fip_tx_descr_size);
539 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
540 if (p_drv_buf->fip_rx_descr_size_set) {
541 p_buf->p_val = &p_drv_buf->fip_rx_descr_size;
542 return sizeof(p_drv_buf->fip_rx_descr_size);
545 case DRV_TLV_LINK_FAILURE_COUNT:
546 if (p_drv_buf->link_failures_set) {
547 p_buf->p_val = &p_drv_buf->link_failures;
548 return sizeof(p_drv_buf->link_failures);
551 case DRV_TLV_FCOE_BOOT_PROGRESS:
552 if (p_drv_buf->fcoe_boot_progress_set) {
553 p_buf->p_val = &p_drv_buf->fcoe_boot_progress;
554 return sizeof(p_drv_buf->fcoe_boot_progress);
557 case DRV_TLV_RX_BROADCAST_PACKETS:
558 if (p_drv_buf->rx_bcast_set) {
559 p_buf->p_val = &p_drv_buf->rx_bcast;
560 return sizeof(p_drv_buf->rx_bcast);
563 case DRV_TLV_TX_BROADCAST_PACKETS:
564 if (p_drv_buf->tx_bcast_set) {
565 p_buf->p_val = &p_drv_buf->tx_bcast;
566 return sizeof(p_drv_buf->tx_bcast);
569 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
570 if (p_drv_buf->fcoe_txq_depth_set) {
571 p_buf->p_val = &p_drv_buf->fcoe_txq_depth;
572 return sizeof(p_drv_buf->fcoe_txq_depth);
575 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
576 if (p_drv_buf->fcoe_rxq_depth_set) {
577 p_buf->p_val = &p_drv_buf->fcoe_rxq_depth;
578 return sizeof(p_drv_buf->fcoe_rxq_depth);
581 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
582 if (p_drv_buf->fcoe_rx_frames_set) {
583 p_buf->p_val = &p_drv_buf->fcoe_rx_frames;
584 return sizeof(p_drv_buf->fcoe_rx_frames);
587 case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
588 if (p_drv_buf->fcoe_rx_bytes_set) {
589 p_buf->p_val = &p_drv_buf->fcoe_rx_bytes;
590 return sizeof(p_drv_buf->fcoe_rx_bytes);
593 case DRV_TLV_FCOE_TX_FRAMES_SENT:
594 if (p_drv_buf->fcoe_tx_frames_set) {
595 p_buf->p_val = &p_drv_buf->fcoe_tx_frames;
596 return sizeof(p_drv_buf->fcoe_tx_frames);
599 case DRV_TLV_FCOE_TX_BYTES_SENT:
600 if (p_drv_buf->fcoe_tx_bytes_set) {
601 p_buf->p_val = &p_drv_buf->fcoe_tx_bytes;
602 return sizeof(p_drv_buf->fcoe_tx_bytes);
605 case DRV_TLV_CRC_ERROR_COUNT:
606 if (p_drv_buf->crc_count_set) {
607 p_buf->p_val = &p_drv_buf->crc_count;
608 return sizeof(p_drv_buf->crc_count);
611 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
612 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
613 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
614 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
615 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
616 idx = (p_tlv->tlv_type -
617 DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
619 if (p_drv_buf->crc_err_src_fcid_set[idx]) {
620 p_buf->p_val = &p_drv_buf->crc_err_src_fcid[idx];
621 return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
624 case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
625 case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
626 case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
627 case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
628 case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
629 idx = (p_tlv->tlv_type - DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
631 return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
633 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
634 if (p_drv_buf->losync_err_set) {
635 p_buf->p_val = &p_drv_buf->losync_err;
636 return sizeof(p_drv_buf->losync_err);
639 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
640 if (p_drv_buf->losig_err_set) {
641 p_buf->p_val = &p_drv_buf->losig_err;
642 return sizeof(p_drv_buf->losig_err);
645 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
646 if (p_drv_buf->primtive_err_set) {
647 p_buf->p_val = &p_drv_buf->primtive_err;
648 return sizeof(p_drv_buf->primtive_err);
651 case DRV_TLV_DISPARITY_ERROR_COUNT:
652 if (p_drv_buf->disparity_err_set) {
653 p_buf->p_val = &p_drv_buf->disparity_err;
654 return sizeof(p_drv_buf->disparity_err);
657 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
658 if (p_drv_buf->code_violation_err_set) {
659 p_buf->p_val = &p_drv_buf->code_violation_err;
660 return sizeof(p_drv_buf->code_violation_err);
663 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
664 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
665 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
666 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
667 idx = p_tlv->tlv_type -
668 DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
669 if (p_drv_buf->flogi_param_set[idx]) {
670 p_buf->p_val = &p_drv_buf->flogi_param[idx];
671 return sizeof(p_drv_buf->flogi_param[idx]);
674 case DRV_TLV_LAST_FLOGI_TIMESTAMP:
675 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
677 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
678 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
679 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
680 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
681 idx = p_tlv->tlv_type -
682 DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
684 if (p_drv_buf->flogi_acc_param_set[idx]) {
685 p_buf->p_val = &p_drv_buf->flogi_acc_param[idx];
686 return sizeof(p_drv_buf->flogi_acc_param[idx]);
689 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
690 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
692 case DRV_TLV_LAST_FLOGI_RJT:
693 if (p_drv_buf->flogi_rjt_set) {
694 p_buf->p_val = &p_drv_buf->flogi_rjt;
695 return sizeof(p_drv_buf->flogi_rjt);
698 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
699 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
701 case DRV_TLV_FDISCS_SENT_COUNT:
702 if (p_drv_buf->fdiscs_set) {
703 p_buf->p_val = &p_drv_buf->fdiscs;
704 return sizeof(p_drv_buf->fdiscs);
707 case DRV_TLV_FDISC_ACCS_RECEIVED:
708 if (p_drv_buf->fdisc_acc_set) {
709 p_buf->p_val = &p_drv_buf->fdisc_acc;
710 return sizeof(p_drv_buf->fdisc_acc);
713 case DRV_TLV_FDISC_RJTS_RECEIVED:
714 if (p_drv_buf->fdisc_rjt_set) {
715 p_buf->p_val = &p_drv_buf->fdisc_rjt;
716 return sizeof(p_drv_buf->fdisc_rjt);
719 case DRV_TLV_PLOGI_SENT_COUNT:
720 if (p_drv_buf->plogi_set) {
721 p_buf->p_val = &p_drv_buf->plogi;
722 return sizeof(p_drv_buf->plogi);
725 case DRV_TLV_PLOGI_ACCS_RECEIVED:
726 if (p_drv_buf->plogi_acc_set) {
727 p_buf->p_val = &p_drv_buf->plogi_acc;
728 return sizeof(p_drv_buf->plogi_acc);
731 case DRV_TLV_PLOGI_RJTS_RECEIVED:
732 if (p_drv_buf->plogi_rjt_set) {
733 p_buf->p_val = &p_drv_buf->plogi_rjt;
734 return sizeof(p_drv_buf->plogi_rjt);
737 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
738 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
739 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
740 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
741 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
742 idx = (p_tlv->tlv_type -
743 DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
745 if (p_drv_buf->plogi_dst_fcid_set[idx]) {
746 p_buf->p_val = &p_drv_buf->plogi_dst_fcid[idx];
747 return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
750 case DRV_TLV_PLOGI_1_TIMESTAMP:
751 case DRV_TLV_PLOGI_2_TIMESTAMP:
752 case DRV_TLV_PLOGI_3_TIMESTAMP:
753 case DRV_TLV_PLOGI_4_TIMESTAMP:
754 case DRV_TLV_PLOGI_5_TIMESTAMP:
755 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
757 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
759 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
760 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
761 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
762 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
763 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
764 idx = (p_tlv->tlv_type -
765 DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
767 if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
768 p_buf->p_val = &p_drv_buf->plogi_acc_src_fcid[idx];
769 return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
772 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
773 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
774 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
775 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
776 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
777 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
778 p_time = &p_drv_buf->plogi_acc_tstamp[idx];
780 return qed_mfw_get_tlv_time_value(p_time, p_buf);
781 case DRV_TLV_LOGOS_ISSUED:
782 if (p_drv_buf->tx_plogos_set) {
783 p_buf->p_val = &p_drv_buf->tx_plogos;
784 return sizeof(p_drv_buf->tx_plogos);
787 case DRV_TLV_LOGO_ACCS_RECEIVED:
788 if (p_drv_buf->plogo_acc_set) {
789 p_buf->p_val = &p_drv_buf->plogo_acc;
790 return sizeof(p_drv_buf->plogo_acc);
793 case DRV_TLV_LOGO_RJTS_RECEIVED:
794 if (p_drv_buf->plogo_rjt_set) {
795 p_buf->p_val = &p_drv_buf->plogo_rjt;
796 return sizeof(p_drv_buf->plogo_rjt);
799 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
800 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
801 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
802 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
803 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
804 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) /
807 if (p_drv_buf->plogo_src_fcid_set[idx]) {
808 p_buf->p_val = &p_drv_buf->plogo_src_fcid[idx];
809 return sizeof(p_drv_buf->plogo_src_fcid[idx]);
812 case DRV_TLV_LOGO_1_TIMESTAMP:
813 case DRV_TLV_LOGO_2_TIMESTAMP:
814 case DRV_TLV_LOGO_3_TIMESTAMP:
815 case DRV_TLV_LOGO_4_TIMESTAMP:
816 case DRV_TLV_LOGO_5_TIMESTAMP:
817 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_TIMESTAMP) / 2;
819 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
821 case DRV_TLV_LOGOS_RECEIVED:
822 if (p_drv_buf->rx_logos_set) {
823 p_buf->p_val = &p_drv_buf->rx_logos;
824 return sizeof(p_drv_buf->rx_logos);
827 case DRV_TLV_ACCS_ISSUED:
828 if (p_drv_buf->tx_accs_set) {
829 p_buf->p_val = &p_drv_buf->tx_accs;
830 return sizeof(p_drv_buf->tx_accs);
833 case DRV_TLV_PRLIS_ISSUED:
834 if (p_drv_buf->tx_prlis_set) {
835 p_buf->p_val = &p_drv_buf->tx_prlis;
836 return sizeof(p_drv_buf->tx_prlis);
839 case DRV_TLV_ACCS_RECEIVED:
840 if (p_drv_buf->rx_accs_set) {
841 p_buf->p_val = &p_drv_buf->rx_accs;
842 return sizeof(p_drv_buf->rx_accs);
845 case DRV_TLV_ABTS_SENT_COUNT:
846 if (p_drv_buf->tx_abts_set) {
847 p_buf->p_val = &p_drv_buf->tx_abts;
848 return sizeof(p_drv_buf->tx_abts);
851 case DRV_TLV_ABTS_ACCS_RECEIVED:
852 if (p_drv_buf->rx_abts_acc_set) {
853 p_buf->p_val = &p_drv_buf->rx_abts_acc;
854 return sizeof(p_drv_buf->rx_abts_acc);
857 case DRV_TLV_ABTS_RJTS_RECEIVED:
858 if (p_drv_buf->rx_abts_rjt_set) {
859 p_buf->p_val = &p_drv_buf->rx_abts_rjt;
860 return sizeof(p_drv_buf->rx_abts_rjt);
863 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
864 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
865 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
866 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
867 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
868 idx = (p_tlv->tlv_type -
869 DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
871 if (p_drv_buf->abts_dst_fcid_set[idx]) {
872 p_buf->p_val = &p_drv_buf->abts_dst_fcid[idx];
873 return sizeof(p_drv_buf->abts_dst_fcid[idx]);
876 case DRV_TLV_ABTS_1_TIMESTAMP:
877 case DRV_TLV_ABTS_2_TIMESTAMP:
878 case DRV_TLV_ABTS_3_TIMESTAMP:
879 case DRV_TLV_ABTS_4_TIMESTAMP:
880 case DRV_TLV_ABTS_5_TIMESTAMP:
881 idx = (p_tlv->tlv_type - DRV_TLV_ABTS_1_TIMESTAMP) / 2;
883 return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
885 case DRV_TLV_RSCNS_RECEIVED:
886 if (p_drv_buf->rx_rscn_set) {
887 p_buf->p_val = &p_drv_buf->rx_rscn;
888 return sizeof(p_drv_buf->rx_rscn);
891 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
892 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
893 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
894 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
895 idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
897 if (p_drv_buf->rx_rscn_nport_set[idx]) {
898 p_buf->p_val = &p_drv_buf->rx_rscn_nport[idx];
899 return sizeof(p_drv_buf->rx_rscn_nport[idx]);
902 case DRV_TLV_LUN_RESETS_ISSUED:
903 if (p_drv_buf->tx_lun_rst_set) {
904 p_buf->p_val = &p_drv_buf->tx_lun_rst;
905 return sizeof(p_drv_buf->tx_lun_rst);
908 case DRV_TLV_ABORT_TASK_SETS_ISSUED:
909 if (p_drv_buf->abort_task_sets_set) {
910 p_buf->p_val = &p_drv_buf->abort_task_sets;
911 return sizeof(p_drv_buf->abort_task_sets);
914 case DRV_TLV_TPRLOS_SENT:
915 if (p_drv_buf->tx_tprlos_set) {
916 p_buf->p_val = &p_drv_buf->tx_tprlos;
917 return sizeof(p_drv_buf->tx_tprlos);
920 case DRV_TLV_NOS_SENT_COUNT:
921 if (p_drv_buf->tx_nos_set) {
922 p_buf->p_val = &p_drv_buf->tx_nos;
923 return sizeof(p_drv_buf->tx_nos);
926 case DRV_TLV_NOS_RECEIVED_COUNT:
927 if (p_drv_buf->rx_nos_set) {
928 p_buf->p_val = &p_drv_buf->rx_nos;
929 return sizeof(p_drv_buf->rx_nos);
932 case DRV_TLV_OLS_COUNT:
933 if (p_drv_buf->ols_set) {
934 p_buf->p_val = &p_drv_buf->ols;
935 return sizeof(p_drv_buf->ols);
938 case DRV_TLV_LR_COUNT:
939 if (p_drv_buf->lr_set) {
940 p_buf->p_val = &p_drv_buf->lr;
941 return sizeof(p_drv_buf->lr);
944 case DRV_TLV_LRR_COUNT:
945 if (p_drv_buf->lrr_set) {
946 p_buf->p_val = &p_drv_buf->lrr;
947 return sizeof(p_drv_buf->lrr);
950 case DRV_TLV_LIP_SENT_COUNT:
951 if (p_drv_buf->tx_lip_set) {
952 p_buf->p_val = &p_drv_buf->tx_lip;
953 return sizeof(p_drv_buf->tx_lip);
956 case DRV_TLV_LIP_RECEIVED_COUNT:
957 if (p_drv_buf->rx_lip_set) {
958 p_buf->p_val = &p_drv_buf->rx_lip;
959 return sizeof(p_drv_buf->rx_lip);
962 case DRV_TLV_EOFA_COUNT:
963 if (p_drv_buf->eofa_set) {
964 p_buf->p_val = &p_drv_buf->eofa;
965 return sizeof(p_drv_buf->eofa);
968 case DRV_TLV_EOFNI_COUNT:
969 if (p_drv_buf->eofni_set) {
970 p_buf->p_val = &p_drv_buf->eofni;
971 return sizeof(p_drv_buf->eofni);
974 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
975 if (p_drv_buf->scsi_chks_set) {
976 p_buf->p_val = &p_drv_buf->scsi_chks;
977 return sizeof(p_drv_buf->scsi_chks);
980 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
981 if (p_drv_buf->scsi_cond_met_set) {
982 p_buf->p_val = &p_drv_buf->scsi_cond_met;
983 return sizeof(p_drv_buf->scsi_cond_met);
986 case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
987 if (p_drv_buf->scsi_busy_set) {
988 p_buf->p_val = &p_drv_buf->scsi_busy;
989 return sizeof(p_drv_buf->scsi_busy);
992 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
993 if (p_drv_buf->scsi_inter_set) {
994 p_buf->p_val = &p_drv_buf->scsi_inter;
995 return sizeof(p_drv_buf->scsi_inter);
998 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
999 if (p_drv_buf->scsi_inter_cond_met_set) {
1000 p_buf->p_val = &p_drv_buf->scsi_inter_cond_met;
1001 return sizeof(p_drv_buf->scsi_inter_cond_met);
1004 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
1005 if (p_drv_buf->scsi_rsv_conflicts_set) {
1006 p_buf->p_val = &p_drv_buf->scsi_rsv_conflicts;
1007 return sizeof(p_drv_buf->scsi_rsv_conflicts);
1010 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
1011 if (p_drv_buf->scsi_tsk_full_set) {
1012 p_buf->p_val = &p_drv_buf->scsi_tsk_full;
1013 return sizeof(p_drv_buf->scsi_tsk_full);
1016 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
1017 if (p_drv_buf->scsi_aca_active_set) {
1018 p_buf->p_val = &p_drv_buf->scsi_aca_active;
1019 return sizeof(p_drv_buf->scsi_aca_active);
1022 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
1023 if (p_drv_buf->scsi_tsk_abort_set) {
1024 p_buf->p_val = &p_drv_buf->scsi_tsk_abort;
1025 return sizeof(p_drv_buf->scsi_tsk_abort);
1028 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
1029 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
1030 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
1031 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
1032 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
1033 idx = (p_tlv->tlv_type -
1034 DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
1036 if (p_drv_buf->scsi_rx_chk_set[idx]) {
1037 p_buf->p_val = &p_drv_buf->scsi_rx_chk[idx];
1038 return sizeof(p_drv_buf->scsi_rx_chk[idx]);
1041 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
1042 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
1043 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
1044 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
1045 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
1046 idx = (p_tlv->tlv_type - DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
1047 p_time = &p_drv_buf->scsi_chk_tstamp[idx];
1049 return qed_mfw_get_tlv_time_value(p_time, p_buf);
1057 static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
1058 u8 tlv_group, u8 *p_mfw_buf, u32 size)
1060 union qed_mfw_tlv_data *p_tlv_data;
1061 struct qed_tlv_parsed_buf buffer;
1062 struct qed_drv_tlv_hdr tlv;
1067 p_tlv_data = vzalloc(sizeof(*p_tlv_data));
1071 if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
1076 memset(&tlv, 0, sizeof(tlv));
1077 for (offset = 0; offset < size;
1078 offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1079 p_tlv = &p_mfw_buf[offset];
1080 tlv.tlv_type = TLV_TYPE(p_tlv);
1081 tlv.tlv_length = TLV_LENGTH(p_tlv);
1082 tlv.tlv_flags = TLV_FLAGS(p_tlv);
1084 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1085 "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
1086 tlv.tlv_length, tlv.tlv_flags);
1088 if (tlv_group == QED_MFW_TLV_GENERIC)
1089 len = qed_mfw_get_gen_tlv_value(&tlv,
1090 &p_tlv_data->generic,
1092 else if (tlv_group == QED_MFW_TLV_ETH)
1093 len = qed_mfw_get_eth_tlv_value(&tlv,
1096 else if (tlv_group == QED_MFW_TLV_FCOE)
1097 len = qed_mfw_get_fcoe_tlv_value(&tlv,
1102 WARN(len > 4 * tlv.tlv_length,
1103 "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
1104 len, 4 * tlv.tlv_length);
1105 len = min_t(int, len, 4 * tlv.tlv_length);
1106 tlv.tlv_flags |= QED_DRV_TLV_FLAGS_CHANGED;
1107 TLV_FLAGS(p_tlv) = tlv.tlv_flags;
1108 memcpy(p_mfw_buf + offset + sizeof(tlv),
1118 int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1120 u32 addr, size, offset, resp, param, val, global_offsize, global_addr;
1121 u8 tlv_group = 0, id, *p_mfw_buf = NULL, *p_temp;
1122 struct qed_drv_tlv_hdr tlv;
1125 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1127 global_offsize = qed_rd(p_hwfn, p_ptt, addr);
1128 global_addr = SECTION_ADDR(global_offsize, 0);
1129 addr = global_addr + offsetof(struct public_global, data_ptr);
1130 addr = qed_rd(p_hwfn, p_ptt, addr);
1131 size = qed_rd(p_hwfn, p_ptt, global_addr +
1132 offsetof(struct public_global, data_size));
1135 DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
1139 p_mfw_buf = vzalloc(size);
1141 DP_NOTICE(p_hwfn, "Failed allocate memory for p_mfw_buf\n");
1145 /* Read the TLV request to local buffer. MFW represents the TLV in
1146 * little endian format and mcp returns it bigendian format. Hence
1147 * driver need to convert data to little endian first and then do the
1148 * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
1151 for (offset = 0; offset < size; offset += sizeof(u32)) {
1152 val = qed_rd(p_hwfn, p_ptt, addr + offset);
1153 val = be32_to_cpu(val);
1154 memcpy(&p_mfw_buf[offset], &val, sizeof(u32));
1157 /* Parse the headers to enumerate the requested TLV groups */
1158 for (offset = 0; offset < size;
1159 offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1160 p_temp = &p_mfw_buf[offset];
1161 tlv.tlv_type = TLV_TYPE(p_temp);
1162 tlv.tlv_length = TLV_LENGTH(p_temp);
1163 if (qed_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
1164 DP_VERBOSE(p_hwfn, NETIF_MSG_DRV,
1165 "Un recognized TLV %d\n", tlv.tlv_type);
1168 /* Sanitize the TLV groups according to personality */
1169 if ((tlv_group & QED_MFW_TLV_ETH) && !QED_IS_L2_PERSONALITY(p_hwfn)) {
1170 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1171 "Skipping L2 TLVs for non-L2 function\n");
1172 tlv_group &= ~QED_MFW_TLV_ETH;
1175 if ((tlv_group & QED_MFW_TLV_FCOE) &&
1176 p_hwfn->hw_info.personality != QED_PCI_FCOE) {
1177 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1178 "Skipping FCoE TLVs for non-FCoE function\n");
1179 tlv_group &= ~QED_MFW_TLV_FCOE;
1182 /* Update the TLV values in the local buffer */
1183 for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
1185 if (qed_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
1189 /* Write the TLV data to shared memory. The stream of 4 bytes first need
1190 * to be mem-copied to u32 element to make it as LSB format. And then
1191 * converted to big endian as required by mcp-write.
1193 for (offset = 0; offset < size; offset += sizeof(u32)) {
1194 memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
1195 val = cpu_to_be32(val);
1196 qed_wr(p_hwfn, p_ptt, addr + offset, val);
1200 rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,