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