1336695Sdavidcs/*
2336695Sdavidcs * Copyright (c) 2018-2019 Cavium, Inc.
3336695Sdavidcs * All rights reserved.
4336695Sdavidcs *
5336695Sdavidcs *  Redistribution and use in source and binary forms, with or without
6336695Sdavidcs *  modification, are permitted provided that the following conditions
7336695Sdavidcs *  are met:
8336695Sdavidcs *
9336695Sdavidcs *  1. Redistributions of source code must retain the above copyright
10336695Sdavidcs *     notice, this list of conditions and the following disclaimer.
11336695Sdavidcs *  2. Redistributions in binary form must reproduce the above copyright
12336695Sdavidcs *     notice, this list of conditions and the following disclaimer in the
13336695Sdavidcs *     documentation and/or other materials provided with the distribution.
14336695Sdavidcs *
15336695Sdavidcs *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16336695Sdavidcs *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17336695Sdavidcs *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18336695Sdavidcs *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19336695Sdavidcs *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20336695Sdavidcs *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21336695Sdavidcs *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22336695Sdavidcs *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23336695Sdavidcs *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24336695Sdavidcs *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25336695Sdavidcs *  POSSIBILITY OF SUCH DAMAGE.
26336695Sdavidcs */
27336695Sdavidcs
28336695Sdavidcs
29336695Sdavidcs#include <sys/cdefs.h>
30336695Sdavidcs__FBSDID("$FreeBSD: stable/10/sys/dev/qlnx/qlnxe/ecore_mng_tlv.c 337519 2018-08-09 01:39:47Z davidcs $");
31336695Sdavidcs
32336695Sdavidcs#include "bcm_osal.h"
33336695Sdavidcs#include "ecore.h"
34336695Sdavidcs#include "ecore_status.h"
35336695Sdavidcs#include "ecore_mcp.h"
36336695Sdavidcs#include "ecore_hw.h"
37336695Sdavidcs#include "reg_addr.h"
38336695Sdavidcs
39336695Sdavidcs#define TLV_TYPE(p)	(p[0])
40336695Sdavidcs#define TLV_LENGTH(p)	(p[1])
41336695Sdavidcs#define TLV_FLAGS(p)	(p[3])
42336695Sdavidcs
43336695Sdavidcs#define ECORE_TLV_DATA_MAX (14)
44336695Sdavidcsstruct ecore_tlv_parsed_buf {
45336695Sdavidcs	/* To be filled with the address to set in Value field */
46336695Sdavidcs	u8 *p_val;
47336695Sdavidcs
48336695Sdavidcs	/* To be used internally in case the value has to be modified */
49336695Sdavidcs	u8 data[ECORE_TLV_DATA_MAX];
50336695Sdavidcs};
51336695Sdavidcs
52336695Sdavidcsstatic enum _ecore_status_t
53336695Sdavidcsecore_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
54336695Sdavidcs{
55336695Sdavidcs	switch(tlv_type) {
56336695Sdavidcs	case DRV_TLV_FEATURE_FLAGS:
57336695Sdavidcs	case DRV_TLV_LOCAL_ADMIN_ADDR:
58336695Sdavidcs	case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
59336695Sdavidcs	case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
60336695Sdavidcs	case DRV_TLV_OS_DRIVER_STATES:
61336695Sdavidcs	case DRV_TLV_PXE_BOOT_PROGRESS:
62336695Sdavidcs	case DRV_TLV_RX_FRAMES_RECEIVED:
63336695Sdavidcs	case DRV_TLV_RX_BYTES_RECEIVED:
64336695Sdavidcs	case DRV_TLV_TX_FRAMES_SENT:
65336695Sdavidcs	case DRV_TLV_TX_BYTES_SENT:
66336695Sdavidcs	case DRV_TLV_NPIV_ENABLED:
67336695Sdavidcs	case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
68336695Sdavidcs	case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
69336695Sdavidcs	case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
70336695Sdavidcs	case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
71336695Sdavidcs	case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
72336695Sdavidcs    case DRV_TLV_NCSI_TX_BYTES_SENT:
73336695Sdavidcs		*tlv_group |= ECORE_MFW_TLV_GENERIC;
74336695Sdavidcs		break;
75336695Sdavidcs	case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
76336695Sdavidcs	case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
77336695Sdavidcs	case DRV_TLV_PROMISCUOUS_MODE:
78336695Sdavidcs	case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
79336695Sdavidcs	case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
80336695Sdavidcs	case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
81336695Sdavidcs	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
82336695Sdavidcs	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
83336695Sdavidcs	case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
84336695Sdavidcs	case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
85336695Sdavidcs	case DRV_TLV_IOV_OFFLOAD:
86336695Sdavidcs	case DRV_TLV_TX_QUEUES_EMPTY:
87336695Sdavidcs	case DRV_TLV_RX_QUEUES_EMPTY:
88336695Sdavidcs	case DRV_TLV_TX_QUEUES_FULL:
89336695Sdavidcs	case DRV_TLV_RX_QUEUES_FULL:
90336695Sdavidcs		*tlv_group |= ECORE_MFW_TLV_ETH;
91336695Sdavidcs		break;
92336695Sdavidcs	case DRV_TLV_SCSI_TO:
93336695Sdavidcs	case DRV_TLV_R_T_TOV:
94336695Sdavidcs	case DRV_TLV_R_A_TOV:
95336695Sdavidcs	case DRV_TLV_E_D_TOV:
96336695Sdavidcs	case DRV_TLV_CR_TOV:
97336695Sdavidcs	case DRV_TLV_BOOT_TYPE:
98336695Sdavidcs	case DRV_TLV_NPIV_STATE:
99336695Sdavidcs	case DRV_TLV_NUM_OF_NPIV_IDS:
100336695Sdavidcs	case DRV_TLV_SWITCH_NAME:
101336695Sdavidcs	case DRV_TLV_SWITCH_PORT_NUM:
102336695Sdavidcs	case DRV_TLV_SWITCH_PORT_ID:
103336695Sdavidcs	case DRV_TLV_VENDOR_NAME:
104336695Sdavidcs	case DRV_TLV_SWITCH_MODEL:
105336695Sdavidcs	case DRV_TLV_SWITCH_FW_VER:
106336695Sdavidcs	case DRV_TLV_QOS_PRIORITY_PER_802_1P:
107336695Sdavidcs	case DRV_TLV_PORT_ALIAS:
108336695Sdavidcs	case DRV_TLV_PORT_STATE:
109336695Sdavidcs	case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
110336695Sdavidcs	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
111336695Sdavidcs	case DRV_TLV_LINK_FAILURE_COUNT:
112336695Sdavidcs	case DRV_TLV_FCOE_BOOT_PROGRESS:
113336695Sdavidcs	case DRV_TLV_RX_BROADCAST_PACKETS:
114336695Sdavidcs	case DRV_TLV_TX_BROADCAST_PACKETS:
115336695Sdavidcs	case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
116336695Sdavidcs	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
117336695Sdavidcs	case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
118336695Sdavidcs	case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
119336695Sdavidcs	case DRV_TLV_FCOE_TX_FRAMES_SENT:
120336695Sdavidcs	case DRV_TLV_FCOE_TX_BYTES_SENT:
121336695Sdavidcs	case DRV_TLV_CRC_ERROR_COUNT:
122336695Sdavidcs	case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
123336695Sdavidcs	case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
124336695Sdavidcs	case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
125336695Sdavidcs	case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
126336695Sdavidcs	case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
127336695Sdavidcs	case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
128336695Sdavidcs	case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
129336695Sdavidcs	case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
130336695Sdavidcs	case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
131336695Sdavidcs	case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
132336695Sdavidcs	case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
133336695Sdavidcs	case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
134336695Sdavidcs	case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
135336695Sdavidcs	case DRV_TLV_DISPARITY_ERROR_COUNT:
136336695Sdavidcs	case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
137336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
138336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
139336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
140336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
141336695Sdavidcs	case DRV_TLV_LAST_FLOGI_TIMESTAMP:
142336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
143336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
144336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
145336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
146336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
147336695Sdavidcs	case DRV_TLV_LAST_FLOGI_RJT:
148336695Sdavidcs	case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
149336695Sdavidcs	case DRV_TLV_FDISCS_SENT_COUNT:
150336695Sdavidcs	case DRV_TLV_FDISC_ACCS_RECEIVED:
151336695Sdavidcs	case DRV_TLV_FDISC_RJTS_RECEIVED:
152336695Sdavidcs	case DRV_TLV_PLOGI_SENT_COUNT:
153336695Sdavidcs	case DRV_TLV_PLOGI_ACCS_RECEIVED:
154336695Sdavidcs	case DRV_TLV_PLOGI_RJTS_RECEIVED:
155336695Sdavidcs	case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
156336695Sdavidcs	case DRV_TLV_PLOGI_1_TIMESTAMP:
157336695Sdavidcs	case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
158336695Sdavidcs	case DRV_TLV_PLOGI_2_TIMESTAMP:
159336695Sdavidcs	case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
160336695Sdavidcs	case DRV_TLV_PLOGI_3_TIMESTAMP:
161336695Sdavidcs	case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
162336695Sdavidcs	case DRV_TLV_PLOGI_4_TIMESTAMP:
163336695Sdavidcs	case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
164336695Sdavidcs	case DRV_TLV_PLOGI_5_TIMESTAMP:
165336695Sdavidcs	case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
166336695Sdavidcs	case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
167336695Sdavidcs	case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
168336695Sdavidcs	case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
169336695Sdavidcs	case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
170336695Sdavidcs	case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
171336695Sdavidcs	case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
172336695Sdavidcs	case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
173336695Sdavidcs	case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
174336695Sdavidcs	case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
175336695Sdavidcs	case DRV_TLV_LOGOS_ISSUED:
176336695Sdavidcs	case DRV_TLV_LOGO_ACCS_RECEIVED:
177336695Sdavidcs	case DRV_TLV_LOGO_RJTS_RECEIVED:
178336695Sdavidcs	case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
179336695Sdavidcs	case DRV_TLV_LOGO_1_TIMESTAMP:
180336695Sdavidcs	case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
181336695Sdavidcs	case DRV_TLV_LOGO_2_TIMESTAMP:
182336695Sdavidcs	case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
183336695Sdavidcs	case DRV_TLV_LOGO_3_TIMESTAMP:
184336695Sdavidcs	case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
185336695Sdavidcs	case DRV_TLV_LOGO_4_TIMESTAMP:
186336695Sdavidcs	case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
187336695Sdavidcs	case DRV_TLV_LOGO_5_TIMESTAMP:
188336695Sdavidcs	case DRV_TLV_LOGOS_RECEIVED:
189336695Sdavidcs	case DRV_TLV_ACCS_ISSUED:
190336695Sdavidcs	case DRV_TLV_PRLIS_ISSUED:
191336695Sdavidcs	case DRV_TLV_ACCS_RECEIVED:
192336695Sdavidcs	case DRV_TLV_ABTS_SENT_COUNT:
193336695Sdavidcs	case DRV_TLV_ABTS_ACCS_RECEIVED:
194336695Sdavidcs	case DRV_TLV_ABTS_RJTS_RECEIVED:
195336695Sdavidcs	case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
196336695Sdavidcs	case DRV_TLV_ABTS_1_TIMESTAMP:
197336695Sdavidcs	case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
198336695Sdavidcs	case DRV_TLV_ABTS_2_TIMESTAMP:
199336695Sdavidcs	case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
200336695Sdavidcs	case DRV_TLV_ABTS_3_TIMESTAMP:
201336695Sdavidcs	case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
202336695Sdavidcs	case DRV_TLV_ABTS_4_TIMESTAMP:
203336695Sdavidcs	case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
204336695Sdavidcs	case DRV_TLV_ABTS_5_TIMESTAMP:
205336695Sdavidcs	case DRV_TLV_RSCNS_RECEIVED:
206336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
207336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
208336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
209336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
210336695Sdavidcs	case DRV_TLV_LUN_RESETS_ISSUED:
211336695Sdavidcs	case DRV_TLV_ABORT_TASK_SETS_ISSUED:
212336695Sdavidcs	case DRV_TLV_TPRLOS_SENT:
213336695Sdavidcs	case DRV_TLV_NOS_SENT_COUNT:
214336695Sdavidcs	case DRV_TLV_NOS_RECEIVED_COUNT:
215336695Sdavidcs	case DRV_TLV_OLS_COUNT:
216336695Sdavidcs	case DRV_TLV_LR_COUNT:
217336695Sdavidcs	case DRV_TLV_LRR_COUNT:
218336695Sdavidcs	case DRV_TLV_LIP_SENT_COUNT:
219336695Sdavidcs	case DRV_TLV_LIP_RECEIVED_COUNT:
220336695Sdavidcs	case DRV_TLV_EOFA_COUNT:
221336695Sdavidcs	case DRV_TLV_EOFNI_COUNT:
222336695Sdavidcs	case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
223336695Sdavidcs	case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
224336695Sdavidcs	case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
225336695Sdavidcs	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
226336695Sdavidcs	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
227336695Sdavidcs	case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
228336695Sdavidcs	case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
229336695Sdavidcs	case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
230336695Sdavidcs	case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
231336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
232336695Sdavidcs	case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
233336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
234336695Sdavidcs	case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
235336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
236336695Sdavidcs	case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
237336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
238336695Sdavidcs	case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
239336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
240336695Sdavidcs	case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
241336695Sdavidcs		*tlv_group = ECORE_MFW_TLV_FCOE;
242336695Sdavidcs		break;
243336695Sdavidcs	case DRV_TLV_TARGET_LLMNR_ENABLED:
244336695Sdavidcs	case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
245336695Sdavidcs	case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
246336695Sdavidcs	case DRV_TLV_AUTHENTICATION_METHOD:
247336695Sdavidcs	case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
248336695Sdavidcs	case DRV_TLV_MAX_FRAME_SIZE:
249336695Sdavidcs	case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
250336695Sdavidcs	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
251336695Sdavidcs	case DRV_TLV_ISCSI_BOOT_PROGRESS:
252336695Sdavidcs	case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
253336695Sdavidcs	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
254336695Sdavidcs	case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
255336695Sdavidcs	case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
256336695Sdavidcs	case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
257336695Sdavidcs	case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
258336695Sdavidcs		*tlv_group |= ECORE_MFW_TLV_ISCSI;
259336695Sdavidcs		break;
260336695Sdavidcs	default:
261336695Sdavidcs		return ECORE_INVAL;
262336695Sdavidcs	}
263336695Sdavidcs
264336695Sdavidcs	return ECORE_SUCCESS;
265336695Sdavidcs}
266336695Sdavidcs
267336695Sdavidcsstatic int
268336695Sdavidcsecore_mfw_get_gen_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
269336695Sdavidcs			    struct ecore_mfw_tlv_generic *p_drv_buf,
270336695Sdavidcs			    struct ecore_tlv_parsed_buf *p_buf)
271336695Sdavidcs{
272336695Sdavidcs	switch (p_tlv->tlv_type) {
273336695Sdavidcs	case DRV_TLV_FEATURE_FLAGS:
274336695Sdavidcs		if (p_drv_buf->flags.b_set) {
275336695Sdavidcs			OSAL_MEM_ZERO(p_buf->data,
276336695Sdavidcs				      sizeof(u8) * ECORE_TLV_DATA_MAX);
277336695Sdavidcs			p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
278336695Sdavidcs					 1 : 0;
279336695Sdavidcs			p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
280336695Sdavidcs					   1 : 0) << 1;
281336695Sdavidcs			p_buf->p_val = p_buf->data;
282336695Sdavidcs			return 2;
283336695Sdavidcs		}
284336695Sdavidcs		break;
285336695Sdavidcs
286336695Sdavidcs	case DRV_TLV_LOCAL_ADMIN_ADDR:
287336695Sdavidcs	case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
288336695Sdavidcs	case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
289336695Sdavidcs	{
290336695Sdavidcs		int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
291336695Sdavidcs
292336695Sdavidcs		if (p_drv_buf->mac_set[idx]) {
293336695Sdavidcs			p_buf->p_val = p_drv_buf->mac[idx];
294336695Sdavidcs			return 6;
295336695Sdavidcs		}
296336695Sdavidcs		break;
297336695Sdavidcs	}
298336695Sdavidcs
299336695Sdavidcs	case DRV_TLV_RX_FRAMES_RECEIVED:
300336695Sdavidcs		if (p_drv_buf->rx_frames_set) {
301336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_frames;
302336695Sdavidcs			return sizeof(p_drv_buf->rx_frames);
303336695Sdavidcs		}
304336695Sdavidcs		break;
305336695Sdavidcs	case DRV_TLV_RX_BYTES_RECEIVED:
306336695Sdavidcs		if (p_drv_buf->rx_bytes_set) {
307336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_bytes;
308336695Sdavidcs			return sizeof(p_drv_buf->rx_bytes);
309336695Sdavidcs		}
310336695Sdavidcs		break;
311336695Sdavidcs	case DRV_TLV_TX_FRAMES_SENT:
312336695Sdavidcs		if (p_drv_buf->tx_frames_set) {
313336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_frames;
314336695Sdavidcs			return sizeof(p_drv_buf->tx_frames);
315336695Sdavidcs		}
316336695Sdavidcs		break;
317336695Sdavidcs	case DRV_TLV_TX_BYTES_SENT:
318336695Sdavidcs		if (p_drv_buf->tx_bytes_set) {
319336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_bytes;
320336695Sdavidcs			return sizeof(p_drv_buf->tx_bytes);
321336695Sdavidcs		}
322336695Sdavidcs		break;
323336695Sdavidcs	default:
324336695Sdavidcs		break;
325336695Sdavidcs	}
326336695Sdavidcs
327336695Sdavidcs	return -1;
328336695Sdavidcs}
329336695Sdavidcs
330336695Sdavidcsstatic int
331336695Sdavidcsecore_mfw_get_eth_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
332336695Sdavidcs			    struct ecore_mfw_tlv_eth *p_drv_buf,
333336695Sdavidcs			    struct ecore_tlv_parsed_buf *p_buf)
334336695Sdavidcs{
335336695Sdavidcs	switch (p_tlv->tlv_type) {
336336695Sdavidcs	case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
337336695Sdavidcs		if (p_drv_buf->lso_maxoff_size_set) {
338336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->lso_maxoff_size;
339336695Sdavidcs			return sizeof(p_drv_buf->lso_maxoff_size);
340336695Sdavidcs		}
341336695Sdavidcs		break;
342336695Sdavidcs	case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
343336695Sdavidcs		if (p_drv_buf->lso_minseg_size_set) {
344336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->lso_minseg_size;
345336695Sdavidcs			return sizeof(p_drv_buf->lso_minseg_size);
346336695Sdavidcs		}
347336695Sdavidcs		break;
348336695Sdavidcs	case DRV_TLV_PROMISCUOUS_MODE:
349336695Sdavidcs		if (p_drv_buf->prom_mode_set) {
350336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->prom_mode;
351336695Sdavidcs			return sizeof(p_drv_buf->prom_mode);
352336695Sdavidcs		}
353336695Sdavidcs		break;
354336695Sdavidcs	case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
355336695Sdavidcs		if (p_drv_buf->tx_descr_size_set) {
356336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_descr_size;
357336695Sdavidcs			return sizeof(p_drv_buf->tx_descr_size);
358336695Sdavidcs		}
359336695Sdavidcs		break;
360336695Sdavidcs	case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
361336695Sdavidcs		if (p_drv_buf->rx_descr_size_set) {
362336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_descr_size;
363336695Sdavidcs			return sizeof(p_drv_buf->rx_descr_size);
364336695Sdavidcs		}
365336695Sdavidcs		break;
366336695Sdavidcs	case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
367336695Sdavidcs		if (p_drv_buf->netq_count_set) {
368336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->netq_count;
369336695Sdavidcs			return sizeof(p_drv_buf->netq_count);
370336695Sdavidcs		}
371336695Sdavidcs		break;
372336695Sdavidcs	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
373336695Sdavidcs		if (p_drv_buf->tcp4_offloads_set) {
374336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tcp4_offloads;
375336695Sdavidcs			return sizeof(p_drv_buf->tcp4_offloads);
376336695Sdavidcs		}
377336695Sdavidcs		break;
378336695Sdavidcs	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
379336695Sdavidcs		if (p_drv_buf->tcp6_offloads_set) {
380336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tcp6_offloads;
381336695Sdavidcs			return sizeof(p_drv_buf->tcp6_offloads);
382336695Sdavidcs		}
383336695Sdavidcs		break;
384336695Sdavidcs	case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
385336695Sdavidcs		if (p_drv_buf->tx_descr_qdepth_set) {
386336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_descr_qdepth;
387336695Sdavidcs			return sizeof(p_drv_buf->tx_descr_qdepth);
388336695Sdavidcs		}
389336695Sdavidcs		break;
390336695Sdavidcs	case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
391336695Sdavidcs		if (p_drv_buf->rx_descr_qdepth_set) {
392336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_descr_qdepth;
393336695Sdavidcs			return sizeof(p_drv_buf->rx_descr_qdepth);
394336695Sdavidcs		}
395336695Sdavidcs		break;
396336695Sdavidcs	case DRV_TLV_IOV_OFFLOAD:
397336695Sdavidcs		if (p_drv_buf->iov_offload_set) {
398336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->iov_offload;
399336695Sdavidcs			return sizeof(p_drv_buf->iov_offload);
400336695Sdavidcs		}
401336695Sdavidcs		break;
402336695Sdavidcs	case DRV_TLV_TX_QUEUES_EMPTY:
403336695Sdavidcs		if (p_drv_buf->txqs_empty_set) {
404336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->txqs_empty;
405336695Sdavidcs			return sizeof(p_drv_buf->txqs_empty);
406336695Sdavidcs		}
407336695Sdavidcs		break;
408336695Sdavidcs	case DRV_TLV_RX_QUEUES_EMPTY:
409336695Sdavidcs		if (p_drv_buf->rxqs_empty_set) {
410336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rxqs_empty;
411336695Sdavidcs			return sizeof(p_drv_buf->rxqs_empty);
412336695Sdavidcs		}
413336695Sdavidcs		break;
414336695Sdavidcs	case DRV_TLV_TX_QUEUES_FULL:
415336695Sdavidcs		if (p_drv_buf->num_txqs_full_set) {
416336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->num_txqs_full;
417336695Sdavidcs			return sizeof(p_drv_buf->num_txqs_full);
418336695Sdavidcs		}
419336695Sdavidcs		break;
420336695Sdavidcs	case DRV_TLV_RX_QUEUES_FULL:
421336695Sdavidcs		if (p_drv_buf->num_rxqs_full_set) {
422336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->num_rxqs_full;
423336695Sdavidcs			return sizeof(p_drv_buf->num_rxqs_full);
424336695Sdavidcs		}
425336695Sdavidcs		break;
426336695Sdavidcs	default:
427336695Sdavidcs		break;
428336695Sdavidcs	}
429336695Sdavidcs
430336695Sdavidcs	return -1;
431336695Sdavidcs}
432336695Sdavidcs
433336695Sdavidcsstatic int
434336695Sdavidcsecore_mfw_get_tlv_time_value(struct ecore_mfw_tlv_time *p_time,
435336695Sdavidcs			     struct ecore_tlv_parsed_buf *p_buf)
436336695Sdavidcs{
437336695Sdavidcs	if (!p_time->b_set)
438336695Sdavidcs		return -1;
439336695Sdavidcs
440336695Sdavidcs	/* Validate numbers */
441336695Sdavidcs	if (p_time->month > 12)
442336695Sdavidcs		p_time->month = 0;
443336695Sdavidcs	if (p_time->day > 31)
444336695Sdavidcs		p_time->day = 0;
445336695Sdavidcs	if (p_time->hour > 23)
446336695Sdavidcs		p_time->hour = 0;
447336695Sdavidcs	if (p_time->min > 59)
448336695Sdavidcs		p_time->hour = 0;
449336695Sdavidcs	if (p_time->msec > 999)
450336695Sdavidcs		p_time->msec = 0;
451336695Sdavidcs	if (p_time->usec > 999)
452336695Sdavidcs		p_time->usec = 0;
453336695Sdavidcs
454336695Sdavidcs	OSAL_MEM_ZERO(p_buf->data, sizeof(u8) * ECORE_TLV_DATA_MAX);
455336695Sdavidcs	OSAL_SNPRINTF(p_buf->data, 14, "%d%d%d%d%d%d",
456336695Sdavidcs		      p_time->month, p_time->day,
457336695Sdavidcs		      p_time->hour, p_time->min,
458336695Sdavidcs		      p_time->msec, p_time->usec);
459336695Sdavidcs
460336695Sdavidcs	p_buf->p_val = p_buf->data;
461336695Sdavidcs	return 14;
462336695Sdavidcs}
463336695Sdavidcs
464336695Sdavidcsstatic int
465336695Sdavidcsecore_mfw_get_fcoe_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
466336695Sdavidcs			     struct ecore_mfw_tlv_fcoe *p_drv_buf,
467336695Sdavidcs			     struct ecore_tlv_parsed_buf *p_buf)
468336695Sdavidcs{
469336695Sdavidcs	switch (p_tlv->tlv_type) {
470336695Sdavidcs	case DRV_TLV_SCSI_TO:
471336695Sdavidcs		if (p_drv_buf->scsi_timeout_set) {
472336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_timeout;
473336695Sdavidcs			return sizeof(p_drv_buf->scsi_timeout);
474336695Sdavidcs		}
475336695Sdavidcs		break;
476336695Sdavidcs	case DRV_TLV_R_T_TOV:
477336695Sdavidcs		if (p_drv_buf->rt_tov_set) {
478336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rt_tov;
479336695Sdavidcs			return sizeof(p_drv_buf->rt_tov);
480336695Sdavidcs		}
481336695Sdavidcs		break;
482336695Sdavidcs	case DRV_TLV_R_A_TOV:
483336695Sdavidcs		if (p_drv_buf->ra_tov_set) {
484336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->ra_tov;
485336695Sdavidcs			return sizeof(p_drv_buf->ra_tov);
486336695Sdavidcs		}
487336695Sdavidcs		break;
488336695Sdavidcs	case DRV_TLV_E_D_TOV:
489336695Sdavidcs		if (p_drv_buf->ed_tov_set) {
490336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->ed_tov;
491336695Sdavidcs			return sizeof(p_drv_buf->ed_tov);
492336695Sdavidcs		}
493336695Sdavidcs		break;
494336695Sdavidcs	case DRV_TLV_CR_TOV:
495336695Sdavidcs		if (p_drv_buf->cr_tov_set) {
496336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->cr_tov;
497336695Sdavidcs			return sizeof(p_drv_buf->cr_tov);
498336695Sdavidcs		}
499336695Sdavidcs		break;
500336695Sdavidcs	case DRV_TLV_BOOT_TYPE:
501336695Sdavidcs		if (p_drv_buf->boot_type_set) {
502336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->boot_type;
503336695Sdavidcs			return sizeof(p_drv_buf->boot_type);
504336695Sdavidcs		}
505336695Sdavidcs		break;
506336695Sdavidcs	case DRV_TLV_NPIV_STATE:
507336695Sdavidcs		if (p_drv_buf->npiv_state_set) {
508336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->npiv_state;
509336695Sdavidcs			return sizeof(p_drv_buf->npiv_state);
510336695Sdavidcs		}
511336695Sdavidcs		break;
512336695Sdavidcs	case DRV_TLV_NUM_OF_NPIV_IDS:
513336695Sdavidcs		if (p_drv_buf->num_npiv_ids_set) {
514336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->num_npiv_ids;
515336695Sdavidcs			return sizeof(p_drv_buf->num_npiv_ids);
516336695Sdavidcs		}
517336695Sdavidcs		break;
518336695Sdavidcs	case DRV_TLV_SWITCH_NAME:
519336695Sdavidcs		if (p_drv_buf->switch_name_set) {
520336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->switch_name;
521336695Sdavidcs			return sizeof(p_drv_buf->switch_name);
522336695Sdavidcs		}
523336695Sdavidcs		break;
524336695Sdavidcs	case DRV_TLV_SWITCH_PORT_NUM:
525336695Sdavidcs		if (p_drv_buf->switch_portnum_set) {
526336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->switch_portnum;
527336695Sdavidcs			return sizeof(p_drv_buf->switch_portnum);
528336695Sdavidcs		}
529336695Sdavidcs		break;
530336695Sdavidcs	case DRV_TLV_SWITCH_PORT_ID:
531336695Sdavidcs		if (p_drv_buf->switch_portid_set) {
532336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->switch_portid;
533336695Sdavidcs			return sizeof(p_drv_buf->switch_portid);
534336695Sdavidcs		}
535336695Sdavidcs		break;
536336695Sdavidcs	case DRV_TLV_VENDOR_NAME:
537336695Sdavidcs		if (p_drv_buf->vendor_name_set) {
538336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->vendor_name;
539336695Sdavidcs			return sizeof(p_drv_buf->vendor_name);
540336695Sdavidcs		}
541336695Sdavidcs		break;
542336695Sdavidcs	case DRV_TLV_SWITCH_MODEL:
543336695Sdavidcs		if (p_drv_buf->switch_model_set) {
544336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->switch_model;
545336695Sdavidcs			return sizeof(p_drv_buf->switch_model);
546336695Sdavidcs		}
547336695Sdavidcs		break;
548336695Sdavidcs	case DRV_TLV_SWITCH_FW_VER:
549336695Sdavidcs		if (p_drv_buf->switch_fw_version_set) {
550336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->switch_fw_version;
551336695Sdavidcs			return sizeof(p_drv_buf->switch_fw_version);
552336695Sdavidcs		}
553336695Sdavidcs		break;
554336695Sdavidcs	case DRV_TLV_QOS_PRIORITY_PER_802_1P:
555336695Sdavidcs		if (p_drv_buf->qos_pri_set) {
556336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->qos_pri;
557336695Sdavidcs			return sizeof(p_drv_buf->qos_pri);
558336695Sdavidcs		}
559336695Sdavidcs		break;
560336695Sdavidcs	case DRV_TLV_PORT_ALIAS:
561336695Sdavidcs		if (p_drv_buf->port_alias_set) {
562336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->port_alias;
563336695Sdavidcs			return sizeof(p_drv_buf->port_alias);
564336695Sdavidcs		}
565336695Sdavidcs		break;
566336695Sdavidcs	case DRV_TLV_PORT_STATE:
567336695Sdavidcs		if (p_drv_buf->port_state_set) {
568336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->port_state;
569336695Sdavidcs			return sizeof(p_drv_buf->port_state);
570336695Sdavidcs		}
571336695Sdavidcs		break;
572336695Sdavidcs	case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
573336695Sdavidcs		if (p_drv_buf->fip_tx_descr_size_set) {
574336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fip_tx_descr_size;
575336695Sdavidcs			return sizeof(p_drv_buf->fip_tx_descr_size);
576336695Sdavidcs		}
577336695Sdavidcs		break;
578336695Sdavidcs	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
579336695Sdavidcs		if (p_drv_buf->fip_rx_descr_size_set) {
580336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fip_rx_descr_size;
581336695Sdavidcs			return sizeof(p_drv_buf->fip_rx_descr_size);
582336695Sdavidcs		}
583336695Sdavidcs		break;
584336695Sdavidcs	case DRV_TLV_LINK_FAILURE_COUNT:
585336695Sdavidcs		if (p_drv_buf->link_failures_set) {
586336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->link_failures;
587336695Sdavidcs			return sizeof(p_drv_buf->link_failures);
588336695Sdavidcs		}
589336695Sdavidcs		break;
590336695Sdavidcs	case DRV_TLV_FCOE_BOOT_PROGRESS:
591336695Sdavidcs		if (p_drv_buf->fcoe_boot_progress_set) {
592336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_boot_progress;
593336695Sdavidcs			return sizeof(p_drv_buf->fcoe_boot_progress);
594336695Sdavidcs		}
595336695Sdavidcs		break;
596336695Sdavidcs	case DRV_TLV_RX_BROADCAST_PACKETS:
597336695Sdavidcs		if (p_drv_buf->rx_bcast_set) {
598336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_bcast;
599336695Sdavidcs			return sizeof(p_drv_buf->rx_bcast);
600336695Sdavidcs		}
601336695Sdavidcs		break;
602336695Sdavidcs	case DRV_TLV_TX_BROADCAST_PACKETS:
603336695Sdavidcs		if (p_drv_buf->tx_bcast_set) {
604336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_bcast;
605336695Sdavidcs			return sizeof(p_drv_buf->tx_bcast);
606336695Sdavidcs		}
607336695Sdavidcs		break;
608336695Sdavidcs	case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
609336695Sdavidcs		if (p_drv_buf->fcoe_txq_depth_set) {
610336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_txq_depth;
611336695Sdavidcs			return sizeof(p_drv_buf->fcoe_txq_depth);
612336695Sdavidcs		}
613336695Sdavidcs		break;
614336695Sdavidcs	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
615336695Sdavidcs		if (p_drv_buf->fcoe_rxq_depth_set) {
616336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rxq_depth;
617336695Sdavidcs			return sizeof(p_drv_buf->fcoe_rxq_depth);
618336695Sdavidcs		}
619336695Sdavidcs		break;
620336695Sdavidcs	case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
621336695Sdavidcs		if (p_drv_buf->fcoe_rx_frames_set) {
622336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rx_frames;
623336695Sdavidcs			return sizeof(p_drv_buf->fcoe_rx_frames);
624336695Sdavidcs		}
625336695Sdavidcs		break;
626336695Sdavidcs	case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
627336695Sdavidcs		if (p_drv_buf->fcoe_rx_bytes_set) {
628336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_rx_bytes;
629336695Sdavidcs			return sizeof(p_drv_buf->fcoe_rx_bytes);
630336695Sdavidcs		}
631336695Sdavidcs		break;
632336695Sdavidcs	case DRV_TLV_FCOE_TX_FRAMES_SENT:
633336695Sdavidcs		if (p_drv_buf->fcoe_tx_frames_set) {
634336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_tx_frames;
635336695Sdavidcs			return sizeof(p_drv_buf->fcoe_tx_frames);
636336695Sdavidcs		}
637336695Sdavidcs		break;
638336695Sdavidcs	case DRV_TLV_FCOE_TX_BYTES_SENT:
639336695Sdavidcs		if (p_drv_buf->fcoe_tx_bytes_set) {
640336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fcoe_tx_bytes;
641336695Sdavidcs			return sizeof(p_drv_buf->fcoe_tx_bytes);
642336695Sdavidcs		}
643336695Sdavidcs		break;
644336695Sdavidcs	case DRV_TLV_CRC_ERROR_COUNT:
645336695Sdavidcs		if (p_drv_buf->crc_count_set) {
646336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->crc_count;
647336695Sdavidcs			return sizeof(p_drv_buf->crc_count);
648336695Sdavidcs		}
649336695Sdavidcs		break;
650336695Sdavidcs	case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
651336695Sdavidcs	case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
652336695Sdavidcs	case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
653336695Sdavidcs	case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
654336695Sdavidcs	case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
655336695Sdavidcs	{
656336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
657336695Sdavidcs			  DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
658336695Sdavidcs
659336695Sdavidcs		if (p_drv_buf->crc_err_src_fcid_set[idx]) {
660336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->crc_err_src_fcid[idx];
661336695Sdavidcs			return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
662336695Sdavidcs		}
663336695Sdavidcs		break;
664336695Sdavidcs	}
665336695Sdavidcs
666336695Sdavidcs	case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
667336695Sdavidcs	case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
668336695Sdavidcs	case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
669336695Sdavidcs	case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
670336695Sdavidcs	case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
671336695Sdavidcs	{
672336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
673336695Sdavidcs			  DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
674336695Sdavidcs
675336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
676336695Sdavidcs						    p_buf);
677336695Sdavidcs	}
678336695Sdavidcs
679336695Sdavidcs	case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
680336695Sdavidcs		if (p_drv_buf->losync_err_set) {
681336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->losync_err;
682336695Sdavidcs			return sizeof(p_drv_buf->losync_err);
683336695Sdavidcs		}
684336695Sdavidcs		break;
685336695Sdavidcs	case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
686336695Sdavidcs		if (p_drv_buf->losig_err_set) {
687336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->losig_err;
688336695Sdavidcs			return sizeof(p_drv_buf->losig_err);
689336695Sdavidcs		}
690336695Sdavidcs		break;
691336695Sdavidcs	case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
692336695Sdavidcs		if (p_drv_buf->primtive_err_set) {
693336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->primtive_err;
694336695Sdavidcs			return sizeof(p_drv_buf->primtive_err);
695336695Sdavidcs		}
696336695Sdavidcs		break;
697336695Sdavidcs	case DRV_TLV_DISPARITY_ERROR_COUNT:
698336695Sdavidcs		if (p_drv_buf->disparity_err_set) {
699336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->disparity_err;
700336695Sdavidcs			return sizeof(p_drv_buf->disparity_err);
701336695Sdavidcs		}
702336695Sdavidcs		break;
703336695Sdavidcs	case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
704336695Sdavidcs		if (p_drv_buf->code_violation_err_set) {
705336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->code_violation_err;
706336695Sdavidcs			return sizeof(p_drv_buf->code_violation_err);
707336695Sdavidcs		}
708336695Sdavidcs		break;
709336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
710336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
711336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
712336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
713336695Sdavidcs	{
714336695Sdavidcs		u8 idx = p_tlv->tlv_type -
715336695Sdavidcs			 DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
716336695Sdavidcs		if (p_drv_buf->flogi_param_set[idx]) {
717336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->flogi_param[idx];
718336695Sdavidcs			return sizeof(p_drv_buf->flogi_param[idx]);
719336695Sdavidcs		}
720336695Sdavidcs		break;
721336695Sdavidcs	}
722336695Sdavidcs	case DRV_TLV_LAST_FLOGI_TIMESTAMP:
723336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
724336695Sdavidcs						    p_buf);
725336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
726336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
727336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
728336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
729336695Sdavidcs	{
730336695Sdavidcs		u8 idx = p_tlv->tlv_type -
731336695Sdavidcs			 DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
732336695Sdavidcs
733336695Sdavidcs		if (p_drv_buf->flogi_acc_param_set[idx]) {
734336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->flogi_acc_param[idx];
735336695Sdavidcs			return sizeof(p_drv_buf->flogi_acc_param[idx]);
736336695Sdavidcs		}
737336695Sdavidcs		break;
738336695Sdavidcs	}
739336695Sdavidcs	case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
740336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
741336695Sdavidcs						    p_buf);
742336695Sdavidcs	case DRV_TLV_LAST_FLOGI_RJT:
743336695Sdavidcs		if (p_drv_buf->flogi_rjt_set) {
744336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->flogi_rjt;
745336695Sdavidcs			return sizeof(p_drv_buf->flogi_rjt);
746336695Sdavidcs		}
747336695Sdavidcs		break;
748336695Sdavidcs	case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
749336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
750336695Sdavidcs						    p_buf);
751336695Sdavidcs	case DRV_TLV_FDISCS_SENT_COUNT:
752336695Sdavidcs		if (p_drv_buf->fdiscs_set) {
753336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fdiscs;
754336695Sdavidcs			return sizeof(p_drv_buf->fdiscs);
755336695Sdavidcs		}
756336695Sdavidcs		break;
757336695Sdavidcs	case DRV_TLV_FDISC_ACCS_RECEIVED:
758336695Sdavidcs		if (p_drv_buf->fdisc_acc_set) {
759336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fdisc_acc;
760336695Sdavidcs			return sizeof(p_drv_buf->fdisc_acc);
761336695Sdavidcs		}
762336695Sdavidcs		break;
763336695Sdavidcs	case DRV_TLV_FDISC_RJTS_RECEIVED:
764336695Sdavidcs		if (p_drv_buf->fdisc_rjt_set) {
765336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->fdisc_rjt;
766336695Sdavidcs			return sizeof(p_drv_buf->fdisc_rjt);
767336695Sdavidcs		}
768336695Sdavidcs		break;
769336695Sdavidcs	case DRV_TLV_PLOGI_SENT_COUNT:
770336695Sdavidcs		if (p_drv_buf->plogi_set) {
771336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogi;
772336695Sdavidcs			return sizeof(p_drv_buf->plogi);
773336695Sdavidcs		}
774336695Sdavidcs		break;
775336695Sdavidcs	case DRV_TLV_PLOGI_ACCS_RECEIVED:
776336695Sdavidcs		if (p_drv_buf->plogi_acc_set) {
777336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogi_acc;
778336695Sdavidcs			return sizeof(p_drv_buf->plogi_acc);
779336695Sdavidcs		}
780336695Sdavidcs		break;
781336695Sdavidcs	case DRV_TLV_PLOGI_RJTS_RECEIVED:
782336695Sdavidcs		if (p_drv_buf->plogi_rjt_set) {
783336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogi_rjt;
784336695Sdavidcs			return sizeof(p_drv_buf->plogi_rjt);
785336695Sdavidcs		}
786336695Sdavidcs		break;
787336695Sdavidcs	case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
788336695Sdavidcs	case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
789336695Sdavidcs	case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
790336695Sdavidcs	case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
791336695Sdavidcs	case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
792336695Sdavidcs	{
793336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
794336695Sdavidcs			  DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
795336695Sdavidcs
796336695Sdavidcs		if (p_drv_buf->plogi_dst_fcid_set[idx]) {
797336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogi_dst_fcid[idx];
798336695Sdavidcs			return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
799336695Sdavidcs		}
800336695Sdavidcs		break;
801336695Sdavidcs	}
802336695Sdavidcs	case DRV_TLV_PLOGI_1_TIMESTAMP:
803336695Sdavidcs	case DRV_TLV_PLOGI_2_TIMESTAMP:
804336695Sdavidcs	case DRV_TLV_PLOGI_3_TIMESTAMP:
805336695Sdavidcs	case DRV_TLV_PLOGI_4_TIMESTAMP:
806336695Sdavidcs	case DRV_TLV_PLOGI_5_TIMESTAMP:
807336695Sdavidcs	{
808336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
809336695Sdavidcs			  DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
810336695Sdavidcs
811336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
812336695Sdavidcs						    p_buf);
813336695Sdavidcs	}
814336695Sdavidcs
815336695Sdavidcs	case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
816336695Sdavidcs	case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
817336695Sdavidcs	case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
818336695Sdavidcs	case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
819336695Sdavidcs	case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
820336695Sdavidcs	{
821336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
822336695Sdavidcs			  DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
823336695Sdavidcs
824336695Sdavidcs		if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
825336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogi_acc_src_fcid[idx];
826336695Sdavidcs			return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
827336695Sdavidcs		}
828336695Sdavidcs		break;
829336695Sdavidcs	}
830336695Sdavidcs	case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
831336695Sdavidcs	case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
832336695Sdavidcs	case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
833336695Sdavidcs	case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
834336695Sdavidcs	case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
835336695Sdavidcs	{
836336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
837336695Sdavidcs			  DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
838336695Sdavidcs
839336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogi_acc_tstamp[idx],
840336695Sdavidcs						    p_buf);
841336695Sdavidcs	}
842336695Sdavidcs
843336695Sdavidcs	case DRV_TLV_LOGOS_ISSUED:
844336695Sdavidcs		if (p_drv_buf->tx_plogos_set) {
845336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_plogos;
846336695Sdavidcs			return sizeof(p_drv_buf->tx_plogos);
847336695Sdavidcs		}
848336695Sdavidcs		break;
849336695Sdavidcs	case DRV_TLV_LOGO_ACCS_RECEIVED:
850336695Sdavidcs		if (p_drv_buf->plogo_acc_set) {
851336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogo_acc;
852336695Sdavidcs			return sizeof(p_drv_buf->plogo_acc);
853336695Sdavidcs		}
854336695Sdavidcs		break;
855336695Sdavidcs	case DRV_TLV_LOGO_RJTS_RECEIVED:
856336695Sdavidcs		if (p_drv_buf->plogo_rjt_set) {
857336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogo_rjt;
858336695Sdavidcs			return sizeof(p_drv_buf->plogo_rjt);
859336695Sdavidcs		}
860336695Sdavidcs		break;
861336695Sdavidcs	case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
862336695Sdavidcs	case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
863336695Sdavidcs	case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
864336695Sdavidcs	case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
865336695Sdavidcs	case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
866336695Sdavidcs	{
867336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
868336695Sdavidcs			  DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) / 2;
869336695Sdavidcs
870336695Sdavidcs		if (p_drv_buf->plogo_src_fcid_set[idx]) {
871336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->plogo_src_fcid[idx];
872336695Sdavidcs			return sizeof(p_drv_buf->plogo_src_fcid[idx]);
873336695Sdavidcs		}
874336695Sdavidcs		break;
875336695Sdavidcs	}
876336695Sdavidcs	case DRV_TLV_LOGO_1_TIMESTAMP:
877336695Sdavidcs	case DRV_TLV_LOGO_2_TIMESTAMP:
878336695Sdavidcs	case DRV_TLV_LOGO_3_TIMESTAMP:
879336695Sdavidcs	case DRV_TLV_LOGO_4_TIMESTAMP:
880336695Sdavidcs	case DRV_TLV_LOGO_5_TIMESTAMP:
881336695Sdavidcs	{
882336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
883336695Sdavidcs			  DRV_TLV_LOGO_1_TIMESTAMP) / 2;
884336695Sdavidcs
885336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
886336695Sdavidcs						    p_buf);
887336695Sdavidcs	}
888336695Sdavidcs	case DRV_TLV_LOGOS_RECEIVED:
889336695Sdavidcs		if (p_drv_buf->rx_logos_set) {
890336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_logos;
891336695Sdavidcs			return sizeof(p_drv_buf->rx_logos);
892336695Sdavidcs		}
893336695Sdavidcs		break;
894336695Sdavidcs	case DRV_TLV_ACCS_ISSUED:
895336695Sdavidcs		if (p_drv_buf->tx_accs_set) {
896336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_accs;
897336695Sdavidcs			return sizeof(p_drv_buf->tx_accs);
898336695Sdavidcs		}
899336695Sdavidcs		break;
900336695Sdavidcs	case DRV_TLV_PRLIS_ISSUED:
901336695Sdavidcs		if (p_drv_buf->tx_prlis_set) {
902336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_prlis;
903336695Sdavidcs			return sizeof(p_drv_buf->tx_prlis);
904336695Sdavidcs		}
905336695Sdavidcs		break;
906336695Sdavidcs	case DRV_TLV_ACCS_RECEIVED:
907336695Sdavidcs		if (p_drv_buf->rx_accs_set) {
908336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_accs;
909336695Sdavidcs			return sizeof(p_drv_buf->rx_accs);
910336695Sdavidcs		}
911336695Sdavidcs		break;
912336695Sdavidcs	case DRV_TLV_ABTS_SENT_COUNT:
913336695Sdavidcs		if (p_drv_buf->tx_abts_set) {
914336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_abts;
915336695Sdavidcs			return sizeof(p_drv_buf->tx_abts);
916336695Sdavidcs		}
917336695Sdavidcs		break;
918336695Sdavidcs	case DRV_TLV_ABTS_ACCS_RECEIVED:
919336695Sdavidcs		if (p_drv_buf->rx_abts_acc_set) {
920336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_abts_acc;
921336695Sdavidcs			return sizeof(p_drv_buf->rx_abts_acc);
922336695Sdavidcs		}
923336695Sdavidcs		break;
924336695Sdavidcs	case DRV_TLV_ABTS_RJTS_RECEIVED:
925336695Sdavidcs		if (p_drv_buf->rx_abts_rjt_set) {
926336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_abts_rjt;
927336695Sdavidcs			return sizeof(p_drv_buf->rx_abts_rjt);
928336695Sdavidcs		}
929336695Sdavidcs		break;
930336695Sdavidcs	case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
931336695Sdavidcs	case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
932336695Sdavidcs	case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
933336695Sdavidcs	case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
934336695Sdavidcs	case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
935336695Sdavidcs	{
936336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
937336695Sdavidcs			  DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
938336695Sdavidcs
939336695Sdavidcs		if (p_drv_buf->abts_dst_fcid_set[idx]) {
940336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->abts_dst_fcid[idx];
941336695Sdavidcs			return sizeof(p_drv_buf->abts_dst_fcid[idx]);
942336695Sdavidcs		}
943336695Sdavidcs		break;
944336695Sdavidcs	}
945336695Sdavidcs	case DRV_TLV_ABTS_1_TIMESTAMP:
946336695Sdavidcs	case DRV_TLV_ABTS_2_TIMESTAMP:
947336695Sdavidcs	case DRV_TLV_ABTS_3_TIMESTAMP:
948336695Sdavidcs	case DRV_TLV_ABTS_4_TIMESTAMP:
949336695Sdavidcs	case DRV_TLV_ABTS_5_TIMESTAMP:
950336695Sdavidcs	{
951336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
952336695Sdavidcs			  DRV_TLV_ABTS_1_TIMESTAMP) / 2;
953336695Sdavidcs
954336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
955336695Sdavidcs						    p_buf);
956336695Sdavidcs	}
957336695Sdavidcs
958336695Sdavidcs	case DRV_TLV_RSCNS_RECEIVED:
959336695Sdavidcs		if (p_drv_buf->rx_rscn_set) {
960336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_rscn;
961336695Sdavidcs			return sizeof(p_drv_buf->rx_rscn);
962336695Sdavidcs		}
963336695Sdavidcs		break;
964336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
965336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
966336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
967336695Sdavidcs	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
968336695Sdavidcs	{
969336695Sdavidcs		u8 idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
970336695Sdavidcs
971336695Sdavidcs		if (p_drv_buf->rx_rscn_nport_set[idx]) {
972336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_rscn_nport[idx];
973336695Sdavidcs			return sizeof(p_drv_buf->rx_rscn_nport[idx]);
974336695Sdavidcs		}
975336695Sdavidcs		break;
976336695Sdavidcs	}
977336695Sdavidcs	case DRV_TLV_LUN_RESETS_ISSUED:
978336695Sdavidcs		if (p_drv_buf->tx_lun_rst_set) {
979336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_lun_rst;
980336695Sdavidcs			return sizeof(p_drv_buf->tx_lun_rst);
981336695Sdavidcs		}
982336695Sdavidcs		break;
983336695Sdavidcs	case DRV_TLV_ABORT_TASK_SETS_ISSUED:
984336695Sdavidcs		if (p_drv_buf->abort_task_sets_set) {
985336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->abort_task_sets;
986336695Sdavidcs			return sizeof(p_drv_buf->abort_task_sets);
987336695Sdavidcs		}
988336695Sdavidcs		break;
989336695Sdavidcs	case DRV_TLV_TPRLOS_SENT:
990336695Sdavidcs		if (p_drv_buf->tx_tprlos_set) {
991336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_tprlos;
992336695Sdavidcs			return sizeof(p_drv_buf->tx_tprlos);
993336695Sdavidcs		}
994336695Sdavidcs		break;
995336695Sdavidcs	case DRV_TLV_NOS_SENT_COUNT:
996336695Sdavidcs		if (p_drv_buf->tx_nos_set) {
997336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_nos;
998336695Sdavidcs			return sizeof(p_drv_buf->tx_nos);
999336695Sdavidcs		}
1000336695Sdavidcs		break;
1001336695Sdavidcs	case DRV_TLV_NOS_RECEIVED_COUNT:
1002336695Sdavidcs		if (p_drv_buf->rx_nos_set) {
1003336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_nos;
1004336695Sdavidcs			return sizeof(p_drv_buf->rx_nos);
1005336695Sdavidcs		}
1006336695Sdavidcs		break;
1007336695Sdavidcs	case DRV_TLV_OLS_COUNT:
1008336695Sdavidcs		if (p_drv_buf->ols_set) {
1009336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->ols;
1010336695Sdavidcs			return sizeof(p_drv_buf->ols);
1011336695Sdavidcs		}
1012336695Sdavidcs		break;
1013336695Sdavidcs	case DRV_TLV_LR_COUNT:
1014336695Sdavidcs		if (p_drv_buf->lr_set) {
1015336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->lr;
1016336695Sdavidcs			return sizeof(p_drv_buf->lr);
1017336695Sdavidcs		}
1018336695Sdavidcs		break;
1019336695Sdavidcs	case DRV_TLV_LRR_COUNT:
1020336695Sdavidcs		if (p_drv_buf->lrr_set) {
1021336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->lrr;
1022336695Sdavidcs			return sizeof(p_drv_buf->lrr);
1023336695Sdavidcs		}
1024336695Sdavidcs		break;
1025336695Sdavidcs	case DRV_TLV_LIP_SENT_COUNT:
1026336695Sdavidcs		if (p_drv_buf->tx_lip_set) {
1027336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_lip;
1028336695Sdavidcs			return sizeof(p_drv_buf->tx_lip);
1029336695Sdavidcs		}
1030336695Sdavidcs		break;
1031336695Sdavidcs	case DRV_TLV_LIP_RECEIVED_COUNT:
1032336695Sdavidcs		if (p_drv_buf->rx_lip_set) {
1033336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_lip;
1034336695Sdavidcs			return sizeof(p_drv_buf->rx_lip);
1035336695Sdavidcs		}
1036336695Sdavidcs		break;
1037336695Sdavidcs	case DRV_TLV_EOFA_COUNT:
1038336695Sdavidcs		if (p_drv_buf->eofa_set) {
1039336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->eofa;
1040336695Sdavidcs			return sizeof(p_drv_buf->eofa);
1041336695Sdavidcs		}
1042336695Sdavidcs		break;
1043336695Sdavidcs	case DRV_TLV_EOFNI_COUNT:
1044336695Sdavidcs		if (p_drv_buf->eofni_set) {
1045336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->eofni;
1046336695Sdavidcs			return sizeof(p_drv_buf->eofni);
1047336695Sdavidcs		}
1048336695Sdavidcs		break;
1049336695Sdavidcs	case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
1050336695Sdavidcs		if (p_drv_buf->scsi_chks_set) {
1051336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_chks;
1052336695Sdavidcs			return sizeof(p_drv_buf->scsi_chks);
1053336695Sdavidcs		}
1054336695Sdavidcs		break;
1055336695Sdavidcs	case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
1056336695Sdavidcs		if (p_drv_buf->scsi_cond_met_set) {
1057336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_cond_met;
1058336695Sdavidcs			return sizeof(p_drv_buf->scsi_cond_met);
1059336695Sdavidcs		}
1060336695Sdavidcs		break;
1061336695Sdavidcs	case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
1062336695Sdavidcs		if (p_drv_buf->scsi_busy_set) {
1063336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_busy;
1064336695Sdavidcs			return sizeof(p_drv_buf->scsi_busy);
1065336695Sdavidcs		}
1066336695Sdavidcs		break;
1067336695Sdavidcs	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
1068336695Sdavidcs		if (p_drv_buf->scsi_inter_set) {
1069336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_inter;
1070336695Sdavidcs			return sizeof(p_drv_buf->scsi_inter);
1071336695Sdavidcs		}
1072336695Sdavidcs		break;
1073336695Sdavidcs	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
1074336695Sdavidcs		if (p_drv_buf->scsi_inter_cond_met_set) {
1075336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_inter_cond_met;
1076336695Sdavidcs			return sizeof(p_drv_buf->scsi_inter_cond_met);
1077336695Sdavidcs		}
1078336695Sdavidcs		break;
1079336695Sdavidcs	case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
1080336695Sdavidcs		if (p_drv_buf->scsi_rsv_conflicts_set) {
1081336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_rsv_conflicts;
1082336695Sdavidcs			return sizeof(p_drv_buf->scsi_rsv_conflicts);
1083336695Sdavidcs		}
1084336695Sdavidcs		break;
1085336695Sdavidcs	case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
1086336695Sdavidcs		if (p_drv_buf->scsi_tsk_full_set) {
1087336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_tsk_full;
1088336695Sdavidcs			return sizeof(p_drv_buf->scsi_tsk_full);
1089336695Sdavidcs		}
1090336695Sdavidcs		break;
1091336695Sdavidcs	case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
1092336695Sdavidcs		if (p_drv_buf->scsi_aca_active_set) {
1093336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_aca_active;
1094336695Sdavidcs			return sizeof(p_drv_buf->scsi_aca_active);
1095336695Sdavidcs		}
1096336695Sdavidcs		break;
1097336695Sdavidcs	case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
1098336695Sdavidcs		if (p_drv_buf->scsi_tsk_abort_set) {
1099336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_tsk_abort;
1100336695Sdavidcs			return sizeof(p_drv_buf->scsi_tsk_abort);
1101336695Sdavidcs		}
1102336695Sdavidcs		break;
1103336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
1104336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
1105336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
1106336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
1107336695Sdavidcs	case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
1108336695Sdavidcs	{
1109336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
1110336695Sdavidcs			  DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
1111336695Sdavidcs
1112336695Sdavidcs		if (p_drv_buf->scsi_rx_chk_set[idx]) {
1113336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->scsi_rx_chk[idx];
1114336695Sdavidcs			return sizeof(p_drv_buf->scsi_rx_chk[idx]);
1115336695Sdavidcs		}
1116336695Sdavidcs		break;
1117336695Sdavidcs	}
1118336695Sdavidcs	case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
1119336695Sdavidcs	case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
1120336695Sdavidcs	case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
1121336695Sdavidcs	case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
1122336695Sdavidcs	case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
1123336695Sdavidcs	{
1124336695Sdavidcs		u8 idx = (p_tlv->tlv_type -
1125336695Sdavidcs			  DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
1126336695Sdavidcs
1127336695Sdavidcs		return ecore_mfw_get_tlv_time_value(&p_drv_buf->scsi_chk_tstamp[idx],
1128336695Sdavidcs						    p_buf);
1129336695Sdavidcs	}
1130336695Sdavidcs
1131336695Sdavidcs	default:
1132336695Sdavidcs		break;
1133336695Sdavidcs	}
1134336695Sdavidcs
1135336695Sdavidcs	return -1;
1136336695Sdavidcs}
1137336695Sdavidcs
1138336695Sdavidcsstatic int
1139336695Sdavidcsecore_mfw_get_iscsi_tlv_value(struct ecore_drv_tlv_hdr *p_tlv,
1140336695Sdavidcs			      struct ecore_mfw_tlv_iscsi *p_drv_buf,
1141336695Sdavidcs			      struct ecore_tlv_parsed_buf *p_buf)
1142336695Sdavidcs{
1143336695Sdavidcs	switch (p_tlv->tlv_type) {
1144336695Sdavidcs	case DRV_TLV_TARGET_LLMNR_ENABLED:
1145336695Sdavidcs		if (p_drv_buf->target_llmnr_set) {
1146336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->target_llmnr;
1147336695Sdavidcs			return sizeof(p_drv_buf->target_llmnr);
1148336695Sdavidcs		}
1149336695Sdavidcs		break;
1150336695Sdavidcs	case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
1151336695Sdavidcs		if (p_drv_buf->header_digest_set) {
1152336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->header_digest;
1153336695Sdavidcs			return sizeof(p_drv_buf->header_digest);
1154336695Sdavidcs		}
1155336695Sdavidcs		break;
1156336695Sdavidcs	case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
1157336695Sdavidcs		if (p_drv_buf->data_digest_set) {
1158336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->data_digest;
1159336695Sdavidcs			return sizeof(p_drv_buf->data_digest);
1160336695Sdavidcs		}
1161336695Sdavidcs		break;
1162336695Sdavidcs	case DRV_TLV_AUTHENTICATION_METHOD:
1163336695Sdavidcs		if (p_drv_buf->auth_method_set) {
1164336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->auth_method;
1165336695Sdavidcs			return sizeof(p_drv_buf->auth_method);
1166336695Sdavidcs		}
1167336695Sdavidcs		break;
1168336695Sdavidcs	case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
1169336695Sdavidcs		if (p_drv_buf->boot_taget_portal_set) {
1170336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->boot_taget_portal;
1171336695Sdavidcs			return sizeof(p_drv_buf->boot_taget_portal);
1172336695Sdavidcs		}
1173336695Sdavidcs		break;
1174336695Sdavidcs	case DRV_TLV_MAX_FRAME_SIZE:
1175336695Sdavidcs		if (p_drv_buf->frame_size_set) {
1176336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->frame_size;
1177336695Sdavidcs			return sizeof(p_drv_buf->frame_size);
1178336695Sdavidcs		}
1179336695Sdavidcs		break;
1180336695Sdavidcs	case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
1181336695Sdavidcs		if (p_drv_buf->tx_desc_size_set) {
1182336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_desc_size;
1183336695Sdavidcs			return sizeof(p_drv_buf->tx_desc_size);
1184336695Sdavidcs		}
1185336695Sdavidcs		break;
1186336695Sdavidcs	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
1187336695Sdavidcs		if (p_drv_buf->rx_desc_size_set) {
1188336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_desc_size;
1189336695Sdavidcs			return sizeof(p_drv_buf->rx_desc_size);
1190336695Sdavidcs		}
1191336695Sdavidcs		break;
1192336695Sdavidcs	case DRV_TLV_ISCSI_BOOT_PROGRESS:
1193336695Sdavidcs		if (p_drv_buf->boot_progress_set) {
1194336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->boot_progress;
1195336695Sdavidcs			return sizeof(p_drv_buf->boot_progress);
1196336695Sdavidcs		}
1197336695Sdavidcs		break;
1198336695Sdavidcs	case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
1199336695Sdavidcs		if (p_drv_buf->tx_desc_qdepth_set) {
1200336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_desc_qdepth;
1201336695Sdavidcs			return sizeof(p_drv_buf->tx_desc_qdepth);
1202336695Sdavidcs		}
1203336695Sdavidcs		break;
1204336695Sdavidcs	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
1205336695Sdavidcs		if (p_drv_buf->rx_desc_qdepth_set) {
1206336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_desc_qdepth;
1207336695Sdavidcs			return sizeof(p_drv_buf->rx_desc_qdepth);
1208336695Sdavidcs		}
1209336695Sdavidcs		break;
1210336695Sdavidcs	case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
1211336695Sdavidcs		if (p_drv_buf->rx_frames_set) {
1212336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_frames;
1213336695Sdavidcs			return sizeof(p_drv_buf->rx_frames);
1214336695Sdavidcs		}
1215336695Sdavidcs		break;
1216336695Sdavidcs	case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
1217336695Sdavidcs		if (p_drv_buf->rx_bytes_set) {
1218336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->rx_bytes;
1219336695Sdavidcs			return sizeof(p_drv_buf->rx_bytes);
1220336695Sdavidcs		}
1221336695Sdavidcs		break;
1222336695Sdavidcs	case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
1223336695Sdavidcs		if (p_drv_buf->tx_frames_set) {
1224336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_frames;
1225336695Sdavidcs			return sizeof(p_drv_buf->tx_frames);
1226336695Sdavidcs		}
1227336695Sdavidcs		break;
1228336695Sdavidcs	case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
1229336695Sdavidcs		if (p_drv_buf->tx_bytes_set) {
1230336695Sdavidcs			p_buf->p_val = (u8 *)&p_drv_buf->tx_bytes;
1231336695Sdavidcs			return sizeof(p_drv_buf->tx_bytes);
1232336695Sdavidcs		}
1233336695Sdavidcs		break;
1234336695Sdavidcs	default:
1235336695Sdavidcs		break;
1236336695Sdavidcs	}
1237336695Sdavidcs
1238336695Sdavidcs	return -1;
1239336695Sdavidcs}
1240336695Sdavidcs
1241336695Sdavidcsstatic enum _ecore_status_t ecore_mfw_update_tlvs(struct ecore_hwfn *p_hwfn,
1242336695Sdavidcs						  u8 tlv_group, u8 *p_mfw_buf,
1243336695Sdavidcs						  u32 size)
1244336695Sdavidcs{
1245336695Sdavidcs	union ecore_mfw_tlv_data *p_tlv_data;
1246336695Sdavidcs	struct ecore_tlv_parsed_buf buffer;
1247336695Sdavidcs	struct ecore_drv_tlv_hdr tlv;
1248336695Sdavidcs	u32 offset;
1249336695Sdavidcs	int len;
1250336695Sdavidcs	u8 *p_tlv;
1251336695Sdavidcs
1252336695Sdavidcs	p_tlv_data = OSAL_VZALLOC(p_hwfn->p_dev, sizeof(*p_tlv_data));
1253336695Sdavidcs	if (!p_tlv_data)
1254336695Sdavidcs		return ECORE_NOMEM;
1255336695Sdavidcs
1256336695Sdavidcs	if (OSAL_MFW_FILL_TLV_DATA(p_hwfn,tlv_group, p_tlv_data)) {
1257336695Sdavidcs		OSAL_VFREE(p_hwfn->p_dev, p_tlv_data);
1258336695Sdavidcs		return ECORE_INVAL;
1259336695Sdavidcs	}
1260336695Sdavidcs
1261336695Sdavidcs	OSAL_MEMSET(&tlv, 0, sizeof(tlv));
1262336695Sdavidcs	for (offset = 0; offset < size;
1263336695Sdavidcs	     offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1264336695Sdavidcs		p_tlv = &p_mfw_buf[offset];
1265336695Sdavidcs		tlv.tlv_type = TLV_TYPE(p_tlv);
1266336695Sdavidcs		tlv.tlv_length = TLV_LENGTH(p_tlv);
1267336695Sdavidcs		tlv.tlv_flags = TLV_FLAGS(p_tlv);
1268336695Sdavidcs
1269336695Sdavidcs		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1270336695Sdavidcs			   "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
1271336695Sdavidcs			   tlv.tlv_length, tlv.tlv_flags);
1272336695Sdavidcs
1273336695Sdavidcs		if (tlv_group == ECORE_MFW_TLV_GENERIC)
1274336695Sdavidcs			len = ecore_mfw_get_gen_tlv_value(&tlv, &p_tlv_data->generic, &buffer);
1275336695Sdavidcs		else if (tlv_group == ECORE_MFW_TLV_ETH)
1276336695Sdavidcs			len = ecore_mfw_get_eth_tlv_value(&tlv, &p_tlv_data->eth, &buffer);
1277336695Sdavidcs		else if (tlv_group == ECORE_MFW_TLV_FCOE)
1278336695Sdavidcs			len = ecore_mfw_get_fcoe_tlv_value(&tlv, &p_tlv_data->fcoe, &buffer);
1279336695Sdavidcs		else
1280336695Sdavidcs			len = ecore_mfw_get_iscsi_tlv_value(&tlv, &p_tlv_data->iscsi, &buffer);
1281336695Sdavidcs
1282336695Sdavidcs		if (len > 0) {
1283336695Sdavidcs			OSAL_WARN(len > 4 * tlv.tlv_length,
1284336695Sdavidcs				  "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
1285336695Sdavidcs				  len, 4 * tlv.tlv_length);
1286336695Sdavidcs			len = OSAL_MIN_T(int, len, 4 * tlv.tlv_length);
1287336695Sdavidcs			tlv.tlv_flags |= ECORE_DRV_TLV_FLAGS_CHANGED;
1288336695Sdavidcs			TLV_FLAGS(p_tlv) = tlv.tlv_flags;
1289336695Sdavidcs			OSAL_MEMCPY(p_mfw_buf + offset + sizeof(tlv),
1290336695Sdavidcs				    buffer.p_val, len);
1291336695Sdavidcs		}
1292336695Sdavidcs	}
1293336695Sdavidcs
1294336695Sdavidcs	OSAL_VFREE(p_hwfn->p_dev, p_tlv_data);
1295336695Sdavidcs
1296336695Sdavidcs	return ECORE_SUCCESS;
1297336695Sdavidcs}
1298336695Sdavidcs
1299336695Sdavidcsenum _ecore_status_t
1300336695Sdavidcsecore_mfw_process_tlv_req(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
1301336695Sdavidcs{
1302336695Sdavidcs	u32 addr, size, offset, resp, param, val;
1303336695Sdavidcs	u8 tlv_group = 0, id, *p_mfw_buf = OSAL_NULL, *p_temp;
1304336695Sdavidcs	u32 global_offsize, global_addr;
1305336695Sdavidcs	enum _ecore_status_t rc;
1306336695Sdavidcs	struct ecore_drv_tlv_hdr tlv;
1307336695Sdavidcs
1308336695Sdavidcs	addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
1309336695Sdavidcs				    PUBLIC_GLOBAL);
1310336695Sdavidcs	global_offsize = ecore_rd(p_hwfn, p_ptt, addr);
1311336695Sdavidcs	global_addr = SECTION_ADDR(global_offsize, 0);
1312336695Sdavidcs	addr = global_addr + OFFSETOF(struct public_global, data_ptr);
1313336695Sdavidcs	addr = ecore_rd(p_hwfn, p_ptt, addr);
1314336695Sdavidcs	size = ecore_rd(p_hwfn, p_ptt, global_addr +
1315336695Sdavidcs			OFFSETOF(struct public_global, data_size));
1316336695Sdavidcs
1317336695Sdavidcs	if (!size) {
1318336695Sdavidcs		DP_NOTICE(p_hwfn, false, "Invalid TLV req size = %d\n", size);
1319336695Sdavidcs		goto drv_done;
1320336695Sdavidcs	}
1321336695Sdavidcs
1322336695Sdavidcs	p_mfw_buf = (void *)OSAL_VZALLOC(p_hwfn->p_dev, size);
1323336695Sdavidcs	if (!p_mfw_buf) {
1324336695Sdavidcs		DP_NOTICE(p_hwfn, false, "Failed allocate memory for p_mfw_buf\n");
1325336695Sdavidcs		goto drv_done;
1326336695Sdavidcs	}
1327336695Sdavidcs
1328336695Sdavidcs	/* Read the TLV request to local buffer. MFW represents the TLV in
1329336695Sdavidcs	 * little endian format and mcp returns it bigendian format. Hence
1330336695Sdavidcs	 * driver need to convert data to little endian first and then do the
1331336695Sdavidcs	 * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
1332336695Sdavidcs	 *
1333336695Sdavidcs	 */
1334336695Sdavidcs	for (offset = 0; offset < size; offset += sizeof(u32)) {
1335336695Sdavidcs		val = ecore_rd(p_hwfn, p_ptt, addr + offset);
1336336695Sdavidcs		val = OSAL_BE32_TO_CPU(val);
1337336695Sdavidcs		OSAL_MEMCPY(&p_mfw_buf[offset], &val, sizeof(u32));
1338336695Sdavidcs	}
1339336695Sdavidcs
1340336695Sdavidcs	/* Parse the headers to enumerate the requested TLV groups */
1341336695Sdavidcs	for (offset = 0; offset < size;
1342336695Sdavidcs	     offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
1343336695Sdavidcs		p_temp = &p_mfw_buf[offset];
1344336695Sdavidcs		tlv.tlv_type = TLV_TYPE(p_temp);
1345336695Sdavidcs		tlv.tlv_length = TLV_LENGTH(p_temp);
1346336695Sdavidcs		if (ecore_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
1347336695Sdavidcs			DP_VERBOSE(p_hwfn, ECORE_MSG_DRV,
1348336695Sdavidcs				   "Un recognized TLV %d\n", tlv.tlv_type);
1349336695Sdavidcs	}
1350336695Sdavidcs
1351336695Sdavidcs	/* Sanitize the TLV groups according to personality */
1352336695Sdavidcs	if ((tlv_group & ECORE_MFW_TLV_FCOE)  &&
1353336695Sdavidcs	    p_hwfn->hw_info.personality != ECORE_PCI_FCOE) {
1354336695Sdavidcs		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1355336695Sdavidcs			   "Skipping FCoE TLVs for non-FCoE function\n");
1356336695Sdavidcs		tlv_group &= ~ECORE_MFW_TLV_FCOE;
1357336695Sdavidcs	}
1358336695Sdavidcs
1359336695Sdavidcs	if ((tlv_group & ECORE_MFW_TLV_ISCSI) &&
1360336695Sdavidcs	    p_hwfn->hw_info.personality != ECORE_PCI_ISCSI) {
1361336695Sdavidcs		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1362336695Sdavidcs			   "Skipping iSCSI TLVs for non-iSCSI function\n");
1363336695Sdavidcs		tlv_group &= ~ECORE_MFW_TLV_ISCSI;
1364336695Sdavidcs	}
1365336695Sdavidcs
1366336695Sdavidcs	if ((tlv_group & ECORE_MFW_TLV_ETH) &&
1367336695Sdavidcs	    !ECORE_IS_L2_PERSONALITY(p_hwfn)) {
1368336695Sdavidcs		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
1369336695Sdavidcs			   "Skipping L2 TLVs for non-L2 function\n");
1370336695Sdavidcs		tlv_group &= ~ECORE_MFW_TLV_ETH;
1371336695Sdavidcs	}
1372336695Sdavidcs
1373336695Sdavidcs	/* Update the TLV values in the local buffer */
1374336695Sdavidcs	for (id = ECORE_MFW_TLV_GENERIC; id < ECORE_MFW_TLV_MAX; id <<= 1) {
1375336695Sdavidcs		if (tlv_group & id) {
1376336695Sdavidcs			if (ecore_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
1377336695Sdavidcs				goto drv_done;
1378336695Sdavidcs		}
1379336695Sdavidcs	}
1380336695Sdavidcs
1381336695Sdavidcs	/* Write the TLV data to shared memory. The stream of 4 bytes first need
1382336695Sdavidcs	 * to be mem-copied to u32 element to make it as LSB format. And then
1383336695Sdavidcs	 * converted to big endian as required by mcp-write.
1384336695Sdavidcs	 */
1385336695Sdavidcs	for (offset = 0; offset < size; offset += sizeof(u32)) {
1386336695Sdavidcs		OSAL_MEMCPY(&val, &p_mfw_buf[offset], sizeof(u32));
1387336695Sdavidcs		val = OSAL_CPU_TO_BE32(val);
1388336695Sdavidcs		ecore_wr(p_hwfn, p_ptt, addr + offset, val);
1389336695Sdavidcs	}
1390336695Sdavidcs
1391336695Sdavidcsdrv_done:
1392336695Sdavidcs	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1393336695Sdavidcs			   &param);
1394336695Sdavidcs
1395336695Sdavidcs	OSAL_VFREE(p_hwfn->p_dev, p_mfw_buf);
1396336695Sdavidcs
1397336695Sdavidcs	return rc;
1398336695Sdavidcs}
1399