treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / net / ethernet / qlogic / qed / qed_mng_tlv.c
blob6c16158d80900f7074599dbdd05ae188f2575bd6
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/types.h>
3 #include <asm/byteorder.h>
4 #include <linux/bug.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>
10 #include "qed.h"
11 #include "qed_hw.h"
12 #include "qed_mcp.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 */
22 void *p_val;
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)
30 switch (tlv_type) {
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;
49 break;
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;
66 break;
67 case DRV_TLV_SCSI_TO:
68 case DRV_TLV_R_T_TOV:
69 case DRV_TLV_R_A_TOV:
70 case DRV_TLV_E_D_TOV:
71 case DRV_TLV_CR_TOV:
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;
217 break;
218 case DRV_TLV_TARGET_LLMNR_ENABLED:
219 case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
220 case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
221 case DRV_TLV_AUTHENTICATION_METHOD:
222 case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
223 case DRV_TLV_MAX_FRAME_SIZE:
224 case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
225 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
226 case DRV_TLV_ISCSI_BOOT_PROGRESS:
227 case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
228 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
229 case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
230 case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
231 case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
232 case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
233 *tlv_group |= QED_MFW_TLV_ISCSI;
234 break;
235 default:
236 return -EINVAL;
239 return 0;
242 /* Returns size of the data buffer or, -1 in case TLV data is not available. */
243 static int
244 qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
245 struct qed_mfw_tlv_generic *p_drv_buf,
246 struct qed_tlv_parsed_buf *p_buf)
248 switch (p_tlv->tlv_type) {
249 case DRV_TLV_FEATURE_FLAGS:
250 if (p_drv_buf->flags.b_set) {
251 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
252 p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
253 1 : 0;
254 p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
255 1 : 0) << 1;
256 p_buf->p_val = p_buf->data;
257 return QED_MFW_TLV_FLAGS_SIZE;
259 break;
261 case DRV_TLV_LOCAL_ADMIN_ADDR:
262 case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
263 case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
265 int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
267 if (p_drv_buf->mac_set[idx]) {
268 p_buf->p_val = p_drv_buf->mac[idx];
269 return ETH_ALEN;
271 break;
274 case DRV_TLV_RX_FRAMES_RECEIVED:
275 if (p_drv_buf->rx_frames_set) {
276 p_buf->p_val = &p_drv_buf->rx_frames;
277 return sizeof(p_drv_buf->rx_frames);
279 break;
280 case DRV_TLV_RX_BYTES_RECEIVED:
281 if (p_drv_buf->rx_bytes_set) {
282 p_buf->p_val = &p_drv_buf->rx_bytes;
283 return sizeof(p_drv_buf->rx_bytes);
285 break;
286 case DRV_TLV_TX_FRAMES_SENT:
287 if (p_drv_buf->tx_frames_set) {
288 p_buf->p_val = &p_drv_buf->tx_frames;
289 return sizeof(p_drv_buf->tx_frames);
291 break;
292 case DRV_TLV_TX_BYTES_SENT:
293 if (p_drv_buf->tx_bytes_set) {
294 p_buf->p_val = &p_drv_buf->tx_bytes;
295 return sizeof(p_drv_buf->tx_bytes);
297 break;
298 default:
299 break;
302 return -1;
305 static int
306 qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
307 struct qed_mfw_tlv_eth *p_drv_buf,
308 struct qed_tlv_parsed_buf *p_buf)
310 switch (p_tlv->tlv_type) {
311 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
312 if (p_drv_buf->lso_maxoff_size_set) {
313 p_buf->p_val = &p_drv_buf->lso_maxoff_size;
314 return sizeof(p_drv_buf->lso_maxoff_size);
316 break;
317 case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
318 if (p_drv_buf->lso_minseg_size_set) {
319 p_buf->p_val = &p_drv_buf->lso_minseg_size;
320 return sizeof(p_drv_buf->lso_minseg_size);
322 break;
323 case DRV_TLV_PROMISCUOUS_MODE:
324 if (p_drv_buf->prom_mode_set) {
325 p_buf->p_val = &p_drv_buf->prom_mode;
326 return sizeof(p_drv_buf->prom_mode);
328 break;
329 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
330 if (p_drv_buf->tx_descr_size_set) {
331 p_buf->p_val = &p_drv_buf->tx_descr_size;
332 return sizeof(p_drv_buf->tx_descr_size);
334 break;
335 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
336 if (p_drv_buf->rx_descr_size_set) {
337 p_buf->p_val = &p_drv_buf->rx_descr_size;
338 return sizeof(p_drv_buf->rx_descr_size);
340 break;
341 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
342 if (p_drv_buf->netq_count_set) {
343 p_buf->p_val = &p_drv_buf->netq_count;
344 return sizeof(p_drv_buf->netq_count);
346 break;
347 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
348 if (p_drv_buf->tcp4_offloads_set) {
349 p_buf->p_val = &p_drv_buf->tcp4_offloads;
350 return sizeof(p_drv_buf->tcp4_offloads);
352 break;
353 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
354 if (p_drv_buf->tcp6_offloads_set) {
355 p_buf->p_val = &p_drv_buf->tcp6_offloads;
356 return sizeof(p_drv_buf->tcp6_offloads);
358 break;
359 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
360 if (p_drv_buf->tx_descr_qdepth_set) {
361 p_buf->p_val = &p_drv_buf->tx_descr_qdepth;
362 return sizeof(p_drv_buf->tx_descr_qdepth);
364 break;
365 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
366 if (p_drv_buf->rx_descr_qdepth_set) {
367 p_buf->p_val = &p_drv_buf->rx_descr_qdepth;
368 return sizeof(p_drv_buf->rx_descr_qdepth);
370 break;
371 case DRV_TLV_IOV_OFFLOAD:
372 if (p_drv_buf->iov_offload_set) {
373 p_buf->p_val = &p_drv_buf->iov_offload;
374 return sizeof(p_drv_buf->iov_offload);
376 break;
377 case DRV_TLV_TX_QUEUES_EMPTY:
378 if (p_drv_buf->txqs_empty_set) {
379 p_buf->p_val = &p_drv_buf->txqs_empty;
380 return sizeof(p_drv_buf->txqs_empty);
382 break;
383 case DRV_TLV_RX_QUEUES_EMPTY:
384 if (p_drv_buf->rxqs_empty_set) {
385 p_buf->p_val = &p_drv_buf->rxqs_empty;
386 return sizeof(p_drv_buf->rxqs_empty);
388 break;
389 case DRV_TLV_TX_QUEUES_FULL:
390 if (p_drv_buf->num_txqs_full_set) {
391 p_buf->p_val = &p_drv_buf->num_txqs_full;
392 return sizeof(p_drv_buf->num_txqs_full);
394 break;
395 case DRV_TLV_RX_QUEUES_FULL:
396 if (p_drv_buf->num_rxqs_full_set) {
397 p_buf->p_val = &p_drv_buf->num_rxqs_full;
398 return sizeof(p_drv_buf->num_rxqs_full);
400 break;
401 default:
402 break;
405 return -1;
408 static int
409 qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
410 struct qed_tlv_parsed_buf *p_buf)
412 if (!p_time->b_set)
413 return -1;
415 /* Validate numbers */
416 if (p_time->month > 12)
417 p_time->month = 0;
418 if (p_time->day > 31)
419 p_time->day = 0;
420 if (p_time->hour > 23)
421 p_time->hour = 0;
422 if (p_time->min > 59)
423 p_time->hour = 0;
424 if (p_time->msec > 999)
425 p_time->msec = 0;
426 if (p_time->usec > 999)
427 p_time->usec = 0;
429 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
430 snprintf(p_buf->data, 14, "%d%d%d%d%d%d",
431 p_time->month, p_time->day,
432 p_time->hour, p_time->min, p_time->msec, p_time->usec);
434 p_buf->p_val = p_buf->data;
436 return QED_MFW_TLV_TIME_SIZE;
439 static int
440 qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
441 struct qed_mfw_tlv_fcoe *p_drv_buf,
442 struct qed_tlv_parsed_buf *p_buf)
444 struct qed_mfw_tlv_time *p_time;
445 u8 idx;
447 switch (p_tlv->tlv_type) {
448 case DRV_TLV_SCSI_TO:
449 if (p_drv_buf->scsi_timeout_set) {
450 p_buf->p_val = &p_drv_buf->scsi_timeout;
451 return sizeof(p_drv_buf->scsi_timeout);
453 break;
454 case DRV_TLV_R_T_TOV:
455 if (p_drv_buf->rt_tov_set) {
456 p_buf->p_val = &p_drv_buf->rt_tov;
457 return sizeof(p_drv_buf->rt_tov);
459 break;
460 case DRV_TLV_R_A_TOV:
461 if (p_drv_buf->ra_tov_set) {
462 p_buf->p_val = &p_drv_buf->ra_tov;
463 return sizeof(p_drv_buf->ra_tov);
465 break;
466 case DRV_TLV_E_D_TOV:
467 if (p_drv_buf->ed_tov_set) {
468 p_buf->p_val = &p_drv_buf->ed_tov;
469 return sizeof(p_drv_buf->ed_tov);
471 break;
472 case DRV_TLV_CR_TOV:
473 if (p_drv_buf->cr_tov_set) {
474 p_buf->p_val = &p_drv_buf->cr_tov;
475 return sizeof(p_drv_buf->cr_tov);
477 break;
478 case DRV_TLV_BOOT_TYPE:
479 if (p_drv_buf->boot_type_set) {
480 p_buf->p_val = &p_drv_buf->boot_type;
481 return sizeof(p_drv_buf->boot_type);
483 break;
484 case DRV_TLV_NPIV_STATE:
485 if (p_drv_buf->npiv_state_set) {
486 p_buf->p_val = &p_drv_buf->npiv_state;
487 return sizeof(p_drv_buf->npiv_state);
489 break;
490 case DRV_TLV_NUM_OF_NPIV_IDS:
491 if (p_drv_buf->num_npiv_ids_set) {
492 p_buf->p_val = &p_drv_buf->num_npiv_ids;
493 return sizeof(p_drv_buf->num_npiv_ids);
495 break;
496 case DRV_TLV_SWITCH_NAME:
497 if (p_drv_buf->switch_name_set) {
498 p_buf->p_val = &p_drv_buf->switch_name;
499 return sizeof(p_drv_buf->switch_name);
501 break;
502 case DRV_TLV_SWITCH_PORT_NUM:
503 if (p_drv_buf->switch_portnum_set) {
504 p_buf->p_val = &p_drv_buf->switch_portnum;
505 return sizeof(p_drv_buf->switch_portnum);
507 break;
508 case DRV_TLV_SWITCH_PORT_ID:
509 if (p_drv_buf->switch_portid_set) {
510 p_buf->p_val = &p_drv_buf->switch_portid;
511 return sizeof(p_drv_buf->switch_portid);
513 break;
514 case DRV_TLV_VENDOR_NAME:
515 if (p_drv_buf->vendor_name_set) {
516 p_buf->p_val = &p_drv_buf->vendor_name;
517 return sizeof(p_drv_buf->vendor_name);
519 break;
520 case DRV_TLV_SWITCH_MODEL:
521 if (p_drv_buf->switch_model_set) {
522 p_buf->p_val = &p_drv_buf->switch_model;
523 return sizeof(p_drv_buf->switch_model);
525 break;
526 case DRV_TLV_SWITCH_FW_VER:
527 if (p_drv_buf->switch_fw_version_set) {
528 p_buf->p_val = &p_drv_buf->switch_fw_version;
529 return sizeof(p_drv_buf->switch_fw_version);
531 break;
532 case DRV_TLV_QOS_PRIORITY_PER_802_1P:
533 if (p_drv_buf->qos_pri_set) {
534 p_buf->p_val = &p_drv_buf->qos_pri;
535 return sizeof(p_drv_buf->qos_pri);
537 break;
538 case DRV_TLV_PORT_ALIAS:
539 if (p_drv_buf->port_alias_set) {
540 p_buf->p_val = &p_drv_buf->port_alias;
541 return sizeof(p_drv_buf->port_alias);
543 break;
544 case DRV_TLV_PORT_STATE:
545 if (p_drv_buf->port_state_set) {
546 p_buf->p_val = &p_drv_buf->port_state;
547 return sizeof(p_drv_buf->port_state);
549 break;
550 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
551 if (p_drv_buf->fip_tx_descr_size_set) {
552 p_buf->p_val = &p_drv_buf->fip_tx_descr_size;
553 return sizeof(p_drv_buf->fip_tx_descr_size);
555 break;
556 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
557 if (p_drv_buf->fip_rx_descr_size_set) {
558 p_buf->p_val = &p_drv_buf->fip_rx_descr_size;
559 return sizeof(p_drv_buf->fip_rx_descr_size);
561 break;
562 case DRV_TLV_LINK_FAILURE_COUNT:
563 if (p_drv_buf->link_failures_set) {
564 p_buf->p_val = &p_drv_buf->link_failures;
565 return sizeof(p_drv_buf->link_failures);
567 break;
568 case DRV_TLV_FCOE_BOOT_PROGRESS:
569 if (p_drv_buf->fcoe_boot_progress_set) {
570 p_buf->p_val = &p_drv_buf->fcoe_boot_progress;
571 return sizeof(p_drv_buf->fcoe_boot_progress);
573 break;
574 case DRV_TLV_RX_BROADCAST_PACKETS:
575 if (p_drv_buf->rx_bcast_set) {
576 p_buf->p_val = &p_drv_buf->rx_bcast;
577 return sizeof(p_drv_buf->rx_bcast);
579 break;
580 case DRV_TLV_TX_BROADCAST_PACKETS:
581 if (p_drv_buf->tx_bcast_set) {
582 p_buf->p_val = &p_drv_buf->tx_bcast;
583 return sizeof(p_drv_buf->tx_bcast);
585 break;
586 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
587 if (p_drv_buf->fcoe_txq_depth_set) {
588 p_buf->p_val = &p_drv_buf->fcoe_txq_depth;
589 return sizeof(p_drv_buf->fcoe_txq_depth);
591 break;
592 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
593 if (p_drv_buf->fcoe_rxq_depth_set) {
594 p_buf->p_val = &p_drv_buf->fcoe_rxq_depth;
595 return sizeof(p_drv_buf->fcoe_rxq_depth);
597 break;
598 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
599 if (p_drv_buf->fcoe_rx_frames_set) {
600 p_buf->p_val = &p_drv_buf->fcoe_rx_frames;
601 return sizeof(p_drv_buf->fcoe_rx_frames);
603 break;
604 case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
605 if (p_drv_buf->fcoe_rx_bytes_set) {
606 p_buf->p_val = &p_drv_buf->fcoe_rx_bytes;
607 return sizeof(p_drv_buf->fcoe_rx_bytes);
609 break;
610 case DRV_TLV_FCOE_TX_FRAMES_SENT:
611 if (p_drv_buf->fcoe_tx_frames_set) {
612 p_buf->p_val = &p_drv_buf->fcoe_tx_frames;
613 return sizeof(p_drv_buf->fcoe_tx_frames);
615 break;
616 case DRV_TLV_FCOE_TX_BYTES_SENT:
617 if (p_drv_buf->fcoe_tx_bytes_set) {
618 p_buf->p_val = &p_drv_buf->fcoe_tx_bytes;
619 return sizeof(p_drv_buf->fcoe_tx_bytes);
621 break;
622 case DRV_TLV_CRC_ERROR_COUNT:
623 if (p_drv_buf->crc_count_set) {
624 p_buf->p_val = &p_drv_buf->crc_count;
625 return sizeof(p_drv_buf->crc_count);
627 break;
628 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
629 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
630 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
631 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
632 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
633 idx = (p_tlv->tlv_type -
634 DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
636 if (p_drv_buf->crc_err_src_fcid_set[idx]) {
637 p_buf->p_val = &p_drv_buf->crc_err_src_fcid[idx];
638 return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
640 break;
641 case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
642 case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
643 case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
644 case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
645 case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
646 idx = (p_tlv->tlv_type - DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
648 return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
649 p_buf);
650 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
651 if (p_drv_buf->losync_err_set) {
652 p_buf->p_val = &p_drv_buf->losync_err;
653 return sizeof(p_drv_buf->losync_err);
655 break;
656 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
657 if (p_drv_buf->losig_err_set) {
658 p_buf->p_val = &p_drv_buf->losig_err;
659 return sizeof(p_drv_buf->losig_err);
661 break;
662 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
663 if (p_drv_buf->primtive_err_set) {
664 p_buf->p_val = &p_drv_buf->primtive_err;
665 return sizeof(p_drv_buf->primtive_err);
667 break;
668 case DRV_TLV_DISPARITY_ERROR_COUNT:
669 if (p_drv_buf->disparity_err_set) {
670 p_buf->p_val = &p_drv_buf->disparity_err;
671 return sizeof(p_drv_buf->disparity_err);
673 break;
674 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
675 if (p_drv_buf->code_violation_err_set) {
676 p_buf->p_val = &p_drv_buf->code_violation_err;
677 return sizeof(p_drv_buf->code_violation_err);
679 break;
680 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
681 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
682 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
683 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
684 idx = p_tlv->tlv_type -
685 DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
686 if (p_drv_buf->flogi_param_set[idx]) {
687 p_buf->p_val = &p_drv_buf->flogi_param[idx];
688 return sizeof(p_drv_buf->flogi_param[idx]);
690 break;
691 case DRV_TLV_LAST_FLOGI_TIMESTAMP:
692 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
693 p_buf);
694 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
695 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
696 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
697 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
698 idx = p_tlv->tlv_type -
699 DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
701 if (p_drv_buf->flogi_acc_param_set[idx]) {
702 p_buf->p_val = &p_drv_buf->flogi_acc_param[idx];
703 return sizeof(p_drv_buf->flogi_acc_param[idx]);
705 break;
706 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
707 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
708 p_buf);
709 case DRV_TLV_LAST_FLOGI_RJT:
710 if (p_drv_buf->flogi_rjt_set) {
711 p_buf->p_val = &p_drv_buf->flogi_rjt;
712 return sizeof(p_drv_buf->flogi_rjt);
714 break;
715 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
716 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
717 p_buf);
718 case DRV_TLV_FDISCS_SENT_COUNT:
719 if (p_drv_buf->fdiscs_set) {
720 p_buf->p_val = &p_drv_buf->fdiscs;
721 return sizeof(p_drv_buf->fdiscs);
723 break;
724 case DRV_TLV_FDISC_ACCS_RECEIVED:
725 if (p_drv_buf->fdisc_acc_set) {
726 p_buf->p_val = &p_drv_buf->fdisc_acc;
727 return sizeof(p_drv_buf->fdisc_acc);
729 break;
730 case DRV_TLV_FDISC_RJTS_RECEIVED:
731 if (p_drv_buf->fdisc_rjt_set) {
732 p_buf->p_val = &p_drv_buf->fdisc_rjt;
733 return sizeof(p_drv_buf->fdisc_rjt);
735 break;
736 case DRV_TLV_PLOGI_SENT_COUNT:
737 if (p_drv_buf->plogi_set) {
738 p_buf->p_val = &p_drv_buf->plogi;
739 return sizeof(p_drv_buf->plogi);
741 break;
742 case DRV_TLV_PLOGI_ACCS_RECEIVED:
743 if (p_drv_buf->plogi_acc_set) {
744 p_buf->p_val = &p_drv_buf->plogi_acc;
745 return sizeof(p_drv_buf->plogi_acc);
747 break;
748 case DRV_TLV_PLOGI_RJTS_RECEIVED:
749 if (p_drv_buf->plogi_rjt_set) {
750 p_buf->p_val = &p_drv_buf->plogi_rjt;
751 return sizeof(p_drv_buf->plogi_rjt);
753 break;
754 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
755 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
756 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
757 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
758 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
759 idx = (p_tlv->tlv_type -
760 DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
762 if (p_drv_buf->plogi_dst_fcid_set[idx]) {
763 p_buf->p_val = &p_drv_buf->plogi_dst_fcid[idx];
764 return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
766 break;
767 case DRV_TLV_PLOGI_1_TIMESTAMP:
768 case DRV_TLV_PLOGI_2_TIMESTAMP:
769 case DRV_TLV_PLOGI_3_TIMESTAMP:
770 case DRV_TLV_PLOGI_4_TIMESTAMP:
771 case DRV_TLV_PLOGI_5_TIMESTAMP:
772 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
774 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
775 p_buf);
776 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
777 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
778 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
779 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
780 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
781 idx = (p_tlv->tlv_type -
782 DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
784 if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
785 p_buf->p_val = &p_drv_buf->plogi_acc_src_fcid[idx];
786 return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
788 break;
789 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
790 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
791 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
792 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
793 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
794 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
795 p_time = &p_drv_buf->plogi_acc_tstamp[idx];
797 return qed_mfw_get_tlv_time_value(p_time, p_buf);
798 case DRV_TLV_LOGOS_ISSUED:
799 if (p_drv_buf->tx_plogos_set) {
800 p_buf->p_val = &p_drv_buf->tx_plogos;
801 return sizeof(p_drv_buf->tx_plogos);
803 break;
804 case DRV_TLV_LOGO_ACCS_RECEIVED:
805 if (p_drv_buf->plogo_acc_set) {
806 p_buf->p_val = &p_drv_buf->plogo_acc;
807 return sizeof(p_drv_buf->plogo_acc);
809 break;
810 case DRV_TLV_LOGO_RJTS_RECEIVED:
811 if (p_drv_buf->plogo_rjt_set) {
812 p_buf->p_val = &p_drv_buf->plogo_rjt;
813 return sizeof(p_drv_buf->plogo_rjt);
815 break;
816 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
817 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
818 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
819 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
820 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
821 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) /
824 if (p_drv_buf->plogo_src_fcid_set[idx]) {
825 p_buf->p_val = &p_drv_buf->plogo_src_fcid[idx];
826 return sizeof(p_drv_buf->plogo_src_fcid[idx]);
828 break;
829 case DRV_TLV_LOGO_1_TIMESTAMP:
830 case DRV_TLV_LOGO_2_TIMESTAMP:
831 case DRV_TLV_LOGO_3_TIMESTAMP:
832 case DRV_TLV_LOGO_4_TIMESTAMP:
833 case DRV_TLV_LOGO_5_TIMESTAMP:
834 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_TIMESTAMP) / 2;
836 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
837 p_buf);
838 case DRV_TLV_LOGOS_RECEIVED:
839 if (p_drv_buf->rx_logos_set) {
840 p_buf->p_val = &p_drv_buf->rx_logos;
841 return sizeof(p_drv_buf->rx_logos);
843 break;
844 case DRV_TLV_ACCS_ISSUED:
845 if (p_drv_buf->tx_accs_set) {
846 p_buf->p_val = &p_drv_buf->tx_accs;
847 return sizeof(p_drv_buf->tx_accs);
849 break;
850 case DRV_TLV_PRLIS_ISSUED:
851 if (p_drv_buf->tx_prlis_set) {
852 p_buf->p_val = &p_drv_buf->tx_prlis;
853 return sizeof(p_drv_buf->tx_prlis);
855 break;
856 case DRV_TLV_ACCS_RECEIVED:
857 if (p_drv_buf->rx_accs_set) {
858 p_buf->p_val = &p_drv_buf->rx_accs;
859 return sizeof(p_drv_buf->rx_accs);
861 break;
862 case DRV_TLV_ABTS_SENT_COUNT:
863 if (p_drv_buf->tx_abts_set) {
864 p_buf->p_val = &p_drv_buf->tx_abts;
865 return sizeof(p_drv_buf->tx_abts);
867 break;
868 case DRV_TLV_ABTS_ACCS_RECEIVED:
869 if (p_drv_buf->rx_abts_acc_set) {
870 p_buf->p_val = &p_drv_buf->rx_abts_acc;
871 return sizeof(p_drv_buf->rx_abts_acc);
873 break;
874 case DRV_TLV_ABTS_RJTS_RECEIVED:
875 if (p_drv_buf->rx_abts_rjt_set) {
876 p_buf->p_val = &p_drv_buf->rx_abts_rjt;
877 return sizeof(p_drv_buf->rx_abts_rjt);
879 break;
880 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
881 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
882 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
883 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
884 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
885 idx = (p_tlv->tlv_type -
886 DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
888 if (p_drv_buf->abts_dst_fcid_set[idx]) {
889 p_buf->p_val = &p_drv_buf->abts_dst_fcid[idx];
890 return sizeof(p_drv_buf->abts_dst_fcid[idx]);
892 break;
893 case DRV_TLV_ABTS_1_TIMESTAMP:
894 case DRV_TLV_ABTS_2_TIMESTAMP:
895 case DRV_TLV_ABTS_3_TIMESTAMP:
896 case DRV_TLV_ABTS_4_TIMESTAMP:
897 case DRV_TLV_ABTS_5_TIMESTAMP:
898 idx = (p_tlv->tlv_type - DRV_TLV_ABTS_1_TIMESTAMP) / 2;
900 return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
901 p_buf);
902 case DRV_TLV_RSCNS_RECEIVED:
903 if (p_drv_buf->rx_rscn_set) {
904 p_buf->p_val = &p_drv_buf->rx_rscn;
905 return sizeof(p_drv_buf->rx_rscn);
907 break;
908 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
909 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
910 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
911 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
912 idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
914 if (p_drv_buf->rx_rscn_nport_set[idx]) {
915 p_buf->p_val = &p_drv_buf->rx_rscn_nport[idx];
916 return sizeof(p_drv_buf->rx_rscn_nport[idx]);
918 break;
919 case DRV_TLV_LUN_RESETS_ISSUED:
920 if (p_drv_buf->tx_lun_rst_set) {
921 p_buf->p_val = &p_drv_buf->tx_lun_rst;
922 return sizeof(p_drv_buf->tx_lun_rst);
924 break;
925 case DRV_TLV_ABORT_TASK_SETS_ISSUED:
926 if (p_drv_buf->abort_task_sets_set) {
927 p_buf->p_val = &p_drv_buf->abort_task_sets;
928 return sizeof(p_drv_buf->abort_task_sets);
930 break;
931 case DRV_TLV_TPRLOS_SENT:
932 if (p_drv_buf->tx_tprlos_set) {
933 p_buf->p_val = &p_drv_buf->tx_tprlos;
934 return sizeof(p_drv_buf->tx_tprlos);
936 break;
937 case DRV_TLV_NOS_SENT_COUNT:
938 if (p_drv_buf->tx_nos_set) {
939 p_buf->p_val = &p_drv_buf->tx_nos;
940 return sizeof(p_drv_buf->tx_nos);
942 break;
943 case DRV_TLV_NOS_RECEIVED_COUNT:
944 if (p_drv_buf->rx_nos_set) {
945 p_buf->p_val = &p_drv_buf->rx_nos;
946 return sizeof(p_drv_buf->rx_nos);
948 break;
949 case DRV_TLV_OLS_COUNT:
950 if (p_drv_buf->ols_set) {
951 p_buf->p_val = &p_drv_buf->ols;
952 return sizeof(p_drv_buf->ols);
954 break;
955 case DRV_TLV_LR_COUNT:
956 if (p_drv_buf->lr_set) {
957 p_buf->p_val = &p_drv_buf->lr;
958 return sizeof(p_drv_buf->lr);
960 break;
961 case DRV_TLV_LRR_COUNT:
962 if (p_drv_buf->lrr_set) {
963 p_buf->p_val = &p_drv_buf->lrr;
964 return sizeof(p_drv_buf->lrr);
966 break;
967 case DRV_TLV_LIP_SENT_COUNT:
968 if (p_drv_buf->tx_lip_set) {
969 p_buf->p_val = &p_drv_buf->tx_lip;
970 return sizeof(p_drv_buf->tx_lip);
972 break;
973 case DRV_TLV_LIP_RECEIVED_COUNT:
974 if (p_drv_buf->rx_lip_set) {
975 p_buf->p_val = &p_drv_buf->rx_lip;
976 return sizeof(p_drv_buf->rx_lip);
978 break;
979 case DRV_TLV_EOFA_COUNT:
980 if (p_drv_buf->eofa_set) {
981 p_buf->p_val = &p_drv_buf->eofa;
982 return sizeof(p_drv_buf->eofa);
984 break;
985 case DRV_TLV_EOFNI_COUNT:
986 if (p_drv_buf->eofni_set) {
987 p_buf->p_val = &p_drv_buf->eofni;
988 return sizeof(p_drv_buf->eofni);
990 break;
991 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
992 if (p_drv_buf->scsi_chks_set) {
993 p_buf->p_val = &p_drv_buf->scsi_chks;
994 return sizeof(p_drv_buf->scsi_chks);
996 break;
997 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
998 if (p_drv_buf->scsi_cond_met_set) {
999 p_buf->p_val = &p_drv_buf->scsi_cond_met;
1000 return sizeof(p_drv_buf->scsi_cond_met);
1002 break;
1003 case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
1004 if (p_drv_buf->scsi_busy_set) {
1005 p_buf->p_val = &p_drv_buf->scsi_busy;
1006 return sizeof(p_drv_buf->scsi_busy);
1008 break;
1009 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
1010 if (p_drv_buf->scsi_inter_set) {
1011 p_buf->p_val = &p_drv_buf->scsi_inter;
1012 return sizeof(p_drv_buf->scsi_inter);
1014 break;
1015 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
1016 if (p_drv_buf->scsi_inter_cond_met_set) {
1017 p_buf->p_val = &p_drv_buf->scsi_inter_cond_met;
1018 return sizeof(p_drv_buf->scsi_inter_cond_met);
1020 break;
1021 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
1022 if (p_drv_buf->scsi_rsv_conflicts_set) {
1023 p_buf->p_val = &p_drv_buf->scsi_rsv_conflicts;
1024 return sizeof(p_drv_buf->scsi_rsv_conflicts);
1026 break;
1027 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
1028 if (p_drv_buf->scsi_tsk_full_set) {
1029 p_buf->p_val = &p_drv_buf->scsi_tsk_full;
1030 return sizeof(p_drv_buf->scsi_tsk_full);
1032 break;
1033 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
1034 if (p_drv_buf->scsi_aca_active_set) {
1035 p_buf->p_val = &p_drv_buf->scsi_aca_active;
1036 return sizeof(p_drv_buf->scsi_aca_active);
1038 break;
1039 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
1040 if (p_drv_buf->scsi_tsk_abort_set) {
1041 p_buf->p_val = &p_drv_buf->scsi_tsk_abort;
1042 return sizeof(p_drv_buf->scsi_tsk_abort);
1044 break;
1045 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
1046 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
1047 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
1048 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
1049 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
1050 idx = (p_tlv->tlv_type -
1051 DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
1053 if (p_drv_buf->scsi_rx_chk_set[idx]) {
1054 p_buf->p_val = &p_drv_buf->scsi_rx_chk[idx];
1055 return sizeof(p_drv_buf->scsi_rx_chk[idx]);
1057 break;
1058 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
1059 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
1060 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
1061 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
1062 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
1063 idx = (p_tlv->tlv_type - DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
1064 p_time = &p_drv_buf->scsi_chk_tstamp[idx];
1066 return qed_mfw_get_tlv_time_value(p_time, p_buf);
1067 default:
1068 break;
1071 return -1;
1074 static int
1075 qed_mfw_get_iscsi_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
1076 struct qed_mfw_tlv_iscsi *p_drv_buf,
1077 struct qed_tlv_parsed_buf *p_buf)
1079 switch (p_tlv->tlv_type) {
1080 case DRV_TLV_TARGET_LLMNR_ENABLED:
1081 if (p_drv_buf->target_llmnr_set) {
1082 p_buf->p_val = &p_drv_buf->target_llmnr;
1083 return sizeof(p_drv_buf->target_llmnr);
1085 break;
1086 case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
1087 if (p_drv_buf->header_digest_set) {
1088 p_buf->p_val = &p_drv_buf->header_digest;
1089 return sizeof(p_drv_buf->header_digest);
1091 break;
1092 case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
1093 if (p_drv_buf->data_digest_set) {
1094 p_buf->p_val = &p_drv_buf->data_digest;
1095 return sizeof(p_drv_buf->data_digest);
1097 break;
1098 case DRV_TLV_AUTHENTICATION_METHOD:
1099 if (p_drv_buf->auth_method_set) {
1100 p_buf->p_val = &p_drv_buf->auth_method;
1101 return sizeof(p_drv_buf->auth_method);
1103 break;
1104 case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
1105 if (p_drv_buf->boot_taget_portal_set) {
1106 p_buf->p_val = &p_drv_buf->boot_taget_portal;
1107 return sizeof(p_drv_buf->boot_taget_portal);
1109 break;
1110 case DRV_TLV_MAX_FRAME_SIZE:
1111 if (p_drv_buf->frame_size_set) {
1112 p_buf->p_val = &p_drv_buf->frame_size;
1113 return sizeof(p_drv_buf->frame_size);
1115 break;
1116 case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
1117 if (p_drv_buf->tx_desc_size_set) {
1118 p_buf->p_val = &p_drv_buf->tx_desc_size;
1119 return sizeof(p_drv_buf->tx_desc_size);
1121 break;
1122 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
1123 if (p_drv_buf->rx_desc_size_set) {
1124 p_buf->p_val = &p_drv_buf->rx_desc_size;
1125 return sizeof(p_drv_buf->rx_desc_size);
1127 break;
1128 case DRV_TLV_ISCSI_BOOT_PROGRESS:
1129 if (p_drv_buf->boot_progress_set) {
1130 p_buf->p_val = &p_drv_buf->boot_progress;
1131 return sizeof(p_drv_buf->boot_progress);
1133 break;
1134 case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
1135 if (p_drv_buf->tx_desc_qdepth_set) {
1136 p_buf->p_val = &p_drv_buf->tx_desc_qdepth;
1137 return sizeof(p_drv_buf->tx_desc_qdepth);
1139 break;
1140 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
1141 if (p_drv_buf->rx_desc_qdepth_set) {
1142 p_buf->p_val = &p_drv_buf->rx_desc_qdepth;
1143 return sizeof(p_drv_buf->rx_desc_qdepth);
1145 break;
1146 case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
1147 if (p_drv_buf->rx_frames_set) {
1148 p_buf->p_val = &p_drv_buf->rx_frames;
1149 return sizeof(p_drv_buf->rx_frames);
1151 break;
1152 case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
1153 if (p_drv_buf->rx_bytes_set) {
1154 p_buf->p_val = &p_drv_buf->rx_bytes;
1155 return sizeof(p_drv_buf->rx_bytes);
1157 break;
1158 case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
1159 if (p_drv_buf->tx_frames_set) {
1160 p_buf->p_val = &p_drv_buf->tx_frames;
1161 return sizeof(p_drv_buf->tx_frames);
1163 break;
1164 case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
1165 if (p_drv_buf->tx_bytes_set) {
1166 p_buf->p_val = &p_drv_buf->tx_bytes;
1167 return sizeof(p_drv_buf->tx_bytes);
1169 break;
1170 default:
1171 break;
1174 return -1;
1177 static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
1178 u8 tlv_group, u8 *p_mfw_buf, u32 size)
1180 union qed_mfw_tlv_data *p_tlv_data;
1181 struct qed_tlv_parsed_buf buffer;
1182 struct qed_drv_tlv_hdr tlv;
1183 int len = 0;
1184 u32 offset;
1185 u8 *p_tlv;
1187 p_tlv_data = vzalloc(sizeof(*p_tlv_data));
1188 if (!p_tlv_data)
1189 return -ENOMEM;
1191 if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
1192 vfree(p_tlv_data);
1193 return -EINVAL;
1196 memset(&tlv, 0, sizeof(tlv));
1197 for (offset = 0; offset < size;
1198 offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1199 p_tlv = &p_mfw_buf[offset];
1200 tlv.tlv_type = TLV_TYPE(p_tlv);
1201 tlv.tlv_length = TLV_LENGTH(p_tlv);
1202 tlv.tlv_flags = TLV_FLAGS(p_tlv);
1204 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1205 "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
1206 tlv.tlv_length, tlv.tlv_flags);
1208 if (tlv_group == QED_MFW_TLV_GENERIC)
1209 len = qed_mfw_get_gen_tlv_value(&tlv,
1210 &p_tlv_data->generic,
1211 &buffer);
1212 else if (tlv_group == QED_MFW_TLV_ETH)
1213 len = qed_mfw_get_eth_tlv_value(&tlv,
1214 &p_tlv_data->eth,
1215 &buffer);
1216 else if (tlv_group == QED_MFW_TLV_FCOE)
1217 len = qed_mfw_get_fcoe_tlv_value(&tlv,
1218 &p_tlv_data->fcoe,
1219 &buffer);
1220 else
1221 len = qed_mfw_get_iscsi_tlv_value(&tlv,
1222 &p_tlv_data->iscsi,
1223 &buffer);
1225 if (len > 0) {
1226 WARN(len > 4 * tlv.tlv_length,
1227 "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
1228 len, 4 * tlv.tlv_length);
1229 len = min_t(int, len, 4 * tlv.tlv_length);
1230 tlv.tlv_flags |= QED_DRV_TLV_FLAGS_CHANGED;
1231 TLV_FLAGS(p_tlv) = tlv.tlv_flags;
1232 memcpy(p_mfw_buf + offset + sizeof(tlv),
1233 buffer.p_val, len);
1237 vfree(p_tlv_data);
1239 return 0;
1242 int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1244 u32 addr, size, offset, resp, param, val, global_offsize, global_addr;
1245 u8 tlv_group = 0, id, *p_mfw_buf = NULL, *p_temp;
1246 struct qed_drv_tlv_hdr tlv;
1247 int rc;
1249 addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1250 PUBLIC_GLOBAL);
1251 global_offsize = qed_rd(p_hwfn, p_ptt, addr);
1252 global_addr = SECTION_ADDR(global_offsize, 0);
1253 addr = global_addr + offsetof(struct public_global, data_ptr);
1254 addr = qed_rd(p_hwfn, p_ptt, addr);
1255 size = qed_rd(p_hwfn, p_ptt, global_addr +
1256 offsetof(struct public_global, data_size));
1258 if (!size) {
1259 DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
1260 goto drv_done;
1263 p_mfw_buf = vzalloc(size);
1264 if (!p_mfw_buf) {
1265 DP_NOTICE(p_hwfn, "Failed allocate memory for p_mfw_buf\n");
1266 goto drv_done;
1269 /* Read the TLV request to local buffer. MFW represents the TLV in
1270 * little endian format and mcp returns it bigendian format. Hence
1271 * driver need to convert data to little endian first and then do the
1272 * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
1275 for (offset = 0; offset < size; offset += sizeof(u32)) {
1276 val = qed_rd(p_hwfn, p_ptt, addr + offset);
1277 val = be32_to_cpu(val);
1278 memcpy(&p_mfw_buf[offset], &val, sizeof(u32));
1281 /* Parse the headers to enumerate the requested TLV groups */
1282 for (offset = 0; offset < size;
1283 offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1284 p_temp = &p_mfw_buf[offset];
1285 tlv.tlv_type = TLV_TYPE(p_temp);
1286 tlv.tlv_length = TLV_LENGTH(p_temp);
1287 if (qed_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
1288 DP_VERBOSE(p_hwfn, NETIF_MSG_DRV,
1289 "Un recognized TLV %d\n", tlv.tlv_type);
1292 /* Sanitize the TLV groups according to personality */
1293 if ((tlv_group & QED_MFW_TLV_ETH) && !QED_IS_L2_PERSONALITY(p_hwfn)) {
1294 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1295 "Skipping L2 TLVs for non-L2 function\n");
1296 tlv_group &= ~QED_MFW_TLV_ETH;
1299 if ((tlv_group & QED_MFW_TLV_FCOE) &&
1300 p_hwfn->hw_info.personality != QED_PCI_FCOE) {
1301 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1302 "Skipping FCoE TLVs for non-FCoE function\n");
1303 tlv_group &= ~QED_MFW_TLV_FCOE;
1306 if ((tlv_group & QED_MFW_TLV_ISCSI) &&
1307 p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
1308 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1309 "Skipping iSCSI TLVs for non-iSCSI function\n");
1310 tlv_group &= ~QED_MFW_TLV_ISCSI;
1313 /* Update the TLV values in the local buffer */
1314 for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
1315 if (tlv_group & id)
1316 if (qed_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
1317 goto drv_done;
1320 /* Write the TLV data to shared memory. The stream of 4 bytes first need
1321 * to be mem-copied to u32 element to make it as LSB format. And then
1322 * converted to big endian as required by mcp-write.
1324 for (offset = 0; offset < size; offset += sizeof(u32)) {
1325 memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
1326 val = cpu_to_be32(val);
1327 qed_wr(p_hwfn, p_ptt, addr + offset, val);
1330 drv_done:
1331 rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1332 &param);
1334 vfree(p_mfw_buf);
1336 return rc;