]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: hns3: add tm flush when setting tm
authorHao Lan <lanhao@huawei.com>
Thu, 20 Jul 2023 02:05:08 +0000 (10:05 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Sep 2023 07:47:50 +0000 (09:47 +0200)
[ Upstream commit 6d2336120aa6e1a8a64fa5d6ee5c3f3d0809fe9b ]

When the tm module is configured with traffic, traffic
may be abnormal. This patch fixes this problem.
Before the tm module is configured, traffic processing
should be stopped. After the tm module is configured,
traffic processing is enabled.

Signed-off-by: Hao Lan <lanhao@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h

index 06f29e80104c064bcde8fb607d2126974c6582f2..6df84184173d1c2247f0c36b42b7dfa15eaebf1a 100644 (file)
@@ -102,6 +102,7 @@ enum HNAE3_DEV_CAP_BITS {
        HNAE3_DEV_SUPPORT_FEC_STATS_B,
        HNAE3_DEV_SUPPORT_LANE_NUM_B,
        HNAE3_DEV_SUPPORT_WOL_B,
+       HNAE3_DEV_SUPPORT_TM_FLUSH_B,
 };
 
 #define hnae3_ae_dev_fd_supported(ae_dev) \
@@ -173,6 +174,9 @@ enum HNAE3_DEV_CAP_BITS {
 #define hnae3_ae_dev_wol_supported(ae_dev) \
        test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps)
 
+#define hnae3_ae_dev_tm_flush_supported(hdev) \
+       test_bit(HNAE3_DEV_SUPPORT_TM_FLUSH_B, (hdev)->ae_dev->caps)
+
 enum HNAE3_PF_CAP_BITS {
        HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0,
 };
index 16ba98ff2c9b1aafc8c442554ea0f7d88bf8b201..dcecb23daac6e15c240d9834c7eb29c2b8cb5d4a 100644 (file)
@@ -156,6 +156,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = {
        {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B},
        {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B},
        {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B},
+       {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B},
 };
 
 static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = {
index 18f1b4bf362da9b83f4fe9fd8d4885842ff4d7dc..2b7197ce0ae8fcae190ed04ad510faf0dd1e32d3 100644 (file)
@@ -153,6 +153,7 @@ enum hclge_opcode_type {
        HCLGE_OPC_TM_INTERNAL_STS       = 0x0850,
        HCLGE_OPC_TM_INTERNAL_CNT       = 0x0851,
        HCLGE_OPC_TM_INTERNAL_STS_1     = 0x0852,
+       HCLGE_OPC_TM_FLUSH              = 0x0872,
 
        /* Packet buffer allocate commands */
        HCLGE_OPC_TX_BUFF_ALLOC         = 0x0901,
@@ -349,6 +350,7 @@ enum HCLGE_COMM_CAP_BITS {
        HCLGE_COMM_CAP_FEC_STATS_B = 25,
        HCLGE_COMM_CAP_LANE_NUM_B = 27,
        HCLGE_COMM_CAP_WOL_B = 28,
+       HCLGE_COMM_CAP_TM_FLUSH_B = 31,
 };
 
 enum HCLGE_COMM_API_CAP_BITS {
index 207b2e3f3fc2be1dc339d9ba65dd8234a9ba680e..dce158d4aeef64aaca8b3c4e50074378cff90cff 100644 (file)
@@ -411,6 +411,9 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
        }, {
                .name = "support wake on lan",
                .cap_bit = HNAE3_DEV_SUPPORT_WOL_B,
+       }, {
+               .name = "support tm flush",
+               .cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B,
        }
 };
 
index 09362823140d58384552f77e57e4bf99ca9e03c5..fad5a5ff3cda54f5dfd4717a362d83cbac9e6358 100644 (file)
@@ -227,6 +227,10 @@ static int hclge_notify_down_uinit(struct hclge_dev *hdev)
        if (ret)
                return ret;
 
+       ret = hclge_tm_flush_cfg(hdev, true);
+       if (ret)
+               return ret;
+
        return hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
 }
 
@@ -238,6 +242,10 @@ static int hclge_notify_init_up(struct hclge_dev *hdev)
        if (ret)
                return ret;
 
+       ret = hclge_tm_flush_cfg(hdev, false);
+       if (ret)
+               return ret;
+
        return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
 }
 
@@ -324,6 +332,7 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
        struct net_device *netdev = h->kinfo.netdev;
        struct hclge_dev *hdev = vport->back;
        u8 i, j, pfc_map, *prio_tc;
+       int last_bad_ret = 0;
        int ret;
 
        if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
@@ -361,13 +370,28 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
        if (ret)
                return ret;
 
-       ret = hclge_buffer_alloc(hdev);
-       if (ret) {
-               hclge_notify_client(hdev, HNAE3_UP_CLIENT);
+       ret = hclge_tm_flush_cfg(hdev, true);
+       if (ret)
                return ret;
-       }
 
-       return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
+       /* No matter whether the following operations are performed
+        * successfully or not, disabling the tm flush and notify
+        * the network status to up are necessary.
+        * Do not return immediately.
+        */
+       ret = hclge_buffer_alloc(hdev);
+       if (ret)
+               last_bad_ret = ret;
+
+       ret = hclge_tm_flush_cfg(hdev, false);
+       if (ret)
+               last_bad_ret = ret;
+
+       ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT);
+       if (ret)
+               last_bad_ret = ret;
+
+       return last_bad_ret;
 }
 
 static int hclge_ieee_setapp(struct hnae3_handle *h, struct dcb_app *app)
index 150f146fa24fbbb4f7e7e7a71c9a0c7e87ada380..de509e5751a7c5105b06452e5e892e3025241005 100644 (file)
@@ -1485,7 +1485,11 @@ int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
                return ret;
 
        /* Cfg schd mode for each level schd */
-       return hclge_tm_schd_mode_hw(hdev);
+       ret = hclge_tm_schd_mode_hw(hdev);
+       if (ret)
+               return ret;
+
+       return hclge_tm_flush_cfg(hdev, false);
 }
 
 static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
@@ -2114,3 +2118,28 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev,
 
        return 0;
 }
+
+int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable)
+{
+       struct hclge_desc desc;
+       int ret;
+
+       if (!hnae3_ae_dev_tm_flush_supported(hdev))
+               return 0;
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_FLUSH, false);
+
+       desc.data[0] = cpu_to_le32(enable ? HCLGE_TM_FLUSH_EN_MSK : 0);
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "failed to config tm flush, ret = %d\n", ret);
+               return ret;
+       }
+
+       if (enable)
+               msleep(HCLGE_TM_FLUSH_TIME_MS);
+
+       return ret;
+}
index dd6f1fd486cf24d326c808e4d902732ca9329cf7..45dcfef3f90cca95072835bf975afb96250c6b08 100644 (file)
@@ -33,6 +33,9 @@ enum hclge_opcode_type;
 #define HCLGE_DSCP_MAP_TC_BD_NUM       2
 #define HCLGE_DSCP_TC_SHIFT(n)         (((n) & 1) * 4)
 
+#define HCLGE_TM_FLUSH_TIME_MS 10
+#define HCLGE_TM_FLUSH_EN_MSK  BIT(0)
+
 struct hclge_pg_to_pri_link_cmd {
        u8 pg_id;
        u8 rsvd1[3];
@@ -272,4 +275,5 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev,
                             struct hclge_tm_shaper_para *para);
 int hclge_up_to_tc_map(struct hclge_dev *hdev);
 int hclge_dscp_to_tc_map(struct hclge_dev *hdev);
+int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable);
 #endif