Linux-libre 5.7.3-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / qlogic / qed / qed_mng_tlv.c
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"
14
15 #define TLV_TYPE(p)     (p[0])
16 #define TLV_LENGTH(p)   (p[1])
17 #define TLV_FLAGS(p)    (p[3])
18
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;
23
24         /* To be used internally in case the value has to be modified */
25         u8 data[QED_TLV_DATA_MAX];
26 };
27
28 static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
29 {
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;
237         }
238
239         return 0;
240 }
241
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)
247 {
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;
258                 }
259                 break;
260
261         case DRV_TLV_LOCAL_ADMIN_ADDR:
262         case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
263         case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
264                 {
265                         int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
266
267                         if (p_drv_buf->mac_set[idx]) {
268                                 p_buf->p_val = p_drv_buf->mac[idx];
269                                 return ETH_ALEN;
270                         }
271                         break;
272                 }
273
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);
278                 }
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);
284                 }
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);
290                 }
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);
296                 }
297                 break;
298         default:
299                 break;
300         }
301
302         return -1;
303 }
304
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)
309 {
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);
315                 }
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);
321                 }
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);
327                 }
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);
333                 }
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);
339                 }
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);
345                 }
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);
351                 }
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);
357                 }
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);
363                 }
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);
369                 }
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);
375                 }
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);
381                 }
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);
387                 }
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);
393                 }
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);
399                 }
400                 break;
401         default:
402                 break;
403         }
404
405         return -1;
406 }
407
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)
411 {
412         if (!p_time->b_set)
413                 return -1;
414
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;
428
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);
433
434         p_buf->p_val = p_buf->data;
435
436         return QED_MFW_TLV_TIME_SIZE;
437 }
438
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)
443 {
444         struct qed_mfw_tlv_time *p_time;
445         u8 idx;
446
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);
452                 }
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);
458                 }
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);
464                 }
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);
470                 }
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);
476                 }
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);
482                 }
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);
488                 }
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);
494                 }
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);
500                 }
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);
506                 }
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);
512                 }
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);
518                 }
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);
524                 }
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);
530                 }
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);
536                 }
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);
542                 }
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);
548                 }
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);
554                 }
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);
560                 }
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);
566                 }
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);
572                 }
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);
578                 }
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);
584                 }
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);
590                 }
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);
596                 }
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);
602                 }
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);
608                 }
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);
614                 }
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);
620                 }
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);
626                 }
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;
635
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]);
639                 }
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;
647
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);
654                 }
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);
660                 }
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);
666                 }
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);
672                 }
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);
678                 }
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]);
689                 }
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;
700
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]);
704                 }
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);
713                 }
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);
722                 }
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);
728                 }
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);
734                 }
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);
740                 }
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);
746                 }
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);
752                 }
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;
761
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]);
765                 }
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;
773
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;
783
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]);
787                 }
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];
796
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);
802                 }
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);
808                 }
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);
814                 }
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) /
822                         2;
823
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]);
827                 }
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;
835
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);
842                 }
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);
848                 }
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);
854                 }
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);
860                 }
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);
866                 }
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);
872                 }
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);
878                 }
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;
887
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]);
891                 }
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;
899
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);
906                 }
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;
913
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]);
917                 }
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);
923                 }
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);
929                 }
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);
935                 }
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);
941                 }
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);
947                 }
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);
953                 }
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);
959                 }
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);
965                 }
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);
971                 }
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);
977                 }
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);
983                 }
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);
989                 }
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);
995                 }
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);
1001                 }
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);
1007                 }
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);
1013                 }
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);
1019                 }
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);
1025                 }
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);
1031                 }
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);
1037                 }
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);
1043                 }
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;
1052
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]);
1056                 }
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];
1065
1066                 return qed_mfw_get_tlv_time_value(p_time, p_buf);
1067         default:
1068                 break;
1069         }
1070
1071         return -1;
1072 }
1073
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)
1078 {
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);
1084                 }
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);
1090                 }
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);
1096                 }
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);
1102                 }
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);
1108                 }
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);
1114                 }
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);
1120                 }
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);
1126                 }
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);
1132                 }
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);
1138                 }
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);
1144                 }
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);
1150                 }
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);
1156                 }
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);
1162                 }
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);
1168                 }
1169                 break;
1170         default:
1171                 break;
1172         }
1173
1174         return -1;
1175 }
1176
1177 static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
1178                                u8 tlv_group, u8 *p_mfw_buf, u32 size)
1179 {
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;
1186
1187         p_tlv_data = vzalloc(sizeof(*p_tlv_data));
1188         if (!p_tlv_data)
1189                 return -ENOMEM;
1190
1191         if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
1192                 vfree(p_tlv_data);
1193                 return -EINVAL;
1194         }
1195
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);
1203
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);
1207
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);
1224
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);
1234                 }
1235         }
1236
1237         vfree(p_tlv_data);
1238
1239         return 0;
1240 }
1241
1242 int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
1243 {
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;
1248
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));
1257
1258         if (!size) {
1259                 DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
1260                 goto drv_done;
1261         }
1262
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;
1267         }
1268
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.
1273          *
1274          */
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));
1279         }
1280
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);
1290         }
1291
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;
1297         }
1298
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;
1304         }
1305
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;
1311         }
1312
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;
1318         }
1319
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.
1323          */
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);
1328         }
1329
1330 drv_done:
1331         rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1332                          &param);
1333
1334         vfree(p_mfw_buf);
1335
1336         return rc;
1337 }