lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 835/917] net: hns3: fix pfc packet number incorrect after querying pfc parameters
    Date
    From: Jie Wang <wangjie125@huawei.com>

    [ 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>
    ---
    .../hisilicon/hns3/hns3pf/hclge_dcb.c | 18 ++---
    .../hisilicon/hns3/hns3pf/hclge_main.c | 4 +-
    .../hisilicon/hns3/hns3pf/hclge_main.h | 4 ++
    .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 68 +++++++++----------
    .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 4 +-
    5 files changed, 48 insertions(+), 50 deletions(-)

    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
    index 91cb578f56b80..90013c131e949 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
    @@ -286,28 +286,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;
    }

    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    index ffd85cd297ef3..66c407d0d507e 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    @@ -26,8 +26,6 @@
    #include "hclge_devlink.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
    @@ -548,7 +546,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;
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
    index 9111b8c84d786..2fa6e14c96e5b 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
    @@ -824,6 +824,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 {
    @@ -1136,4 +1139,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
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    index 95074e91a8466..a50e2edbf4a0f 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    @@ -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)
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    index 2ee9b795f71dc..1db7f40b45255 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    @@ -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);
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-11-16 01:01    [W:2.319 / U:0.212 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site