GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / net / ethernet / qlogic / qed / qed_mng_tlv.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /* Copyright (c) 2019-2020 Marvell International Ltd. */
3
4 #include <linux/types.h>
5 #include <asm/byteorder.h>
6 #include <linux/bug.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>
12 #include "qed.h"
13 #include "qed_hw.h"
14 #include "qed_mcp.h"
15 #include "qed_reg_addr.h"
16
17 #define TLV_TYPE(p)     (p[0])
18 #define TLV_LENGTH(p)   (p[1])
19 #define TLV_FLAGS(p)    (p[3])
20
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 */
24         void *p_val;
25
26         /* To be used internally in case the value has to be modified */
27         u8 data[QED_TLV_DATA_MAX];
28 };
29
30 static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
31 {
32         switch (tlv_type) {
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;
51                 break;
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;
68                 break;
69         case DRV_TLV_SCSI_TO:
70         case DRV_TLV_R_T_TOV:
71         case DRV_TLV_R_A_TOV:
72         case DRV_TLV_E_D_TOV:
73         case DRV_TLV_CR_TOV:
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;
219                 break;
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;
236                 break;
237         default:
238                 return -EINVAL;
239         }
240
241         return 0;
242 }
243
244 /* Returns size of the data buffer or, -1 in case TLV data is not available. */
245 static int
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)
249 {
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 ?
255                             1 : 0;
256                         p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
257                                            1 : 0) << 1;
258                         p_buf->p_val = p_buf->data;
259                         return QED_MFW_TLV_FLAGS_SIZE;
260                 }
261                 break;
262
263         case DRV_TLV_LOCAL_ADMIN_ADDR:
264         case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
265         case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
266                 {
267                         int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
268
269                         if (p_drv_buf->mac_set[idx]) {
270                                 p_buf->p_val = p_drv_buf->mac[idx];
271                                 return ETH_ALEN;
272                         }
273                         break;
274                 }
275
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);
280                 }
281                 break;
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);
286                 }
287                 break;
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);
292                 }
293                 break;
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);
298                 }
299                 break;
300         default:
301                 break;
302         }
303
304         return -1;
305 }
306
307 static int
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)
311 {
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);
317                 }
318                 break;
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);
323                 }
324                 break;
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);
329                 }
330                 break;
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);
335                 }
336                 break;
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);
341                 }
342                 break;
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);
347                 }
348                 break;
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);
353                 }
354                 break;
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);
359                 }
360                 break;
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);
365                 }
366                 break;
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);
371                 }
372                 break;
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);
377                 }
378                 break;
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);
383                 }
384                 break;
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);
389                 }
390                 break;
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);
395                 }
396                 break;
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);
401                 }
402                 break;
403         default:
404                 break;
405         }
406
407         return -1;
408 }
409
410 static int
411 qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
412                            struct qed_tlv_parsed_buf *p_buf)
413 {
414         if (!p_time->b_set)
415                 return -1;
416
417         /* Validate numbers */
418         if (p_time->month > 12)
419                 p_time->month = 0;
420         if (p_time->day > 31)
421                 p_time->day = 0;
422         if (p_time->hour > 23)
423                 p_time->hour = 0;
424         if (p_time->min > 59)
425                 p_time->min = 0;
426         if (p_time->msec > 999)
427                 p_time->msec = 0;
428         if (p_time->usec > 999)
429                 p_time->usec = 0;
430
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);
435
436         p_buf->p_val = p_buf->data;
437
438         return QED_MFW_TLV_TIME_SIZE;
439 }
440
441 static int
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)
445 {
446         struct qed_mfw_tlv_time *p_time;
447         u8 idx;
448
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);
454                 }
455                 break;
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);
460                 }
461                 break;
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);
466                 }
467                 break;
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);
472                 }
473                 break;
474         case DRV_TLV_CR_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);
478                 }
479                 break;
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);
484                 }
485                 break;
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);
490                 }
491                 break;
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);
496                 }
497                 break;
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);
502                 }
503                 break;
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);
508                 }
509                 break;
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);
514                 }
515                 break;
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);
520                 }
521                 break;
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);
526                 }
527                 break;
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);
532                 }
533                 break;
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);
538                 }
539                 break;
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);
544                 }
545                 break;
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);
550                 }
551                 break;
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);
556                 }
557                 break;
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);
562                 }
563                 break;
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);
568                 }
569                 break;
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);
574                 }
575                 break;
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);
580                 }
581                 break;
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);
586                 }
587                 break;
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);
592                 }
593                 break;
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);
598                 }
599                 break;
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);
604                 }
605                 break;
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);
610                 }
611                 break;
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);
616                 }
617                 break;
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);
622                 }
623                 break;
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);
628                 }
629                 break;
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;
637
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]);
641                 }
642                 break;
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;
649
650                 return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
651                                                   p_buf);
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);
656                 }
657                 break;
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);
662                 }
663                 break;
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);
668                 }
669                 break;
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);
674                 }
675                 break;
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);
680                 }
681                 break;
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]);
691                 }
692                 break;
693         case DRV_TLV_LAST_FLOGI_TIMESTAMP:
694                 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
695                                                   p_buf);
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;
702
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]);
706                 }
707                 break;
708         case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
709                 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
710                                                   p_buf);
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);
715                 }
716                 break;
717         case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
718                 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
719                                                   p_buf);
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);
724                 }
725                 break;
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);
730                 }
731                 break;
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);
736                 }
737                 break;
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);
742                 }
743                 break;
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);
748                 }
749                 break;
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);
754                 }
755                 break;
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;
763
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]);
767                 }
768                 break;
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;
775
776                 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
777                                                   p_buf);
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;
785
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]);
789                 }
790                 break;
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];
798
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);
804                 }
805                 break;
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);
810                 }
811                 break;
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);
816                 }
817                 break;
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) /
824                         2;
825
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]);
829                 }
830                 break;
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;
837
838                 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
839                                                   p_buf);
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);
844                 }
845                 break;
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);
850                 }
851                 break;
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);
856                 }
857                 break;
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);
862                 }
863                 break;
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);
868                 }
869                 break;
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);
874                 }
875                 break;
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);
880                 }
881                 break;
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;
889
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]);
893                 }
894                 break;
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;
901
902                 return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
903                                                   p_buf);
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);
908                 }
909                 break;
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;
915
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]);
919                 }
920                 break;
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);
925                 }
926                 break;
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);
931                 }
932                 break;
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);
937                 }
938                 break;
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);
943                 }
944                 break;
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);
949                 }
950                 break;
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);
955                 }
956                 break;
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);
961                 }
962                 break;
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);
967                 }
968                 break;
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);
973                 }
974                 break;
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);
979                 }
980                 break;
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);
985                 }
986                 break;
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);
991                 }
992                 break;
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);
997                 }
998                 break;
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);
1003                 }
1004                 break;
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);
1009                 }
1010                 break;
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);
1015                 }
1016                 break;
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);
1021                 }
1022                 break;
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);
1027                 }
1028                 break;
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);
1033                 }
1034                 break;
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);
1039                 }
1040                 break;
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);
1045                 }
1046                 break;
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;
1054
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]);
1058                 }
1059                 break;
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];
1067
1068                 return qed_mfw_get_tlv_time_value(p_time, p_buf);
1069         default:
1070                 break;
1071         }
1072
1073         return -1;
1074 }
1075
1076 static int
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)
1080 {
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);
1086                 }
1087                 break;
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);
1092                 }
1093                 break;
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);
1098                 }
1099                 break;
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);
1104                 }
1105                 break;
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);
1110                 }
1111                 break;
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);
1116                 }
1117                 break;
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);
1122                 }
1123                 break;
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);
1128                 }
1129                 break;
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);
1134                 }
1135                 break;
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);
1140                 }
1141                 break;
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);
1146                 }
1147                 break;
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);
1152                 }
1153                 break;
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);
1158                 }
1159                 break;
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);
1164                 }
1165                 break;
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);
1170                 }
1171                 break;
1172         default:
1173                 break;
1174         }
1175
1176         return -1;
1177 }
1178
1179 static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
1180                                u8 tlv_group, u8 *p_mfw_buf, u32 size)
1181 {
1182         union qed_mfw_tlv_data *p_tlv_data;
1183         struct qed_tlv_parsed_buf buffer;
1184         struct qed_drv_tlv_hdr tlv;
1185         int len = 0;
1186         u32 offset;
1187         u8 *p_tlv;
1188
1189         p_tlv_data = vzalloc(sizeof(*p_tlv_data));
1190         if (!p_tlv_data)
1191                 return -ENOMEM;
1192
1193         if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
1194                 vfree(p_tlv_data);
1195                 return -EINVAL;
1196         }
1197
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);
1205
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);
1209
1210                 if (tlv_group == QED_MFW_TLV_GENERIC)
1211                         len = qed_mfw_get_gen_tlv_value(&tlv,
1212                                                         &p_tlv_data->generic,
1213                                                         &buffer);
1214                 else if (tlv_group == QED_MFW_TLV_ETH)
1215                         len = qed_mfw_get_eth_tlv_value(&tlv,
1216                                                         &p_tlv_data->eth,
1217                                                         &buffer);
1218                 else if (tlv_group == QED_MFW_TLV_FCOE)
1219                         len = qed_mfw_get_fcoe_tlv_value(&tlv,
1220                                                          &p_tlv_data->fcoe,
1221                                                          &buffer);
1222                 else
1223                         len = qed_mfw_get_iscsi_tlv_value(&tlv,
1224                                                           &p_tlv_data->iscsi,
1225                                                           &buffer);
1226
1227                 if (len > 0) {
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),
1235                                buffer.p_val, len);
1236                 }
1237         }
1238
1239         vfree(p_tlv_data);
1240
1241         return 0;
1242 }
1243
1244 int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1245 {
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;
1249         int rc;
1250
1251         addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1252                                     PUBLIC_GLOBAL);
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));
1259
1260         if (!size) {
1261                 DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
1262                 goto drv_done;
1263         }
1264
1265         p_mfw_buf = vzalloc(size);
1266         if (!p_mfw_buf) {
1267                 DP_NOTICE(p_hwfn, "Failed allocate memory for p_mfw_buf\n");
1268                 goto drv_done;
1269         }
1270
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.
1275          *
1276          */
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));
1281         }
1282
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);
1292         }
1293
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;
1299         }
1300
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;
1306         }
1307
1308         if ((tlv_group & QED_MFW_TLV_ISCSI) &&
1309             p_hwfn->hw_info.personality != QED_PCI_ISCSI) {
1310                 DP_VERBOSE(p_hwfn, QED_MSG_SP,
1311                            "Skipping iSCSI TLVs for non-iSCSI function\n");
1312                 tlv_group &= ~QED_MFW_TLV_ISCSI;
1313         }
1314
1315         /* Update the TLV values in the local buffer */
1316         for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
1317                 if (tlv_group & id)
1318                         if (qed_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
1319                                 goto drv_done;
1320         }
1321
1322         /* Write the TLV data to shared memory. The stream of 4 bytes first need
1323          * to be mem-copied to u32 element to make it as LSB format. And then
1324          * converted to big endian as required by mcp-write.
1325          */
1326         for (offset = 0; offset < size; offset += sizeof(u32)) {
1327                 memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
1328                 val = (__force u32)cpu_to_be32(val);
1329                 qed_wr(p_hwfn, p_ptt, addr + offset, val);
1330         }
1331
1332 drv_done:
1333         rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1334                          &param);
1335
1336         vfree(p_mfw_buf);
1337
1338         return rc;
1339 }