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