1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1,  (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 
22 /*
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1,  (the "License").
26 
27 * You may not use this file except in compliance with the License.
28 
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
31 
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35 
36 #include "bcm_osal.h"
37 #include "ecore.h"
38 #include "ecore_sp_commands.h"
39 #include "ecore_dcbx.h"
40 #include "ecore_cxt.h"
41 #include "ecore_gtt_reg_addr.h"
42 #include "ecore_iro.h"
43 #ifdef CONFIG_ECORE_ROCE
44 #include "ecore_roce.h"
45 #endif
46 #include "ecore_iov_api.h"
47 
48 #define ECORE_DCBX_MAX_MIB_READ_TRY	(100)
49 #define ECORE_ETH_TYPE_DEFAULT		(0)
50 #define ECORE_ETH_TYPE_ROCE		(0x8915)
51 #define ECORE_UDP_PORT_TYPE_ROCE_V2	(0x12B7)
52 #define ECORE_ETH_TYPE_FCOE		(0x8906)
53 #define ECORE_TCP_PORT_ISCSI		(0xCBC)
54 
55 #define ECORE_DCBX_INVALID_PRIORITY	0xFF
56 
57 /* Get Traffic Class from priority traffic class table, 4 bits represent
58  * the traffic class corresponding to the priority.
59  */
60 #define ECORE_DCBX_PRIO2TC(prio_tc_tbl, prio) \
61 		((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
62 
63 static bool ecore_dcbx_app_ethtype(u32 app_info_bitmap)
64 {
65 	return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
66 		  DCBX_APP_SF_ETHTYPE);
67 }
68 
69 static bool ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap)
70 {
71 	u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
72 
73 	/* Old MFW */
74 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
75 		return ecore_dcbx_app_ethtype(app_info_bitmap);
76 
77 	return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE);
78 }
79 
80 static bool ecore_dcbx_app_port(u32 app_info_bitmap)
81 {
82 	return !!(ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
83 		  DCBX_APP_SF_PORT);
84 }
85 
86 static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
87 {
88 	u8 mfw_val = ECORE_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
89 
90 	/* Old MFW */
91 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
92 		return ecore_dcbx_app_port(app_info_bitmap);
93 
94 	return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT);
95 }
96 
97 static bool ecore_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
98 {
99 	bool ethtype;
100 
101 	if (ieee)
102 		ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
103 	else
104 		ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
105 
106 	return !!(ethtype && (proto_id == ECORE_ETH_TYPE_DEFAULT));
107 }
108 
109 static bool ecore_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
110 {
111 	bool port;
112 
113 	if (ieee)
114 		port = ecore_dcbx_ieee_app_port(app_info_bitmap,
115 						DCBX_APP_SF_IEEE_TCP_PORT);
116 	else
117 		port = ecore_dcbx_app_port(app_info_bitmap);
118 
119 	return !!(port && (proto_id == ECORE_TCP_PORT_ISCSI));
120 }
121 
122 static bool ecore_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
123 {
124 	bool ethtype;
125 
126 	if (ieee)
127 		ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
128 	else
129 		ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
130 
131 	return !!(ethtype && (proto_id == ECORE_ETH_TYPE_FCOE));
132 }
133 
134 static bool ecore_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
135 {
136 	bool ethtype;
137 
138 	if (ieee)
139 		ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
140 	else
141 		ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
142 
143 	return !!(ethtype && (proto_id == ECORE_ETH_TYPE_ROCE));
144 }
145 
146 static bool ecore_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
147 {
148 	bool port;
149 
150 	if (ieee)
151 		port = ecore_dcbx_ieee_app_port(app_info_bitmap,
152 						DCBX_APP_SF_IEEE_UDP_PORT);
153 	else
154 		port = ecore_dcbx_app_port(app_info_bitmap);
155 
156 	return !!(port && (proto_id == ECORE_UDP_PORT_TYPE_ROCE_V2));
157 }
158 
159 static bool ecore_dcbx_iwarp_tlv(struct ecore_hwfn *p_hwfn, u32 app_info_bitmap,
160 				 u16 proto_id, bool ieee)
161 {
162 	bool port;
163 
164 	if (!p_hwfn->p_dcbx_info->iwarp_port)
165 		return false;
166 
167 	if (ieee)
168 		port = ecore_dcbx_ieee_app_port(app_info_bitmap,
169 						DCBX_APP_SF_IEEE_TCP_PORT);
170 	else
171 		port = ecore_dcbx_app_port(app_info_bitmap);
172 
173 	return !!(port && (proto_id == p_hwfn->p_dcbx_info->iwarp_port));
174 }
175 
176 static void
177 ecore_dcbx_dp_protocol(struct ecore_hwfn *p_hwfn,
178 		       struct ecore_dcbx_results *p_data)
179 {
180 	enum dcbx_protocol_type id;
181 	int i;
182 
183 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "DCBX negotiated: %d\n",
184 		   p_data->dcbx_enabled);
185 
186 	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
187 		id = ecore_dcbx_app_update[i].id;
188 
189 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
190 			   "%s info: update %d, enable %d, prio %d, tc %d, num_active_tc %d dscp_enable = %d dscp_val = %d\n",
191 			   ecore_dcbx_app_update[i].name, p_data->arr[id].update,
192 			   p_data->arr[id].enable, p_data->arr[id].priority,
193 			   p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc,
194 			   p_data->arr[id].dscp_enable,
195 			   p_data->arr[id].dscp_val);
196 	}
197 }
198 
199 static void
200 ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
201 		      struct ecore_hwfn *p_hwfn,
202 		      bool enable, u8 prio, u8 tc,
203 		      enum dcbx_protocol_type type,
204 		      enum ecore_pci_personality personality)
205 {
206 	struct ecore_dcbx_dscp_params *dscp = &p_hwfn->p_dcbx_info->get.dscp;
207 
208 	/* PF update ramrod data */
209 	p_data->arr[type].enable = enable;
210 	p_data->arr[type].priority = prio;
211 	p_data->arr[type].tc = tc;
212 	p_data->arr[type].dscp_enable = dscp->enabled;
213 	if (p_data->arr[type].dscp_enable) {
214 		u8 i;
215 
216 		for (i = 0; i < ECORE_DCBX_DSCP_SIZE; i++)
217 			if (prio == dscp->dscp_pri_map[i]) {
218 				p_data->arr[type].dscp_val = i;
219 				break;
220 			}
221 	}
222 
223 	if (enable && p_data->arr[type].dscp_enable)
224 		p_data->arr[type].update = UPDATE_DCB_DSCP;
225 	else if (enable)
226 		p_data->arr[type].update = UPDATE_DCB;
227 	else
228 		p_data->arr[type].update = DONT_UPDATE_DCB_DSCP;
229 
230 	/* QM reconf data */
231 	if (p_hwfn->hw_info.personality == personality)
232 		p_hwfn->hw_info.offload_tc = tc;
233 }
234 
235 /* Update app protocol data and hw_info fields with the TLV info */
236 static void
237 ecore_dcbx_update_app_info(struct ecore_dcbx_results *p_data,
238 			   struct ecore_hwfn *p_hwfn,
239 			   bool enable, u8 prio, u8 tc,
240 			   enum dcbx_protocol_type type)
241 {
242 	enum ecore_pci_personality personality;
243 	enum dcbx_protocol_type id;
244 	char *name;
245 	int i;
246 
247 	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
248 		id = ecore_dcbx_app_update[i].id;
249 
250 		if (type != id)
251 			continue;
252 
253 		personality = ecore_dcbx_app_update[i].personality;
254 		name = ecore_dcbx_app_update[i].name;
255 
256 		ecore_dcbx_set_params(p_data, p_hwfn, enable,
257 				      prio, tc, type, personality);
258 	}
259 }
260 
261 static enum _ecore_status_t
262 ecore_dcbx_get_app_priority(u8 pri_bitmap, u8 *priority)
263 {
264 	u32 pri_mask, pri = ECORE_MAX_PFC_PRIORITIES;
265 	u32 index = ECORE_MAX_PFC_PRIORITIES - 1;
266 	enum _ecore_status_t rc = ECORE_SUCCESS;
267 
268 	/* Bitmap 1 corresponds to priority 0, return priority 0 */
269 	if (pri_bitmap == 1) {
270 		*priority = 0;
271 		return rc;
272 	}
273 
274 	/* Choose the highest priority */
275 	while ((ECORE_MAX_PFC_PRIORITIES == pri) && index) {
276 		pri_mask = 1 << index;
277 		if (pri_bitmap & pri_mask)
278 			pri = index;
279 		index--;
280 	}
281 
282 	if (pri < ECORE_MAX_PFC_PRIORITIES)
283 		*priority = (u8)pri;
284 	else
285 		rc = ECORE_INVAL;
286 
287 	return rc;
288 }
289 
290 static bool
291 ecore_dcbx_get_app_protocol_type(struct ecore_hwfn *p_hwfn,
292 				 u32 app_prio_bitmap, u16 id,
293 				 enum dcbx_protocol_type *type, bool ieee)
294 {
295 	if (ecore_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) {
296 		*type = DCBX_PROTOCOL_FCOE;
297 	} else if (ecore_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) {
298 		*type = DCBX_PROTOCOL_ROCE;
299 	} else if (ecore_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) {
300 		*type = DCBX_PROTOCOL_ISCSI;
301 	} else if (ecore_dcbx_default_tlv(app_prio_bitmap, id, ieee)) {
302 		*type = DCBX_PROTOCOL_ETH;
303 	} else if (ecore_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) {
304 		*type = DCBX_PROTOCOL_ROCE_V2;
305 	} else if (ecore_dcbx_iwarp_tlv(p_hwfn, app_prio_bitmap, id, ieee)) {
306 		*type = DCBX_PROTOCOL_IWARP;
307 	} else {
308 		*type = DCBX_MAX_PROTOCOL_TYPE;
309 		DP_ERR(p_hwfn,
310 		       "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
311 		       id, app_prio_bitmap);
312 		return false;
313 	}
314 
315 	return true;
316 }
317 
318 /*  Parse app TLV's to update TC information in hw_info structure for
319  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
320  */
321 static enum _ecore_status_t
322 ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn,
323 		       struct ecore_dcbx_results *p_data,
324 		       struct dcbx_app_priority_entry *p_tbl, u32 pri_tc_tbl,
325 		       int count, u8 dcbx_version)
326 {
327 	enum dcbx_protocol_type type;
328 	u8 tc, priority_map;
329 	bool enable, ieee;
330 	u16 protocol_id;
331 	u8 priority;
332 	enum _ecore_status_t rc = ECORE_SUCCESS;
333 	int i;
334 
335 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
336 		   "Num APP entries = %d pri_tc_tbl = 0x%x dcbx_version = %u\n",
337 		   count, pri_tc_tbl, dcbx_version);
338 
339 	ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE);
340 	/* Parse APP TLV */
341 	for (i = 0; i < count; i++) {
342 		protocol_id = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
343 						  DCBX_APP_PROTOCOL_ID);
344 		priority_map = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
345 						   DCBX_APP_PRI_MAP);
346 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Id = 0x%x pri_map = %u\n",
347 			   protocol_id, priority_map);
348 		rc = ecore_dcbx_get_app_priority(priority_map, &priority);
349 		if (rc == ECORE_INVAL) {
350 			DP_ERR(p_hwfn, "Invalid priority\n");
351 			return ECORE_INVAL;
352 		}
353 
354 		tc = ECORE_DCBX_PRIO2TC(pri_tc_tbl, priority);
355 		if (ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
356 						     protocol_id, &type,
357 						     ieee)) {
358 			/* ETH always have the enable bit reset, as it gets
359 			 * vlan information per packet. For other protocols,
360 			 * should be set according to the dcbx_enabled
361 			 * indication, but we only got here if there was an
362 			 * app tlv for the protocol, so dcbx must be enabled.
363 			 */
364 			enable = !(type == DCBX_PROTOCOL_ETH);
365 
366 			ecore_dcbx_update_app_info(p_data, p_hwfn, enable,
367 						   priority, tc, type);
368 		}
369 	}
370 
371 	/* Update ramrod protocol data and hw_info fields
372 	 * with default info when corresponding APP TLV's are not detected.
373 	 * The enabled field has a different logic for ethernet as only for
374 	 * ethernet dcb should disabled by default, as the information arrives
375 	 * from the OS (unless an explicit app tlv was present).
376 	 */
377 	tc = p_data->arr[DCBX_PROTOCOL_ETH].tc;
378 	priority = p_data->arr[DCBX_PROTOCOL_ETH].priority;
379 	for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) {
380 		if (p_data->arr[type].update)
381 			continue;
382 
383 		enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
384 		ecore_dcbx_update_app_info(p_data, p_hwfn, enable,
385 					   priority, tc, type);
386 	}
387 
388 	return ECORE_SUCCESS;
389 }
390 
391 /* Parse app TLV's to update TC information in hw_info structure for
392  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
393  */
394 static enum _ecore_status_t
395 ecore_dcbx_process_mib_info(struct ecore_hwfn *p_hwfn)
396 {
397 	struct dcbx_app_priority_feature *p_app;
398 	enum _ecore_status_t rc = ECORE_SUCCESS;
399 	struct ecore_dcbx_results data = { 0 };
400 	struct dcbx_app_priority_entry *p_tbl;
401 	struct dcbx_ets_feature *p_ets;
402 	struct ecore_hw_info *p_info;
403 	u32 pri_tc_tbl, flags;
404 	u8 dcbx_version;
405 	int num_entries;
406 
407 	flags = p_hwfn->p_dcbx_info->operational.flags;
408 	dcbx_version = ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION);
409 
410 	p_app = &p_hwfn->p_dcbx_info->operational.features.app;
411 	p_tbl = p_app->app_pri_tbl;
412 
413 	p_ets = &p_hwfn->p_dcbx_info->operational.features.ets;
414 	pri_tc_tbl = p_ets->pri_tc_tbl[0];
415 
416 	p_info = &p_hwfn->hw_info;
417 	num_entries = ECORE_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
418 
419 	rc = ecore_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl,
420 				    num_entries, dcbx_version);
421 	if (rc != ECORE_SUCCESS)
422 		return rc;
423 
424 	p_info->num_active_tc = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
425 	p_hwfn->qm_info.ooo_tc = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_OOO_TC);
426 	data.pf_id = p_hwfn->rel_pf_id;
427 	data.dcbx_enabled = !!dcbx_version;
428 
429 	ecore_dcbx_dp_protocol(p_hwfn, &data);
430 
431 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->results, &data,
432 		    sizeof(struct ecore_dcbx_results));
433 
434 	return ECORE_SUCCESS;
435 }
436 
437 static enum _ecore_status_t
438 ecore_dcbx_copy_mib(struct ecore_hwfn *p_hwfn,
439 		    struct ecore_ptt *p_ptt,
440 		    struct ecore_dcbx_mib_meta_data *p_data,
441 		    enum ecore_mib_read_type type)
442 {
443 	enum _ecore_status_t rc = ECORE_SUCCESS;
444 	u32 prefix_seq_num, suffix_seq_num;
445 	int read_count = 0;
446 
447 	/* The data is considered to be valid only if both sequence numbers are
448 	 * the same.
449 	 */
450 	do {
451 		if (type == ECORE_DCBX_REMOTE_LLDP_MIB) {
452 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote,
453 					  p_data->addr, p_data->size);
454 			prefix_seq_num = p_data->lldp_remote->prefix_seq_num;
455 			suffix_seq_num = p_data->lldp_remote->suffix_seq_num;
456 		} else {
457 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->mib,
458 					  p_data->addr, p_data->size);
459 			prefix_seq_num = p_data->mib->prefix_seq_num;
460 			suffix_seq_num = p_data->mib->suffix_seq_num;
461 		}
462 		read_count++;
463 
464 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
465 			   "mib type = %d, try count = %d prefix seq num  = %d suffix seq num = %d\n",
466 			   type, read_count, prefix_seq_num, suffix_seq_num);
467 	} while ((prefix_seq_num != suffix_seq_num) &&
468 		 (read_count < ECORE_DCBX_MAX_MIB_READ_TRY));
469 
470 	if (read_count >= ECORE_DCBX_MAX_MIB_READ_TRY) {
471 		DP_ERR(p_hwfn,
472 		       "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
473 		       type, read_count, prefix_seq_num, suffix_seq_num);
474 		rc = ECORE_IO;
475 	}
476 
477 	return rc;
478 }
479 
480 static void
481 ecore_dcbx_get_priority_info(struct ecore_hwfn *p_hwfn,
482 			     struct ecore_dcbx_app_prio *p_prio,
483 			     struct ecore_dcbx_results *p_results)
484 {
485 	u8 val;
486 
487 	p_prio->roce = ECORE_DCBX_INVALID_PRIORITY;
488 	p_prio->roce_v2 = ECORE_DCBX_INVALID_PRIORITY;
489 	p_prio->iscsi = ECORE_DCBX_INVALID_PRIORITY;
490 	p_prio->fcoe = ECORE_DCBX_INVALID_PRIORITY;
491 
492 	if (p_results->arr[DCBX_PROTOCOL_ROCE].update &&
493 	    p_results->arr[DCBX_PROTOCOL_ROCE].enable)
494 		p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority;
495 
496 	if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update &&
497 	    p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) {
498 		val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority;
499 		p_prio->roce_v2 = val;
500 	}
501 
502 	if (p_results->arr[DCBX_PROTOCOL_ISCSI].update &&
503 	    p_results->arr[DCBX_PROTOCOL_ISCSI].enable)
504 		p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority;
505 
506 	if (p_results->arr[DCBX_PROTOCOL_FCOE].update &&
507 	    p_results->arr[DCBX_PROTOCOL_FCOE].enable)
508 		p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority;
509 
510 	if (p_results->arr[DCBX_PROTOCOL_ETH].update &&
511 	    p_results->arr[DCBX_PROTOCOL_ETH].enable)
512 		p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority;
513 
514 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
515 		   "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
516 		   p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe,
517 		   p_prio->eth);
518 }
519 
520 static void
521 ecore_dcbx_get_app_data(struct ecore_hwfn *p_hwfn,
522 			struct dcbx_app_priority_feature *p_app,
523 			struct dcbx_app_priority_entry *p_tbl,
524 			struct ecore_dcbx_params *p_params, bool ieee)
525 {
526 	struct ecore_app_entry *entry;
527 	u8 pri_map;
528 	int i;
529 
530 	p_params->app_willing = ECORE_MFW_GET_FIELD(p_app->flags,
531 						    DCBX_APP_WILLING);
532 	p_params->app_valid = ECORE_MFW_GET_FIELD(p_app->flags,
533 						  DCBX_APP_ENABLED);
534 	p_params->app_error = ECORE_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR);
535 	p_params->num_app_entries = ECORE_MFW_GET_FIELD(p_app->flags,
536 							DCBX_APP_NUM_ENTRIES);
537 	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
538 		entry = &p_params->app_entry[i];
539 		if (ieee) {
540 			u8 sf_ieee;
541 			u32 val;
542 
543 			sf_ieee = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
544 						      DCBX_APP_SF_IEEE);
545 			switch (sf_ieee) {
546 			case DCBX_APP_SF_IEEE_RESERVED:
547 				/* Old MFW */
548 				val = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
549 							    DCBX_APP_SF);
550 				entry->sf_ieee = val ?
551 					ECORE_DCBX_SF_IEEE_TCP_UDP_PORT :
552 					ECORE_DCBX_SF_IEEE_ETHTYPE;
553 				break;
554 			case DCBX_APP_SF_IEEE_ETHTYPE:
555 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_ETHTYPE;
556 				break;
557 			case DCBX_APP_SF_IEEE_TCP_PORT:
558 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_TCP_PORT;
559 				break;
560 			case DCBX_APP_SF_IEEE_UDP_PORT:
561 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_UDP_PORT;
562 				break;
563 			case DCBX_APP_SF_IEEE_TCP_UDP_PORT:
564 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_TCP_UDP_PORT;
565 				break;
566 			}
567 		} else {
568 			entry->ethtype = !(ECORE_MFW_GET_FIELD(p_tbl[i].entry,
569 							       DCBX_APP_SF));
570 		}
571 
572 		pri_map = ECORE_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP);
573 		ecore_dcbx_get_app_priority(pri_map, &entry->prio);
574 		entry->proto_id = ECORE_MFW_GET_FIELD(p_tbl[i].entry,
575 						      DCBX_APP_PROTOCOL_ID);
576 		ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
577 						 entry->proto_id,
578 						 &entry->proto_type, ieee);
579 	}
580 
581 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
582 		   "APP params: willing %d, valid %d error = %d\n",
583 		   p_params->app_willing, p_params->app_valid,
584 		   p_params->app_error);
585 }
586 
587 static void
588 ecore_dcbx_get_pfc_data(struct ecore_hwfn *p_hwfn,
589 			u32 pfc, struct ecore_dcbx_params *p_params)
590 {
591 	u8 pfc_map;
592 
593 	p_params->pfc.willing = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING);
594 	p_params->pfc.max_tc = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS);
595 	p_params->pfc.enabled = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED);
596 	pfc_map = ECORE_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP);
597 	p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0);
598 	p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1);
599 	p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2);
600 	p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3);
601 	p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4);
602 	p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5);
603 	p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6);
604 	p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7);
605 
606 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
607 		   "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n",
608 		   p_params->pfc.willing, pfc_map, p_params->pfc.max_tc,
609 		   p_params->pfc.enabled);
610 }
611 
612 static void
613 ecore_dcbx_get_ets_data(struct ecore_hwfn *p_hwfn,
614 			struct dcbx_ets_feature *p_ets,
615 			struct ecore_dcbx_params *p_params)
616 {
617 	u32 bw_map[2], tsa_map[2], pri_map;
618 	int i;
619 
620 	p_params->ets_willing = ECORE_MFW_GET_FIELD(p_ets->flags,
621 						    DCBX_ETS_WILLING);
622 	p_params->ets_enabled = ECORE_MFW_GET_FIELD(p_ets->flags,
623 						    DCBX_ETS_ENABLED);
624 	p_params->ets_cbs = ECORE_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS);
625 	p_params->max_ets_tc = ECORE_MFW_GET_FIELD(p_ets->flags,
626 						   DCBX_ETS_MAX_TCS);
627 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
628 		   "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
629 		   p_params->ets_willing, p_params->ets_enabled,
630 		   p_params->ets_cbs, p_ets->pri_tc_tbl[0],
631 		   p_params->max_ets_tc);
632 	if (p_params->ets_enabled && !p_params->max_ets_tc)
633 	{
634 		p_params->max_ets_tc = ECORE_MAX_PFC_PRIORITIES;
635 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
636 			   "ETS params: max_ets_tc is forced to %d\n",
637 		   p_params->max_ets_tc);
638 	}
639 	/* 8 bit tsa and bw data corresponding to each of the 8 TC's are
640 	 * encoded in a type u32 array of size 2.
641 	 */
642 	bw_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[0]);
643 	bw_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[1]);
644 	tsa_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[0]);
645 	tsa_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[1]);
646 	pri_map = p_ets->pri_tc_tbl[0];
647 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
648 		p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
649 		p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
650 		p_params->ets_pri_tc_tbl[i] = ECORE_DCBX_PRIO2TC(pri_map, i);
651 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
652 			   "elem %d  bw_tbl %x tsa_tbl %x\n",
653 			   i, p_params->ets_tc_bw_tbl[i],
654 			   p_params->ets_tc_tsa_tbl[i]);
655 	}
656 }
657 
658 static void
659 ecore_dcbx_get_common_params(struct ecore_hwfn *p_hwfn,
660 			     struct dcbx_app_priority_feature *p_app,
661 			     struct dcbx_app_priority_entry *p_tbl,
662 			     struct dcbx_ets_feature *p_ets,
663 			     u32 pfc, struct ecore_dcbx_params *p_params,
664 			     bool ieee)
665 {
666 	ecore_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee);
667 	ecore_dcbx_get_ets_data(p_hwfn, p_ets, p_params);
668 	ecore_dcbx_get_pfc_data(p_hwfn, pfc, p_params);
669 }
670 
671 static void
672 ecore_dcbx_get_local_params(struct ecore_hwfn *p_hwfn,
673 			    struct ecore_ptt *p_ptt,
674 			    struct ecore_dcbx_get *params)
675 {
676 	struct dcbx_features *p_feat;
677 
678 	p_feat = &p_hwfn->p_dcbx_info->local_admin.features;
679 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
680 				     p_feat->app.app_pri_tbl, &p_feat->ets,
681 				     p_feat->pfc, &params->local.params, false);
682 	params->local.valid = true;
683 }
684 
685 static void
686 ecore_dcbx_get_remote_params(struct ecore_hwfn *p_hwfn,
687 			     struct ecore_ptt *p_ptt,
688 			     struct ecore_dcbx_get *params)
689 {
690 	struct dcbx_features *p_feat;
691 
692 	p_feat = &p_hwfn->p_dcbx_info->remote.features;
693 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
694 				     p_feat->app.app_pri_tbl, &p_feat->ets,
695 				     p_feat->pfc, &params->remote.params,
696 				     false);
697 	params->remote.valid = true;
698 }
699 
700 static enum _ecore_status_t
701 ecore_dcbx_get_operational_params(struct ecore_hwfn *p_hwfn,
702 				  struct ecore_ptt *p_ptt,
703 				  struct ecore_dcbx_get *params)
704 {
705 	struct ecore_dcbx_operational_params *p_operational;
706 	struct ecore_dcbx_results *p_results;
707 	struct dcbx_features *p_feat;
708 	bool enabled, err;
709 	u32 flags;
710 	bool val;
711 
712 	flags = p_hwfn->p_dcbx_info->operational.flags;
713 
714 	/* If DCBx version is non zero, then negotiation
715 	 * was successfuly performed
716 	 */
717 	p_operational = &params->operational;
718 	enabled = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) !=
719 		     DCBX_CONFIG_VERSION_DISABLED);
720 	if (!enabled) {
721 		p_operational->enabled = enabled;
722 		p_operational->valid = false;
723 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Dcbx is disabled\n");
724 		return ECORE_INVAL;
725 	}
726 
727 	p_feat = &p_hwfn->p_dcbx_info->operational.features;
728 	p_results = &p_hwfn->p_dcbx_info->results;
729 
730 	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
731 		 DCBX_CONFIG_VERSION_IEEE);
732 	p_operational->ieee = val;
733 
734 	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
735 		 DCBX_CONFIG_VERSION_CEE);
736 	p_operational->cee = val;
737 
738 	val = !!(ECORE_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
739 		 DCBX_CONFIG_VERSION_STATIC);
740 	p_operational->local = val;
741 
742 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
743 		   "Version support: ieee %d, cee %d, static %d\n",
744 		   p_operational->ieee, p_operational->cee,
745 		   p_operational->local);
746 
747 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
748 				     p_feat->app.app_pri_tbl, &p_feat->ets,
749 				     p_feat->pfc, &params->operational.params,
750 				     p_operational->ieee);
751 	ecore_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio,
752 				     p_results);
753 	err = ECORE_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR);
754 	p_operational->err = err;
755 	p_operational->enabled = enabled;
756 	p_operational->valid = true;
757 
758 	return ECORE_SUCCESS;
759 }
760 
761 static void
762 ecore_dcbx_get_dscp_params(struct ecore_hwfn *p_hwfn,
763 			   struct ecore_ptt *p_ptt,
764 			   struct ecore_dcbx_get *params)
765 {
766 	struct ecore_dcbx_dscp_params *p_dscp;
767 	struct dcb_dscp_map *p_dscp_map;
768 	int i, j, entry;
769 	u32 pri_map;
770 
771 	p_dscp = &params->dscp;
772 	p_dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
773 	p_dscp->enabled = ECORE_MFW_GET_FIELD(p_dscp_map->flags,
774 					      DCB_DSCP_ENABLE);
775 	/* MFW encodes 64 dscp entries into 8 element array of u32 entries,
776 	 * where each entry holds the 4bit priority map for 8 dscp entries.
777 	 */
778 	for (i = 0, entry = 0; i < ECORE_DCBX_DSCP_SIZE / 8; i++) {
779 		pri_map = OSAL_BE32_TO_CPU(p_dscp_map->dscp_pri_map[i]);
780 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "elem %d pri_map 0x%x\n",
781 			   entry, pri_map);
782 		for (j = 0; j < ECORE_DCBX_DSCP_SIZE / 8; j++, entry++)
783 			p_dscp->dscp_pri_map[entry] = (u32)(pri_map >>
784 							   (j * 4)) & 0xf;
785 	}
786 }
787 
788 static void
789 ecore_dcbx_get_local_lldp_params(struct ecore_hwfn *p_hwfn,
790 				 struct ecore_ptt *p_ptt,
791 				 struct ecore_dcbx_get *params)
792 {
793 	struct lldp_config_params_s *p_local;
794 
795 	p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
796 
797 	OSAL_MEMCPY(params->lldp_local.local_chassis_id,
798 		    p_local->local_chassis_id,
799 		    OSAL_ARRAY_SIZE(p_local->local_chassis_id));
800 	OSAL_MEMCPY(params->lldp_local.local_port_id, p_local->local_port_id,
801 		    OSAL_ARRAY_SIZE(p_local->local_port_id));
802 }
803 
804 static void
805 ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn *p_hwfn,
806 				  struct ecore_ptt *p_ptt,
807 				  struct ecore_dcbx_get *params)
808 {
809 	struct lldp_status_params_s *p_remote;
810 
811 	p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
812 
813 	OSAL_MEMCPY(params->lldp_remote.peer_chassis_id,
814 		    p_remote->peer_chassis_id,
815 		    OSAL_ARRAY_SIZE(p_remote->peer_chassis_id));
816 	OSAL_MEMCPY(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
817 		    OSAL_ARRAY_SIZE(p_remote->peer_port_id));
818 }
819 
820 static enum _ecore_status_t
821 ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
822 		      struct ecore_dcbx_get *p_params,
823 		      enum ecore_mib_read_type type)
824 {
825 	enum _ecore_status_t rc = ECORE_SUCCESS;
826 
827 	switch (type) {
828 	case ECORE_DCBX_REMOTE_MIB:
829 		ecore_dcbx_get_remote_params(p_hwfn, p_ptt, p_params);
830 		break;
831 	case ECORE_DCBX_LOCAL_MIB:
832 		ecore_dcbx_get_local_params(p_hwfn, p_ptt, p_params);
833 		break;
834 	case ECORE_DCBX_OPERATIONAL_MIB:
835 		ecore_dcbx_get_operational_params(p_hwfn, p_ptt, p_params);
836 		break;
837 	case ECORE_DCBX_REMOTE_LLDP_MIB:
838 		ecore_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params);
839 		break;
840 	case ECORE_DCBX_LOCAL_LLDP_MIB:
841 		ecore_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params);
842 		break;
843 	default:
844 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
845 		return ECORE_INVAL;
846 	}
847 
848 	return rc;
849 }
850 
851 static enum _ecore_status_t
852 ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn *p_hwfn,
853 			       struct ecore_ptt *p_ptt)
854 {
855 	struct ecore_dcbx_mib_meta_data data;
856 	enum _ecore_status_t rc = ECORE_SUCCESS;
857 
858 	OSAL_MEM_ZERO(&data, sizeof(data));
859 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
860 							   lldp_config_params);
861 	data.lldp_local = p_hwfn->p_dcbx_info->lldp_local;
862 	data.size = sizeof(struct lldp_config_params_s);
863 	ecore_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size);
864 
865 	return rc;
866 }
867 
868 static enum _ecore_status_t
869 ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn *p_hwfn,
870 				struct ecore_ptt *p_ptt,
871 				enum ecore_mib_read_type type)
872 {
873 	struct ecore_dcbx_mib_meta_data data;
874 	enum _ecore_status_t rc = ECORE_SUCCESS;
875 
876 	OSAL_MEM_ZERO(&data, sizeof(data));
877 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
878 							   lldp_status_params);
879 	data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote;
880 	data.size = sizeof(struct lldp_status_params_s);
881 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
882 
883 	return rc;
884 }
885 
886 static enum _ecore_status_t
887 ecore_dcbx_read_operational_mib(struct ecore_hwfn *p_hwfn,
888 				struct ecore_ptt *p_ptt,
889 				enum ecore_mib_read_type type)
890 {
891 	struct ecore_dcbx_mib_meta_data data;
892 	enum _ecore_status_t rc = ECORE_SUCCESS;
893 
894 	OSAL_MEM_ZERO(&data, sizeof(data));
895 	data.addr = p_hwfn->mcp_info->port_addr +
896 		    offsetof(struct public_port, operational_dcbx_mib);
897 	data.mib = &p_hwfn->p_dcbx_info->operational;
898 	data.size = sizeof(struct dcbx_mib);
899 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
900 
901 	return rc;
902 }
903 
904 static enum _ecore_status_t
905 ecore_dcbx_read_remote_mib(struct ecore_hwfn *p_hwfn,
906 			   struct ecore_ptt *p_ptt,
907 			   enum ecore_mib_read_type type)
908 {
909 	struct ecore_dcbx_mib_meta_data data;
910 	enum _ecore_status_t rc = ECORE_SUCCESS;
911 
912 	OSAL_MEM_ZERO(&data, sizeof(data));
913 	data.addr = p_hwfn->mcp_info->port_addr +
914 		    offsetof(struct public_port, remote_dcbx_mib);
915 	data.mib = &p_hwfn->p_dcbx_info->remote;
916 	data.size = sizeof(struct dcbx_mib);
917 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
918 
919 	return rc;
920 }
921 
922 static enum _ecore_status_t
923 ecore_dcbx_read_local_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
924 {
925 	struct ecore_dcbx_mib_meta_data data;
926 	enum _ecore_status_t rc = ECORE_SUCCESS;
927 
928 	OSAL_MEM_ZERO(&data, sizeof(data));
929 	data.addr = p_hwfn->mcp_info->port_addr +
930 			offsetof(struct public_port, local_admin_dcbx_mib);
931 	data.local_admin = &p_hwfn->p_dcbx_info->local_admin;
932 	data.size = sizeof(struct dcbx_local_params);
933 	ecore_memcpy_from(p_hwfn, p_ptt, data.local_admin,
934 			  data.addr, data.size);
935 
936 	return rc;
937 }
938 
939 static void
940 ecore_dcbx_read_dscp_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
941 {
942 	struct ecore_dcbx_mib_meta_data data;
943 
944 	data.addr = p_hwfn->mcp_info->port_addr +
945 			offsetof(struct public_port, dcb_dscp_map);
946 	data.dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
947 	data.size = sizeof(struct dcb_dscp_map);
948 	ecore_memcpy_from(p_hwfn, p_ptt, data.dscp_map, data.addr, data.size);
949 }
950 
951 static enum _ecore_status_t ecore_dcbx_read_mib(struct ecore_hwfn *p_hwfn,
952 						struct ecore_ptt *p_ptt,
953 						enum ecore_mib_read_type type)
954 {
955 	enum _ecore_status_t rc = ECORE_INVAL;
956 
957 	switch (type) {
958 	case ECORE_DCBX_OPERATIONAL_MIB:
959 		ecore_dcbx_read_dscp_mib(p_hwfn, p_ptt);
960 		rc = ecore_dcbx_read_operational_mib(p_hwfn, p_ptt, type);
961 		break;
962 	case ECORE_DCBX_REMOTE_MIB:
963 		rc = ecore_dcbx_read_remote_mib(p_hwfn, p_ptt, type);
964 		break;
965 	case ECORE_DCBX_LOCAL_MIB:
966 		rc = ecore_dcbx_read_local_mib(p_hwfn, p_ptt);
967 		break;
968 	case ECORE_DCBX_REMOTE_LLDP_MIB:
969 		rc = ecore_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type);
970 		break;
971 	case ECORE_DCBX_LOCAL_LLDP_MIB:
972 		rc = ecore_dcbx_read_local_lldp_mib(p_hwfn, p_ptt);
973 		break;
974 	default:
975 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
976 	}
977 
978 	return rc;
979 }
980 
981 /*
982  * Read updated MIB.
983  * Reconfigure QM and invoke PF update ramrod command if operational MIB
984  * change is detected.
985  */
986 enum _ecore_status_t
987 ecore_dcbx_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
988 			    enum ecore_mib_read_type type)
989 {
990 	enum _ecore_status_t rc = ECORE_SUCCESS;
991 
992 	rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
993 	if (rc)
994 		return rc;
995 
996 	if (type == ECORE_DCBX_OPERATIONAL_MIB) {
997 		ecore_dcbx_get_dscp_params(p_hwfn, p_ptt,
998 					   &p_hwfn->p_dcbx_info->get);
999 
1000 		rc = ecore_dcbx_process_mib_info(p_hwfn);
1001 		if (!rc) {
1002 			bool enabled;
1003 
1004 			/* reconfigure tcs of QM queues according
1005 			 * to negotiation results
1006 			 */
1007 			ecore_qm_reconf(p_hwfn, p_ptt);
1008 
1009 			/* update storm FW with negotiation results */
1010 			ecore_sp_pf_update_dcbx(p_hwfn);
1011 
1012 			/* set eagle enigne 1 flow control workaround
1013 			 * according to negotiation results
1014 			 */
1015 			enabled = p_hwfn->p_dcbx_info->results.dcbx_enabled;
1016 
1017 #ifdef CONFIG_ECORE_ROCE
1018 			/* for roce PFs, we may want to enable/disable DPM
1019 			 * when DCBx change occurs
1020 			 */
1021 			if (ECORE_IS_ROCE_PERSONALITY(p_hwfn))
1022 				ecore_roce_dpm_dcbx(p_hwfn, p_ptt);
1023 #endif
1024 		}
1025 	}
1026 
1027 	ecore_dcbx_get_params(p_hwfn, p_ptt, &p_hwfn->p_dcbx_info->get, type);
1028 
1029 	if (type == ECORE_DCBX_OPERATIONAL_MIB) {
1030 		struct ecore_dcbx_results *p_data;
1031 		u16 val;
1032 
1033 		/* Update the DSCP to TC mapping bit if required */
1034 		if (p_hwfn->p_dcbx_info->dscp_nig_update) {
1035 			ecore_wr(p_hwfn, p_ptt, NIG_REG_DSCP_TO_TC_MAP_ENABLE,
1036 				 0x1);
1037 			p_hwfn->p_dcbx_info->dscp_nig_update = false;
1038 		}
1039 
1040 		/* Configure in NIG which protocols support EDPM and should
1041 		 * honor PFC.
1042 		 */
1043 		p_data = &p_hwfn->p_dcbx_info->results;
1044 		val = (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE].tc) |
1045 			(0x1 << p_data->arr[DCBX_PROTOCOL_ROCE_V2].tc);
1046 		val <<= NIG_REG_TX_EDPM_CTRL_TX_EDPM_TC_EN_SHIFT;
1047 		val |= NIG_REG_TX_EDPM_CTRL_TX_EDPM_EN;
1048 		ecore_wr(p_hwfn, p_ptt, NIG_REG_TX_EDPM_CTRL, val);
1049 	}
1050 
1051 	OSAL_DCBX_AEN(p_hwfn, type);
1052 
1053 	return rc;
1054 }
1055 
1056 enum _ecore_status_t ecore_dcbx_info_alloc(struct ecore_hwfn *p_hwfn)
1057 {
1058 #ifndef __EXTRACT__LINUX__
1059 	OSAL_BUILD_BUG_ON(ECORE_LLDP_CHASSIS_ID_STAT_LEN !=
1060 			  LLDP_CHASSIS_ID_STAT_LEN);
1061 	OSAL_BUILD_BUG_ON(ECORE_LLDP_PORT_ID_STAT_LEN !=
1062 			  LLDP_PORT_ID_STAT_LEN);
1063 	OSAL_BUILD_BUG_ON(ECORE_DCBX_MAX_APP_PROTOCOL !=
1064 			  DCBX_MAX_APP_PROTOCOL);
1065 #endif
1066 
1067 	p_hwfn->p_dcbx_info = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
1068 					  sizeof(*p_hwfn->p_dcbx_info));
1069 	if (!p_hwfn->p_dcbx_info) {
1070 		DP_NOTICE(p_hwfn, true,
1071 			  "Failed to allocate `struct ecore_dcbx_info'");
1072 		return ECORE_NOMEM;
1073 	}
1074 
1075 	p_hwfn->p_dcbx_info->iwarp_port =
1076 		p_hwfn->pf_params.rdma_pf_params.iwarp_port;
1077 
1078 	return ECORE_SUCCESS;
1079 }
1080 
1081 void ecore_dcbx_info_free(struct ecore_hwfn *p_hwfn)
1082 {
1083 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_dcbx_info);
1084 	p_hwfn->p_dcbx_info = OSAL_NULL;
1085 }
1086 
1087 static void ecore_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
1088 					    struct ecore_dcbx_results *p_src,
1089 					    enum dcbx_protocol_type type)
1090 {
1091 	p_data->dcb_enable_flag = p_src->arr[type].enable;
1092 	p_data->dcb_priority = p_src->arr[type].priority;
1093 	p_data->dcb_tc = p_src->arr[type].tc;
1094 	p_data->dscp_enable_flag = p_src->arr[type].dscp_enable;
1095 	p_data->dscp_val = p_src->arr[type].dscp_val;
1096 }
1097 
1098 /* Set pf update ramrod command params */
1099 void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results *p_src,
1100 				     struct pf_update_ramrod_data *p_dest)
1101 {
1102 	struct protocol_dcb_data *p_dcb_data;
1103 	u8 update_flag;
1104 
1105 	p_dest->pf_id = p_src->pf_id;
1106 
1107 	update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update;
1108 	p_dest->update_fcoe_dcb_data_mode = update_flag;
1109 
1110 	update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update;
1111 	p_dest->update_roce_dcb_data_mode = update_flag;
1112 
1113 	update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update;
1114 	p_dest->update_rroce_dcb_data_mode = update_flag;
1115 
1116 	update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update;
1117 	p_dest->update_iscsi_dcb_data_mode = update_flag;
1118 	update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update;
1119 	p_dest->update_eth_dcb_data_mode = update_flag;
1120 	update_flag = p_src->arr[DCBX_PROTOCOL_IWARP].update;
1121 	p_dest->update_iwarp_dcb_data_mode = update_flag;
1122 
1123 	p_dcb_data = &p_dest->fcoe_dcb_data;
1124 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE);
1125 	p_dcb_data = &p_dest->roce_dcb_data;
1126 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE);
1127 	p_dcb_data = &p_dest->rroce_dcb_data;
1128 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src,
1129 					DCBX_PROTOCOL_ROCE_V2);
1130 	p_dcb_data = &p_dest->iscsi_dcb_data;
1131 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI);
1132 	p_dcb_data = &p_dest->eth_dcb_data;
1133 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
1134 	p_dcb_data = &p_dest->iwarp_dcb_data;
1135 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_IWARP);
1136 }
1137 
1138 enum _ecore_status_t ecore_dcbx_query_params(struct ecore_hwfn *p_hwfn,
1139 					     struct ecore_dcbx_get *p_get,
1140 					     enum ecore_mib_read_type type)
1141 {
1142 	struct ecore_ptt *p_ptt;
1143 	enum _ecore_status_t rc;
1144 
1145 	if (IS_VF(p_hwfn->p_dev))
1146 		return ECORE_INVAL;
1147 
1148 	p_ptt = ecore_ptt_acquire(p_hwfn);
1149 	if (!p_ptt) {
1150 		rc = ECORE_TIMEOUT;
1151 		DP_ERR(p_hwfn, "rc = %d\n", rc);
1152 		return rc;
1153 	}
1154 
1155 	rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
1156 	if (rc != ECORE_SUCCESS)
1157 		goto out;
1158 
1159 	rc = ecore_dcbx_get_params(p_hwfn, p_ptt, p_get, type);
1160 
1161 out:
1162 	ecore_ptt_release(p_hwfn, p_ptt);
1163 	return rc;
1164 }
1165 
1166 static void
1167 ecore_dcbx_set_pfc_data(struct ecore_hwfn *p_hwfn,
1168 			u32 *pfc, struct ecore_dcbx_params *p_params)
1169 {
1170 	u8 pfc_map = 0;
1171 	int i;
1172 
1173 	*pfc &= ~DCBX_PFC_ERROR_MASK;
1174 
1175 	if (p_params->pfc.willing)
1176 		*pfc |= DCBX_PFC_WILLING_MASK;
1177 	else
1178 		*pfc &= ~DCBX_PFC_WILLING_MASK;
1179 
1180 	if (p_params->pfc.enabled)
1181 		*pfc |= DCBX_PFC_ENABLED_MASK;
1182 	else
1183 		*pfc &= ~DCBX_PFC_ENABLED_MASK;
1184 
1185 	*pfc &= ~DCBX_PFC_CAPS_MASK;
1186 	*pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT;
1187 
1188 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++)
1189 		if (p_params->pfc.prio[i])
1190 			pfc_map |= (1 << i);
1191 	*pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK;
1192 	*pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT);
1193 
1194 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "pfc = 0x%x\n", *pfc);
1195 }
1196 
1197 static void
1198 ecore_dcbx_set_ets_data(struct ecore_hwfn *p_hwfn,
1199 			struct dcbx_ets_feature *p_ets,
1200 			struct ecore_dcbx_params *p_params)
1201 {
1202 	u8 *bw_map, *tsa_map;
1203 	u32 val;
1204 	int i;
1205 
1206 	if (p_params->ets_willing)
1207 		p_ets->flags |= DCBX_ETS_WILLING_MASK;
1208 	else
1209 		p_ets->flags &= ~DCBX_ETS_WILLING_MASK;
1210 
1211 	if (p_params->ets_cbs)
1212 		p_ets->flags |= DCBX_ETS_CBS_MASK;
1213 	else
1214 		p_ets->flags &= ~DCBX_ETS_CBS_MASK;
1215 
1216 	if (p_params->ets_enabled)
1217 		p_ets->flags |= DCBX_ETS_ENABLED_MASK;
1218 	else
1219 		p_ets->flags &= ~DCBX_ETS_ENABLED_MASK;
1220 
1221 	p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK;
1222 	p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT;
1223 
1224 	bw_map = (u8 *)&p_ets->tc_bw_tbl[0];
1225 	tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0];
1226 	p_ets->pri_tc_tbl[0] = 0;
1227 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
1228 		bw_map[i] = p_params->ets_tc_bw_tbl[i];
1229 		tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
1230 		/* Copy the priority value to the corresponding 4 bits in the
1231 		 * traffic class table.
1232 		 */
1233 		val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
1234 		p_ets->pri_tc_tbl[0] |= val;
1235 	}
1236 	for (i = 0; i < 2; i++) {
1237 		p_ets->tc_bw_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_bw_tbl[i]);
1238 		p_ets->tc_tsa_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_tsa_tbl[i]);
1239 	}
1240 
1241 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
1242 		   "flags = 0x%x pri_tc = 0x%x tc_bwl[] = {0x%x, 0x%x} tc_tsa = {0x%x, 0x%x}\n",
1243 		   p_ets->flags, p_ets->pri_tc_tbl[0], p_ets->tc_bw_tbl[0],
1244 		   p_ets->tc_bw_tbl[1], p_ets->tc_tsa_tbl[0],
1245 		   p_ets->tc_tsa_tbl[1]);
1246 }
1247 
1248 static void
1249 ecore_dcbx_set_app_data(struct ecore_hwfn *p_hwfn,
1250 			struct dcbx_app_priority_feature *p_app,
1251 			struct ecore_dcbx_params *p_params, bool ieee)
1252 {
1253 	u32 *entry;
1254 	int i;
1255 
1256 	if (p_params->app_willing)
1257 		p_app->flags |= DCBX_APP_WILLING_MASK;
1258 	else
1259 		p_app->flags &= ~DCBX_APP_WILLING_MASK;
1260 
1261 	if (p_params->app_valid)
1262 		p_app->flags |= DCBX_APP_ENABLED_MASK;
1263 	else
1264 		p_app->flags &= ~DCBX_APP_ENABLED_MASK;
1265 
1266 	p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK;
1267 	p_app->flags |= (u32)p_params->num_app_entries <<
1268 					DCBX_APP_NUM_ENTRIES_SHIFT;
1269 
1270 	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
1271 		entry = &p_app->app_pri_tbl[i].entry;
1272 		*entry = 0;
1273 		if (ieee) {
1274 			*entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK);
1275 			switch (p_params->app_entry[i].sf_ieee) {
1276 			case ECORE_DCBX_SF_IEEE_ETHTYPE:
1277 				*entry  |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE <<
1278 					    DCBX_APP_SF_IEEE_SHIFT);
1279 				*entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
1280 					    DCBX_APP_SF_SHIFT);
1281 				break;
1282 			case ECORE_DCBX_SF_IEEE_TCP_PORT:
1283 				*entry  |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT <<
1284 					    DCBX_APP_SF_IEEE_SHIFT);
1285 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
1286 					    DCBX_APP_SF_SHIFT);
1287 				break;
1288 			case ECORE_DCBX_SF_IEEE_UDP_PORT:
1289 				*entry  |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT <<
1290 					    DCBX_APP_SF_IEEE_SHIFT);
1291 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
1292 					    DCBX_APP_SF_SHIFT);
1293 				break;
1294 			case ECORE_DCBX_SF_IEEE_TCP_UDP_PORT:
1295 				*entry  |= (u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT <<
1296 					    DCBX_APP_SF_IEEE_SHIFT;
1297 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
1298 					    DCBX_APP_SF_SHIFT);
1299 				break;
1300 			}
1301 		} else {
1302 			*entry &= ~DCBX_APP_SF_MASK;
1303 			if (p_params->app_entry[i].ethtype)
1304 				*entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
1305 					    DCBX_APP_SF_SHIFT);
1306 			else
1307 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
1308 					    DCBX_APP_SF_SHIFT);
1309 		}
1310 		*entry &= ~DCBX_APP_PROTOCOL_ID_MASK;
1311 		*entry |= ((u32)p_params->app_entry[i].proto_id <<
1312 				DCBX_APP_PROTOCOL_ID_SHIFT);
1313 		*entry &= ~DCBX_APP_PRI_MAP_MASK;
1314 		*entry |= ((u32)(p_params->app_entry[i].prio) <<
1315 				DCBX_APP_PRI_MAP_SHIFT);
1316 	}
1317 
1318 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_app->flags);
1319 }
1320 
1321 static enum _ecore_status_t
1322 ecore_dcbx_set_local_params(struct ecore_hwfn *p_hwfn,
1323 			    struct dcbx_local_params *local_admin,
1324 			    struct ecore_dcbx_set *params)
1325 {
1326 	bool ieee = false;
1327 
1328 	local_admin->flags = 0;
1329 	OSAL_MEMCPY(&local_admin->features,
1330 		    &p_hwfn->p_dcbx_info->operational.features,
1331 		    sizeof(local_admin->features));
1332 
1333 	if (params->enabled) {
1334 		local_admin->config = params->ver_num;
1335 		ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE);
1336 	} else
1337 		local_admin->config = DCBX_CONFIG_VERSION_DISABLED;
1338 
1339 	if (params->override_flags & ECORE_DCBX_OVERRIDE_PFC_CFG)
1340 		ecore_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc,
1341 					&params->config.params);
1342 
1343 	if (params->override_flags & ECORE_DCBX_OVERRIDE_ETS_CFG)
1344 		ecore_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets,
1345 					&params->config.params);
1346 
1347 	if (params->override_flags & ECORE_DCBX_OVERRIDE_APP_CFG)
1348 		ecore_dcbx_set_app_data(p_hwfn, &local_admin->features.app,
1349 					&params->config.params, ieee);
1350 
1351 	return ECORE_SUCCESS;
1352 }
1353 
1354 static enum _ecore_status_t
1355 ecore_dcbx_set_dscp_params(struct ecore_hwfn *p_hwfn,
1356 			   struct dcb_dscp_map *p_dscp_map,
1357 			   struct ecore_dcbx_set *p_params)
1358 {
1359 	int entry, i, j;
1360 	u32 val;
1361 
1362 	OSAL_MEMCPY(p_dscp_map, &p_hwfn->p_dcbx_info->dscp_map,
1363 		    sizeof(*p_dscp_map));
1364 
1365 	p_dscp_map->flags &= ~DCB_DSCP_ENABLE_MASK;
1366 	if (p_params->dscp.enabled)
1367 		p_dscp_map->flags |= DCB_DSCP_ENABLE_MASK;
1368 
1369 	for (i = 0, entry = 0; i < 8; i++) {
1370 		val = 0;
1371 		for (j = 0; j < 8; j++, entry++)
1372 			val |= (((u32)p_params->dscp.dscp_pri_map[entry]) <<
1373 				(j * 4));
1374 
1375 		p_dscp_map->dscp_pri_map[i] = OSAL_CPU_TO_BE32(val);
1376 	}
1377 
1378 	p_hwfn->p_dcbx_info->dscp_nig_update = true;
1379 
1380 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_dscp_map->flags);
1381 
1382 	return ECORE_SUCCESS;
1383 }
1384 
1385 enum _ecore_status_t ecore_dcbx_config_params(struct ecore_hwfn *p_hwfn,
1386 					      struct ecore_ptt *p_ptt,
1387 					      struct ecore_dcbx_set *params,
1388 					      bool hw_commit)
1389 {
1390 	struct dcbx_local_params local_admin;
1391 	struct ecore_dcbx_mib_meta_data data;
1392 	struct dcb_dscp_map dscp_map;
1393 	u32 resp = 0, param = 0;
1394 	enum _ecore_status_t rc = ECORE_SUCCESS;
1395 
1396 	if (!hw_commit) {
1397 		OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set, params,
1398 			    sizeof(p_hwfn->p_dcbx_info->set));
1399 		return ECORE_SUCCESS;
1400 	}
1401 
1402 	/* clear set-parmas cache */
1403 	OSAL_MEMSET(&p_hwfn->p_dcbx_info->set, 0,
1404 		    sizeof(struct ecore_dcbx_set));
1405 
1406 	OSAL_MEMSET(&local_admin, 0, sizeof(local_admin));
1407 	ecore_dcbx_set_local_params(p_hwfn, &local_admin, params);
1408 
1409 	data.addr = p_hwfn->mcp_info->port_addr +
1410 			offsetof(struct public_port, local_admin_dcbx_mib);
1411 	data.local_admin = &local_admin;
1412 	data.size = sizeof(struct dcbx_local_params);
1413 	ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size);
1414 
1415 	if (params->override_flags & ECORE_DCBX_OVERRIDE_DSCP_CFG) {
1416 		OSAL_MEMSET(&dscp_map, 0, sizeof(dscp_map));
1417 		ecore_dcbx_set_dscp_params(p_hwfn, &dscp_map, params);
1418 
1419 		data.addr = p_hwfn->mcp_info->port_addr +
1420 				offsetof(struct public_port, dcb_dscp_map);
1421 		data.dscp_map = &dscp_map;
1422 		data.size = sizeof(struct dcb_dscp_map);
1423 		ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.dscp_map,
1424 				data.size);
1425 	}
1426 
1427 	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX,
1428 			   1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, &param);
1429 	if (rc != ECORE_SUCCESS) {
1430 		DP_NOTICE(p_hwfn, false,
1431 			  "Failed to send DCBX update request\n");
1432 		return rc;
1433 	}
1434 
1435 	return rc;
1436 }
1437 
1438 enum _ecore_status_t ecore_dcbx_get_config_params(struct ecore_hwfn *p_hwfn,
1439 						  struct ecore_dcbx_set *params)
1440 {
1441 	struct ecore_dcbx_get *dcbx_info;
1442 	int rc;
1443 
1444 	if (p_hwfn->p_dcbx_info->set.config.valid) {
1445 		OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
1446 			    sizeof(struct ecore_dcbx_set));
1447 		return ECORE_SUCCESS;
1448 	}
1449 
1450 	dcbx_info = OSAL_ALLOC(p_hwfn->p_dev, GFP_KERNEL,
1451 			       sizeof(*dcbx_info));
1452 	if (!dcbx_info) {
1453 		DP_ERR(p_hwfn, "Failed to allocate struct ecore_dcbx_info\n");
1454 		return ECORE_NOMEM;
1455 	}
1456 
1457 	OSAL_MEMSET(dcbx_info, 0, sizeof(*dcbx_info));
1458 	rc = ecore_dcbx_query_params(p_hwfn, dcbx_info,
1459 				     ECORE_DCBX_OPERATIONAL_MIB);
1460 	if (rc) {
1461 		OSAL_FREE(p_hwfn->p_dev, dcbx_info);
1462 		return rc;
1463 	}
1464 	p_hwfn->p_dcbx_info->set.override_flags = 0;
1465 
1466 	p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED;
1467 	if (dcbx_info->operational.cee)
1468 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE;
1469 	if (dcbx_info->operational.ieee)
1470 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE;
1471 	if (dcbx_info->operational.local)
1472 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC;
1473 
1474 	p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled;
1475 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set.config.params,
1476 		    &dcbx_info->operational.params,
1477 		    sizeof(struct ecore_dcbx_admin_params));
1478 	p_hwfn->p_dcbx_info->set.config.valid = true;
1479 
1480 	OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
1481 		    sizeof(struct ecore_dcbx_set));
1482 
1483 	OSAL_FREE(p_hwfn->p_dev, dcbx_info);
1484 
1485 	return ECORE_SUCCESS;
1486 }
1487