mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-25 15:24:17 +08:00
bnxt_en: Add DCBNL DSCP application protocol support.
Expand the .ieee_setapp() and ieee_delapp() DCBNL methods to support DSCP. This allows DSCP values to user priority mappings instead of using VLAN priorities. Each DSCP mapping is added or deleted one entry at a time using the firmware API. The firmware call can only be made from a PF. Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
cde49a42a9
commit
afdc8a8484
@ -1281,6 +1281,7 @@ struct bnxt {
|
|||||||
struct ieee_ets *ieee_ets;
|
struct ieee_ets *ieee_ets;
|
||||||
u8 dcbx_cap;
|
u8 dcbx_cap;
|
||||||
u8 default_pri;
|
u8 default_pri;
|
||||||
|
u8 max_dscp_value;
|
||||||
#endif /* CONFIG_BNXT_DCB */
|
#endif /* CONFIG_BNXT_DCB */
|
||||||
|
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
|
@ -385,6 +385,61 @@ set_app_exit:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bnxt_hwrm_queue_dscp_qcaps(struct bnxt *bp)
|
||||||
|
{
|
||||||
|
struct hwrm_queue_dscp_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
|
struct hwrm_queue_dscp_qcaps_input req = {0};
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (bp->hwrm_spec_code < 0x10800 || BNXT_VF(bp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_DSCP_QCAPS, -1, -1);
|
||||||
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
|
if (!rc) {
|
||||||
|
bp->max_dscp_value = (1 << resp->num_dscp_bits) - 1;
|
||||||
|
if (bp->max_dscp_value < 0x3f)
|
||||||
|
bp->max_dscp_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app,
|
||||||
|
bool add)
|
||||||
|
{
|
||||||
|
struct hwrm_queue_dscp2pri_cfg_input req = {0};
|
||||||
|
struct bnxt_dscp2pri_entry *dscp2pri;
|
||||||
|
dma_addr_t mapping;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (bp->hwrm_spec_code < 0x10800)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_DSCP2PRI_CFG, -1, -1);
|
||||||
|
dscp2pri = dma_alloc_coherent(&bp->pdev->dev, sizeof(*dscp2pri),
|
||||||
|
&mapping, GFP_KERNEL);
|
||||||
|
if (!dscp2pri)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
req.src_data_addr = cpu_to_le64(mapping);
|
||||||
|
dscp2pri->dscp = app->protocol;
|
||||||
|
if (add)
|
||||||
|
dscp2pri->mask = 0x3f;
|
||||||
|
else
|
||||||
|
dscp2pri->mask = 0;
|
||||||
|
dscp2pri->pri = app->priority;
|
||||||
|
req.entry_cnt = cpu_to_le16(1);
|
||||||
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
|
if (rc)
|
||||||
|
rc = -EIO;
|
||||||
|
dma_free_coherent(&bp->pdev->dev, sizeof(*dscp2pri), dscp2pri,
|
||||||
|
mapping);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc)
|
static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc)
|
||||||
{
|
{
|
||||||
int total_ets_bw = 0;
|
int total_ets_bw = 0;
|
||||||
@ -551,15 +606,30 @@ static int bnxt_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bnxt_dcbnl_ieee_dscp_app_prep(struct bnxt *bp, struct dcb_app *app)
|
||||||
|
{
|
||||||
|
if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) {
|
||||||
|
if (!bp->max_dscp_value)
|
||||||
|
return -ENOTSUPP;
|
||||||
|
if (app->protocol > bp->max_dscp_value)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int bnxt_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
|
static int bnxt_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
|
||||||
{
|
{
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
int rc = -EINVAL;
|
int rc;
|
||||||
|
|
||||||
if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
|
if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
|
||||||
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = bnxt_dcbnl_ieee_dscp_app_prep(bp, app);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = dcb_ieee_setapp(dev, app);
|
rc = dcb_ieee_setapp(dev, app);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -570,6 +640,9 @@ static int bnxt_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
|
|||||||
app->protocol == ROCE_V2_UDP_DPORT))
|
app->protocol == ROCE_V2_UDP_DPORT))
|
||||||
rc = bnxt_hwrm_set_dcbx_app(bp, app, true);
|
rc = bnxt_hwrm_set_dcbx_app(bp, app, true);
|
||||||
|
|
||||||
|
if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
|
||||||
|
rc = bnxt_hwrm_queue_dscp2pri_cfg(bp, app, true);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,6 +655,10 @@ static int bnxt_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
|
|||||||
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = bnxt_dcbnl_ieee_dscp_app_prep(bp, app);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = dcb_ieee_delapp(dev, app);
|
rc = dcb_ieee_delapp(dev, app);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -591,6 +668,9 @@ static int bnxt_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
|
|||||||
app->protocol == ROCE_V2_UDP_DPORT))
|
app->protocol == ROCE_V2_UDP_DPORT))
|
||||||
rc = bnxt_hwrm_set_dcbx_app(bp, app, false);
|
rc = bnxt_hwrm_set_dcbx_app(bp, app, false);
|
||||||
|
|
||||||
|
if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
|
||||||
|
rc = bnxt_hwrm_queue_dscp2pri_cfg(bp, app, false);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,6 +722,7 @@ void bnxt_dcb_init(struct bnxt *bp)
|
|||||||
if (bp->hwrm_spec_code < 0x10501)
|
if (bp->hwrm_spec_code < 0x10501)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bnxt_hwrm_queue_dscp_qcaps(bp);
|
||||||
bp->dcbx_cap = DCB_CAP_DCBX_VER_IEEE;
|
bp->dcbx_cap = DCB_CAP_DCBX_VER_IEEE;
|
||||||
if (BNXT_PF(bp) && !(bp->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
|
if (BNXT_PF(bp) && !(bp->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
|
||||||
bp->dcbx_cap |= DCB_CAP_DCBX_HOST;
|
bp->dcbx_cap |= DCB_CAP_DCBX_HOST;
|
||||||
|
@ -33,6 +33,12 @@ struct bnxt_cos2bw_cfg {
|
|||||||
u8 unused;
|
u8 unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bnxt_dscp2pri_entry {
|
||||||
|
u8 dscp;
|
||||||
|
u8 mask;
|
||||||
|
u8 pri;
|
||||||
|
};
|
||||||
|
|
||||||
#define BNXT_LLQ(q_profile) \
|
#define BNXT_LLQ(q_profile) \
|
||||||
((q_profile) == \
|
((q_profile) == \
|
||||||
QUEUE_QPORTCFG_RESP_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_ROCE)
|
QUEUE_QPORTCFG_RESP_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS_ROCE)
|
||||||
|
Loading…
Reference in New Issue
Block a user