xref: /dpdk/drivers/net/qede/base/ecore_dcbx.c (revision 5018f1fc5f18d517c672559d4cc74784a579e037)
13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause
29adde217SRasesh Mody  * Copyright (c) 2016 - 2018 Cavium Inc.
326ae839dSRasesh Mody  * All rights reserved.
49adde217SRasesh Mody  * www.cavium.com
526ae839dSRasesh Mody  */
626ae839dSRasesh Mody 
726ae839dSRasesh Mody #include "bcm_osal.h"
826ae839dSRasesh Mody #include "ecore.h"
926ae839dSRasesh Mody #include "ecore_sp_commands.h"
1026ae839dSRasesh Mody #include "ecore_dcbx.h"
1126ae839dSRasesh Mody #include "ecore_cxt.h"
1226ae839dSRasesh Mody #include "ecore_gtt_reg_addr.h"
1326ae839dSRasesh Mody #include "ecore_iro.h"
14869c47d0SRasesh Mody #include "ecore_iov_api.h"
1526ae839dSRasesh Mody 
1626ae839dSRasesh Mody #define ECORE_DCBX_MAX_MIB_READ_TRY	(100)
1726ae839dSRasesh Mody #define ECORE_ETH_TYPE_DEFAULT		(0)
1826ae839dSRasesh Mody 
1926ae839dSRasesh Mody #define ECORE_DCBX_INVALID_PRIORITY	0xFF
2026ae839dSRasesh Mody 
2126ae839dSRasesh Mody /* Get Traffic Class from priority traffic class table, 4 bits represent
2226ae839dSRasesh Mody  * the traffic class corresponding to the priority.
2326ae839dSRasesh Mody  */
2426ae839dSRasesh Mody #define ECORE_DCBX_PRIO2TC(prio_tc_tbl, prio) \
2522d07d93SRasesh Mody 		((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
2626ae839dSRasesh Mody 
ecore_dcbx_app_ethtype(u32 app_info_bitmap)2726ae839dSRasesh Mody static bool ecore_dcbx_app_ethtype(u32 app_info_bitmap)
2826ae839dSRasesh Mody {
2904b00049SRasesh Mody 	return !!(GET_MFW_FIELD(app_info_bitmap, DCBX_APP_SF) ==
303d1babcaSRasesh Mody 		  DCBX_APP_SF_ETHTYPE);
313d1babcaSRasesh Mody }
323d1babcaSRasesh Mody 
ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap)333d1babcaSRasesh Mody static bool ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap)
343d1babcaSRasesh Mody {
3504b00049SRasesh Mody 	u8 mfw_val = GET_MFW_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
363d1babcaSRasesh Mody 
373d1babcaSRasesh Mody 	/* Old MFW */
383d1babcaSRasesh Mody 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
393d1babcaSRasesh Mody 		return ecore_dcbx_app_ethtype(app_info_bitmap);
403d1babcaSRasesh Mody 
413d1babcaSRasesh Mody 	return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE);
4226ae839dSRasesh Mody }
4326ae839dSRasesh Mody 
ecore_dcbx_app_port(u32 app_info_bitmap)4426ae839dSRasesh Mody static bool ecore_dcbx_app_port(u32 app_info_bitmap)
4526ae839dSRasesh Mody {
4604b00049SRasesh Mody 	return !!(GET_MFW_FIELD(app_info_bitmap, DCBX_APP_SF) ==
473d1babcaSRasesh Mody 		  DCBX_APP_SF_PORT);
4826ae839dSRasesh Mody }
4926ae839dSRasesh Mody 
ecore_dcbx_ieee_app_port(u32 app_info_bitmap,u8 type)5022d07d93SRasesh Mody static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
5122d07d93SRasesh Mody {
5204b00049SRasesh Mody 	u8 mfw_val = GET_MFW_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
5322d07d93SRasesh Mody 
5422d07d93SRasesh Mody 	/* Old MFW */
5522d07d93SRasesh Mody 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
5622d07d93SRasesh Mody 		return ecore_dcbx_app_port(app_info_bitmap);
5722d07d93SRasesh Mody 
583d1babcaSRasesh Mody 	return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT);
5922d07d93SRasesh Mody }
6022d07d93SRasesh Mody 
ecore_dcbx_default_tlv(u32 app_info_bitmap,u16 proto_id,bool ieee)613d1babcaSRasesh Mody static bool ecore_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
6226ae839dSRasesh Mody {
633d1babcaSRasesh Mody 	bool ethtype;
6426ae839dSRasesh Mody 
653d1babcaSRasesh Mody 	if (ieee)
663d1babcaSRasesh Mody 		ethtype = ecore_dcbx_ieee_app_ethtype(app_info_bitmap);
673d1babcaSRasesh Mody 	else
683d1babcaSRasesh Mody 		ethtype = ecore_dcbx_app_ethtype(app_info_bitmap);
6926ae839dSRasesh Mody 
703d1babcaSRasesh Mody 	return !!(ethtype && (proto_id == ECORE_ETH_TYPE_DEFAULT));
7122d07d93SRasesh Mody }
7222d07d93SRasesh Mody 
ecore_dcbx_iwarp_tlv(struct ecore_hwfn * p_hwfn,u32 app_info_bitmap,u16 proto_id,bool ieee)732e2680e0SRasesh Mody static bool ecore_dcbx_iwarp_tlv(struct ecore_hwfn *p_hwfn, u32 app_info_bitmap,
742e2680e0SRasesh Mody 				 u16 proto_id, bool ieee)
752e2680e0SRasesh Mody {
762e2680e0SRasesh Mody 	bool port;
772e2680e0SRasesh Mody 
782e2680e0SRasesh Mody 	if (!p_hwfn->p_dcbx_info->iwarp_port)
792e2680e0SRasesh Mody 		return false;
802e2680e0SRasesh Mody 
812e2680e0SRasesh Mody 	if (ieee)
822e2680e0SRasesh Mody 		port = ecore_dcbx_ieee_app_port(app_info_bitmap,
832e2680e0SRasesh Mody 						DCBX_APP_SF_IEEE_TCP_PORT);
842e2680e0SRasesh Mody 	else
852e2680e0SRasesh Mody 		port = ecore_dcbx_app_port(app_info_bitmap);
862e2680e0SRasesh Mody 
872e2680e0SRasesh Mody 	return !!(port && (proto_id == p_hwfn->p_dcbx_info->iwarp_port));
882e2680e0SRasesh Mody }
892e2680e0SRasesh Mody 
9026ae839dSRasesh Mody static void
ecore_dcbx_dp_protocol(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_results * p_data)9126ae839dSRasesh Mody ecore_dcbx_dp_protocol(struct ecore_hwfn *p_hwfn,
9226ae839dSRasesh Mody 		       struct ecore_dcbx_results *p_data)
9326ae839dSRasesh Mody {
9426ae839dSRasesh Mody 	enum dcbx_protocol_type id;
9526ae839dSRasesh Mody 	int i;
9626ae839dSRasesh Mody 
973d1babcaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "DCBX negotiated: %d\n",
983d1babcaSRasesh Mody 		   p_data->dcbx_enabled);
9926ae839dSRasesh Mody 
1003d1babcaSRasesh Mody 	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
10126ae839dSRasesh Mody 		id = ecore_dcbx_app_update[i].id;
10226ae839dSRasesh Mody 
1033d1babcaSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
10422d07d93SRasesh Mody 			   "%s info: update %d, enable %d, prio %d, tc %d,"
10522d07d93SRasesh Mody 			   " num_active_tc %d dscp_enable = %d dscp_val = %d\n",
1063d1babcaSRasesh Mody 			   ecore_dcbx_app_update[i].name,
1073d1babcaSRasesh Mody 			   p_data->arr[id].update,
1083d1babcaSRasesh Mody 			   p_data->arr[id].enable, p_data->arr[id].priority,
1093d1babcaSRasesh Mody 			   p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc,
1103d1babcaSRasesh Mody 			   p_data->arr[id].dscp_enable,
1113d1babcaSRasesh Mody 			   p_data->arr[id].dscp_val);
11226ae839dSRasesh Mody 	}
11326ae839dSRasesh Mody }
11426ae839dSRasesh Mody 
ecore_dcbx_get_dscp_value(struct ecore_hwfn * p_hwfn,u8 pri)11513c0ec8aSRasesh Mody u8 ecore_dcbx_get_dscp_value(struct ecore_hwfn *p_hwfn, u8 pri)
11613c0ec8aSRasesh Mody {
11713c0ec8aSRasesh Mody 	struct ecore_dcbx_dscp_params *dscp = &p_hwfn->p_dcbx_info->get.dscp;
11813c0ec8aSRasesh Mody 	u8 i;
11913c0ec8aSRasesh Mody 
12013c0ec8aSRasesh Mody 	if (!dscp->enabled)
12113c0ec8aSRasesh Mody 		return ECORE_DCBX_DSCP_DISABLED;
12213c0ec8aSRasesh Mody 
12313c0ec8aSRasesh Mody 	for (i = 0; i < ECORE_DCBX_DSCP_SIZE; i++)
12413c0ec8aSRasesh Mody 		if (pri == dscp->dscp_pri_map[i])
12513c0ec8aSRasesh Mody 			return i;
12613c0ec8aSRasesh Mody 
12713c0ec8aSRasesh Mody 	return ECORE_DCBX_DSCP_DISABLED;
12813c0ec8aSRasesh Mody }
12913c0ec8aSRasesh Mody 
1307a5dfdc1SRasesh Mody static void
ecore_dcbx_set_params(struct ecore_dcbx_results * p_data,struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,bool enable,u8 prio,u8 tc,enum dcbx_protocol_type type,enum ecore_pci_personality personality)13126ae839dSRasesh Mody ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
1329aea0e7dSRasesh Mody 		      struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
133d4806abaSRasesh Mody 		      bool enable, u8 prio, u8 tc,
13426ae839dSRasesh Mody 		      enum dcbx_protocol_type type,
13526ae839dSRasesh Mody 		      enum ecore_pci_personality personality)
13626ae839dSRasesh Mody {
13726ae839dSRasesh Mody 	/* PF update ramrod data */
13826ae839dSRasesh Mody 	p_data->arr[type].enable = enable;
13926ae839dSRasesh Mody 	p_data->arr[type].priority = prio;
14026ae839dSRasesh Mody 	p_data->arr[type].tc = tc;
14113c0ec8aSRasesh Mody 	p_data->arr[type].dscp_val = ecore_dcbx_get_dscp_value(p_hwfn, prio);
14213c0ec8aSRasesh Mody 	if (p_data->arr[type].dscp_val == ECORE_DCBX_DSCP_DISABLED) {
14313c0ec8aSRasesh Mody 		p_data->arr[type].dscp_enable = false;
14413c0ec8aSRasesh Mody 		p_data->arr[type].dscp_val = 0;
14513c0ec8aSRasesh Mody 	} else {
14613c0ec8aSRasesh Mody 		p_data->arr[type].dscp_enable = true;
14722d07d93SRasesh Mody 	}
14822d07d93SRasesh Mody 	p_data->arr[type].update = UPDATE_DCB_DSCP;
14922d07d93SRasesh Mody 
15036f45bceSRasesh Mody 	/* Do not add valn tag 0 when DCB is enabled and port is in UFP mode */
151*5018f1fcSJoyce Kong 	if (OSAL_GET_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits))
15236f45bceSRasesh Mody 		p_data->arr[type].dont_add_vlan0 = true;
15336f45bceSRasesh Mody 
1543d1babcaSRasesh Mody 	/* QM reconf data */
1550e9c6de3SRasesh Mody 	if (p_hwfn->hw_info.personality == personality)
1563d1babcaSRasesh Mody 		p_hwfn->hw_info.offload_tc = tc;
1579aea0e7dSRasesh Mody 
1589aea0e7dSRasesh Mody 	/* Configure dcbx vlan priority in doorbell block for roce EDPM */
159*5018f1fcSJoyce Kong 	if (OSAL_GET_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits) &&
160*5018f1fcSJoyce Kong 	    type == DCBX_PROTOCOL_ROCE) {
1619aea0e7dSRasesh Mody 		ecore_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1);
16252fa735cSRasesh Mody 		ecore_wr(p_hwfn, p_ptt, DORQ_REG_PF_PCP, prio << 1);
1639aea0e7dSRasesh Mody 	}
16426ae839dSRasesh Mody }
16526ae839dSRasesh Mody 
16626ae839dSRasesh Mody /* Update app protocol data and hw_info fields with the TLV info */
16726ae839dSRasesh Mody static void
ecore_dcbx_update_app_info(struct ecore_dcbx_results * p_data,struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,bool enable,u8 prio,u8 tc,enum dcbx_protocol_type type)16826ae839dSRasesh Mody ecore_dcbx_update_app_info(struct ecore_dcbx_results *p_data,
1699aea0e7dSRasesh Mody 			   struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
170d4806abaSRasesh Mody 			   bool enable, u8 prio, u8 tc,
17126ae839dSRasesh Mody 			   enum dcbx_protocol_type type)
17226ae839dSRasesh Mody {
17326ae839dSRasesh Mody 	enum ecore_pci_personality personality;
17426ae839dSRasesh Mody 	enum dcbx_protocol_type id;
17526ae839dSRasesh Mody 	int i;
17626ae839dSRasesh Mody 
1773d1babcaSRasesh Mody 	for (i = 0; i < OSAL_ARRAY_SIZE(ecore_dcbx_app_update); i++) {
17826ae839dSRasesh Mody 		id = ecore_dcbx_app_update[i].id;
17926ae839dSRasesh Mody 
18026ae839dSRasesh Mody 		if (type != id)
18126ae839dSRasesh Mody 			continue;
18226ae839dSRasesh Mody 
18326ae839dSRasesh Mody 		personality = ecore_dcbx_app_update[i].personality;
18426ae839dSRasesh Mody 
1859aea0e7dSRasesh Mody 		ecore_dcbx_set_params(p_data, p_hwfn, p_ptt, enable,
18626ae839dSRasesh Mody 				      prio, tc, type, personality);
18726ae839dSRasesh Mody 	}
18826ae839dSRasesh Mody }
18926ae839dSRasesh Mody 
19026ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_get_app_priority(u8 pri_bitmap,u8 * priority)19126ae839dSRasesh Mody ecore_dcbx_get_app_priority(u8 pri_bitmap, u8 *priority)
19226ae839dSRasesh Mody {
19326ae839dSRasesh Mody 	u32 pri_mask, pri = ECORE_MAX_PFC_PRIORITIES;
19426ae839dSRasesh Mody 	u32 index = ECORE_MAX_PFC_PRIORITIES - 1;
19526ae839dSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
19626ae839dSRasesh Mody 
19726ae839dSRasesh Mody 	/* Bitmap 1 corresponds to priority 0, return priority 0 */
19826ae839dSRasesh Mody 	if (pri_bitmap == 1) {
19926ae839dSRasesh Mody 		*priority = 0;
20026ae839dSRasesh Mody 		return rc;
20126ae839dSRasesh Mody 	}
20226ae839dSRasesh Mody 
20326ae839dSRasesh Mody 	/* Choose the highest priority */
20426ae839dSRasesh Mody 	while ((pri == ECORE_MAX_PFC_PRIORITIES) && index) {
20526ae839dSRasesh Mody 		pri_mask = 1 << index;
20626ae839dSRasesh Mody 		if (pri_bitmap & pri_mask)
20726ae839dSRasesh Mody 			pri = index;
20826ae839dSRasesh Mody 		index--;
20926ae839dSRasesh Mody 	}
21026ae839dSRasesh Mody 
21126ae839dSRasesh Mody 	if (pri < ECORE_MAX_PFC_PRIORITIES)
21226ae839dSRasesh Mody 		*priority = (u8)pri;
21326ae839dSRasesh Mody 	else
21426ae839dSRasesh Mody 		rc = ECORE_INVAL;
21526ae839dSRasesh Mody 
21626ae839dSRasesh Mody 	return rc;
21726ae839dSRasesh Mody }
21826ae839dSRasesh Mody 
21926ae839dSRasesh Mody static bool
ecore_dcbx_get_app_protocol_type(struct ecore_hwfn * p_hwfn,u32 app_prio_bitmap,u16 id,enum dcbx_protocol_type * type,bool ieee)22026ae839dSRasesh Mody ecore_dcbx_get_app_protocol_type(struct ecore_hwfn *p_hwfn,
22122d07d93SRasesh Mody 				 u32 app_prio_bitmap, u16 id,
22222d07d93SRasesh Mody 				 enum dcbx_protocol_type *type, bool ieee)
22326ae839dSRasesh Mody {
2243d1babcaSRasesh Mody 	if (ecore_dcbx_default_tlv(app_prio_bitmap, id, ieee)) {
22526ae839dSRasesh Mody 		*type = DCBX_PROTOCOL_ETH;
22626ae839dSRasesh Mody 	} else {
22722d07d93SRasesh Mody 		*type = DCBX_MAX_PROTOCOL_TYPE;
228651f3d4dSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
229651f3d4dSRasesh Mody 			    "No action required, App TLV entry = 0x%x\n",
230651f3d4dSRasesh Mody 			   app_prio_bitmap);
2313d1babcaSRasesh Mody 		return false;
23226ae839dSRasesh Mody 	}
23326ae839dSRasesh Mody 
2343d1babcaSRasesh Mody 	return true;
23526ae839dSRasesh Mody }
23626ae839dSRasesh Mody 
23726ae839dSRasesh Mody /* Parse app TLV's to update TC information in hw_info structure for
23826ae839dSRasesh Mody  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
23926ae839dSRasesh Mody  */
24026ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_process_tlv(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_dcbx_results * p_data,struct dcbx_app_priority_entry * p_tbl,u32 pri_tc_tbl,int count,u8 dcbx_version)2419aea0e7dSRasesh Mody ecore_dcbx_process_tlv(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
24226ae839dSRasesh Mody 		       struct ecore_dcbx_results *p_data,
24326ae839dSRasesh Mody 		       struct dcbx_app_priority_entry *p_tbl, u32 pri_tc_tbl,
24422d07d93SRasesh Mody 		       int count, u8 dcbx_version)
24526ae839dSRasesh Mody {
24622d07d93SRasesh Mody 	enum dcbx_protocol_type type;
24747af7019SRasesh Mody 	bool enable, ieee, eth_tlv;
2483d1babcaSRasesh Mody 	u8 tc, priority_map;
24926ae839dSRasesh Mody 	u16 protocol_id;
2503d1babcaSRasesh Mody 	u8 priority;
2513d1babcaSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
25222d07d93SRasesh Mody 	int i;
25326ae839dSRasesh Mody 
254d4806abaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
255d4806abaSRasesh Mody 		   "Num APP entries = %d pri_tc_tbl = 0x%x dcbx_version = %u\n",
256d4806abaSRasesh Mody 		   count, pri_tc_tbl, dcbx_version);
25726ae839dSRasesh Mody 
25822d07d93SRasesh Mody 	ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE);
25947af7019SRasesh Mody 	eth_tlv = false;
26026ae839dSRasesh Mody 	/* Parse APP TLV */
26126ae839dSRasesh Mody 	for (i = 0; i < count; i++) {
26204b00049SRasesh Mody 		protocol_id = GET_MFW_FIELD(p_tbl[i].entry,
26326ae839dSRasesh Mody 					    DCBX_APP_PROTOCOL_ID);
26404b00049SRasesh Mody 		priority_map = GET_MFW_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP);
265d4806abaSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Id = 0x%x pri_map = %u\n",
266d4806abaSRasesh Mody 			   protocol_id, priority_map);
26726ae839dSRasesh Mody 		rc = ecore_dcbx_get_app_priority(priority_map, &priority);
26826ae839dSRasesh Mody 		if (rc == ECORE_INVAL) {
26926ae839dSRasesh Mody 			DP_ERR(p_hwfn, "Invalid priority\n");
2703d1babcaSRasesh Mody 			return ECORE_INVAL;
27126ae839dSRasesh Mody 		}
27226ae839dSRasesh Mody 
27326ae839dSRasesh Mody 		tc = ECORE_DCBX_PRIO2TC(pri_tc_tbl, priority);
27426ae839dSRasesh Mody 		if (ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
27522d07d93SRasesh Mody 						     protocol_id, &type,
27622d07d93SRasesh Mody 						     ieee)) {
27726ae839dSRasesh Mody 			/* ETH always have the enable bit reset, as it gets
27826ae839dSRasesh Mody 			 * vlan information per packet. For other protocols,
27926ae839dSRasesh Mody 			 * should be set according to the dcbx_enabled
28026ae839dSRasesh Mody 			 * indication, but we only got here if there was an
28126ae839dSRasesh Mody 			 * app tlv for the protocol, so dcbx must be enabled.
28226ae839dSRasesh Mody 			 */
28347af7019SRasesh Mody 			if (type == DCBX_PROTOCOL_ETH) {
28447af7019SRasesh Mody 				enable = false;
28547af7019SRasesh Mody 				eth_tlv = true;
28647af7019SRasesh Mody 			} else {
28747af7019SRasesh Mody 				enable = true;
28847af7019SRasesh Mody 			}
28926ae839dSRasesh Mody 
2909aea0e7dSRasesh Mody 			ecore_dcbx_update_app_info(p_data, p_hwfn, p_ptt,
2919aea0e7dSRasesh Mody 						   enable, priority, tc, type);
29226ae839dSRasesh Mody 		}
29326ae839dSRasesh Mody 	}
29447af7019SRasesh Mody 
29547af7019SRasesh Mody 	/* If Eth TLV is not detected, use UFP TC as default TC */
296*5018f1fcSJoyce Kong 	if (OSAL_GET_BIT(ECORE_MF_UFP_SPECIFIC,
29747af7019SRasesh Mody 			  &p_hwfn->p_dev->mf_bits) && !eth_tlv)
29847af7019SRasesh Mody 		p_data->arr[DCBX_PROTOCOL_ETH].tc = p_hwfn->ufp_info.tc;
29947af7019SRasesh Mody 
30026ae839dSRasesh Mody 	/* Update ramrod protocol data and hw_info fields
30126ae839dSRasesh Mody 	 * with default info when corresponding APP TLV's are not detected.
30226ae839dSRasesh Mody 	 * The enabled field has a different logic for ethernet as only for
30326ae839dSRasesh Mody 	 * ethernet dcb should disabled by default, as the information arrives
30426ae839dSRasesh Mody 	 * from the OS (unless an explicit app tlv was present).
30526ae839dSRasesh Mody 	 */
30626ae839dSRasesh Mody 	tc = p_data->arr[DCBX_PROTOCOL_ETH].tc;
30726ae839dSRasesh Mody 	priority = p_data->arr[DCBX_PROTOCOL_ETH].priority;
30826ae839dSRasesh Mody 	for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) {
30926ae839dSRasesh Mody 		if (p_data->arr[type].update)
31026ae839dSRasesh Mody 			continue;
31126ae839dSRasesh Mody 
3129aea0e7dSRasesh Mody 		/* if no app tlv was present, don't override in FW */
3133b307c55SRasesh Mody 		ecore_dcbx_update_app_info(p_data, p_hwfn, p_ptt,
3143b307c55SRasesh Mody 					  p_data->arr[DCBX_PROTOCOL_ETH].enable,
31526ae839dSRasesh Mody 					  priority, tc, type);
31626ae839dSRasesh Mody 	}
31726ae839dSRasesh Mody 
31826ae839dSRasesh Mody 	return ECORE_SUCCESS;
31926ae839dSRasesh Mody }
32026ae839dSRasesh Mody 
32126ae839dSRasesh Mody /* Parse app TLV's to update TC information in hw_info structure for
32226ae839dSRasesh Mody  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
32326ae839dSRasesh Mody  */
32426ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_process_mib_info(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)3259aea0e7dSRasesh Mody ecore_dcbx_process_mib_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
32626ae839dSRasesh Mody {
32726ae839dSRasesh Mody 	struct dcbx_app_priority_feature *p_app;
32826ae839dSRasesh Mody 	struct dcbx_app_priority_entry *p_tbl;
3299ed26bc7SRasesh Mody 	struct ecore_dcbx_results data;
33026ae839dSRasesh Mody 	struct dcbx_ets_feature *p_ets;
33126ae839dSRasesh Mody 	struct ecore_hw_info *p_info;
33226ae839dSRasesh Mody 	u32 pri_tc_tbl, flags;
33322d07d93SRasesh Mody 	u8 dcbx_version;
33426ae839dSRasesh Mody 	int num_entries;
335c68f27a2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
33626ae839dSRasesh Mody 
33726ae839dSRasesh Mody 	flags = p_hwfn->p_dcbx_info->operational.flags;
33804b00049SRasesh Mody 	dcbx_version = GET_MFW_FIELD(flags, DCBX_CONFIG_VERSION);
33926ae839dSRasesh Mody 
34026ae839dSRasesh Mody 	p_app = &p_hwfn->p_dcbx_info->operational.features.app;
34126ae839dSRasesh Mody 	p_tbl = p_app->app_pri_tbl;
34226ae839dSRasesh Mody 
34326ae839dSRasesh Mody 	p_ets = &p_hwfn->p_dcbx_info->operational.features.ets;
34426ae839dSRasesh Mody 	pri_tc_tbl = p_ets->pri_tc_tbl[0];
34526ae839dSRasesh Mody 
34626ae839dSRasesh Mody 	p_info = &p_hwfn->hw_info;
34704b00049SRasesh Mody 	num_entries = GET_MFW_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
34826ae839dSRasesh Mody 
3499ed26bc7SRasesh Mody 	OSAL_MEMSET(&data, 0, sizeof(struct ecore_dcbx_results));
3509aea0e7dSRasesh Mody 	rc = ecore_dcbx_process_tlv(p_hwfn, p_ptt, &data, p_tbl, pri_tc_tbl,
35122d07d93SRasesh Mody 				    num_entries, dcbx_version);
35226ae839dSRasesh Mody 	if (rc != ECORE_SUCCESS)
35326ae839dSRasesh Mody 		return rc;
35426ae839dSRasesh Mody 
35504b00049SRasesh Mody 	p_info->num_active_tc = GET_MFW_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
35604b00049SRasesh Mody 	p_hwfn->qm_info.ooo_tc = GET_MFW_FIELD(p_ets->flags, DCBX_OOO_TC);
35726ae839dSRasesh Mody 	data.pf_id = p_hwfn->rel_pf_id;
35822d07d93SRasesh Mody 	data.dcbx_enabled = !!dcbx_version;
35926ae839dSRasesh Mody 
36026ae839dSRasesh Mody 	ecore_dcbx_dp_protocol(p_hwfn, &data);
36126ae839dSRasesh Mody 
36226ae839dSRasesh Mody 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->results, &data,
36326ae839dSRasesh Mody 		    sizeof(struct ecore_dcbx_results));
36426ae839dSRasesh Mody 
36526ae839dSRasesh Mody 	return ECORE_SUCCESS;
36626ae839dSRasesh Mody }
36726ae839dSRasesh Mody 
36826ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_copy_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_dcbx_mib_meta_data * p_data,enum ecore_mib_read_type type)36926ae839dSRasesh Mody ecore_dcbx_copy_mib(struct ecore_hwfn *p_hwfn,
37026ae839dSRasesh Mody 		    struct ecore_ptt *p_ptt,
37126ae839dSRasesh Mody 		    struct ecore_dcbx_mib_meta_data *p_data,
37226ae839dSRasesh Mody 		    enum ecore_mib_read_type type)
37326ae839dSRasesh Mody {
37426ae839dSRasesh Mody 	u32 prefix_seq_num, suffix_seq_num;
37526ae839dSRasesh Mody 	int read_count = 0;
376c68f27a2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
37726ae839dSRasesh Mody 
3783d1babcaSRasesh Mody 	/* The data is considered to be valid only if both sequence numbers are
3793d1babcaSRasesh Mody 	 * the same.
3803d1babcaSRasesh Mody 	 */
38126ae839dSRasesh Mody 	do {
38226ae839dSRasesh Mody 		if (type == ECORE_DCBX_REMOTE_LLDP_MIB) {
38326ae839dSRasesh Mody 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote,
38426ae839dSRasesh Mody 					  p_data->addr, p_data->size);
38526ae839dSRasesh Mody 			prefix_seq_num = p_data->lldp_remote->prefix_seq_num;
38626ae839dSRasesh Mody 			suffix_seq_num = p_data->lldp_remote->suffix_seq_num;
38781dba2b2SRasesh Mody 		} else if (type == ECORE_DCBX_LLDP_TLVS) {
38881dba2b2SRasesh Mody 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->lldp_tlvs,
38981dba2b2SRasesh Mody 					  p_data->addr, p_data->size);
39081dba2b2SRasesh Mody 			prefix_seq_num = p_data->lldp_tlvs->prefix_seq_num;
39181dba2b2SRasesh Mody 			suffix_seq_num = p_data->lldp_tlvs->suffix_seq_num;
39281dba2b2SRasesh Mody 
39326ae839dSRasesh Mody 		} else {
39426ae839dSRasesh Mody 			ecore_memcpy_from(p_hwfn, p_ptt, p_data->mib,
39526ae839dSRasesh Mody 					  p_data->addr, p_data->size);
39626ae839dSRasesh Mody 			prefix_seq_num = p_data->mib->prefix_seq_num;
39726ae839dSRasesh Mody 			suffix_seq_num = p_data->mib->suffix_seq_num;
39826ae839dSRasesh Mody 		}
39926ae839dSRasesh Mody 		read_count++;
40026ae839dSRasesh Mody 
40126ae839dSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
4029455b556SRasesh Mody 			   "mib type = %d, try count = %d prefix seq num  ="
4039455b556SRasesh Mody 			   " %d suffix seq num = %d\n",
40426ae839dSRasesh Mody 			   type, read_count, prefix_seq_num, suffix_seq_num);
40526ae839dSRasesh Mody 	} while ((prefix_seq_num != suffix_seq_num) &&
40626ae839dSRasesh Mody 		 (read_count < ECORE_DCBX_MAX_MIB_READ_TRY));
40726ae839dSRasesh Mody 
40826ae839dSRasesh Mody 	if (read_count >= ECORE_DCBX_MAX_MIB_READ_TRY) {
40926ae839dSRasesh Mody 		DP_ERR(p_hwfn,
4109455b556SRasesh Mody 		       "MIB read err, mib type = %d, try count ="
4119455b556SRasesh Mody 		       " %d prefix seq num = %d suffix seq num = %d\n",
41226ae839dSRasesh Mody 		       type, read_count, prefix_seq_num, suffix_seq_num);
41326ae839dSRasesh Mody 		rc = ECORE_IO;
41426ae839dSRasesh Mody 	}
41526ae839dSRasesh Mody 
41626ae839dSRasesh Mody 	return rc;
41726ae839dSRasesh Mody }
41826ae839dSRasesh Mody 
4193d1babcaSRasesh Mody static void
ecore_dcbx_get_priority_info(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_app_prio * p_prio,struct ecore_dcbx_results * p_results)42026ae839dSRasesh Mody ecore_dcbx_get_priority_info(struct ecore_hwfn *p_hwfn,
42126ae839dSRasesh Mody 			     struct ecore_dcbx_app_prio *p_prio,
42226ae839dSRasesh Mody 			     struct ecore_dcbx_results *p_results)
42326ae839dSRasesh Mody {
4243d1babcaSRasesh Mody 	u8 val;
42526ae839dSRasesh Mody 
42626ae839dSRasesh Mody 	if (p_results->arr[DCBX_PROTOCOL_ETH].update &&
4273d1babcaSRasesh Mody 	    p_results->arr[DCBX_PROTOCOL_ETH].enable)
42826ae839dSRasesh Mody 		p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority;
42926ae839dSRasesh Mody 
4303d1babcaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
4313d1babcaSRasesh Mody 		   "Priorities: eth %d\n",
4323d1babcaSRasesh Mody 		   p_prio->eth);
43326ae839dSRasesh Mody }
43426ae839dSRasesh Mody 
43526ae839dSRasesh Mody static void
ecore_dcbx_get_app_data(struct ecore_hwfn * p_hwfn,struct dcbx_app_priority_feature * p_app,struct dcbx_app_priority_entry * p_tbl,struct ecore_dcbx_params * p_params,bool ieee)43626ae839dSRasesh Mody ecore_dcbx_get_app_data(struct ecore_hwfn *p_hwfn,
43726ae839dSRasesh Mody 			struct dcbx_app_priority_feature *p_app,
43826ae839dSRasesh Mody 			struct dcbx_app_priority_entry *p_tbl,
43922d07d93SRasesh Mody 			struct ecore_dcbx_params *p_params, bool ieee)
44026ae839dSRasesh Mody {
44122d07d93SRasesh Mody 	struct ecore_app_entry *entry;
44222d07d93SRasesh Mody 	u8 pri_map;
44326ae839dSRasesh Mody 	int i;
44426ae839dSRasesh Mody 
44504b00049SRasesh Mody 	p_params->app_willing = GET_MFW_FIELD(p_app->flags, DCBX_APP_WILLING);
44604b00049SRasesh Mody 	p_params->app_valid = GET_MFW_FIELD(p_app->flags, DCBX_APP_ENABLED);
44704b00049SRasesh Mody 	p_params->app_error = GET_MFW_FIELD(p_app->flags, DCBX_APP_ERROR);
44804b00049SRasesh Mody 	p_params->num_app_entries = GET_MFW_FIELD(p_app->flags,
44922d07d93SRasesh Mody 						  DCBX_APP_NUM_ENTRIES);
450211507c1SRasesh Mody 	for (i = 0; i < p_params->num_app_entries; i++) {
45122d07d93SRasesh Mody 		entry = &p_params->app_entry[i];
45222d07d93SRasesh Mody 		if (ieee) {
45322d07d93SRasesh Mody 			u8 sf_ieee;
45422d07d93SRasesh Mody 			u32 val;
45522d07d93SRasesh Mody 
45604b00049SRasesh Mody 			sf_ieee = GET_MFW_FIELD(p_tbl[i].entry,
45722d07d93SRasesh Mody 						DCBX_APP_SF_IEEE);
45822d07d93SRasesh Mody 			switch (sf_ieee) {
45922d07d93SRasesh Mody 			case DCBX_APP_SF_IEEE_RESERVED:
46022d07d93SRasesh Mody 				/* Old MFW */
46104b00049SRasesh Mody 				val = GET_MFW_FIELD(p_tbl[i].entry,
46222d07d93SRasesh Mody 						    DCBX_APP_SF);
46322d07d93SRasesh Mody 				entry->sf_ieee = val ?
46422d07d93SRasesh Mody 					ECORE_DCBX_SF_IEEE_TCP_UDP_PORT :
46522d07d93SRasesh Mody 					ECORE_DCBX_SF_IEEE_ETHTYPE;
46622d07d93SRasesh Mody 				break;
46722d07d93SRasesh Mody 			case DCBX_APP_SF_IEEE_ETHTYPE:
46822d07d93SRasesh Mody 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_ETHTYPE;
46922d07d93SRasesh Mody 				break;
47022d07d93SRasesh Mody 			case DCBX_APP_SF_IEEE_TCP_PORT:
47122d07d93SRasesh Mody 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_TCP_PORT;
47222d07d93SRasesh Mody 				break;
47322d07d93SRasesh Mody 			case DCBX_APP_SF_IEEE_UDP_PORT:
47422d07d93SRasesh Mody 				entry->sf_ieee = ECORE_DCBX_SF_IEEE_UDP_PORT;
47522d07d93SRasesh Mody 				break;
47622d07d93SRasesh Mody 			case DCBX_APP_SF_IEEE_TCP_UDP_PORT:
47722d07d93SRasesh Mody 				entry->sf_ieee =
47822d07d93SRasesh Mody 						ECORE_DCBX_SF_IEEE_TCP_UDP_PORT;
47922d07d93SRasesh Mody 				break;
48022d07d93SRasesh Mody 			}
48122d07d93SRasesh Mody 		} else {
48204b00049SRasesh Mody 			entry->ethtype = !(GET_MFW_FIELD(p_tbl[i].entry,
48322d07d93SRasesh Mody 							 DCBX_APP_SF));
48422d07d93SRasesh Mody 		}
48522d07d93SRasesh Mody 
48604b00049SRasesh Mody 		pri_map = GET_MFW_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP);
48722d07d93SRasesh Mody 		ecore_dcbx_get_app_priority(pri_map, &entry->prio);
48804b00049SRasesh Mody 		entry->proto_id = GET_MFW_FIELD(p_tbl[i].entry,
48922d07d93SRasesh Mody 						DCBX_APP_PROTOCOL_ID);
49022d07d93SRasesh Mody 		ecore_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
49122d07d93SRasesh Mody 						 entry->proto_id,
49222d07d93SRasesh Mody 						 &entry->proto_type, ieee);
49322d07d93SRasesh Mody 	}
49426ae839dSRasesh Mody 
49526ae839dSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
49622d07d93SRasesh Mody 		   "APP params: willing %d, valid %d error = %d\n",
49722d07d93SRasesh Mody 		   p_params->app_willing, p_params->app_valid,
49822d07d93SRasesh Mody 		   p_params->app_error);
49926ae839dSRasesh Mody }
50026ae839dSRasesh Mody 
50126ae839dSRasesh Mody static void
ecore_dcbx_get_pfc_data(struct ecore_hwfn * p_hwfn,u32 pfc,struct ecore_dcbx_params * p_params)50226ae839dSRasesh Mody ecore_dcbx_get_pfc_data(struct ecore_hwfn *p_hwfn,
50326ae839dSRasesh Mody 			u32 pfc, struct ecore_dcbx_params *p_params)
50426ae839dSRasesh Mody {
50522d07d93SRasesh Mody 	u8 pfc_map;
50622d07d93SRasesh Mody 
50704b00049SRasesh Mody 	p_params->pfc.willing = GET_MFW_FIELD(pfc, DCBX_PFC_WILLING);
50804b00049SRasesh Mody 	p_params->pfc.max_tc = GET_MFW_FIELD(pfc, DCBX_PFC_CAPS);
50904b00049SRasesh Mody 	p_params->pfc.enabled = GET_MFW_FIELD(pfc, DCBX_PFC_ENABLED);
51004b00049SRasesh Mody 	pfc_map = GET_MFW_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP);
51122d07d93SRasesh Mody 	p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0);
51222d07d93SRasesh Mody 	p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1);
51322d07d93SRasesh Mody 	p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2);
51422d07d93SRasesh Mody 	p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3);
51522d07d93SRasesh Mody 	p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4);
51622d07d93SRasesh Mody 	p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5);
51722d07d93SRasesh Mody 	p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6);
51822d07d93SRasesh Mody 	p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7);
51926ae839dSRasesh Mody 
52026ae839dSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
521d4806abaSRasesh Mody 		   "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n",
522d4806abaSRasesh Mody 		   p_params->pfc.willing, pfc_map, p_params->pfc.max_tc,
523d4806abaSRasesh Mody 		   p_params->pfc.enabled);
52426ae839dSRasesh Mody }
52526ae839dSRasesh Mody 
52626ae839dSRasesh Mody static void
ecore_dcbx_get_ets_data(struct ecore_hwfn * p_hwfn,struct dcbx_ets_feature * p_ets,struct ecore_dcbx_params * p_params)52726ae839dSRasesh Mody ecore_dcbx_get_ets_data(struct ecore_hwfn *p_hwfn,
52826ae839dSRasesh Mody 			struct dcbx_ets_feature *p_ets,
52926ae839dSRasesh Mody 			struct ecore_dcbx_params *p_params)
53026ae839dSRasesh Mody {
53122d07d93SRasesh Mody 	u32 bw_map[2], tsa_map[2], pri_map;
53226ae839dSRasesh Mody 	int i;
53326ae839dSRasesh Mody 
53404b00049SRasesh Mody 	p_params->ets_willing = GET_MFW_FIELD(p_ets->flags, DCBX_ETS_WILLING);
53504b00049SRasesh Mody 	p_params->ets_enabled = GET_MFW_FIELD(p_ets->flags, DCBX_ETS_ENABLED);
53604b00049SRasesh Mody 	p_params->ets_cbs = GET_MFW_FIELD(p_ets->flags, DCBX_ETS_CBS);
53704b00049SRasesh Mody 	p_params->max_ets_tc = GET_MFW_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
53826ae839dSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
539d4806abaSRasesh Mody 		   "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
540d4806abaSRasesh Mody 		   p_params->ets_willing, p_params->ets_enabled,
541d4806abaSRasesh Mody 		   p_params->ets_cbs, p_ets->pri_tc_tbl[0],
542d4806abaSRasesh Mody 		   p_params->max_ets_tc);
54326ae839dSRasesh Mody 
54426ae839dSRasesh Mody 	/* 8 bit tsa and bw data corresponding to each of the 8 TC's are
54526ae839dSRasesh Mody 	 * encoded in a type u32 array of size 2.
54626ae839dSRasesh Mody 	 */
54722d07d93SRasesh Mody 	bw_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[0]);
54822d07d93SRasesh Mody 	bw_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_bw_tbl[1]);
54922d07d93SRasesh Mody 	tsa_map[0] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[0]);
55022d07d93SRasesh Mody 	tsa_map[1] = OSAL_BE32_TO_CPU(p_ets->tc_tsa_tbl[1]);
5513d1babcaSRasesh Mody 	pri_map = p_ets->pri_tc_tbl[0];
55222d07d93SRasesh Mody 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
55322d07d93SRasesh Mody 		p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
55422d07d93SRasesh Mody 		p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
55522d07d93SRasesh Mody 		p_params->ets_pri_tc_tbl[i] = ECORE_DCBX_PRIO2TC(pri_map, i);
55626ae839dSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
55726ae839dSRasesh Mody 			   "elem %d  bw_tbl %x tsa_tbl %x\n",
55826ae839dSRasesh Mody 			   i, p_params->ets_tc_bw_tbl[i],
55926ae839dSRasesh Mody 			   p_params->ets_tc_tsa_tbl[i]);
56026ae839dSRasesh Mody 	}
56126ae839dSRasesh Mody }
56226ae839dSRasesh Mody 
5633d1babcaSRasesh Mody static void
ecore_dcbx_get_common_params(struct ecore_hwfn * p_hwfn,struct dcbx_app_priority_feature * p_app,struct dcbx_app_priority_entry * p_tbl,struct dcbx_ets_feature * p_ets,u32 pfc,struct ecore_dcbx_params * p_params,bool ieee)56426ae839dSRasesh Mody ecore_dcbx_get_common_params(struct ecore_hwfn *p_hwfn,
56526ae839dSRasesh Mody 			     struct dcbx_app_priority_feature *p_app,
56626ae839dSRasesh Mody 			     struct dcbx_app_priority_entry *p_tbl,
56726ae839dSRasesh Mody 			     struct dcbx_ets_feature *p_ets,
56822d07d93SRasesh Mody 			     u32 pfc, struct ecore_dcbx_params *p_params,
56922d07d93SRasesh Mody 			     bool ieee)
57026ae839dSRasesh Mody {
57122d07d93SRasesh Mody 	ecore_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee);
57226ae839dSRasesh Mody 	ecore_dcbx_get_ets_data(p_hwfn, p_ets, p_params);
57326ae839dSRasesh Mody 	ecore_dcbx_get_pfc_data(p_hwfn, pfc, p_params);
57426ae839dSRasesh Mody }
57526ae839dSRasesh Mody 
5763d1babcaSRasesh Mody static void
ecore_dcbx_get_local_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)57726ae839dSRasesh Mody ecore_dcbx_get_local_params(struct ecore_hwfn *p_hwfn,
57826ae839dSRasesh Mody 			    struct ecore_dcbx_get *params)
57926ae839dSRasesh Mody {
5803d1babcaSRasesh Mody 	struct dcbx_features *p_feat;
58126ae839dSRasesh Mody 
5823d1babcaSRasesh Mody 	p_feat = &p_hwfn->p_dcbx_info->local_admin.features;
5833d1babcaSRasesh Mody 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
5843d1babcaSRasesh Mody 				     p_feat->app.app_pri_tbl, &p_feat->ets,
5853d1babcaSRasesh Mody 				     p_feat->pfc, &params->local.params, false);
5863d1babcaSRasesh Mody 	params->local.valid = true;
58726ae839dSRasesh Mody }
58826ae839dSRasesh Mody 
5893d1babcaSRasesh Mody static void
ecore_dcbx_get_remote_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)59026ae839dSRasesh Mody ecore_dcbx_get_remote_params(struct ecore_hwfn *p_hwfn,
59126ae839dSRasesh Mody 			     struct ecore_dcbx_get *params)
59226ae839dSRasesh Mody {
5933d1babcaSRasesh Mody 	struct dcbx_features *p_feat;
59426ae839dSRasesh Mody 
5953d1babcaSRasesh Mody 	p_feat = &p_hwfn->p_dcbx_info->remote.features;
5963d1babcaSRasesh Mody 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
5973d1babcaSRasesh Mody 				     p_feat->app.app_pri_tbl, &p_feat->ets,
5983d1babcaSRasesh Mody 				     p_feat->pfc, &params->remote.params,
59922d07d93SRasesh Mody 				     false);
6003d1babcaSRasesh Mody 	params->remote.valid = true;
60126ae839dSRasesh Mody }
60226ae839dSRasesh Mody 
ecore_dcbx_get_dscp_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)60313c0ec8aSRasesh Mody static void  ecore_dcbx_get_dscp_params(struct ecore_hwfn *p_hwfn,
60413c0ec8aSRasesh Mody 					struct ecore_dcbx_get *params)
60513c0ec8aSRasesh Mody {
60613c0ec8aSRasesh Mody 	struct ecore_dcbx_dscp_params *p_dscp;
60713c0ec8aSRasesh Mody 	struct dcb_dscp_map *p_dscp_map;
60813c0ec8aSRasesh Mody 	int i, j, entry;
60913c0ec8aSRasesh Mody 	u32 pri_map;
61013c0ec8aSRasesh Mody 
61113c0ec8aSRasesh Mody 	p_dscp = &params->dscp;
61213c0ec8aSRasesh Mody 	p_dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
61313c0ec8aSRasesh Mody 	p_dscp->enabled = GET_MFW_FIELD(p_dscp_map->flags, DCB_DSCP_ENABLE);
61413c0ec8aSRasesh Mody 
61513c0ec8aSRasesh Mody 	/* MFW encodes 64 dscp entries into 8 element array of u32 entries,
61613c0ec8aSRasesh Mody 	 * where each entry holds the 4bit priority map for 8 dscp entries.
61713c0ec8aSRasesh Mody 	 */
61813c0ec8aSRasesh Mody 	for (i = 0, entry = 0; i < ECORE_DCBX_DSCP_SIZE / 8; i++) {
61913c0ec8aSRasesh Mody 		pri_map = OSAL_BE32_TO_CPU(p_dscp_map->dscp_pri_map[i]);
62013c0ec8aSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "elem %d pri_map 0x%x\n",
62113c0ec8aSRasesh Mody 			   entry, pri_map);
62213c0ec8aSRasesh Mody 		for (j = 0; j < ECORE_DCBX_DSCP_SIZE / 8; j++, entry++)
62313c0ec8aSRasesh Mody 			p_dscp->dscp_pri_map[entry] = (u32)(pri_map >>
62413c0ec8aSRasesh Mody 							   (j * 4)) & 0xf;
62513c0ec8aSRasesh Mody 	}
62613c0ec8aSRasesh Mody }
62713c0ec8aSRasesh Mody 
62810409fabSRasesh Mody static void
ecore_dcbx_get_operational_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)62926ae839dSRasesh Mody ecore_dcbx_get_operational_params(struct ecore_hwfn *p_hwfn,
63026ae839dSRasesh Mody 				  struct ecore_dcbx_get *params)
63126ae839dSRasesh Mody {
63226ae839dSRasesh Mody 	struct ecore_dcbx_operational_params *p_operational;
63326ae839dSRasesh Mody 	struct ecore_dcbx_results *p_results;
6343d1babcaSRasesh Mody 	struct dcbx_features *p_feat;
63526ae839dSRasesh Mody 	bool enabled, err;
6363d1babcaSRasesh Mody 	u32 flags;
6373d1babcaSRasesh Mody 	bool val;
63826ae839dSRasesh Mody 
63926ae839dSRasesh Mody 	flags = p_hwfn->p_dcbx_info->operational.flags;
64026ae839dSRasesh Mody 
64126ae839dSRasesh Mody 	/* If DCBx version is non zero, then negotiation
64226ae839dSRasesh Mody 	 * was successfuly performed
64326ae839dSRasesh Mody 	 */
64426ae839dSRasesh Mody 	p_operational = &params->operational;
64504b00049SRasesh Mody 	enabled = !!(GET_MFW_FIELD(flags, DCBX_CONFIG_VERSION) !=
6463d1babcaSRasesh Mody 		     DCBX_CONFIG_VERSION_DISABLED);
64726ae839dSRasesh Mody 	if (!enabled) {
64826ae839dSRasesh Mody 		p_operational->enabled = enabled;
64926ae839dSRasesh Mody 		p_operational->valid = false;
650d4806abaSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Dcbx is disabled\n");
65110409fabSRasesh Mody 		return;
65226ae839dSRasesh Mody 	}
65326ae839dSRasesh Mody 
6543d1babcaSRasesh Mody 	p_feat = &p_hwfn->p_dcbx_info->operational.features;
65526ae839dSRasesh Mody 	p_results = &p_hwfn->p_dcbx_info->results;
65626ae839dSRasesh Mody 
65704b00049SRasesh Mody 	val = !!(GET_MFW_FIELD(flags, DCBX_CONFIG_VERSION) ==
6583d1babcaSRasesh Mody 		 DCBX_CONFIG_VERSION_IEEE);
6593d1babcaSRasesh Mody 	p_operational->ieee = val;
6603d1babcaSRasesh Mody 
66104b00049SRasesh Mody 	val = !!(GET_MFW_FIELD(flags, DCBX_CONFIG_VERSION) ==
6623d1babcaSRasesh Mody 		 DCBX_CONFIG_VERSION_CEE);
6633d1babcaSRasesh Mody 	p_operational->cee = val;
6643d1babcaSRasesh Mody 
66504b00049SRasesh Mody 	val = !!(GET_MFW_FIELD(flags, DCBX_CONFIG_VERSION) ==
6663d1babcaSRasesh Mody 		 DCBX_CONFIG_VERSION_STATIC);
6673d1babcaSRasesh Mody 	p_operational->local = val;
66826ae839dSRasesh Mody 
66926ae839dSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
67022d07d93SRasesh Mody 		   "Version support: ieee %d, cee %d, static %d\n",
67122d07d93SRasesh Mody 		   p_operational->ieee, p_operational->cee,
67222d07d93SRasesh Mody 		   p_operational->local);
67326ae839dSRasesh Mody 
6743d1babcaSRasesh Mody 	ecore_dcbx_get_common_params(p_hwfn, &p_feat->app,
6753d1babcaSRasesh Mody 				     p_feat->app.app_pri_tbl, &p_feat->ets,
6763d1babcaSRasesh Mody 				     p_feat->pfc, &params->operational.params,
67722d07d93SRasesh Mody 				     p_operational->ieee);
67826ae839dSRasesh Mody 	ecore_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio,
67926ae839dSRasesh Mody 				     p_results);
68004b00049SRasesh Mody 	err = GET_MFW_FIELD(p_feat->app.flags, DCBX_APP_ERROR);
68126ae839dSRasesh Mody 	p_operational->err = err;
68226ae839dSRasesh Mody 	p_operational->enabled = enabled;
68326ae839dSRasesh Mody 	p_operational->valid = true;
68426ae839dSRasesh Mody }
68526ae839dSRasesh Mody 
ecore_dcbx_get_local_lldp_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)68630ecf673SRasesh Mody static void ecore_dcbx_get_local_lldp_params(struct ecore_hwfn *p_hwfn,
68726ae839dSRasesh Mody 					     struct ecore_dcbx_get *params)
68826ae839dSRasesh Mody {
6893d1babcaSRasesh Mody 	struct lldp_config_params_s *p_local;
69026ae839dSRasesh Mody 
6913d1babcaSRasesh Mody 	p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
69226ae839dSRasesh Mody 
6933d1babcaSRasesh Mody 	OSAL_MEMCPY(params->lldp_local.local_chassis_id,
6943d1babcaSRasesh Mody 		    p_local->local_chassis_id,
6953ea74d89SRasesh Mody 		    sizeof(params->lldp_local.local_chassis_id));
6963d1babcaSRasesh Mody 	OSAL_MEMCPY(params->lldp_local.local_port_id, p_local->local_port_id,
6973ea74d89SRasesh Mody 		    sizeof(params->lldp_local.local_port_id));
69826ae839dSRasesh Mody }
69926ae839dSRasesh Mody 
ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * params)70030ecf673SRasesh Mody static void ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn *p_hwfn,
70126ae839dSRasesh Mody 					      struct ecore_dcbx_get *params)
70226ae839dSRasesh Mody {
7033d1babcaSRasesh Mody 	struct lldp_status_params_s *p_remote;
70426ae839dSRasesh Mody 
7053d1babcaSRasesh Mody 	p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
70626ae839dSRasesh Mody 
7073d1babcaSRasesh Mody 	OSAL_MEMCPY(params->lldp_remote.peer_chassis_id,
7083d1babcaSRasesh Mody 		    p_remote->peer_chassis_id,
7093ea74d89SRasesh Mody 		    sizeof(params->lldp_remote.peer_chassis_id));
7103d1babcaSRasesh Mody 	OSAL_MEMCPY(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
7113ea74d89SRasesh Mody 		    sizeof(params->lldp_remote.peer_port_id));
71226ae839dSRasesh Mody }
71326ae839dSRasesh Mody 
71426ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_get_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * p_params,enum ecore_mib_read_type type)71530ecf673SRasesh Mody ecore_dcbx_get_params(struct ecore_hwfn *p_hwfn,
7163d1babcaSRasesh Mody 		      struct ecore_dcbx_get *p_params,
7173d1babcaSRasesh Mody 		      enum ecore_mib_read_type type)
71826ae839dSRasesh Mody {
71926ae839dSRasesh Mody 	switch (type) {
72026ae839dSRasesh Mody 	case ECORE_DCBX_REMOTE_MIB:
72130ecf673SRasesh Mody 		ecore_dcbx_get_remote_params(p_hwfn, p_params);
72226ae839dSRasesh Mody 		break;
72326ae839dSRasesh Mody 	case ECORE_DCBX_LOCAL_MIB:
72430ecf673SRasesh Mody 		ecore_dcbx_get_local_params(p_hwfn, p_params);
72526ae839dSRasesh Mody 		break;
72626ae839dSRasesh Mody 	case ECORE_DCBX_OPERATIONAL_MIB:
72730ecf673SRasesh Mody 		ecore_dcbx_get_operational_params(p_hwfn, p_params);
72826ae839dSRasesh Mody 		break;
72926ae839dSRasesh Mody 	case ECORE_DCBX_REMOTE_LLDP_MIB:
73030ecf673SRasesh Mody 		ecore_dcbx_get_remote_lldp_params(p_hwfn, p_params);
73126ae839dSRasesh Mody 		break;
73226ae839dSRasesh Mody 	case ECORE_DCBX_LOCAL_LLDP_MIB:
73330ecf673SRasesh Mody 		ecore_dcbx_get_local_lldp_params(p_hwfn, p_params);
73426ae839dSRasesh Mody 		break;
73526ae839dSRasesh Mody 	default:
73626ae839dSRasesh Mody 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
73726ae839dSRasesh Mody 		return ECORE_INVAL;
73826ae839dSRasesh Mody 	}
73926ae839dSRasesh Mody 
74030ecf673SRasesh Mody 	return ECORE_SUCCESS;
74126ae839dSRasesh Mody }
74226ae839dSRasesh Mody 
74326ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)74426ae839dSRasesh Mody ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn *p_hwfn,
74526ae839dSRasesh Mody 			       struct ecore_ptt *p_ptt)
74626ae839dSRasesh Mody {
74726ae839dSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
7483d1babcaSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
74926ae839dSRasesh Mody 
7503d1babcaSRasesh Mody 	OSAL_MEM_ZERO(&data, sizeof(data));
75126ae839dSRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
75226ae839dSRasesh Mody 							   lldp_config_params);
75326ae839dSRasesh Mody 	data.lldp_local = p_hwfn->p_dcbx_info->lldp_local;
75426ae839dSRasesh Mody 	data.size = sizeof(struct lldp_config_params_s);
75526ae839dSRasesh Mody 	ecore_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size);
75626ae839dSRasesh Mody 
75726ae839dSRasesh Mody 	return rc;
75826ae839dSRasesh Mody }
75926ae839dSRasesh Mody 
76026ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_mib_read_type type)76126ae839dSRasesh Mody ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn *p_hwfn,
76226ae839dSRasesh Mody 				struct ecore_ptt *p_ptt,
76326ae839dSRasesh Mody 				enum ecore_mib_read_type type)
76426ae839dSRasesh Mody {
76526ae839dSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
7663d1babcaSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
76726ae839dSRasesh Mody 
76822d07d93SRasesh Mody 	OSAL_MEM_ZERO(&data, sizeof(data));
76926ae839dSRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
77026ae839dSRasesh Mody 							   lldp_status_params);
77126ae839dSRasesh Mody 	data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote;
77226ae839dSRasesh Mody 	data.size = sizeof(struct lldp_status_params_s);
77326ae839dSRasesh Mody 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
77426ae839dSRasesh Mody 
77526ae839dSRasesh Mody 	return rc;
77626ae839dSRasesh Mody }
77726ae839dSRasesh Mody 
77826ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_read_operational_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_mib_read_type type)77926ae839dSRasesh Mody ecore_dcbx_read_operational_mib(struct ecore_hwfn *p_hwfn,
78026ae839dSRasesh Mody 				struct ecore_ptt *p_ptt,
78126ae839dSRasesh Mody 				enum ecore_mib_read_type type)
78226ae839dSRasesh Mody {
78326ae839dSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
78426ae839dSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
78526ae839dSRasesh Mody 
78622d07d93SRasesh Mody 	OSAL_MEM_ZERO(&data, sizeof(data));
78726ae839dSRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr +
78826ae839dSRasesh Mody 	    offsetof(struct public_port, operational_dcbx_mib);
78926ae839dSRasesh Mody 	data.mib = &p_hwfn->p_dcbx_info->operational;
79026ae839dSRasesh Mody 	data.size = sizeof(struct dcbx_mib);
79126ae839dSRasesh Mody 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
79226ae839dSRasesh Mody 
79326ae839dSRasesh Mody 	return rc;
79426ae839dSRasesh Mody }
79526ae839dSRasesh Mody 
79626ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_read_remote_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_mib_read_type type)79726ae839dSRasesh Mody ecore_dcbx_read_remote_mib(struct ecore_hwfn *p_hwfn,
79826ae839dSRasesh Mody 			   struct ecore_ptt *p_ptt,
79926ae839dSRasesh Mody 			   enum ecore_mib_read_type type)
80026ae839dSRasesh Mody {
80126ae839dSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
80226ae839dSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
80326ae839dSRasesh Mody 
80422d07d93SRasesh Mody 	OSAL_MEM_ZERO(&data, sizeof(data));
80526ae839dSRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr +
80626ae839dSRasesh Mody 	    offsetof(struct public_port, remote_dcbx_mib);
80726ae839dSRasesh Mody 	data.mib = &p_hwfn->p_dcbx_info->remote;
80826ae839dSRasesh Mody 	data.size = sizeof(struct dcbx_mib);
80926ae839dSRasesh Mody 	rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
81026ae839dSRasesh Mody 
81126ae839dSRasesh Mody 	return rc;
81226ae839dSRasesh Mody }
81326ae839dSRasesh Mody 
81426ae839dSRasesh Mody static enum _ecore_status_t
ecore_dcbx_read_local_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)81526ae839dSRasesh Mody ecore_dcbx_read_local_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
81626ae839dSRasesh Mody {
81726ae839dSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
81826ae839dSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
81926ae839dSRasesh Mody 
8203d1babcaSRasesh Mody 	OSAL_MEM_ZERO(&data, sizeof(data));
82126ae839dSRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr +
82226ae839dSRasesh Mody 	    offsetof(struct public_port, local_admin_dcbx_mib);
82326ae839dSRasesh Mody 	data.local_admin = &p_hwfn->p_dcbx_info->local_admin;
82426ae839dSRasesh Mody 	data.size = sizeof(struct dcbx_local_params);
82526ae839dSRasesh Mody 	ecore_memcpy_from(p_hwfn, p_ptt, data.local_admin,
82626ae839dSRasesh Mody 			  data.addr, data.size);
82726ae839dSRasesh Mody 
82826ae839dSRasesh Mody 	return rc;
82926ae839dSRasesh Mody }
83026ae839dSRasesh Mody 
83122d07d93SRasesh Mody static void
ecore_dcbx_read_dscp_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)83222d07d93SRasesh Mody ecore_dcbx_read_dscp_mib(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
83322d07d93SRasesh Mody {
83422d07d93SRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
83522d07d93SRasesh Mody 
83622d07d93SRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr +
83722d07d93SRasesh Mody 			offsetof(struct public_port, dcb_dscp_map);
83822d07d93SRasesh Mody 	data.dscp_map = &p_hwfn->p_dcbx_info->dscp_map;
83922d07d93SRasesh Mody 	data.size = sizeof(struct dcb_dscp_map);
84022d07d93SRasesh Mody 	ecore_memcpy_from(p_hwfn, p_ptt, data.dscp_map, data.addr, data.size);
84122d07d93SRasesh Mody }
84222d07d93SRasesh Mody 
ecore_dcbx_read_mib(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_mib_read_type type)84326ae839dSRasesh Mody static enum _ecore_status_t ecore_dcbx_read_mib(struct ecore_hwfn *p_hwfn,
84426ae839dSRasesh Mody 						struct ecore_ptt *p_ptt,
84526ae839dSRasesh Mody 						enum ecore_mib_read_type type)
84626ae839dSRasesh Mody {
8473d1babcaSRasesh Mody 	enum _ecore_status_t rc = ECORE_INVAL;
84826ae839dSRasesh Mody 
84926ae839dSRasesh Mody 	switch (type) {
85026ae839dSRasesh Mody 	case ECORE_DCBX_OPERATIONAL_MIB:
85122d07d93SRasesh Mody 		ecore_dcbx_read_dscp_mib(p_hwfn, p_ptt);
85226ae839dSRasesh Mody 		rc = ecore_dcbx_read_operational_mib(p_hwfn, p_ptt, type);
85326ae839dSRasesh Mody 		break;
85426ae839dSRasesh Mody 	case ECORE_DCBX_REMOTE_MIB:
85526ae839dSRasesh Mody 		rc = ecore_dcbx_read_remote_mib(p_hwfn, p_ptt, type);
85626ae839dSRasesh Mody 		break;
85726ae839dSRasesh Mody 	case ECORE_DCBX_LOCAL_MIB:
85826ae839dSRasesh Mody 		rc = ecore_dcbx_read_local_mib(p_hwfn, p_ptt);
85926ae839dSRasesh Mody 		break;
86026ae839dSRasesh Mody 	case ECORE_DCBX_REMOTE_LLDP_MIB:
86126ae839dSRasesh Mody 		rc = ecore_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type);
86226ae839dSRasesh Mody 		break;
86326ae839dSRasesh Mody 	case ECORE_DCBX_LOCAL_LLDP_MIB:
86426ae839dSRasesh Mody 		rc = ecore_dcbx_read_local_lldp_mib(p_hwfn, p_ptt);
86526ae839dSRasesh Mody 		break;
86626ae839dSRasesh Mody 	default:
86726ae839dSRasesh Mody 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
86826ae839dSRasesh Mody 	}
86926ae839dSRasesh Mody 
870c68f27a2SRasesh Mody 	return ECORE_SUCCESS;
87126ae839dSRasesh Mody }
87226ae839dSRasesh Mody 
87326ae839dSRasesh Mody /*
87426ae839dSRasesh Mody  * Read updated MIB.
87526ae839dSRasesh Mody  * Reconfigure QM and invoke PF update ramrod command if operational MIB
87626ae839dSRasesh Mody  * change is detected.
87726ae839dSRasesh Mody  */
87826ae839dSRasesh Mody enum _ecore_status_t
ecore_dcbx_mib_update_event(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_mib_read_type type)87926ae839dSRasesh Mody ecore_dcbx_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
88026ae839dSRasesh Mody 			    enum ecore_mib_read_type type)
88126ae839dSRasesh Mody {
88226ae839dSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
88326ae839dSRasesh Mody 
88426ae839dSRasesh Mody 	rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
88526ae839dSRasesh Mody 	if (rc)
88626ae839dSRasesh Mody 		return rc;
88726ae839dSRasesh Mody 
88826ae839dSRasesh Mody 	if (type == ECORE_DCBX_OPERATIONAL_MIB) {
88930ecf673SRasesh Mody 		ecore_dcbx_get_dscp_params(p_hwfn, &p_hwfn->p_dcbx_info->get);
89022d07d93SRasesh Mody 
8919aea0e7dSRasesh Mody 		rc = ecore_dcbx_process_mib_info(p_hwfn, p_ptt);
89226ae839dSRasesh Mody 		if (!rc) {
89326ae839dSRasesh Mody 			/* reconfigure tcs of QM queues according
89426ae839dSRasesh Mody 			 * to negotiation results
89526ae839dSRasesh Mody 			 */
89626ae839dSRasesh Mody 			ecore_qm_reconf(p_hwfn, p_ptt);
89726ae839dSRasesh Mody 
89826ae839dSRasesh Mody 			/* update storm FW with negotiation results */
8992a0c610bSRasesh Mody 			ecore_sp_pf_update_dcbx(p_hwfn);
90026ae839dSRasesh Mody 		}
90126ae839dSRasesh Mody 	}
90230ecf673SRasesh Mody 
90330ecf673SRasesh Mody 	ecore_dcbx_get_params(p_hwfn, &p_hwfn->p_dcbx_info->get, type);
90422d07d93SRasesh Mody 
9053eed444aSRasesh Mody 	/* Update the DSCP to TC mapping enable bit if required */
90622d07d93SRasesh Mody 	if ((type == ECORE_DCBX_OPERATIONAL_MIB) &&
90722d07d93SRasesh Mody 	    p_hwfn->p_dcbx_info->dscp_nig_update) {
90813c0ec8aSRasesh Mody 		u8 val = !!p_hwfn->p_dcbx_info->get.dscp.enabled;
9093eed444aSRasesh Mody 		u32 addr = NIG_REG_DSCP_TO_TC_MAP_ENABLE;
91013c0ec8aSRasesh Mody 
9113eed444aSRasesh Mody 		rc = ecore_all_ppfids_wr(p_hwfn, p_ptt, addr, val);
9123eed444aSRasesh Mody 		if (rc != ECORE_SUCCESS) {
9133eed444aSRasesh Mody 			DP_NOTICE(p_hwfn, false,
9143eed444aSRasesh Mody 				  "Failed to update the DSCP to TC mapping enable bit\n");
9153eed444aSRasesh Mody 			return rc;
9163eed444aSRasesh Mody 		}
9173eed444aSRasesh Mody 
91822d07d93SRasesh Mody 		p_hwfn->p_dcbx_info->dscp_nig_update = false;
91922d07d93SRasesh Mody 	}
92022d07d93SRasesh Mody 
92126ae839dSRasesh Mody 	OSAL_DCBX_AEN(p_hwfn, type);
92226ae839dSRasesh Mody 
92326ae839dSRasesh Mody 	return rc;
92426ae839dSRasesh Mody }
92526ae839dSRasesh Mody 
ecore_dcbx_info_alloc(struct ecore_hwfn * p_hwfn)92626ae839dSRasesh Mody enum _ecore_status_t ecore_dcbx_info_alloc(struct ecore_hwfn *p_hwfn)
92726ae839dSRasesh Mody {
92826ae839dSRasesh Mody 	p_hwfn->p_dcbx_info = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
9293d1babcaSRasesh Mody 					  sizeof(*p_hwfn->p_dcbx_info));
93026ae839dSRasesh Mody 	if (!p_hwfn->p_dcbx_info) {
93198abf84eSRasesh Mody 		DP_NOTICE(p_hwfn, false,
93226ae839dSRasesh Mody 			  "Failed to allocate `struct ecore_dcbx_info'");
9332e2680e0SRasesh Mody 		return ECORE_NOMEM;
93426ae839dSRasesh Mody 	}
93526ae839dSRasesh Mody 
9362e2680e0SRasesh Mody 	p_hwfn->p_dcbx_info->iwarp_port =
9372e2680e0SRasesh Mody 		p_hwfn->pf_params.rdma_pf_params.iwarp_port;
9382e2680e0SRasesh Mody 
9392e2680e0SRasesh Mody 	return ECORE_SUCCESS;
94026ae839dSRasesh Mody }
94126ae839dSRasesh Mody 
ecore_dcbx_info_free(struct ecore_hwfn * p_hwfn)9425f4504bfSRasesh Mody void ecore_dcbx_info_free(struct ecore_hwfn *p_hwfn)
94326ae839dSRasesh Mody {
94426ae839dSRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_dcbx_info);
94526ae839dSRasesh Mody }
94626ae839dSRasesh Mody 
ecore_dcbx_update_protocol_data(struct protocol_dcb_data * p_data,struct ecore_dcbx_results * p_src,enum dcbx_protocol_type type)94726ae839dSRasesh Mody static void ecore_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
94826ae839dSRasesh Mody 					    struct ecore_dcbx_results *p_src,
94926ae839dSRasesh Mody 					    enum dcbx_protocol_type type)
95026ae839dSRasesh Mody {
95126ae839dSRasesh Mody 	p_data->dcb_enable_flag = p_src->arr[type].enable;
95226ae839dSRasesh Mody 	p_data->dcb_priority = p_src->arr[type].priority;
95326ae839dSRasesh Mody 	p_data->dcb_tc = p_src->arr[type].tc;
95422d07d93SRasesh Mody 	p_data->dscp_enable_flag = p_src->arr[type].dscp_enable;
95522d07d93SRasesh Mody 	p_data->dscp_val = p_src->arr[type].dscp_val;
95636f45bceSRasesh Mody 	p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0;
95726ae839dSRasesh Mody }
95826ae839dSRasesh Mody 
95926ae839dSRasesh Mody /* Set pf update ramrod command params */
ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results * p_src,struct pf_update_ramrod_data * p_dest)96026ae839dSRasesh Mody void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results *p_src,
96126ae839dSRasesh Mody 				     struct pf_update_ramrod_data *p_dest)
96226ae839dSRasesh Mody {
96326ae839dSRasesh Mody 	struct protocol_dcb_data *p_dcb_data;
964d4806abaSRasesh Mody 	u8 update_flag;
96526ae839dSRasesh Mody 
96626ae839dSRasesh Mody 	update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update;
967806474a6SRasesh Mody 	p_dest->update_eth_dcb_data_mode = update_flag;
9682e2680e0SRasesh Mody 	update_flag = p_src->arr[DCBX_PROTOCOL_IWARP].update;
9692e2680e0SRasesh Mody 	p_dest->update_iwarp_dcb_data_mode = update_flag;
97026ae839dSRasesh Mody 
97126ae839dSRasesh Mody 	p_dcb_data = &p_dest->eth_dcb_data;
97226ae839dSRasesh Mody 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
9732e2680e0SRasesh Mody 	p_dcb_data = &p_dest->iwarp_dcb_data;
9742e2680e0SRasesh Mody 	ecore_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_IWARP);
97526ae839dSRasesh Mody }
97626ae839dSRasesh Mody 
ecore_dcbx_query_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_get * p_get,enum ecore_mib_read_type type)9773d1babcaSRasesh Mody enum _ecore_status_t ecore_dcbx_query_params(struct ecore_hwfn *p_hwfn,
9783d1babcaSRasesh Mody 					     struct ecore_dcbx_get *p_get,
97926ae839dSRasesh Mody 					     enum ecore_mib_read_type type)
98026ae839dSRasesh Mody {
98126ae839dSRasesh Mody 	struct ecore_ptt *p_ptt;
98226ae839dSRasesh Mody 	enum _ecore_status_t rc;
98326ae839dSRasesh Mody 
9843d1babcaSRasesh Mody 	if (IS_VF(p_hwfn->p_dev))
9853d1babcaSRasesh Mody 		return ECORE_INVAL;
9863d1babcaSRasesh Mody 
98726ae839dSRasesh Mody 	p_ptt = ecore_ptt_acquire(p_hwfn);
988eafbc6fcSRasesh Mody 	if (!p_ptt)
989eafbc6fcSRasesh Mody 		return ECORE_TIMEOUT;
99026ae839dSRasesh Mody 
99126ae839dSRasesh Mody 	rc = ecore_dcbx_read_mib(p_hwfn, p_ptt, type);
99226ae839dSRasesh Mody 	if (rc != ECORE_SUCCESS)
99326ae839dSRasesh Mody 		goto out;
99426ae839dSRasesh Mody 
99513c0ec8aSRasesh Mody 	ecore_dcbx_get_dscp_params(p_hwfn, p_get);
99613c0ec8aSRasesh Mody 
99730ecf673SRasesh Mody 	rc = ecore_dcbx_get_params(p_hwfn, p_get, type);
99826ae839dSRasesh Mody 
99926ae839dSRasesh Mody out:
100026ae839dSRasesh Mody 	ecore_ptt_release(p_hwfn, p_ptt);
100126ae839dSRasesh Mody 	return rc;
100226ae839dSRasesh Mody }
100326ae839dSRasesh Mody 
100422d07d93SRasesh Mody static void
ecore_dcbx_set_pfc_data(struct ecore_hwfn * p_hwfn,u32 * pfc,struct ecore_dcbx_params * p_params)100522d07d93SRasesh Mody ecore_dcbx_set_pfc_data(struct ecore_hwfn *p_hwfn,
100622d07d93SRasesh Mody 			u32 *pfc, struct ecore_dcbx_params *p_params)
100722d07d93SRasesh Mody {
100822d07d93SRasesh Mody 	u8 pfc_map = 0;
100922d07d93SRasesh Mody 	int i;
101022d07d93SRasesh Mody 
101122d07d93SRasesh Mody 	if (p_params->pfc.willing)
101222d07d93SRasesh Mody 		*pfc |= DCBX_PFC_WILLING_MASK;
101322d07d93SRasesh Mody 	else
101422d07d93SRasesh Mody 		*pfc &= ~DCBX_PFC_WILLING_MASK;
101522d07d93SRasesh Mody 
101622d07d93SRasesh Mody 	if (p_params->pfc.enabled)
101722d07d93SRasesh Mody 		*pfc |= DCBX_PFC_ENABLED_MASK;
101822d07d93SRasesh Mody 	else
101922d07d93SRasesh Mody 		*pfc &= ~DCBX_PFC_ENABLED_MASK;
102022d07d93SRasesh Mody 
102122d07d93SRasesh Mody 	*pfc &= ~DCBX_PFC_CAPS_MASK;
102204b00049SRasesh Mody 	*pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_OFFSET;
102322d07d93SRasesh Mody 
102422d07d93SRasesh Mody 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++)
102522d07d93SRasesh Mody 		if (p_params->pfc.prio[i])
10263d1babcaSRasesh Mody 			pfc_map |= (1 << i);
10273d1babcaSRasesh Mody 	*pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK;
102804b00049SRasesh Mody 	*pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_OFFSET);
102922d07d93SRasesh Mody 
103022d07d93SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "pfc = 0x%x\n", *pfc);
103122d07d93SRasesh Mody }
103222d07d93SRasesh Mody 
103322d07d93SRasesh Mody static void
ecore_dcbx_set_ets_data(struct ecore_hwfn * p_hwfn,struct dcbx_ets_feature * p_ets,struct ecore_dcbx_params * p_params)103422d07d93SRasesh Mody ecore_dcbx_set_ets_data(struct ecore_hwfn *p_hwfn,
103522d07d93SRasesh Mody 			struct dcbx_ets_feature *p_ets,
103622d07d93SRasesh Mody 			struct ecore_dcbx_params *p_params)
103722d07d93SRasesh Mody {
103822d07d93SRasesh Mody 	u8 *bw_map, *tsa_map;
10393d1babcaSRasesh Mody 	u32 val;
104022d07d93SRasesh Mody 	int i;
104122d07d93SRasesh Mody 
104222d07d93SRasesh Mody 	if (p_params->ets_willing)
104322d07d93SRasesh Mody 		p_ets->flags |= DCBX_ETS_WILLING_MASK;
104422d07d93SRasesh Mody 	else
104522d07d93SRasesh Mody 		p_ets->flags &= ~DCBX_ETS_WILLING_MASK;
104622d07d93SRasesh Mody 
104722d07d93SRasesh Mody 	if (p_params->ets_cbs)
104822d07d93SRasesh Mody 		p_ets->flags |= DCBX_ETS_CBS_MASK;
104922d07d93SRasesh Mody 	else
105022d07d93SRasesh Mody 		p_ets->flags &= ~DCBX_ETS_CBS_MASK;
105122d07d93SRasesh Mody 
105222d07d93SRasesh Mody 	if (p_params->ets_enabled)
105322d07d93SRasesh Mody 		p_ets->flags |= DCBX_ETS_ENABLED_MASK;
105422d07d93SRasesh Mody 	else
105522d07d93SRasesh Mody 		p_ets->flags &= ~DCBX_ETS_ENABLED_MASK;
105622d07d93SRasesh Mody 
105722d07d93SRasesh Mody 	p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK;
105804b00049SRasesh Mody 	p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_OFFSET;
105922d07d93SRasesh Mody 
106022d07d93SRasesh Mody 	bw_map = (u8 *)&p_ets->tc_bw_tbl[0];
106122d07d93SRasesh Mody 	tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0];
106222d07d93SRasesh Mody 	p_ets->pri_tc_tbl[0] = 0;
106322d07d93SRasesh Mody 	for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++) {
106422d07d93SRasesh Mody 		bw_map[i] = p_params->ets_tc_bw_tbl[i];
106522d07d93SRasesh Mody 		tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
10663d1babcaSRasesh Mody 		/* Copy the priority value to the corresponding 4 bits in the
10673d1babcaSRasesh Mody 		 * traffic class table.
10683d1babcaSRasesh Mody 		 */
10693d1babcaSRasesh Mody 		val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
10703d1babcaSRasesh Mody 		p_ets->pri_tc_tbl[0] |= val;
107122d07d93SRasesh Mody 	}
107222d07d93SRasesh Mody 	for (i = 0; i < 2; i++) {
107322d07d93SRasesh Mody 		p_ets->tc_bw_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_bw_tbl[i]);
107422d07d93SRasesh Mody 		p_ets->tc_tsa_tbl[i] = OSAL_CPU_TO_BE32(p_ets->tc_tsa_tbl[i]);
107522d07d93SRasesh Mody 	}
1076d4806abaSRasesh Mody 
1077d4806abaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
1078d4806abaSRasesh Mody 		   "flags = 0x%x pri_tc = 0x%x tc_bwl[] = {0x%x, 0x%x} tc_tsa = {0x%x, 0x%x}\n",
1079d4806abaSRasesh Mody 		   p_ets->flags, p_ets->pri_tc_tbl[0], p_ets->tc_bw_tbl[0],
1080d4806abaSRasesh Mody 		   p_ets->tc_bw_tbl[1], p_ets->tc_tsa_tbl[0],
1081d4806abaSRasesh Mody 		   p_ets->tc_tsa_tbl[1]);
108222d07d93SRasesh Mody }
108322d07d93SRasesh Mody 
108422d07d93SRasesh Mody static void
ecore_dcbx_set_app_data(struct ecore_hwfn * p_hwfn,struct dcbx_app_priority_feature * p_app,struct ecore_dcbx_params * p_params,bool ieee)108522d07d93SRasesh Mody ecore_dcbx_set_app_data(struct ecore_hwfn *p_hwfn,
108622d07d93SRasesh Mody 			struct dcbx_app_priority_feature *p_app,
108722d07d93SRasesh Mody 			struct ecore_dcbx_params *p_params, bool ieee)
108822d07d93SRasesh Mody {
108922d07d93SRasesh Mody 	u32 *entry;
109022d07d93SRasesh Mody 	int i;
109122d07d93SRasesh Mody 
109222d07d93SRasesh Mody 	if (p_params->app_willing)
109322d07d93SRasesh Mody 		p_app->flags |= DCBX_APP_WILLING_MASK;
109422d07d93SRasesh Mody 	else
109522d07d93SRasesh Mody 		p_app->flags &= ~DCBX_APP_WILLING_MASK;
109622d07d93SRasesh Mody 
109722d07d93SRasesh Mody 	if (p_params->app_valid)
109822d07d93SRasesh Mody 		p_app->flags |= DCBX_APP_ENABLED_MASK;
109922d07d93SRasesh Mody 	else
110022d07d93SRasesh Mody 		p_app->flags &= ~DCBX_APP_ENABLED_MASK;
110122d07d93SRasesh Mody 
110222d07d93SRasesh Mody 	p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK;
110322d07d93SRasesh Mody 	p_app->flags |= (u32)p_params->num_app_entries <<
110404b00049SRasesh Mody 			DCBX_APP_NUM_ENTRIES_OFFSET;
110522d07d93SRasesh Mody 
1106211507c1SRasesh Mody 	for (i = 0; i < p_params->num_app_entries; i++) {
110722d07d93SRasesh Mody 		entry = &p_app->app_pri_tbl[i].entry;
11083d1babcaSRasesh Mody 		*entry = 0;
110922d07d93SRasesh Mody 		if (ieee) {
11103d1babcaSRasesh Mody 			*entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK);
111122d07d93SRasesh Mody 			switch (p_params->app_entry[i].sf_ieee) {
111222d07d93SRasesh Mody 			case ECORE_DCBX_SF_IEEE_ETHTYPE:
111322d07d93SRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE <<
111404b00049SRasesh Mody 					    DCBX_APP_SF_IEEE_OFFSET);
11153d1babcaSRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
111604b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
111722d07d93SRasesh Mody 				break;
111822d07d93SRasesh Mody 			case ECORE_DCBX_SF_IEEE_TCP_PORT:
111922d07d93SRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT <<
112004b00049SRasesh Mody 					    DCBX_APP_SF_IEEE_OFFSET);
11213d1babcaSRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
112204b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
112322d07d93SRasesh Mody 				break;
112422d07d93SRasesh Mody 			case ECORE_DCBX_SF_IEEE_UDP_PORT:
112522d07d93SRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT <<
112604b00049SRasesh Mody 					    DCBX_APP_SF_IEEE_OFFSET);
11273d1babcaSRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
112804b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
112922d07d93SRasesh Mody 				break;
113022d07d93SRasesh Mody 			case ECORE_DCBX_SF_IEEE_TCP_UDP_PORT:
113122d07d93SRasesh Mody 				*entry  |= (u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT <<
113204b00049SRasesh Mody 					    DCBX_APP_SF_IEEE_OFFSET;
11333d1babcaSRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
113404b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
113522d07d93SRasesh Mody 				break;
113622d07d93SRasesh Mody 			}
113722d07d93SRasesh Mody 		} else {
113822d07d93SRasesh Mody 			*entry &= ~DCBX_APP_SF_MASK;
113922d07d93SRasesh Mody 			if (p_params->app_entry[i].ethtype)
114022d07d93SRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_ETHTYPE <<
114104b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
114222d07d93SRasesh Mody 			else
114322d07d93SRasesh Mody 				*entry  |= ((u32)DCBX_APP_SF_PORT <<
114404b00049SRasesh Mody 					    DCBX_APP_SF_OFFSET);
114522d07d93SRasesh Mody 		}
114622d07d93SRasesh Mody 		*entry &= ~DCBX_APP_PROTOCOL_ID_MASK;
114722d07d93SRasesh Mody 		*entry |= ((u32)p_params->app_entry[i].proto_id <<
114804b00049SRasesh Mody 			   DCBX_APP_PROTOCOL_ID_OFFSET);
114922d07d93SRasesh Mody 		*entry &= ~DCBX_APP_PRI_MAP_MASK;
115022d07d93SRasesh Mody 		*entry |= ((u32)(p_params->app_entry[i].prio) <<
115104b00049SRasesh Mody 			   DCBX_APP_PRI_MAP_OFFSET);
115222d07d93SRasesh Mody 	}
1153d4806abaSRasesh Mody 
1154d4806abaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_app->flags);
115522d07d93SRasesh Mody }
115622d07d93SRasesh Mody 
1157eafbc6fcSRasesh Mody static void
ecore_dcbx_set_local_params(struct ecore_hwfn * p_hwfn,struct dcbx_local_params * local_admin,struct ecore_dcbx_set * params)115822d07d93SRasesh Mody ecore_dcbx_set_local_params(struct ecore_hwfn *p_hwfn,
115922d07d93SRasesh Mody 			    struct dcbx_local_params *local_admin,
116022d07d93SRasesh Mody 			    struct ecore_dcbx_set *params)
116122d07d93SRasesh Mody {
116222d07d93SRasesh Mody 	bool ieee = false;
116322d07d93SRasesh Mody 
116422d07d93SRasesh Mody 	local_admin->flags = 0;
116522d07d93SRasesh Mody 	OSAL_MEMCPY(&local_admin->features,
116622d07d93SRasesh Mody 		    &p_hwfn->p_dcbx_info->operational.features,
11673d1babcaSRasesh Mody 		    sizeof(local_admin->features));
116822d07d93SRasesh Mody 
116922d07d93SRasesh Mody 	if (params->enabled) {
117022d07d93SRasesh Mody 		local_admin->config = params->ver_num;
117122d07d93SRasesh Mody 		ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE);
117222d07d93SRasesh Mody 	} else {
117322d07d93SRasesh Mody 		local_admin->config = DCBX_CONFIG_VERSION_DISABLED;
117422d07d93SRasesh Mody 	}
117522d07d93SRasesh Mody 
117649f4b9dcSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "Dcbx version = %d\n",
117749f4b9dcSRasesh Mody 		   local_admin->config);
117849f4b9dcSRasesh Mody 
117922d07d93SRasesh Mody 	if (params->override_flags & ECORE_DCBX_OVERRIDE_PFC_CFG)
118022d07d93SRasesh Mody 		ecore_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc,
118122d07d93SRasesh Mody 					&params->config.params);
118222d07d93SRasesh Mody 
118322d07d93SRasesh Mody 	if (params->override_flags & ECORE_DCBX_OVERRIDE_ETS_CFG)
118422d07d93SRasesh Mody 		ecore_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets,
118522d07d93SRasesh Mody 					&params->config.params);
118622d07d93SRasesh Mody 
118722d07d93SRasesh Mody 	if (params->override_flags & ECORE_DCBX_OVERRIDE_APP_CFG)
118822d07d93SRasesh Mody 		ecore_dcbx_set_app_data(p_hwfn, &local_admin->features.app,
118922d07d93SRasesh Mody 					&params->config.params, ieee);
119022d07d93SRasesh Mody }
119122d07d93SRasesh Mody 
119222d07d93SRasesh Mody static enum _ecore_status_t
ecore_dcbx_set_dscp_params(struct ecore_hwfn * p_hwfn,struct dcb_dscp_map * p_dscp_map,struct ecore_dcbx_set * p_params)119322d07d93SRasesh Mody ecore_dcbx_set_dscp_params(struct ecore_hwfn *p_hwfn,
119422d07d93SRasesh Mody 			   struct dcb_dscp_map *p_dscp_map,
119522d07d93SRasesh Mody 			   struct ecore_dcbx_set *p_params)
119622d07d93SRasesh Mody {
119722d07d93SRasesh Mody 	int entry, i, j;
119822d07d93SRasesh Mody 	u32 val;
119922d07d93SRasesh Mody 
120022d07d93SRasesh Mody 	OSAL_MEMCPY(p_dscp_map, &p_hwfn->p_dcbx_info->dscp_map,
120122d07d93SRasesh Mody 		    sizeof(*p_dscp_map));
120222d07d93SRasesh Mody 
12033d1babcaSRasesh Mody 	p_dscp_map->flags &= ~DCB_DSCP_ENABLE_MASK;
120422d07d93SRasesh Mody 	if (p_params->dscp.enabled)
120522d07d93SRasesh Mody 		p_dscp_map->flags |= DCB_DSCP_ENABLE_MASK;
120622d07d93SRasesh Mody 
120722d07d93SRasesh Mody 	for (i = 0, entry = 0; i < 8; i++) {
120822d07d93SRasesh Mody 		val = 0;
120922d07d93SRasesh Mody 		for (j = 0; j < 8; j++, entry++)
121022d07d93SRasesh Mody 			val |= (((u32)p_params->dscp.dscp_pri_map[entry]) <<
121122d07d93SRasesh Mody 				(j * 4));
121222d07d93SRasesh Mody 
121322d07d93SRasesh Mody 		p_dscp_map->dscp_pri_map[i] = OSAL_CPU_TO_BE32(val);
121422d07d93SRasesh Mody 	}
121522d07d93SRasesh Mody 
121622d07d93SRasesh Mody 	p_hwfn->p_dcbx_info->dscp_nig_update = true;
121722d07d93SRasesh Mody 
1218d4806abaSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "flags = 0x%x\n", p_dscp_map->flags);
121913c0ec8aSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
122013c0ec8aSRasesh Mody 		   "pri_map[] = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
122113c0ec8aSRasesh Mody 		   p_dscp_map->dscp_pri_map[0], p_dscp_map->dscp_pri_map[1],
122213c0ec8aSRasesh Mody 		   p_dscp_map->dscp_pri_map[2], p_dscp_map->dscp_pri_map[3],
122313c0ec8aSRasesh Mody 		   p_dscp_map->dscp_pri_map[4], p_dscp_map->dscp_pri_map[5],
122413c0ec8aSRasesh Mody 		   p_dscp_map->dscp_pri_map[6], p_dscp_map->dscp_pri_map[7]);
1225d4806abaSRasesh Mody 
122622d07d93SRasesh Mody 	return ECORE_SUCCESS;
122722d07d93SRasesh Mody }
122822d07d93SRasesh Mody 
ecore_dcbx_config_params(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_dcbx_set * params,bool hw_commit)122922d07d93SRasesh Mody enum _ecore_status_t ecore_dcbx_config_params(struct ecore_hwfn *p_hwfn,
123022d07d93SRasesh Mody 					      struct ecore_ptt *p_ptt,
123122d07d93SRasesh Mody 					      struct ecore_dcbx_set *params,
123222d07d93SRasesh Mody 					      bool hw_commit)
123322d07d93SRasesh Mody {
123422d07d93SRasesh Mody 	struct dcbx_local_params local_admin;
12353d1babcaSRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
123622d07d93SRasesh Mody 	struct dcb_dscp_map dscp_map;
123722d07d93SRasesh Mody 	u32 resp = 0, param = 0;
12383d1babcaSRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
123922d07d93SRasesh Mody 
124022d07d93SRasesh Mody 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set, params,
12413d1babcaSRasesh Mody 		    sizeof(p_hwfn->p_dcbx_info->set));
124236341ac6SRasesh Mody 	if (!hw_commit)
124322d07d93SRasesh Mody 		return ECORE_SUCCESS;
124422d07d93SRasesh Mody 
124522d07d93SRasesh Mody 	OSAL_MEMSET(&local_admin, 0, sizeof(local_admin));
124622d07d93SRasesh Mody 	ecore_dcbx_set_local_params(p_hwfn, &local_admin, params);
124722d07d93SRasesh Mody 
124822d07d93SRasesh Mody 	data.addr = p_hwfn->mcp_info->port_addr +
124922d07d93SRasesh Mody 			offsetof(struct public_port, local_admin_dcbx_mib);
125022d07d93SRasesh Mody 	data.local_admin = &local_admin;
125122d07d93SRasesh Mody 	data.size = sizeof(struct dcbx_local_params);
125222d07d93SRasesh Mody 	ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size);
125322d07d93SRasesh Mody 
125422d07d93SRasesh Mody 	if (params->override_flags & ECORE_DCBX_OVERRIDE_DSCP_CFG) {
125522d07d93SRasesh Mody 		OSAL_MEMSET(&dscp_map, 0, sizeof(dscp_map));
125622d07d93SRasesh Mody 		ecore_dcbx_set_dscp_params(p_hwfn, &dscp_map, params);
125722d07d93SRasesh Mody 
125822d07d93SRasesh Mody 		data.addr = p_hwfn->mcp_info->port_addr +
125922d07d93SRasesh Mody 				offsetof(struct public_port, dcb_dscp_map);
126022d07d93SRasesh Mody 		data.dscp_map = &dscp_map;
126122d07d93SRasesh Mody 		data.size = sizeof(struct dcb_dscp_map);
126222d07d93SRasesh Mody 		ecore_memcpy_to(p_hwfn, p_ptt, data.addr, data.dscp_map,
126322d07d93SRasesh Mody 				data.size);
126422d07d93SRasesh Mody 	}
126522d07d93SRasesh Mody 
126622d07d93SRasesh Mody 	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX,
126704b00049SRasesh Mody 			   1 << DRV_MB_PARAM_LLDP_SEND_OFFSET, &resp, &param);
126804b00049SRasesh Mody 	if (rc != ECORE_SUCCESS)
126922d07d93SRasesh Mody 		DP_NOTICE(p_hwfn, false,
127022d07d93SRasesh Mody 			  "Failed to send DCBX update request\n");
127122d07d93SRasesh Mody 
127222d07d93SRasesh Mody 	return rc;
127322d07d93SRasesh Mody }
127422d07d93SRasesh Mody 
ecore_dcbx_get_config_params(struct ecore_hwfn * p_hwfn,struct ecore_dcbx_set * params)127522d07d93SRasesh Mody enum _ecore_status_t ecore_dcbx_get_config_params(struct ecore_hwfn *p_hwfn,
127622d07d93SRasesh Mody 						  struct ecore_dcbx_set *params)
127722d07d93SRasesh Mody {
127822d07d93SRasesh Mody 	struct ecore_dcbx_get *dcbx_info;
127922d07d93SRasesh Mody 	int rc;
128022d07d93SRasesh Mody 
128122d07d93SRasesh Mody 	if (p_hwfn->p_dcbx_info->set.config.valid) {
128222d07d93SRasesh Mody 		OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
128322d07d93SRasesh Mody 			    sizeof(struct ecore_dcbx_set));
128422d07d93SRasesh Mody 		return ECORE_SUCCESS;
128522d07d93SRasesh Mody 	}
128622d07d93SRasesh Mody 
128722d07d93SRasesh Mody 	dcbx_info = OSAL_ALLOC(p_hwfn->p_dev, GFP_KERNEL,
12883d1babcaSRasesh Mody 			       sizeof(*dcbx_info));
1289eafbc6fcSRasesh Mody 	if (!dcbx_info)
129022d07d93SRasesh Mody 		return ECORE_NOMEM;
129122d07d93SRasesh Mody 
12923d1babcaSRasesh Mody 	OSAL_MEMSET(dcbx_info, 0, sizeof(*dcbx_info));
129322d07d93SRasesh Mody 	rc = ecore_dcbx_query_params(p_hwfn, dcbx_info,
129422d07d93SRasesh Mody 				     ECORE_DCBX_OPERATIONAL_MIB);
129522d07d93SRasesh Mody 	if (rc) {
129622d07d93SRasesh Mody 		OSAL_FREE(p_hwfn->p_dev, dcbx_info);
129722d07d93SRasesh Mody 		return rc;
129822d07d93SRasesh Mody 	}
129922d07d93SRasesh Mody 	p_hwfn->p_dcbx_info->set.override_flags = 0;
130022d07d93SRasesh Mody 
130122d07d93SRasesh Mody 	p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED;
130222d07d93SRasesh Mody 	if (dcbx_info->operational.cee)
130322d07d93SRasesh Mody 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE;
130422d07d93SRasesh Mody 	if (dcbx_info->operational.ieee)
130522d07d93SRasesh Mody 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE;
130622d07d93SRasesh Mody 	if (dcbx_info->operational.local)
130722d07d93SRasesh Mody 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC;
130822d07d93SRasesh Mody 
130922d07d93SRasesh Mody 	p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled;
131013c0ec8aSRasesh Mody 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set.dscp,
131113c0ec8aSRasesh Mody 		    &p_hwfn->p_dcbx_info->get.dscp,
131213c0ec8aSRasesh Mody 		    sizeof(struct ecore_dcbx_dscp_params));
131322d07d93SRasesh Mody 	OSAL_MEMCPY(&p_hwfn->p_dcbx_info->set.config.params,
131422d07d93SRasesh Mody 		    &dcbx_info->operational.params,
1315211507c1SRasesh Mody 		    sizeof(p_hwfn->p_dcbx_info->set.config.params));
131622d07d93SRasesh Mody 	p_hwfn->p_dcbx_info->set.config.valid = true;
131722d07d93SRasesh Mody 
131822d07d93SRasesh Mody 	OSAL_MEMCPY(params, &p_hwfn->p_dcbx_info->set,
131922d07d93SRasesh Mody 		    sizeof(struct ecore_dcbx_set));
132022d07d93SRasesh Mody 
132122d07d93SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, dcbx_info);
132222d07d93SRasesh Mody 
132322d07d93SRasesh Mody 	return ECORE_SUCCESS;
132422d07d93SRasesh Mody }
132581dba2b2SRasesh Mody 
ecore_lldp_register_tlv(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_lldp_agent agent,u8 tlv_type)132681dba2b2SRasesh Mody enum _ecore_status_t ecore_lldp_register_tlv(struct ecore_hwfn *p_hwfn,
132781dba2b2SRasesh Mody 					     struct ecore_ptt *p_ptt,
132881dba2b2SRasesh Mody 					     enum ecore_lldp_agent agent,
132981dba2b2SRasesh Mody 					     u8 tlv_type)
133081dba2b2SRasesh Mody {
133181dba2b2SRasesh Mody 	u32 mb_param = 0, mcp_resp = 0, mcp_param = 0, val = 0;
133281dba2b2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
133381dba2b2SRasesh Mody 
133481dba2b2SRasesh Mody 	switch (agent) {
133581dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_BRIDGE:
133681dba2b2SRasesh Mody 		val = LLDP_NEAREST_BRIDGE;
133781dba2b2SRasesh Mody 		break;
133881dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE:
133981dba2b2SRasesh Mody 		val = LLDP_NEAREST_NON_TPMR_BRIDGE;
134081dba2b2SRasesh Mody 		break;
134181dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE:
134281dba2b2SRasesh Mody 		val = LLDP_NEAREST_CUSTOMER_BRIDGE;
134381dba2b2SRasesh Mody 		break;
134481dba2b2SRasesh Mody 	default:
134581dba2b2SRasesh Mody 		DP_ERR(p_hwfn, "Invalid agent type %d\n", agent);
134681dba2b2SRasesh Mody 		return ECORE_INVAL;
134781dba2b2SRasesh Mody 	}
134881dba2b2SRasesh Mody 
134981dba2b2SRasesh Mody 	SET_MFW_FIELD(mb_param, DRV_MB_PARAM_LLDP_AGENT, val);
135081dba2b2SRasesh Mody 	SET_MFW_FIELD(mb_param, DRV_MB_PARAM_LLDP_TLV_RX_TYPE, tlv_type);
135181dba2b2SRasesh Mody 
135281dba2b2SRasesh Mody 	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_REGISTER_LLDP_TLVS_RX,
135381dba2b2SRasesh Mody 			   mb_param, &mcp_resp, &mcp_param);
135481dba2b2SRasesh Mody 	if (rc != ECORE_SUCCESS)
135581dba2b2SRasesh Mody 		DP_NOTICE(p_hwfn, false, "Failed to register TLV\n");
135681dba2b2SRasesh Mody 
135781dba2b2SRasesh Mody 	return rc;
135881dba2b2SRasesh Mody }
135981dba2b2SRasesh Mody 
136081dba2b2SRasesh Mody enum _ecore_status_t
ecore_lldp_mib_update_event(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)136181dba2b2SRasesh Mody ecore_lldp_mib_update_event(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
136281dba2b2SRasesh Mody {
136381dba2b2SRasesh Mody 	struct ecore_dcbx_mib_meta_data data;
136481dba2b2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
136581dba2b2SRasesh Mody 	struct lldp_received_tlvs_s tlvs;
136681dba2b2SRasesh Mody 	int i;
136781dba2b2SRasesh Mody 
136881dba2b2SRasesh Mody 	for (i = 0; i < LLDP_MAX_LLDP_AGENTS; i++) {
136981dba2b2SRasesh Mody 		OSAL_MEM_ZERO(&data, sizeof(data));
137081dba2b2SRasesh Mody 		data.addr = p_hwfn->mcp_info->port_addr +
137181dba2b2SRasesh Mody 			    offsetof(struct public_port, lldp_received_tlvs[i]);
137281dba2b2SRasesh Mody 		data.lldp_tlvs = &tlvs;
137381dba2b2SRasesh Mody 		data.size = sizeof(tlvs);
137481dba2b2SRasesh Mody 		rc = ecore_dcbx_copy_mib(p_hwfn, p_ptt, &data,
137581dba2b2SRasesh Mody 					 ECORE_DCBX_LLDP_TLVS);
137681dba2b2SRasesh Mody 		if (rc != ECORE_SUCCESS) {
137781dba2b2SRasesh Mody 			DP_NOTICE(p_hwfn, false, "Failed to read lldp TLVs\n");
137881dba2b2SRasesh Mody 			return rc;
137981dba2b2SRasesh Mody 		}
138081dba2b2SRasesh Mody 
138181dba2b2SRasesh Mody 		if (!tlvs.length)
138281dba2b2SRasesh Mody 			continue;
138381dba2b2SRasesh Mody 
138481dba2b2SRasesh Mody 		for (i = 0; i < MAX_TLV_BUFFER; i++)
138581dba2b2SRasesh Mody 			tlvs.tlvs_buffer[i] =
138681dba2b2SRasesh Mody 				OSAL_CPU_TO_BE32(tlvs.tlvs_buffer[i]);
138781dba2b2SRasesh Mody 
138881dba2b2SRasesh Mody 		OSAL_LLDP_RX_TLVS(p_hwfn, tlvs.tlvs_buffer, tlvs.length);
138981dba2b2SRasesh Mody 	}
139081dba2b2SRasesh Mody 
139181dba2b2SRasesh Mody 	return rc;
139281dba2b2SRasesh Mody }
139381dba2b2SRasesh Mody 
139481dba2b2SRasesh Mody enum _ecore_status_t
ecore_lldp_get_params(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_lldp_config_params * p_params)139581dba2b2SRasesh Mody ecore_lldp_get_params(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
139681dba2b2SRasesh Mody 		      struct ecore_lldp_config_params *p_params)
139781dba2b2SRasesh Mody {
139881dba2b2SRasesh Mody 	struct lldp_config_params_s lldp_params;
139981dba2b2SRasesh Mody 	u32 addr, val;
140081dba2b2SRasesh Mody 	int i;
140181dba2b2SRasesh Mody 
140281dba2b2SRasesh Mody 	switch (p_params->agent) {
140381dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_BRIDGE:
140481dba2b2SRasesh Mody 		val = LLDP_NEAREST_BRIDGE;
140581dba2b2SRasesh Mody 		break;
140681dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE:
140781dba2b2SRasesh Mody 		val = LLDP_NEAREST_NON_TPMR_BRIDGE;
140881dba2b2SRasesh Mody 		break;
140981dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE:
141081dba2b2SRasesh Mody 		val = LLDP_NEAREST_CUSTOMER_BRIDGE;
141181dba2b2SRasesh Mody 		break;
141281dba2b2SRasesh Mody 	default:
141381dba2b2SRasesh Mody 		DP_ERR(p_hwfn, "Invalid agent type %d\n", p_params->agent);
141481dba2b2SRasesh Mody 		return ECORE_INVAL;
141581dba2b2SRasesh Mody 	}
141681dba2b2SRasesh Mody 
141781dba2b2SRasesh Mody 	addr = p_hwfn->mcp_info->port_addr +
141881dba2b2SRasesh Mody 			offsetof(struct public_port, lldp_config_params[val]);
141981dba2b2SRasesh Mody 
142081dba2b2SRasesh Mody 	ecore_memcpy_from(p_hwfn, p_ptt, &lldp_params, addr,
142181dba2b2SRasesh Mody 			  sizeof(lldp_params));
142281dba2b2SRasesh Mody 
142381dba2b2SRasesh Mody 	p_params->tx_interval = GET_MFW_FIELD(lldp_params.config,
142481dba2b2SRasesh Mody 					      LLDP_CONFIG_TX_INTERVAL);
142581dba2b2SRasesh Mody 	p_params->tx_hold = GET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_HOLD);
142681dba2b2SRasesh Mody 	p_params->tx_credit = GET_MFW_FIELD(lldp_params.config,
142781dba2b2SRasesh Mody 					    LLDP_CONFIG_MAX_CREDIT);
142881dba2b2SRasesh Mody 	p_params->rx_enable = GET_MFW_FIELD(lldp_params.config,
142981dba2b2SRasesh Mody 					    LLDP_CONFIG_ENABLE_RX);
143081dba2b2SRasesh Mody 	p_params->tx_enable = GET_MFW_FIELD(lldp_params.config,
143181dba2b2SRasesh Mody 					    LLDP_CONFIG_ENABLE_TX);
143281dba2b2SRasesh Mody 
143381dba2b2SRasesh Mody 	OSAL_MEMCPY(p_params->chassis_id_tlv, lldp_params.local_chassis_id,
143481dba2b2SRasesh Mody 		    sizeof(p_params->chassis_id_tlv));
143581dba2b2SRasesh Mody 	for (i = 0; i < ECORE_LLDP_CHASSIS_ID_STAT_LEN; i++)
143681dba2b2SRasesh Mody 		p_params->chassis_id_tlv[i] =
143781dba2b2SRasesh Mody 				OSAL_BE32_TO_CPU(p_params->chassis_id_tlv[i]);
143881dba2b2SRasesh Mody 
143981dba2b2SRasesh Mody 	OSAL_MEMCPY(p_params->port_id_tlv, lldp_params.local_port_id,
144081dba2b2SRasesh Mody 		    sizeof(p_params->port_id_tlv));
144181dba2b2SRasesh Mody 	for (i = 0; i < ECORE_LLDP_PORT_ID_STAT_LEN; i++)
144281dba2b2SRasesh Mody 		p_params->port_id_tlv[i] =
144381dba2b2SRasesh Mody 				OSAL_BE32_TO_CPU(p_params->port_id_tlv[i]);
144481dba2b2SRasesh Mody 
144581dba2b2SRasesh Mody 	return ECORE_SUCCESS;
144681dba2b2SRasesh Mody }
144781dba2b2SRasesh Mody 
144881dba2b2SRasesh Mody enum _ecore_status_t
ecore_lldp_set_params(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_lldp_config_params * p_params)144981dba2b2SRasesh Mody ecore_lldp_set_params(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
145081dba2b2SRasesh Mody 		      struct ecore_lldp_config_params *p_params)
145181dba2b2SRasesh Mody {
145281dba2b2SRasesh Mody 	u32 mb_param = 0, mcp_resp = 0, mcp_param = 0;
145381dba2b2SRasesh Mody 	struct lldp_config_params_s lldp_params;
145481dba2b2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
145581dba2b2SRasesh Mody 	u32 addr, val;
145681dba2b2SRasesh Mody 	int i;
145781dba2b2SRasesh Mody 
145881dba2b2SRasesh Mody 	switch (p_params->agent) {
145981dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_BRIDGE:
146081dba2b2SRasesh Mody 		val = LLDP_NEAREST_BRIDGE;
146181dba2b2SRasesh Mody 		break;
146281dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE:
146381dba2b2SRasesh Mody 		val = LLDP_NEAREST_NON_TPMR_BRIDGE;
146481dba2b2SRasesh Mody 		break;
146581dba2b2SRasesh Mody 	case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE:
146681dba2b2SRasesh Mody 		val = LLDP_NEAREST_CUSTOMER_BRIDGE;
146781dba2b2SRasesh Mody 		break;
146881dba2b2SRasesh Mody 	default:
146981dba2b2SRasesh Mody 		DP_ERR(p_hwfn, "Invalid agent type %d\n", p_params->agent);
147081dba2b2SRasesh Mody 		return ECORE_INVAL;
147181dba2b2SRasesh Mody 	}
147281dba2b2SRasesh Mody 
147381dba2b2SRasesh Mody 	SET_MFW_FIELD(mb_param, DRV_MB_PARAM_LLDP_AGENT, val);
147481dba2b2SRasesh Mody 	addr = p_hwfn->mcp_info->port_addr +
147581dba2b2SRasesh Mody 			offsetof(struct public_port, lldp_config_params[val]);
147681dba2b2SRasesh Mody 
147781dba2b2SRasesh Mody 	OSAL_MEMSET(&lldp_params, 0, sizeof(lldp_params));
147881dba2b2SRasesh Mody 	SET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_TX_INTERVAL,
147981dba2b2SRasesh Mody 		      p_params->tx_interval);
148081dba2b2SRasesh Mody 	SET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_HOLD, p_params->tx_hold);
148181dba2b2SRasesh Mody 	SET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_MAX_CREDIT,
148281dba2b2SRasesh Mody 		      p_params->tx_credit);
148381dba2b2SRasesh Mody 	SET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_ENABLE_RX,
148481dba2b2SRasesh Mody 		      !!p_params->rx_enable);
148581dba2b2SRasesh Mody 	SET_MFW_FIELD(lldp_params.config, LLDP_CONFIG_ENABLE_TX,
148681dba2b2SRasesh Mody 		      !!p_params->tx_enable);
148781dba2b2SRasesh Mody 
148881dba2b2SRasesh Mody 	for (i = 0; i < ECORE_LLDP_CHASSIS_ID_STAT_LEN; i++)
148981dba2b2SRasesh Mody 		p_params->chassis_id_tlv[i] =
149081dba2b2SRasesh Mody 				OSAL_CPU_TO_BE32(p_params->chassis_id_tlv[i]);
149181dba2b2SRasesh Mody 	OSAL_MEMCPY(lldp_params.local_chassis_id, p_params->chassis_id_tlv,
149281dba2b2SRasesh Mody 		    sizeof(lldp_params.local_chassis_id));
149381dba2b2SRasesh Mody 
149481dba2b2SRasesh Mody 	for (i = 0; i < ECORE_LLDP_PORT_ID_STAT_LEN; i++)
149581dba2b2SRasesh Mody 		p_params->port_id_tlv[i] =
149681dba2b2SRasesh Mody 				OSAL_CPU_TO_BE32(p_params->port_id_tlv[i]);
149781dba2b2SRasesh Mody 	OSAL_MEMCPY(lldp_params.local_port_id, p_params->port_id_tlv,
149881dba2b2SRasesh Mody 		    sizeof(lldp_params.local_port_id));
149981dba2b2SRasesh Mody 
150081dba2b2SRasesh Mody 	ecore_memcpy_to(p_hwfn, p_ptt, addr, &lldp_params, sizeof(lldp_params));
150181dba2b2SRasesh Mody 
150281dba2b2SRasesh Mody 	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_LLDP,
150381dba2b2SRasesh Mody 			   mb_param, &mcp_resp, &mcp_param);
150481dba2b2SRasesh Mody 	if (rc != ECORE_SUCCESS)
150581dba2b2SRasesh Mody 		DP_NOTICE(p_hwfn, false, "SET_LLDP failed, error = %d\n", rc);
150681dba2b2SRasesh Mody 
150781dba2b2SRasesh Mody 	return rc;
150881dba2b2SRasesh Mody }
150981dba2b2SRasesh Mody 
151081dba2b2SRasesh Mody enum _ecore_status_t
ecore_lldp_set_system_tlvs(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_lldp_sys_tlvs * p_params)151181dba2b2SRasesh Mody ecore_lldp_set_system_tlvs(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
151281dba2b2SRasesh Mody 			   struct ecore_lldp_sys_tlvs *p_params)
151381dba2b2SRasesh Mody {
151481dba2b2SRasesh Mody 	u32 mb_param = 0, mcp_resp = 0, mcp_param = 0;
151581dba2b2SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
151681dba2b2SRasesh Mody 	struct lldp_system_tlvs_buffer_s lld_tlv_buf;
151781dba2b2SRasesh Mody 	u32 addr, *p_val;
151881dba2b2SRasesh Mody 	u8 len;
151981dba2b2SRasesh Mody 	int i;
152081dba2b2SRasesh Mody 
152181dba2b2SRasesh Mody 	p_val = (u32 *)p_params->buf;
152281dba2b2SRasesh Mody 	for (i = 0; i < ECORE_LLDP_SYS_TLV_SIZE / 4; i++)
152381dba2b2SRasesh Mody 		p_val[i] = OSAL_CPU_TO_BE32(p_val[i]);
152481dba2b2SRasesh Mody 
152581dba2b2SRasesh Mody 	OSAL_MEMSET(&lld_tlv_buf, 0, sizeof(lld_tlv_buf));
152681dba2b2SRasesh Mody 	SET_MFW_FIELD(lld_tlv_buf.flags, LLDP_SYSTEM_TLV_VALID, 1);
152781dba2b2SRasesh Mody 	SET_MFW_FIELD(lld_tlv_buf.flags, LLDP_SYSTEM_TLV_MANDATORY,
152881dba2b2SRasesh Mody 		      !!p_params->discard_mandatory_tlv);
152981dba2b2SRasesh Mody 	SET_MFW_FIELD(lld_tlv_buf.flags, LLDP_SYSTEM_TLV_LENGTH,
153081dba2b2SRasesh Mody 		      p_params->buf_size);
153181dba2b2SRasesh Mody 	len = ECORE_LLDP_SYS_TLV_SIZE / 2;
153281dba2b2SRasesh Mody 	OSAL_MEMCPY(lld_tlv_buf.data, p_params->buf, len);
153381dba2b2SRasesh Mody 
153481dba2b2SRasesh Mody 	addr = p_hwfn->mcp_info->port_addr +
153581dba2b2SRasesh Mody 		offsetof(struct public_port, system_lldp_tlvs_buf);
153681dba2b2SRasesh Mody 	ecore_memcpy_to(p_hwfn, p_ptt, addr, &lld_tlv_buf, sizeof(lld_tlv_buf));
153781dba2b2SRasesh Mody 
153881dba2b2SRasesh Mody 	if  (p_params->buf_size > len) {
153981dba2b2SRasesh Mody 		addr = p_hwfn->mcp_info->port_addr +
154081dba2b2SRasesh Mody 			offsetof(struct public_port, system_lldp_tlvs_buf2);
154181dba2b2SRasesh Mody 		ecore_memcpy_to(p_hwfn, p_ptt, addr, &p_params->buf[len],
154281dba2b2SRasesh Mody 				ECORE_LLDP_SYS_TLV_SIZE / 2);
154381dba2b2SRasesh Mody 	}
154481dba2b2SRasesh Mody 
154581dba2b2SRasesh Mody 	rc = ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_LLDP,
154681dba2b2SRasesh Mody 			   mb_param, &mcp_resp, &mcp_param);
154781dba2b2SRasesh Mody 	if (rc != ECORE_SUCCESS)
154881dba2b2SRasesh Mody 		DP_NOTICE(p_hwfn, false, "SET_LLDP failed, error = %d\n", rc);
154981dba2b2SRasesh Mody 
155081dba2b2SRasesh Mody 	return rc;
155181dba2b2SRasesh Mody }
15529aea0e7dSRasesh Mody 
15539aea0e7dSRasesh Mody enum _ecore_status_t
ecore_dcbx_get_dscp_priority(struct ecore_hwfn * p_hwfn,u8 dscp_index,u8 * p_dscp_pri)15549aea0e7dSRasesh Mody ecore_dcbx_get_dscp_priority(struct ecore_hwfn *p_hwfn,
15559aea0e7dSRasesh Mody 			     u8 dscp_index, u8 *p_dscp_pri)
15569aea0e7dSRasesh Mody {
15579aea0e7dSRasesh Mody 	struct ecore_dcbx_get *p_dcbx_info;
15589aea0e7dSRasesh Mody 	enum _ecore_status_t rc;
15599aea0e7dSRasesh Mody 
15609aea0e7dSRasesh Mody 	if (dscp_index >= ECORE_DCBX_DSCP_SIZE) {
15619aea0e7dSRasesh Mody 		DP_ERR(p_hwfn, "Invalid dscp index %d\n", dscp_index);
15629aea0e7dSRasesh Mody 		return ECORE_INVAL;
15639aea0e7dSRasesh Mody 	}
15649aea0e7dSRasesh Mody 
15659aea0e7dSRasesh Mody 	p_dcbx_info = OSAL_ALLOC(p_hwfn->p_dev, GFP_KERNEL,
15669aea0e7dSRasesh Mody 				 sizeof(*p_dcbx_info));
15679aea0e7dSRasesh Mody 	if (!p_dcbx_info)
15689aea0e7dSRasesh Mody 		return ECORE_NOMEM;
15699aea0e7dSRasesh Mody 
15709aea0e7dSRasesh Mody 	OSAL_MEMSET(p_dcbx_info, 0, sizeof(*p_dcbx_info));
15719aea0e7dSRasesh Mody 	rc = ecore_dcbx_query_params(p_hwfn, p_dcbx_info,
15729aea0e7dSRasesh Mody 				     ECORE_DCBX_OPERATIONAL_MIB);
15739aea0e7dSRasesh Mody 	if (rc) {
15749aea0e7dSRasesh Mody 		OSAL_FREE(p_hwfn->p_dev, p_dcbx_info);
15759aea0e7dSRasesh Mody 		return rc;
15769aea0e7dSRasesh Mody 	}
15779aea0e7dSRasesh Mody 
15789aea0e7dSRasesh Mody 	*p_dscp_pri = p_dcbx_info->dscp.dscp_pri_map[dscp_index];
15799aea0e7dSRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_dcbx_info);
15809aea0e7dSRasesh Mody 
15819aea0e7dSRasesh Mody 	return ECORE_SUCCESS;
15829aea0e7dSRasesh Mody }
15839aea0e7dSRasesh Mody 
15849aea0e7dSRasesh Mody enum _ecore_status_t
ecore_dcbx_set_dscp_priority(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u8 dscp_index,u8 pri_val)15859aea0e7dSRasesh Mody ecore_dcbx_set_dscp_priority(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
15869aea0e7dSRasesh Mody 			     u8 dscp_index, u8 pri_val)
15879aea0e7dSRasesh Mody {
15889aea0e7dSRasesh Mody 	struct ecore_dcbx_set dcbx_set;
15899aea0e7dSRasesh Mody 	enum _ecore_status_t rc;
15909aea0e7dSRasesh Mody 
15919aea0e7dSRasesh Mody 	if (dscp_index >= ECORE_DCBX_DSCP_SIZE ||
15929aea0e7dSRasesh Mody 	    pri_val >= ECORE_MAX_PFC_PRIORITIES) {
15939aea0e7dSRasesh Mody 		DP_ERR(p_hwfn, "Invalid dscp params: index = %d pri = %d\n",
15949aea0e7dSRasesh Mody 		       dscp_index, pri_val);
15959aea0e7dSRasesh Mody 		return ECORE_INVAL;
15969aea0e7dSRasesh Mody 	}
15979aea0e7dSRasesh Mody 
15989aea0e7dSRasesh Mody 	OSAL_MEMSET(&dcbx_set, 0, sizeof(dcbx_set));
15999aea0e7dSRasesh Mody 	rc = ecore_dcbx_get_config_params(p_hwfn, &dcbx_set);
16009aea0e7dSRasesh Mody 	if (rc)
16019aea0e7dSRasesh Mody 		return rc;
16029aea0e7dSRasesh Mody 
16039aea0e7dSRasesh Mody 	dcbx_set.override_flags = ECORE_DCBX_OVERRIDE_DSCP_CFG;
16049aea0e7dSRasesh Mody 	dcbx_set.dscp.dscp_pri_map[dscp_index] = pri_val;
16059aea0e7dSRasesh Mody 
16069aea0e7dSRasesh Mody 	return ecore_dcbx_config_params(p_hwfn, p_ptt, &dcbx_set, 1);
16079aea0e7dSRasesh Mody }
1608