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, ¶ms->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, ¶ms->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 = ¶ms->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 = ¶ms->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, ¶ms->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 ¶ms->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 ¶ms->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 ¶ms->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, ¶m);
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