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: stable/11/sys/dev/qlnx/qlnxe/ecore_mng_tlv.c 337517 2018-08-09 01:17:35Z davidcs $");
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)
44struct 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
52static enum _ecore_status_t
53ecore_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
267static int
268ecore_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
330static int
331ecore_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
433static int
434ecore_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
464static int
465ecore_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
1138static int
1139ecore_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
1241static 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
1299enum _ecore_status_t
1300ecore_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
1391drv_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