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