summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
diff options
context:
space:
mode:
authorYunsheng Lin <linyunsheng@huawei.com>2017-10-17 14:51:30 +0800
committerDavid S. Miller <davem@davemloft.net>2017-10-19 12:45:45 +0100
commit30d240dfa2e88f7941f72fac9a256358f7d55ad8 (patch)
treef7315b79a9829aa40cd52824c4585c5528b3e99d /drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
parent56fd2b2ca467f22f940282bf2c1ca4e1cb8f4c67 (diff)
net: hns3: Add mqprio hardware offload support in hns3 driver
When using tc qdisc, dcb_ops->setup_tc is used to tell hclge_dcb module to do the tm related setup. Only TC_MQPRIO_MODE_CHANNEL offload mode is supported. Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 1b30a6f966d8..5018d6633133 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -178,7 +178,8 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
u8 num_tc = 0;
int ret;
- if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+ if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+ hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
ret = hclge_ets_validate(hdev, ets, &num_tc, &map_changed);
@@ -228,7 +229,8 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
struct hclge_dev *hdev = vport->back;
u8 i, j, pfc_map, *prio_tc;
- if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+ if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+ hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
prio_tc = hdev->tm_info.prio_tc;
@@ -257,6 +259,9 @@ static u8 hclge_getdcbx(struct hnae3_handle *h)
struct hclge_vport *vport = hclge_get_vport(h);
struct hclge_dev *hdev = vport->back;
+ if (hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
+ return 0;
+
return hdev->dcbx_cap;
}
@@ -276,6 +281,43 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
return 0;
}
+/* Set up TC for hardware offloaded mqprio in channel mode */
+static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
+{
+ struct hclge_vport *vport = hclge_get_vport(h);
+ struct hclge_dev *hdev = vport->back;
+ int ret;
+
+ if (hdev->flag & HCLGE_FLAG_DCB_ENABLE)
+ return -EINVAL;
+
+ if (tc > hdev->tc_max) {
+ dev_err(&hdev->pdev->dev,
+ "setup tc failed, tc(%u) > tc_max(%u)\n",
+ tc, hdev->tc_max);
+ return -EINVAL;
+ }
+
+ hclge_tm_schd_info_update(hdev, tc);
+
+ ret = hclge_tm_prio_tc_info_update(hdev, prio_tc);
+ if (ret)
+ return ret;
+
+ ret = hclge_tm_init_hw(hdev);
+ if (ret)
+ return ret;
+
+ hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+
+ if (tc > 1)
+ hdev->flag |= HCLGE_FLAG_MQPRIO_ENABLE;
+ else
+ hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE;
+
+ return 0;
+}
+
static const struct hnae3_dcb_ops hns3_dcb_ops = {
.ieee_getets = hclge_ieee_getets,
.ieee_setets = hclge_ieee_setets,
@@ -284,6 +326,7 @@ static const struct hnae3_dcb_ops hns3_dcb_ops = {
.getdcbx = hclge_getdcbx,
.setdcbx = hclge_setdcbx,
.map_update = hclge_map_update,
+ .setup_tc = hclge_setup_tc,
};
void hclge_dcb_ops_set(struct hclge_dev *hdev)