xref: /freebsd/sys/dev/qlnx/qlnxe/ecore_mng_tlv.c (revision 85732ac8)
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 }
1399