]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/qlnx/qlnxe/ecore_mng_tlv.c
MFV r355890:
[FreeBSD/FreeBSD.git] / sys / dev / qlnx / qlnxe / ecore_mng_tlv.c
1 /*
2  * Copyright (c) 2018-2019 Cavium, Inc.
3  * All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  *  POSSIBILITY OF SUCH DAMAGE.
26  */
27
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include "bcm_osal.h"
33 #include "ecore.h"
34 #include "ecore_status.h"
35 #include "ecore_mcp.h"
36 #include "ecore_hw.h"
37 #include "reg_addr.h"
38
39 #define TLV_TYPE(p)     (p[0])
40 #define TLV_LENGTH(p)   (p[1])
41 #define TLV_FLAGS(p)    (p[3])
42
43 #define ECORE_TLV_DATA_MAX (14)
44 struct ecore_tlv_parsed_buf {
45         /* To be filled with the address to set in Value field */
46         u8 *p_val;
47
48         /* To be used internally in case the value has to be modified */
49         u8 data[ECORE_TLV_DATA_MAX];
50 };
51
52 static enum _ecore_status_t
53 ecore_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
54 {
55         switch(tlv_type) {
56         case DRV_TLV_FEATURE_FLAGS:
57         case DRV_TLV_LOCAL_ADMIN_ADDR:
58         case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
59         case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
60         case DRV_TLV_OS_DRIVER_STATES:
61         case DRV_TLV_PXE_BOOT_PROGRESS:
62         case DRV_TLV_RX_FRAMES_RECEIVED:
63         case DRV_TLV_RX_BYTES_RECEIVED:
64         case DRV_TLV_TX_FRAMES_SENT:
65         case DRV_TLV_TX_BYTES_SENT:
66         case DRV_TLV_NPIV_ENABLED:
67         case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
68         case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
69         case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
70         case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
71         case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
72     case DRV_TLV_NCSI_TX_BYTES_SENT:
73                 *tlv_group |= ECORE_MFW_TLV_GENERIC;
74                 break;
75         case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
76         case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
77         case DRV_TLV_PROMISCUOUS_MODE:
78         case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
79         case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
80         case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
81         case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
82         case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
83         case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
84         case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
85         case DRV_TLV_IOV_OFFLOAD:
86         case DRV_TLV_TX_QUEUES_EMPTY:
87         case DRV_TLV_RX_QUEUES_EMPTY:
88         case DRV_TLV_TX_QUEUES_FULL:
89         case DRV_TLV_RX_QUEUES_FULL:
90                 *tlv_group |= ECORE_MFW_TLV_ETH;
91                 break;
92         case DRV_TLV_SCSI_TO:
93         case DRV_TLV_R_T_TOV:
94         case DRV_TLV_R_A_TOV:
95         case DRV_TLV_E_D_TOV:
96         case DRV_TLV_CR_TOV:
97         case DRV_TLV_BOOT_TYPE:
98         case DRV_TLV_NPIV_STATE:
99         case DRV_TLV_NUM_OF_NPIV_IDS:
100         case DRV_TLV_SWITCH_NAME:
101         case DRV_TLV_SWITCH_PORT_NUM:
102         case DRV_TLV_SWITCH_PORT_ID:
103         case DRV_TLV_VENDOR_NAME:
104         case DRV_TLV_SWITCH_MODEL:
105         case DRV_TLV_SWITCH_FW_VER:
106         case DRV_TLV_QOS_PRIORITY_PER_802_1P:
107         case DRV_TLV_PORT_ALIAS:
108         case DRV_TLV_PORT_STATE:
109         case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
110         case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
111         case DRV_TLV_LINK_FAILURE_COUNT:
112         case DRV_TLV_FCOE_BOOT_PROGRESS:
113         case DRV_TLV_RX_BROADCAST_PACKETS:
114         case DRV_TLV_TX_BROADCAST_PACKETS:
115         case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
116         case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
117         case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
118         case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
119         case DRV_TLV_FCOE_TX_FRAMES_SENT:
120         case DRV_TLV_FCOE_TX_BYTES_SENT:
121         case DRV_TLV_CRC_ERROR_COUNT:
122         case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
123         case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
124         case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
125         case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
126         case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
127         case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
128         case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
129         case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
130         case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
131         case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
132         case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
133         case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
134         case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
135         case DRV_TLV_DISPARITY_ERROR_COUNT:
136         case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
137         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
138         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
139         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
140         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
141         case DRV_TLV_LAST_FLOGI_TIMESTAMP:
142         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
143         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
144         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
145         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
146         case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
147         case DRV_TLV_LAST_FLOGI_RJT:
148         case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
149         case DRV_TLV_FDISCS_SENT_COUNT:
150         case DRV_TLV_FDISC_ACCS_RECEIVED:
151         case DRV_TLV_FDISC_RJTS_RECEIVED:
152         case DRV_TLV_PLOGI_SENT_COUNT:
153         case DRV_TLV_PLOGI_ACCS_RECEIVED:
154         case DRV_TLV_PLOGI_RJTS_RECEIVED:
155         case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
156         case DRV_TLV_PLOGI_1_TIMESTAMP:
157         case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
158         case DRV_TLV_PLOGI_2_TIMESTAMP:
159         case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
160         case DRV_TLV_PLOGI_3_TIMESTAMP:
161         case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
162         case DRV_TLV_PLOGI_4_TIMESTAMP:
163         case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
164         case DRV_TLV_PLOGI_5_TIMESTAMP:
165         case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
166         case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
167         case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
168         case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
169         case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
170         case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
171         case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
172         case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
173         case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
174         case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
175         case DRV_TLV_LOGOS_ISSUED:
176         case DRV_TLV_LOGO_ACCS_RECEIVED:
177         case DRV_TLV_LOGO_RJTS_RECEIVED:
178         case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
179         case DRV_TLV_LOGO_1_TIMESTAMP:
180         case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
181         case DRV_TLV_LOGO_2_TIMESTAMP:
182         case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
183         case DRV_TLV_LOGO_3_TIMESTAMP:
184         case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
185         case DRV_TLV_LOGO_4_TIMESTAMP:
186         case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
187         case DRV_TLV_LOGO_5_TIMESTAMP:
188         case DRV_TLV_LOGOS_RECEIVED:
189         case DRV_TLV_ACCS_ISSUED:
190         case DRV_TLV_PRLIS_ISSUED:
191         case DRV_TLV_ACCS_RECEIVED:
192         case DRV_TLV_ABTS_SENT_COUNT:
193         case DRV_TLV_ABTS_ACCS_RECEIVED:
194         case DRV_TLV_ABTS_RJTS_RECEIVED:
195         case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
196         case DRV_TLV_ABTS_1_TIMESTAMP:
197         case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
198         case DRV_TLV_ABTS_2_TIMESTAMP:
199         case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
200         case DRV_TLV_ABTS_3_TIMESTAMP:
201         case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
202         case DRV_TLV_ABTS_4_TIMESTAMP:
203         case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
204         case DRV_TLV_ABTS_5_TIMESTAMP:
205         case DRV_TLV_RSCNS_RECEIVED:
206         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
207         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
208         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
209         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
210         case DRV_TLV_LUN_RESETS_ISSUED:
211         case DRV_TLV_ABORT_TASK_SETS_ISSUED:
212         case DRV_TLV_TPRLOS_SENT:
213         case DRV_TLV_NOS_SENT_COUNT:
214         case DRV_TLV_NOS_RECEIVED_COUNT:
215         case DRV_TLV_OLS_COUNT:
216         case DRV_TLV_LR_COUNT:
217         case DRV_TLV_LRR_COUNT:
218         case DRV_TLV_LIP_SENT_COUNT:
219         case DRV_TLV_LIP_RECEIVED_COUNT:
220         case DRV_TLV_EOFA_COUNT:
221         case DRV_TLV_EOFNI_COUNT:
222         case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
223         case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
224         case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
225         case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
226         case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
227         case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
228         case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
229         case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
230         case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
231         case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
232         case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
233         case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
234         case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
235         case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
236         case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
237         case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
238         case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
239         case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
240         case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
241                 *tlv_group = ECORE_MFW_TLV_FCOE;
242                 break;
243         case DRV_TLV_TARGET_LLMNR_ENABLED:
244         case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
245         case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
246         case DRV_TLV_AUTHENTICATION_METHOD:
247         case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
248         case DRV_TLV_MAX_FRAME_SIZE:
249         case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
250         case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
251         case DRV_TLV_ISCSI_BOOT_PROGRESS:
252         case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
253         case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
254         case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
255         case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
256         case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
257         case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
258                 *tlv_group |= ECORE_MFW_TLV_ISCSI;
259                 break;
260         default:
261                 return ECORE_INVAL;
262         }
263
264         return ECORE_SUCCESS;
265 }
266
267 static int
268 ecore_mfw_get_gen_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
269                             struct ecore_mfw_tlv_generic *p_drv_buf,
270                             struct ecore_tlv_parsed_buf *p_buf)
271 {
272         switch (p_tlv->tlv_type) {
273         case DRV_TLV_FEATURE_FLAGS:
274                 if (p_drv_buf->flags.b_set) {
275                         OSAL_MEM_ZERO(p_buf->data,
276                                       sizeof(u8) * ECORE_TLV_DATA_MAX);
277                         p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
278                                          1 : 0;
279                         p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
280                                            1 : 0) << 1;
281                         p_buf->p_val = p_buf->data;
282                         return 2;
283                 }
284                 break;
285
286         case DRV_TLV_LOCAL_ADMIN_ADDR:
287         case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
288         case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
289         {
290                 int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
291
292                 if (p_drv_buf->mac_set[idx]) {
293                         p_buf->p_val = p_drv_buf->mac[idx];
294                         return 6;
295                 }
296                 break;
297         }
298
299         case DRV_TLV_RX_FRAMES_RECEIVED:
300                 if (p_drv_buf->rx_frames_set) {
301                         p_buf->p_val = (u8 *)&p_drv_buf->rx_frames;
302                         return sizeof(p_drv_buf->rx_frames);
303                 }
304                 break;
305         case DRV_TLV_RX_BYTES_RECEIVED:
306                 if (p_drv_buf->rx_bytes_set) {
307                         p_buf->p_val = (u8 *)&p_drv_buf->rx_bytes;
308                         return sizeof(p_drv_buf->rx_bytes);
309                 }
310                 break;
311         case DRV_TLV_TX_FRAMES_SENT:
312                 if (p_drv_buf->tx_frames_set) {
313                         p_buf->p_val = (u8 *)&p_drv_buf->tx_frames;
314                         return sizeof(p_drv_buf->tx_frames);
315                 }
316                 break;
317         case DRV_TLV_TX_BYTES_SENT:
318                 if (p_drv_buf->tx_bytes_set) {
319                         p_buf->p_val = (u8 *)&p_drv_buf->tx_bytes;
320                         return sizeof(p_drv_buf->tx_bytes);
321                 }
322                 break;
323         default:
324                 break;
325         }
326
327         return -1;
328 }
329
330 static int
331 ecore_mfw_get_eth_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
332                             struct ecore_mfw_tlv_eth *p_drv_buf,
333                             struct ecore_tlv_parsed_buf *p_buf)
334 {
335         switch (p_tlv->tlv_type) {
336         case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
337                 if (p_drv_buf->lso_maxoff_size_set) {
338                         p_buf->p_val = (u8 *)&p_drv_buf->lso_maxoff_size;
339                         return sizeof(p_drv_buf->lso_maxoff_size);
340                 }
341                 break;
342         case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
343                 if (p_drv_buf->lso_minseg_size_set) {
344                         p_buf->p_val = (u8 *)&p_drv_buf->lso_minseg_size;
345                         return sizeof(p_drv_buf->lso_minseg_size);
346                 }
347                 break;
348         case DRV_TLV_PROMISCUOUS_MODE:
349                 if (p_drv_buf->prom_mode_set) {
350                         p_buf->p_val = (u8 *)&p_drv_buf->prom_mode;
351                         return sizeof(p_drv_buf->prom_mode);
352                 }
353                 break;
354         case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
355                 if (p_drv_buf->tx_descr_size_set) {
356                         p_buf->p_val = (u8 *)&p_drv_buf->tx_descr_size;
357                         return sizeof(p_drv_buf->tx_descr_size);
358                 }
359                 break;
360         case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
361                 if (p_drv_buf->rx_descr_size_set) {
362                         p_buf->p_val = (u8 *)&p_drv_buf->rx_descr_size;
363                         return sizeof(p_drv_buf->rx_descr_size);
364                 }
365                 break;
366         case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
367                 if (p_drv_buf->netq_count_set) {
368                         p_buf->p_val = (u8 *)&p_drv_buf->netq_count;
369                         return sizeof(p_drv_buf->netq_count);
370                 }
371                 break;
372         case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
373                 if (p_drv_buf->tcp4_offloads_set) {
374                         p_buf->p_val = (u8 *)&p_drv_buf->tcp4_offloads;
375                         return sizeof(p_drv_buf->tcp4_offloads);
376                 }
377                 break;
378         case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
379                 if (p_drv_buf->tcp6_offloads_set) {
380                         p_buf->p_val = (u8 *)&p_drv_buf->tcp6_offloads;
381                         return sizeof(p_drv_buf->tcp6_offloads);
382                 }
383                 break;
384         case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
385                 if (p_drv_buf->tx_descr_qdepth_set) {
386                         p_buf->p_val = (u8 *)&p_drv_buf->tx_descr_qdepth;
387                         return sizeof(p_drv_buf->tx_descr_qdepth);
388                 }
389                 break;
390         case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
391                 if (p_drv_buf->rx_descr_qdepth_set) {
392                         p_buf->p_val = (u8 *)&p_drv_buf->rx_descr_qdepth;
393                         return sizeof(p_drv_buf->rx_descr_qdepth);
394                 }
395                 break;
396         case DRV_TLV_IOV_OFFLOAD:
397                 if (p_drv_buf->iov_offload_set) {
398                         p_buf->p_val = (u8 *)&p_drv_buf->iov_offload;
399                         return sizeof(p_drv_buf->iov_offload);
400                 }
401                 break;
402         case DRV_TLV_TX_QUEUES_EMPTY:
403                 if (p_drv_buf->txqs_empty_set) {
404                         p_buf->p_val = (u8 *)&p_drv_buf->txqs_empty;
405                         return sizeof(p_drv_buf->txqs_empty);
406                 }
407                 break;
408         case DRV_TLV_RX_QUEUES_EMPTY:
409                 if (p_drv_buf->rxqs_empty_set) {
410                         p_buf->p_val = (u8 *)&p_drv_buf->rxqs_empty;
411                         return sizeof(p_drv_buf->rxqs_empty);
412                 }
413                 break;
414         case DRV_TLV_TX_QUEUES_FULL:
415                 if (p_drv_buf->num_txqs_full_set) {
416                         p_buf->p_val = (u8 *)&p_drv_buf->num_txqs_full;
417                         return sizeof(p_drv_buf->num_txqs_full);
418                 }
419                 break;
420         case DRV_TLV_RX_QUEUES_FULL:
421                 if (p_drv_buf->num_rxqs_full_set) {
422                         p_buf->p_val = (u8 *)&p_drv_buf->num_rxqs_full;
423                         return sizeof(p_drv_buf->num_rxqs_full);
424                 }
425                 break;
426         default:
427                 break;
428         }
429
430         return -1;
431 }
432
433 static int
434 ecore_mfw_get_tlv_time_value(struct ecore_mfw_tlv_time *p_time,
435                              struct ecore_tlv_parsed_buf *p_buf)
436 {
437         if (!p_time->b_set)
438                 return -1;
439
440         /* Validate numbers */
441         if (p_time->month > 12)
442                 p_time->month = 0;
443         if (p_time->day > 31)
444                 p_time->day = 0;
445         if (p_time->hour > 23)
446                 p_time->hour = 0;
447         if (p_time->min > 59)
448                 p_time->hour = 0;
449         if (p_time->msec > 999)
450                 p_time->msec = 0;
451         if (p_time->usec > 999)
452                 p_time->usec = 0;
453
454         OSAL_MEM_ZERO(p_buf->data, sizeof(u8) * ECORE_TLV_DATA_MAX);
455         OSAL_SNPRINTF(p_buf->data, 14, "%d%d%d%d%d%d",
456                       p_time->month, p_time->day,
457                       p_time->hour, p_time->min,
458                       p_time->msec, p_time->usec);
459
460         p_buf->p_val = p_buf->data;
461         return 14;
462 }
463
464 static int
465 ecore_mfw_get_fcoe_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
466                              struct ecore_mfw_tlv_fcoe *p_drv_buf,
467                              struct ecore_tlv_parsed_buf *p_buf)
468 {
469         switch (p_tlv->tlv_type) {
470         case DRV_TLV_SCSI_TO:
471                 if (p_drv_buf->scsi_timeout_set) {
472                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_timeout;
473                         return sizeof(p_drv_buf->scsi_timeout);
474                 }
475                 break;
476         case DRV_TLV_R_T_TOV:
477                 if (p_drv_buf->rt_tov_set) {
478                         p_buf->p_val = (u8 *)&p_drv_buf->rt_tov;
479                         return sizeof(p_drv_buf->rt_tov);
480                 }
481                 break;
482         case DRV_TLV_R_A_TOV:
483                 if (p_drv_buf->ra_tov_set) {
484                         p_buf->p_val = (u8 *)&p_drv_buf->ra_tov;
485                         return sizeof(p_drv_buf->ra_tov);
486                 }
487                 break;
488         case DRV_TLV_E_D_TOV:
489                 if (p_drv_buf->ed_tov_set) {
490                         p_buf->p_val = (u8 *)&p_drv_buf->ed_tov;
491                         return sizeof(p_drv_buf->ed_tov);
492                 }
493                 break;
494         case DRV_TLV_CR_TOV:
495                 if (p_drv_buf->cr_tov_set) {
496                         p_buf->p_val = (u8 *)&p_drv_buf->cr_tov;
497                         return sizeof(p_drv_buf->cr_tov);
498                 }
499                 break;
500         case DRV_TLV_BOOT_TYPE:
501                 if (p_drv_buf->boot_type_set) {
502                         p_buf->p_val = (u8 *)&p_drv_buf->boot_type;
503                         return sizeof(p_drv_buf->boot_type);
504                 }
505                 break;
506         case DRV_TLV_NPIV_STATE:
507                 if (p_drv_buf->npiv_state_set) {
508                         p_buf->p_val = (u8 *)&p_drv_buf->npiv_state;
509                         return sizeof(p_drv_buf->npiv_state);
510                 }
511                 break;
512         case DRV_TLV_NUM_OF_NPIV_IDS:
513                 if (p_drv_buf->num_npiv_ids_set) {
514                         p_buf->p_val = (u8 *)&p_drv_buf->num_npiv_ids;
515                         return sizeof(p_drv_buf->num_npiv_ids);
516                 }
517                 break;
518         case DRV_TLV_SWITCH_NAME:
519                 if (p_drv_buf->switch_name_set) {
520                         p_buf->p_val = (u8 *)&p_drv_buf->switch_name;
521                         return sizeof(p_drv_buf->switch_name);
522                 }
523                 break;
524         case DRV_TLV_SWITCH_PORT_NUM:
525                 if (p_drv_buf->switch_portnum_set) {
526                         p_buf->p_val = (u8 *)&p_drv_buf->switch_portnum;
527                         return sizeof(p_drv_buf->switch_portnum);
528                 }
529                 break;
530         case DRV_TLV_SWITCH_PORT_ID:
531                 if (p_drv_buf->switch_portid_set) {
532                         p_buf->p_val = (u8 *)&p_drv_buf->switch_portid;
533                         return sizeof(p_drv_buf->switch_portid);
534                 }
535                 break;
536         case DRV_TLV_VENDOR_NAME:
537                 if (p_drv_buf->vendor_name_set) {
538                         p_buf->p_val = (u8 *)&p_drv_buf->vendor_name;
539                         return sizeof(p_drv_buf->vendor_name);
540                 }
541                 break;
542         case DRV_TLV_SWITCH_MODEL:
543                 if (p_drv_buf->switch_model_set) {
544                         p_buf->p_val = (u8 *)&p_drv_buf->switch_model;
545                         return sizeof(p_drv_buf->switch_model);
546                 }
547                 break;
548         case DRV_TLV_SWITCH_FW_VER:
549                 if (p_drv_buf->switch_fw_version_set) {
550                         p_buf->p_val = (u8 *)&p_drv_buf->switch_fw_version;
551                         return sizeof(p_drv_buf->switch_fw_version);
552                 }
553                 break;
554         case DRV_TLV_QOS_PRIORITY_PER_802_1P:
555                 if (p_drv_buf->qos_pri_set) {
556                         p_buf->p_val = (u8 *)&p_drv_buf->qos_pri;
557                         return sizeof(p_drv_buf->qos_pri);
558                 }
559                 break;
560         case DRV_TLV_PORT_ALIAS:
561                 if (p_drv_buf->port_alias_set) {
562                         p_buf->p_val = (u8 *)&p_drv_buf->port_alias;
563                         return sizeof(p_drv_buf->port_alias);
564                 }
565                 break;
566         case DRV_TLV_PORT_STATE:
567                 if (p_drv_buf->port_state_set) {
568                         p_buf->p_val = (u8 *)&p_drv_buf->port_state;
569                         return sizeof(p_drv_buf->port_state);
570                 }
571                 break;
572         case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
573                 if (p_drv_buf->fip_tx_descr_size_set) {
574                         p_buf->p_val = (u8 *)&p_drv_buf->fip_tx_descr_size;
575                         return sizeof(p_drv_buf->fip_tx_descr_size);
576                 }
577                 break;
578         case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
579                 if (p_drv_buf->fip_rx_descr_size_set) {
580                         p_buf->p_val = (u8 *)&p_drv_buf->fip_rx_descr_size;
581                         return sizeof(p_drv_buf->fip_rx_descr_size);
582                 }
583                 break;
584         case DRV_TLV_LINK_FAILURE_COUNT:
585                 if (p_drv_buf->link_failures_set) {
586                         p_buf->p_val = (u8 *)&p_drv_buf->link_failures;
587                         return sizeof(p_drv_buf->link_failures);
588                 }
589                 break;
590         case DRV_TLV_FCOE_BOOT_PROGRESS:
591                 if (p_drv_buf->fcoe_boot_progress_set) {
592                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_boot_progress;
593                         return sizeof(p_drv_buf->fcoe_boot_progress);
594                 }
595                 break;
596         case DRV_TLV_RX_BROADCAST_PACKETS:
597                 if (p_drv_buf->rx_bcast_set) {
598                         p_buf->p_val = (u8 *)&p_drv_buf->rx_bcast;
599                         return sizeof(p_drv_buf->rx_bcast);
600                 }
601                 break;
602         case DRV_TLV_TX_BROADCAST_PACKETS:
603                 if (p_drv_buf->tx_bcast_set) {
604                         p_buf->p_val = (u8 *)&p_drv_buf->tx_bcast;
605                         return sizeof(p_drv_buf->tx_bcast);
606                 }
607                 break;
608         case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
609                 if (p_drv_buf->fcoe_txq_depth_set) {
610                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_txq_depth;
611                         return sizeof(p_drv_buf->fcoe_txq_depth);
612                 }
613                 break;
614         case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
615                 if (p_drv_buf->fcoe_rxq_depth_set) {
616                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rxq_depth;
617                         return sizeof(p_drv_buf->fcoe_rxq_depth);
618                 }
619                 break;
620         case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
621                 if (p_drv_buf->fcoe_rx_frames_set) {
622                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rx_frames;
623                         return sizeof(p_drv_buf->fcoe_rx_frames);
624                 }
625                 break;
626         case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
627                 if (p_drv_buf->fcoe_rx_bytes_set) {
628                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rx_bytes;
629                         return sizeof(p_drv_buf->fcoe_rx_bytes);
630                 }
631                 break;
632         case DRV_TLV_FCOE_TX_FRAMES_SENT:
633                 if (p_drv_buf->fcoe_tx_frames_set) {
634                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_tx_frames;
635                         return sizeof(p_drv_buf->fcoe_tx_frames);
636                 }
637                 break;
638         case DRV_TLV_FCOE_TX_BYTES_SENT:
639                 if (p_drv_buf->fcoe_tx_bytes_set) {
640                         p_buf->p_val = (u8 *)&p_drv_buf->fcoe_tx_bytes;
641                         return sizeof(p_drv_buf->fcoe_tx_bytes);
642                 }
643                 break;
644         case DRV_TLV_CRC_ERROR_COUNT:
645                 if (p_drv_buf->crc_count_set) {
646                         p_buf->p_val = (u8 *)&p_drv_buf->crc_count;
647                         return sizeof(p_drv_buf->crc_count);
648                 }
649                 break;
650         case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
651         case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
652         case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
653         case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
654         case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
655         {
656                 u8 idx = (p_tlv->tlv_type -
657                           DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
658
659                 if (p_drv_buf->crc_err_src_fcid_set[idx]) {
660                         p_buf->p_val = (u8 *)&p_drv_buf->crc_err_src_fcid[idx];
661                         return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
662                 }
663                 break;
664         }
665
666         case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
667         case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
668         case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
669         case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
670         case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
671         {
672                 u8 idx = (p_tlv->tlv_type -
673                           DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
674
675                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
676                                                     p_buf);
677         }
678
679         case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
680                 if (p_drv_buf->losync_err_set) {
681                         p_buf->p_val = (u8 *)&p_drv_buf->losync_err;
682                         return sizeof(p_drv_buf->losync_err);
683                 }
684                 break;
685         case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
686                 if (p_drv_buf->losig_err_set) {
687                         p_buf->p_val = (u8 *)&p_drv_buf->losig_err;
688                         return sizeof(p_drv_buf->losig_err);
689                 }
690                 break;
691         case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
692                 if (p_drv_buf->primtive_err_set) {
693                         p_buf->p_val = (u8 *)&p_drv_buf->primtive_err;
694                         return sizeof(p_drv_buf->primtive_err);
695                 }
696                 break;
697         case DRV_TLV_DISPARITY_ERROR_COUNT:
698                 if (p_drv_buf->disparity_err_set) {
699                         p_buf->p_val = (u8 *)&p_drv_buf->disparity_err;
700                         return sizeof(p_drv_buf->disparity_err);
701                 }
702                 break;
703         case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
704                 if (p_drv_buf->code_violation_err_set) {
705                         p_buf->p_val = (u8 *)&p_drv_buf->code_violation_err;
706                         return sizeof(p_drv_buf->code_violation_err);
707                 }
708                 break;
709         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
710         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
711         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
712         case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
713         {
714                 u8 idx = p_tlv->tlv_type -
715                          DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
716                 if (p_drv_buf->flogi_param_set[idx]) {
717                         p_buf->p_val = (u8 *)&p_drv_buf->flogi_param[idx];
718                         return sizeof(p_drv_buf->flogi_param[idx]);
719                 }
720                 break;
721         }
722         case DRV_TLV_LAST_FLOGI_TIMESTAMP:
723                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
724                                                     p_buf);
725         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
726         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
727         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
728         case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
729         {
730                 u8 idx = p_tlv->tlv_type -
731                          DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
732
733                 if (p_drv_buf->flogi_acc_param_set[idx]) {
734                         p_buf->p_val = (u8 *)&p_drv_buf->flogi_acc_param[idx];
735                         return sizeof(p_drv_buf->flogi_acc_param[idx]);
736                 }
737                 break;
738         }
739         case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
740                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
741                                                     p_buf);
742         case DRV_TLV_LAST_FLOGI_RJT:
743                 if (p_drv_buf->flogi_rjt_set) {
744                         p_buf->p_val = (u8 *)&p_drv_buf->flogi_rjt;
745                         return sizeof(p_drv_buf->flogi_rjt);
746                 }
747                 break;
748         case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
749                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
750                                                     p_buf);
751         case DRV_TLV_FDISCS_SENT_COUNT:
752                 if (p_drv_buf->fdiscs_set) {
753                         p_buf->p_val = (u8 *)&p_drv_buf->fdiscs;
754                         return sizeof(p_drv_buf->fdiscs);
755                 }
756                 break;
757         case DRV_TLV_FDISC_ACCS_RECEIVED:
758                 if (p_drv_buf->fdisc_acc_set) {
759                         p_buf->p_val = (u8 *)&p_drv_buf->fdisc_acc;
760                         return sizeof(p_drv_buf->fdisc_acc);
761                 }
762                 break;
763         case DRV_TLV_FDISC_RJTS_RECEIVED:
764                 if (p_drv_buf->fdisc_rjt_set) {
765                         p_buf->p_val = (u8 *)&p_drv_buf->fdisc_rjt;
766                         return sizeof(p_drv_buf->fdisc_rjt);
767                 }
768                 break;
769         case DRV_TLV_PLOGI_SENT_COUNT:
770                 if (p_drv_buf->plogi_set) {
771                         p_buf->p_val = (u8 *)&p_drv_buf->plogi;
772                         return sizeof(p_drv_buf->plogi);
773                 }
774                 break;
775         case DRV_TLV_PLOGI_ACCS_RECEIVED:
776                 if (p_drv_buf->plogi_acc_set) {
777                         p_buf->p_val = (u8 *)&p_drv_buf->plogi_acc;
778                         return sizeof(p_drv_buf->plogi_acc);
779                 }
780                 break;
781         case DRV_TLV_PLOGI_RJTS_RECEIVED:
782                 if (p_drv_buf->plogi_rjt_set) {
783                         p_buf->p_val = (u8 *)&p_drv_buf->plogi_rjt;
784                         return sizeof(p_drv_buf->plogi_rjt);
785                 }
786                 break;
787         case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
788         case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
789         case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
790         case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
791         case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
792         {
793                 u8 idx = (p_tlv->tlv_type -
794                           DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
795
796                 if (p_drv_buf->plogi_dst_fcid_set[idx]) {
797                         p_buf->p_val = (u8 *)&p_drv_buf->plogi_dst_fcid[idx];
798                         return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
799                 }
800                 break;
801         }
802         case DRV_TLV_PLOGI_1_TIMESTAMP:
803         case DRV_TLV_PLOGI_2_TIMESTAMP:
804         case DRV_TLV_PLOGI_3_TIMESTAMP:
805         case DRV_TLV_PLOGI_4_TIMESTAMP:
806         case DRV_TLV_PLOGI_5_TIMESTAMP:
807         {
808                 u8 idx = (p_tlv->tlv_type -
809                           DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
810
811                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
812                                                     p_buf);
813         }
814
815         case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
816         case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
817         case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
818         case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
819         case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
820         {
821                 u8 idx = (p_tlv->tlv_type -
822                           DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
823
824                 if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
825                         p_buf->p_val = (u8 *)&p_drv_buf->plogi_acc_src_fcid[idx];
826                         return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
827                 }
828                 break;
829         }
830         case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
831         case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
832         case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
833         case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
834         case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
835         {
836                 u8 idx = (p_tlv->tlv_type -
837                           DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
838
839                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogi_acc_tstamp[idx],
840                                                     p_buf);
841         }
842
843         case DRV_TLV_LOGOS_ISSUED:
844                 if (p_drv_buf->tx_plogos_set) {
845                         p_buf->p_val = (u8 *)&p_drv_buf->tx_plogos;
846                         return sizeof(p_drv_buf->tx_plogos);
847                 }
848                 break;
849         case DRV_TLV_LOGO_ACCS_RECEIVED:
850                 if (p_drv_buf->plogo_acc_set) {
851                         p_buf->p_val = (u8 *)&p_drv_buf->plogo_acc;
852                         return sizeof(p_drv_buf->plogo_acc);
853                 }
854                 break;
855         case DRV_TLV_LOGO_RJTS_RECEIVED:
856                 if (p_drv_buf->plogo_rjt_set) {
857                         p_buf->p_val = (u8 *)&p_drv_buf->plogo_rjt;
858                         return sizeof(p_drv_buf->plogo_rjt);
859                 }
860                 break;
861         case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
862         case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
863         case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
864         case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
865         case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
866         {
867                 u8 idx = (p_tlv->tlv_type -
868                           DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) / 2;
869
870                 if (p_drv_buf->plogo_src_fcid_set[idx]) {
871                         p_buf->p_val = (u8 *)&p_drv_buf->plogo_src_fcid[idx];
872                         return sizeof(p_drv_buf->plogo_src_fcid[idx]);
873                 }
874                 break;
875         }
876         case DRV_TLV_LOGO_1_TIMESTAMP:
877         case DRV_TLV_LOGO_2_TIMESTAMP:
878         case DRV_TLV_LOGO_3_TIMESTAMP:
879         case DRV_TLV_LOGO_4_TIMESTAMP:
880         case DRV_TLV_LOGO_5_TIMESTAMP:
881         {
882                 u8 idx = (p_tlv->tlv_type -
883                           DRV_TLV_LOGO_1_TIMESTAMP) / 2;
884
885                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
886                                                     p_buf);
887         }
888         case DRV_TLV_LOGOS_RECEIVED:
889                 if (p_drv_buf->rx_logos_set) {
890                         p_buf->p_val = (u8 *)&p_drv_buf->rx_logos;
891                         return sizeof(p_drv_buf->rx_logos);
892                 }
893                 break;
894         case DRV_TLV_ACCS_ISSUED:
895                 if (p_drv_buf->tx_accs_set) {
896                         p_buf->p_val = (u8 *)&p_drv_buf->tx_accs;
897                         return sizeof(p_drv_buf->tx_accs);
898                 }
899                 break;
900         case DRV_TLV_PRLIS_ISSUED:
901                 if (p_drv_buf->tx_prlis_set) {
902                         p_buf->p_val = (u8 *)&p_drv_buf->tx_prlis;
903                         return sizeof(p_drv_buf->tx_prlis);
904                 }
905                 break;
906         case DRV_TLV_ACCS_RECEIVED:
907                 if (p_drv_buf->rx_accs_set) {
908                         p_buf->p_val = (u8 *)&p_drv_buf->rx_accs;
909                         return sizeof(p_drv_buf->rx_accs);
910                 }
911                 break;
912         case DRV_TLV_ABTS_SENT_COUNT:
913                 if (p_drv_buf->tx_abts_set) {
914                         p_buf->p_val = (u8 *)&p_drv_buf->tx_abts;
915                         return sizeof(p_drv_buf->tx_abts);
916                 }
917                 break;
918         case DRV_TLV_ABTS_ACCS_RECEIVED:
919                 if (p_drv_buf->rx_abts_acc_set) {
920                         p_buf->p_val = (u8 *)&p_drv_buf->rx_abts_acc;
921                         return sizeof(p_drv_buf->rx_abts_acc);
922                 }
923                 break;
924         case DRV_TLV_ABTS_RJTS_RECEIVED:
925                 if (p_drv_buf->rx_abts_rjt_set) {
926                         p_buf->p_val = (u8 *)&p_drv_buf->rx_abts_rjt;
927                         return sizeof(p_drv_buf->rx_abts_rjt);
928                 }
929                 break;
930         case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
931         case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
932         case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
933         case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
934         case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
935         {
936                 u8 idx = (p_tlv->tlv_type -
937                           DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
938
939                 if (p_drv_buf->abts_dst_fcid_set[idx]) {
940                         p_buf->p_val = (u8 *)&p_drv_buf->abts_dst_fcid[idx];
941                         return sizeof(p_drv_buf->abts_dst_fcid[idx]);
942                 }
943                 break;
944         }
945         case DRV_TLV_ABTS_1_TIMESTAMP:
946         case DRV_TLV_ABTS_2_TIMESTAMP:
947         case DRV_TLV_ABTS_3_TIMESTAMP:
948         case DRV_TLV_ABTS_4_TIMESTAMP:
949         case DRV_TLV_ABTS_5_TIMESTAMP:
950         {
951                 u8 idx = (p_tlv->tlv_type -
952                           DRV_TLV_ABTS_1_TIMESTAMP) / 2;
953
954                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
955                                                     p_buf);
956         }
957
958         case DRV_TLV_RSCNS_RECEIVED:
959                 if (p_drv_buf->rx_rscn_set) {
960                         p_buf->p_val = (u8 *)&p_drv_buf->rx_rscn;
961                         return sizeof(p_drv_buf->rx_rscn);
962                 }
963                 break;
964         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
965         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
966         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
967         case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
968         {
969                 u8 idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
970
971                 if (p_drv_buf->rx_rscn_nport_set[idx]) {
972                         p_buf->p_val = (u8 *)&p_drv_buf->rx_rscn_nport[idx];
973                         return sizeof(p_drv_buf->rx_rscn_nport[idx]);
974                 }
975                 break;
976         }
977         case DRV_TLV_LUN_RESETS_ISSUED:
978                 if (p_drv_buf->tx_lun_rst_set) {
979                         p_buf->p_val = (u8 *)&p_drv_buf->tx_lun_rst;
980                         return sizeof(p_drv_buf->tx_lun_rst);
981                 }
982                 break;
983         case DRV_TLV_ABORT_TASK_SETS_ISSUED:
984                 if (p_drv_buf->abort_task_sets_set) {
985                         p_buf->p_val = (u8 *)&p_drv_buf->abort_task_sets;
986                         return sizeof(p_drv_buf->abort_task_sets);
987                 }
988                 break;
989         case DRV_TLV_TPRLOS_SENT:
990                 if (p_drv_buf->tx_tprlos_set) {
991                         p_buf->p_val = (u8 *)&p_drv_buf->tx_tprlos;
992                         return sizeof(p_drv_buf->tx_tprlos);
993                 }
994                 break;
995         case DRV_TLV_NOS_SENT_COUNT:
996                 if (p_drv_buf->tx_nos_set) {
997                         p_buf->p_val = (u8 *)&p_drv_buf->tx_nos;
998                         return sizeof(p_drv_buf->tx_nos);
999                 }
1000                 break;
1001         case DRV_TLV_NOS_RECEIVED_COUNT:
1002                 if (p_drv_buf->rx_nos_set) {
1003                         p_buf->p_val = (u8 *)&p_drv_buf->rx_nos;
1004                         return sizeof(p_drv_buf->rx_nos);
1005                 }
1006                 break;
1007         case DRV_TLV_OLS_COUNT:
1008                 if (p_drv_buf->ols_set) {
1009                         p_buf->p_val = (u8 *)&p_drv_buf->ols;
1010                         return sizeof(p_drv_buf->ols);
1011                 }
1012                 break;
1013         case DRV_TLV_LR_COUNT:
1014                 if (p_drv_buf->lr_set) {
1015                         p_buf->p_val = (u8 *)&p_drv_buf->lr;
1016                         return sizeof(p_drv_buf->lr);
1017                 }
1018                 break;
1019         case DRV_TLV_LRR_COUNT:
1020                 if (p_drv_buf->lrr_set) {
1021                         p_buf->p_val = (u8 *)&p_drv_buf->lrr;
1022                         return sizeof(p_drv_buf->lrr);
1023                 }
1024                 break;
1025         case DRV_TLV_LIP_SENT_COUNT:
1026                 if (p_drv_buf->tx_lip_set) {
1027                         p_buf->p_val = (u8 *)&p_drv_buf->tx_lip;
1028                         return sizeof(p_drv_buf->tx_lip);
1029                 }
1030                 break;
1031         case DRV_TLV_LIP_RECEIVED_COUNT:
1032                 if (p_drv_buf->rx_lip_set) {
1033                         p_buf->p_val = (u8 *)&p_drv_buf->rx_lip;
1034                         return sizeof(p_drv_buf->rx_lip);
1035                 }
1036                 break;
1037         case DRV_TLV_EOFA_COUNT:
1038                 if (p_drv_buf->eofa_set) {
1039                         p_buf->p_val = (u8 *)&p_drv_buf->eofa;
1040                         return sizeof(p_drv_buf->eofa);
1041                 }
1042                 break;
1043         case DRV_TLV_EOFNI_COUNT:
1044                 if (p_drv_buf->eofni_set) {
1045                         p_buf->p_val = (u8 *)&p_drv_buf->eofni;
1046                         return sizeof(p_drv_buf->eofni);
1047                 }
1048                 break;
1049         case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
1050                 if (p_drv_buf->scsi_chks_set) {
1051                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_chks;
1052                         return sizeof(p_drv_buf->scsi_chks);
1053                 }
1054                 break;
1055         case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
1056                 if (p_drv_buf->scsi_cond_met_set) {
1057                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_cond_met;
1058                         return sizeof(p_drv_buf->scsi_cond_met);
1059                 }
1060                 break;
1061         case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
1062                 if (p_drv_buf->scsi_busy_set) {
1063                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_busy;
1064                         return sizeof(p_drv_buf->scsi_busy);
1065                 }
1066                 break;
1067         case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
1068                 if (p_drv_buf->scsi_inter_set) {
1069                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_inter;
1070                         return sizeof(p_drv_buf->scsi_inter);
1071                 }
1072                 break;
1073         case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
1074                 if (p_drv_buf->scsi_inter_cond_met_set) {
1075                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_inter_cond_met;
1076                         return sizeof(p_drv_buf->scsi_inter_cond_met);
1077                 }
1078                 break;
1079         case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
1080                 if (p_drv_buf->scsi_rsv_conflicts_set) {
1081                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_rsv_conflicts;
1082                         return sizeof(p_drv_buf->scsi_rsv_conflicts);
1083                 }
1084                 break;
1085         case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
1086                 if (p_drv_buf->scsi_tsk_full_set) {
1087                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_tsk_full;
1088                         return sizeof(p_drv_buf->scsi_tsk_full);
1089                 }
1090                 break;
1091         case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
1092                 if (p_drv_buf->scsi_aca_active_set) {
1093                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_aca_active;
1094                         return sizeof(p_drv_buf->scsi_aca_active);
1095                 }
1096                 break;
1097         case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
1098                 if (p_drv_buf->scsi_tsk_abort_set) {
1099                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_tsk_abort;
1100                         return sizeof(p_drv_buf->scsi_tsk_abort);
1101                 }
1102                 break;
1103         case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
1104         case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
1105         case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
1106         case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
1107         case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
1108         {
1109                 u8 idx = (p_tlv->tlv_type -
1110                           DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
1111
1112                 if (p_drv_buf->scsi_rx_chk_set[idx]) {
1113                         p_buf->p_val = (u8 *)&p_drv_buf->scsi_rx_chk[idx];
1114                         return sizeof(p_drv_buf->scsi_rx_chk[idx]);
1115                 }
1116                 break;
1117         }
1118         case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
1119         case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
1120         case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
1121         case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
1122         case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
1123         {
1124                 u8 idx = (p_tlv->tlv_type -
1125                           DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
1126
1127                 return ecore_mfw_get_tlv_time_value(&p_drv_buf->scsi_chk_tstamp[idx],
1128                                                     p_buf);
1129         }
1130
1131         default:
1132                 break;
1133         }
1134
1135         return -1;
1136 }
1137
1138 static int
1139 ecore_mfw_get_iscsi_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
1140                               struct ecore_mfw_tlv_iscsi *p_drv_buf,
1141                               struct ecore_tlv_parsed_buf *p_buf)
1142 {
1143         switch (p_tlv->tlv_type) {
1144         case DRV_TLV_TARGET_LLMNR_ENABLED:
1145                 if (p_drv_buf->target_llmnr_set) {
1146                         p_buf->p_val = (u8 *)&p_drv_buf->target_llmnr;
1147                         return sizeof(p_drv_buf->target_llmnr);
1148                 }
1149                 break;
1150         case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
1151                 if (p_drv_buf->header_digest_set) {
1152                         p_buf->p_val = (u8 *)&p_drv_buf->header_digest;
1153                         return sizeof(p_drv_buf->header_digest);
1154                 }
1155                 break;
1156         case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
1157                 if (p_drv_buf->data_digest_set) {
1158                         p_buf->p_val = (u8 *)&p_drv_buf->data_digest;
1159                         return sizeof(p_drv_buf->data_digest);
1160                 }
1161                 break;
1162         case DRV_TLV_AUTHENTICATION_METHOD:
1163                 if (p_drv_buf->auth_method_set) {
1164                         p_buf->p_val = (u8 *)&p_drv_buf->auth_method;
1165                         return sizeof(p_drv_buf->auth_method);
1166                 }
1167                 break;
1168         case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
1169                 if (p_drv_buf->boot_taget_portal_set) {
1170                         p_buf->p_val = (u8 *)&p_drv_buf->boot_taget_portal;
1171                         return sizeof(p_drv_buf->boot_taget_portal);
1172                 }
1173                 break;
1174         case DRV_TLV_MAX_FRAME_SIZE:
1175                 if (p_drv_buf->frame_size_set) {
1176                         p_buf->p_val = (u8 *)&p_drv_buf->frame_size;
1177                         return sizeof(p_drv_buf->frame_size);
1178                 }
1179                 break;
1180         case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
1181                 if (p_drv_buf->tx_desc_size_set) {
1182                         p_buf->p_val = (u8 *)&p_drv_buf->tx_desc_size;
1183                         return sizeof(p_drv_buf->tx_desc_size);
1184                 }
1185                 break;
1186         case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
1187                 if (p_drv_buf->rx_desc_size_set) {
1188                         p_buf->p_val = (u8 *)&p_drv_buf->rx_desc_size;
1189                         return sizeof(p_drv_buf->rx_desc_size);
1190                 }
1191                 break;
1192         case DRV_TLV_ISCSI_BOOT_PROGRESS:
1193                 if (p_drv_buf->boot_progress_set) {
1194                         p_buf->p_val = (u8 *)&p_drv_buf->boot_progress;
1195                         return sizeof(p_drv_buf->boot_progress);
1196                 }
1197                 break;
1198         case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
1199                 if (p_drv_buf->tx_desc_qdepth_set) {
1200                         p_buf->p_val = (u8 *)&p_drv_buf->tx_desc_qdepth;
1201                         return sizeof(p_drv_buf->tx_desc_qdepth);
1202                 }
1203                 break;
1204         case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
1205                 if (p_drv_buf->rx_desc_qdepth_set) {
1206                         p_buf->p_val = (u8 *)&p_drv_buf->rx_desc_qdepth;
1207                         return sizeof(p_drv_buf->rx_desc_qdepth);
1208                 }
1209                 break;
1210         case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
1211                 if (p_drv_buf->rx_frames_set) {
1212                         p_buf->p_val = (u8 *)&p_drv_buf->rx_frames;
1213                         return sizeof(p_drv_buf->rx_frames);
1214                 }
1215                 break;
1216         case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
1217                 if (p_drv_buf->rx_bytes_set) {
1218                         p_buf->p_val = (u8 *)&p_drv_buf->rx_bytes;
1219                         return sizeof(p_drv_buf->rx_bytes);
1220                 }
1221                 break;
1222         case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
1223                 if (p_drv_buf->tx_frames_set) {
1224                         p_buf->p_val = (u8 *)&p_drv_buf->tx_frames;
1225                         return sizeof(p_drv_buf->tx_frames);
1226                 }
1227                 break;
1228         case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
1229                 if (p_drv_buf->tx_bytes_set) {
1230                         p_buf->p_val = (u8 *)&p_drv_buf->tx_bytes;
1231                         return sizeof(p_drv_buf->tx_bytes);
1232                 }
1233                 break;
1234         default:
1235                 break;
1236         }
1237
1238         return -1;
1239 }
1240
1241 static enum _ecore_status_t ecore_mfw_update_tlvs(struct ecore_hwfn *p_hwfn,
1242                                                   u8 tlv_group, u8 *p_mfw_buf,
1243                                                   u32 size)
1244 {
1245         union ecore_mfw_tlv_data *p_tlv_data;
1246         struct ecore_tlv_parsed_buf buffer;
1247         struct ecore_drv_tlv_hdr tlv;
1248         u32 offset;
1249         int len;
1250         u8 *p_tlv;
1251
1252         p_tlv_data = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_tlv_data));
1253         if (!p_tlv_data)
1254                 return ECORE_NOMEM;
1255
1256         if (OSAL_MFW_FILL_TLV_DATA(p_hwfn,tlv_group, p_tlv_data)) {
1257                 OSAL_VFREE(p_hwfn->p_dev, p_tlv_data);
1258                 return ECORE_INVAL;
1259         }
1260
1261         OSAL_MEMSET(&tlv, 0, sizeof(tlv));
1262         for (offset = 0; offset < size;
1263              offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1264                 p_tlv = &p_mfw_buf[offset];
1265                 tlv.tlv_type = TLV_TYPE(p_tlv);
1266                 tlv.tlv_length = TLV_LENGTH(p_tlv);
1267                 tlv.tlv_flags = TLV_FLAGS(p_tlv);
1268
1269                 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1270                            "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
1271                            tlv.tlv_length, tlv.tlv_flags);
1272
1273                 if (tlv_group == ECORE_MFW_TLV_GENERIC)
1274                         len = ecore_mfw_get_gen_tlv_value(&tlv, &p_tlv_data->generic, &buffer);
1275                 else if (tlv_group == ECORE_MFW_TLV_ETH)
1276                         len = ecore_mfw_get_eth_tlv_value(&tlv, &p_tlv_data->eth, &buffer);
1277                 else if (tlv_group == ECORE_MFW_TLV_FCOE)
1278                         len = ecore_mfw_get_fcoe_tlv_value(&tlv, &p_tlv_data->fcoe, &buffer);
1279                 else
1280                         len = ecore_mfw_get_iscsi_tlv_value(&tlv, &p_tlv_data->iscsi, &buffer);
1281
1282                 if (len > 0) {
1283                         OSAL_WARN(len > 4 * tlv.tlv_length,
1284                                   "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
1285                                   len, 4 * tlv.tlv_length);
1286                         len = OSAL_MIN_T(int, len, 4 * tlv.tlv_length);
1287                         tlv.tlv_flags |= ECORE_DRV_TLV_FLAGS_CHANGED;
1288                         TLV_FLAGS(p_tlv) = tlv.tlv_flags;
1289                         OSAL_MEMCPY(p_mfw_buf + offset + sizeof(tlv),
1290                                     buffer.p_val, len);
1291                 }
1292         }
1293
1294         OSAL_VFREE(p_hwfn->p_dev, p_tlv_data);
1295
1296         return ECORE_SUCCESS;
1297 }
1298
1299 enum _ecore_status_t
1300 ecore_mfw_process_tlv_req(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
1301 {
1302         u32 addr, size, offset, resp, param, val;
1303         u8 tlv_group = 0, id, *p_mfw_buf = OSAL_NULL, *p_temp;
1304         u32 global_offsize, global_addr;
1305         enum _ecore_status_t rc;
1306         struct ecore_drv_tlv_hdr tlv;
1307
1308         addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1309                                     PUBLIC_GLOBAL);
1310         global_offsize = ecore_rd(p_hwfn, p_ptt, addr);
1311         global_addr = SECTION_ADDR(global_offsize, 0);
1312         addr = global_addr + OFFSETOF(struct public_global, data_ptr); 
1313         addr = ecore_rd(p_hwfn, p_ptt, addr);
1314         size = ecore_rd(p_hwfn, p_ptt, global_addr +
1315                         OFFSETOF(struct public_global, data_size));
1316
1317         if (!size) {
1318                 DP_NOTICE(p_hwfn, false, "Invalid TLV req size = %d\n", size);
1319                 goto drv_done;
1320         }
1321
1322         p_mfw_buf = (void *)OSAL_VZALLOC(p_hwfn->p_dev, size);
1323         if (!p_mfw_buf) {
1324                 DP_NOTICE(p_hwfn, false, "Failed allocate memory for p_mfw_buf\n");
1325                 goto drv_done;
1326         }
1327
1328         /* Read the TLV request to local buffer. MFW represents the TLV in
1329          * little endian format and mcp returns it bigendian format. Hence
1330          * driver need to convert data to little endian first and then do the
1331          * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
1332          *
1333          */
1334         for (offset = 0; offset < size; offset += sizeof(u32)) {
1335                 val = ecore_rd(p_hwfn, p_ptt, addr + offset);
1336                 val = OSAL_BE32_TO_CPU(val);
1337                 OSAL_MEMCPY(&p_mfw_buf[offset], &val, sizeof(u32));
1338         }
1339
1340         /* Parse the headers to enumerate the requested TLV groups */
1341         for (offset = 0; offset < size; 
1342              offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1343                 p_temp = &p_mfw_buf[offset];
1344                 tlv.tlv_type = TLV_TYPE(p_temp);
1345                 tlv.tlv_length = TLV_LENGTH(p_temp);
1346                 if (ecore_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
1347                         DP_VERBOSE(p_hwfn, ECORE_MSG_DRV,
1348                                    "Un recognized TLV %d\n", tlv.tlv_type);
1349         }
1350
1351         /* Sanitize the TLV groups according to personality */
1352         if ((tlv_group & ECORE_MFW_TLV_FCOE)  &&
1353             p_hwfn->hw_info.personality != ECORE_PCI_FCOE) {
1354                 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1355                            "Skipping FCoE TLVs for non-FCoE function\n");
1356                 tlv_group &= ~ECORE_MFW_TLV_FCOE;
1357         }
1358
1359         if ((tlv_group & ECORE_MFW_TLV_ISCSI) &&
1360             p_hwfn->hw_info.personality != ECORE_PCI_ISCSI) {
1361                 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1362                            "Skipping iSCSI TLVs for non-iSCSI function\n");
1363                 tlv_group &= ~ECORE_MFW_TLV_ISCSI;
1364         }
1365
1366         if ((tlv_group & ECORE_MFW_TLV_ETH) &&
1367             !ECORE_IS_L2_PERSONALITY(p_hwfn)) {
1368                 DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1369                            "Skipping L2 TLVs for non-L2 function\n");
1370                 tlv_group &= ~ECORE_MFW_TLV_ETH;
1371         }
1372
1373         /* Update the TLV values in the local buffer */
1374         for (id = ECORE_MFW_TLV_GENERIC; id < ECORE_MFW_TLV_MAX; id <<= 1) {
1375                 if (tlv_group & id) {
1376                         if (ecore_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
1377                                 goto drv_done;
1378                 }
1379         }
1380
1381         /* Write the TLV data to shared memory. The stream of 4 bytes first need
1382          * to be mem-copied to u32 element to make it as LSB format. And then
1383          * converted to big endian as required by mcp-write.
1384          */
1385         for (offset = 0; offset < size; offset += sizeof(u32)) {
1386                 OSAL_MEMCPY(&val, &p_mfw_buf[offset], sizeof(u32));
1387                 val = OSAL_CPU_TO_BE32(val);
1388                 ecore_wr(p_hwfn, p_ptt, addr + offset, val);
1389         }
1390
1391 drv_done:
1392         rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1393                            &param);
1394
1395         OSAL_VFREE(p_hwfn->p_dev, p_mfw_buf);
1396
1397         return rc;
1398 }