]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: hns3: fix pfc packet number incorrect after querying pfc parameters
authorJie Wang <wangjie125@huawei.com>
Wed, 10 Nov 2021 13:42:51 +0000 (21:42 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Nov 2021 10:04:43 +0000 (11:04 +0100)
[ Upstream commit 0b653a81a26d66ffe526a54c2177e24fb1400301 ]

Currently, driver will send command to firmware to query pfc packet number
when user uses dcb tool to get pfc parameters. However, the periodic
service task will also periodically query and record MAC statistics,
including pfc packet number.

As the hardware registers of statistics is cleared after reading, it will
cause pfc packet number of MAC statistics are not correct after using dcb
tool to get pfc parameters.

To fix this problem, when user uses dcb tool to get pfc parameters, driver
updates MAC statistics firstly and then get pfc packet number from MAC
statistics.

Fixes: 64fd2300fcc1 ("net: hns3: add support for querying pfc puase packets statistic")
Signed-off-by: Jie Wang <wangjie125@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h

index c60d0626062cfc683d74beb4e4c303e070585030..64cc019cb67cafcd1e1b9139083ffeab9de06e21 100644 (file)
@@ -265,28 +265,24 @@ err_out:
 
 static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
 {
-       u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC];
        struct hclge_vport *vport = hclge_get_vport(h);
        struct hclge_dev *hdev = vport->back;
        int ret;
-       u8 i;
 
        memset(pfc, 0, sizeof(*pfc));
        pfc->pfc_cap = hdev->pfc_max;
        pfc->pfc_en = hdev->tm_info.pfc_en;
 
-       ret = hclge_pfc_tx_stats_get(hdev, requests);
-       if (ret)
+       ret = hclge_mac_update_stats(hdev);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "failed to update MAC stats, ret = %d.\n", ret);
                return ret;
+       }
 
-       ret = hclge_pfc_rx_stats_get(hdev, indications);
-       if (ret)
-               return ret;
+       hclge_pfc_tx_stats_get(hdev, pfc->requests);
+       hclge_pfc_rx_stats_get(hdev, pfc->indications);
 
-       for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-               pfc->requests[i] = requests[i];
-               pfc->indications[i] = indications[i];
-       }
        return 0;
 }
 
index 494af494fc5b17b9aacacdfb8beea6e6f11b801f..a066b9f5ba11c27bbff93c49d5a5200884341146 100644 (file)
@@ -25,8 +25,6 @@
 #include "hnae3.h"
 
 #define HCLGE_NAME                     "hclge"
-#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset)))
-#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
 
 #define HCLGE_BUF_SIZE_UNIT    256U
 #define HCLGE_BUF_MUL_BY       2
@@ -547,7 +545,7 @@ static int hclge_mac_query_reg_num(struct hclge_dev *hdev, u32 *desc_num)
        return 0;
 }
 
-static int hclge_mac_update_stats(struct hclge_dev *hdev)
+int hclge_mac_update_stats(struct hclge_dev *hdev)
 {
        u32 desc_num;
        int ret;
index 29d916055c657f9214192c6597178f56fe17d57e..3a4d04884cd34d064e651ede765a493be0c2b861 100644 (file)
@@ -822,6 +822,9 @@ struct hclge_vf_vlan_cfg {
                (y) = (_k_ ^ ~_v_) & (_k_); \
        } while (0)
 
+#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
+#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset)))
+
 #define HCLGE_MAC_TNL_LOG_SIZE 8
 #define HCLGE_VPORT_NUM 256
 struct hclge_dev {
@@ -1128,4 +1131,5 @@ void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
 int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len);
 int hclge_push_vf_link_status(struct hclge_vport *vport);
 int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
+int hclge_mac_update_stats(struct hclge_dev *hdev);
 #endif
index 124791e4bfeed70794c9e570fff38cf6703299e4..5ff2c98a5542750f997c276bfcf490d2d476f153 100644 (file)
@@ -113,50 +113,50 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
        return 0;
 }
 
-static int hclge_pfc_stats_get(struct hclge_dev *hdev,
-                              enum hclge_opcode_type opcode, u64 *stats)
-{
-       struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM];
-       int ret, i, j;
-
-       if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT ||
-             opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT))
-               return -EINVAL;
-
-       for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1; i++) {
-               hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
-               desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
-       }
-
-       hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
+static const u16 hclge_pfc_tx_stats_offset[] = {
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri0_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri1_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri2_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri3_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri4_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri5_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri6_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri7_pkt_num)
+};
 
-       ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM);
-       if (ret)
-               return ret;
+static const u16 hclge_pfc_rx_stats_offset[] = {
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri0_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri1_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri2_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri3_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri4_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri5_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri6_pkt_num),
+       HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri7_pkt_num)
+};
 
-       for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
-               struct hclge_pfc_stats_cmd *pfc_stats =
-                               (struct hclge_pfc_stats_cmd *)desc[i].data;
+static void hclge_pfc_stats_get(struct hclge_dev *hdev, bool tx, u64 *stats)
+{
+       const u16 *offset;
+       int i;
 
-               for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) {
-                       u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j;
+       if (tx)
+               offset = hclge_pfc_tx_stats_offset;
+       else
+               offset = hclge_pfc_rx_stats_offset;
 
-                       if (index < HCLGE_MAX_TC_NUM)
-                               stats[index] =
-                                       le64_to_cpu(pfc_stats->pkt_num[j]);
-               }
-       }
-       return 0;
+       for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
+               stats[i] = HCLGE_STATS_READ(&hdev->mac_stats, offset[i]);
 }
 
-int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
+void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
 {
-       return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats);
+       hclge_pfc_stats_get(hdev, false, stats);
 }
 
-int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
+void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
 {
-       return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats);
+       hclge_pfc_stats_get(hdev, true, stats);
 }
 
 int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
index 4b2c3a7889800286d3556e75c05ea6808b306f45..72563cd0d1e2696ea38cb51408d2476074f1e261 100644 (file)
@@ -228,8 +228,8 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
 int hclge_tm_init_hw(struct hclge_dev *hdev, bool init);
 int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
 int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
-int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
-int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
+void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
+void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
 int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate);
 int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num);
 int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num);