OSDN Git Service

net: hns3: add statistics for PFC frames and MAC control frames
authorliuzhongzhu <liuzhongzhu@huawei.com>
Tue, 22 Jan 2019 23:39:37 +0000 (07:39 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Jan 2019 19:13:02 +0000 (11:13 -0800)
In the old firmware version, statistics acquisition of
PFC frames and MAC control frames is not supported.
Add command retrieves statistics for PFC frames and
MAC control frames from the firmware.

Signed-off-by: liuzhongzhu <liuzhongzhu@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

index b0ee070..81dbe1b 100644 (file)
@@ -170,8 +170,12 @@ static bool hclge_is_special_opcode(u16 opcode)
        /* these commands have several descriptors,
         * and use the first one to save opcode and return value
         */
-       u16 spec_opcode[3] = {HCLGE_OPC_STATS_64_BIT,
-               HCLGE_OPC_STATS_32_BIT, HCLGE_OPC_STATS_MAC};
+       u16 spec_opcode[] = {HCLGE_OPC_STATS_64_BIT,
+                            HCLGE_OPC_STATS_32_BIT,
+                            HCLGE_OPC_STATS_MAC,
+                            HCLGE_OPC_STATS_MAC_ALL,
+                            HCLGE_OPC_QUERY_32_BIT_REG,
+                            HCLGE_OPC_QUERY_64_BIT_REG};
        int i;
 
        for (i = 0; i < ARRAY_SIZE(spec_opcode); i++) {
@@ -259,6 +263,8 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
 
                        if (desc_ret == HCLGE_CMD_EXEC_SUCCESS)
                                retval = 0;
+                       else if (desc_ret == HCLGE_CMD_NO_AUTH)
+                               retval = -EPERM;
                        else if (desc_ret == HCLGE_CMD_NOT_SUPPORTED)
                                retval = -EOPNOTSUPP;
                        else
index 9f07279..e26a251 100644 (file)
@@ -82,6 +82,8 @@ enum hclge_opcode_type {
        HCLGE_OPC_STATS_64_BIT          = 0x0030,
        HCLGE_OPC_STATS_32_BIT          = 0x0031,
        HCLGE_OPC_STATS_MAC             = 0x0032,
+       HCLGE_OPC_QUERY_MAC_REG_NUM     = 0x0033,
+       HCLGE_OPC_STATS_MAC_ALL         = 0x0034,
 
        HCLGE_OPC_QUERY_REG_NUM         = 0x0040,
        HCLGE_OPC_QUERY_32_BIT_REG      = 0x0041,
index 6fb3144..64b1589 100644 (file)
@@ -118,6 +118,12 @@ static const struct hclge_comm_stats_str g_mac_stats_string[] = {
                HCLGE_MAC_STATS_FIELD_OFF(mac_tx_mac_pause_num)},
        {"mac_rx_mac_pause_num",
                HCLGE_MAC_STATS_FIELD_OFF(mac_rx_mac_pause_num)},
+       {"mac_tx_control_pkt_num",
+               HCLGE_MAC_STATS_FIELD_OFF(mac_tx_ctrl_pkt_num)},
+       {"mac_rx_control_pkt_num",
+               HCLGE_MAC_STATS_FIELD_OFF(mac_rx_ctrl_pkt_num)},
+       {"mac_tx_pfc_pkt_num",
+               HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pause_pkt_num)},
        {"mac_tx_pfc_pri0_pkt_num",
                HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri0_pkt_num)},
        {"mac_tx_pfc_pri1_pkt_num",
@@ -134,6 +140,8 @@ static const struct hclge_comm_stats_str g_mac_stats_string[] = {
                HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri6_pkt_num)},
        {"mac_tx_pfc_pri7_pkt_num",
                HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri7_pkt_num)},
+       {"mac_rx_pfc_pkt_num",
+               HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pause_pkt_num)},
        {"mac_rx_pfc_pri0_pkt_num",
                HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri0_pkt_num)},
        {"mac_rx_pfc_pri1_pkt_num",
@@ -287,10 +295,9 @@ static const struct hclge_mac_mgr_tbl_entry_cmd hclge_mgr_table[] = {
        },
 };
 
-static int hclge_mac_update_stats(struct hclge_dev *hdev)
+static int hclge_mac_update_stats_defective(struct hclge_dev *hdev)
 {
 #define HCLGE_MAC_CMD_NUM 21
-#define HCLGE_RTN_DATA_NUM 4
 
        u64 *data = (u64 *)(&hdev->hw_stats.mac_stats);
        struct hclge_desc desc[HCLGE_MAC_CMD_NUM];
@@ -308,22 +315,102 @@ static int hclge_mac_update_stats(struct hclge_dev *hdev)
        }
 
        for (i = 0; i < HCLGE_MAC_CMD_NUM; i++) {
+               /* for special opcode 0032, only the first desc has the head */
                if (unlikely(i == 0)) {
                        desc_data = (__le64 *)(&desc[i].data[0]);
-                       n = HCLGE_RTN_DATA_NUM - 2;
+                       n = HCLGE_RD_FIRST_STATS_NUM;
                } else {
                        desc_data = (__le64 *)(&desc[i]);
-                       n = HCLGE_RTN_DATA_NUM;
+                       n = HCLGE_RD_OTHER_STATS_NUM;
                }
+
+               for (k = 0; k < n; k++) {
+                       *data += le64_to_cpu(*desc_data);
+                       data++;
+                       desc_data++;
+               }
+       }
+
+       return 0;
+}
+
+static int hclge_mac_update_stats_complete(struct hclge_dev *hdev, u32 desc_num)
+{
+       u64 *data = (u64 *)(&hdev->hw_stats.mac_stats);
+       struct hclge_desc *desc;
+       __le64 *desc_data;
+       u16 i, k, n;
+       int ret;
+
+       desc = kcalloc(desc_num, sizeof(struct hclge_desc), GFP_KERNEL);
+       hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_STATS_MAC_ALL, true);
+       ret = hclge_cmd_send(&hdev->hw, desc, desc_num);
+       if (ret) {
+               kfree(desc);
+               return ret;
+       }
+
+       for (i = 0; i < desc_num; i++) {
+               /* for special opcode 0034, only the first desc has the head */
+               if (i == 0) {
+                       desc_data = (__le64 *)(&desc[i].data[0]);
+                       n = HCLGE_RD_FIRST_STATS_NUM;
+               } else {
+                       desc_data = (__le64 *)(&desc[i]);
+                       n = HCLGE_RD_OTHER_STATS_NUM;
+               }
+
                for (k = 0; k < n; k++) {
-                       *data++ += le64_to_cpu(*desc_data);
+                       *data += le64_to_cpu(*desc_data);
+                       data++;
                        desc_data++;
                }
        }
 
+       kfree(desc);
+
        return 0;
 }
 
+static int hclge_mac_query_reg_num(struct hclge_dev *hdev, u32 *desc_num)
+{
+       struct hclge_desc desc;
+       __le32 *desc_data;
+       u32 reg_num;
+       int ret;
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_MAC_REG_NUM, true);
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret)
+               return ret;
+
+       desc_data = (__le32 *)(&desc.data[0]);
+       reg_num = le32_to_cpu(*desc_data);
+
+       *desc_num = 1 + ((reg_num - 3) >> 2) +
+                   (u32)(((reg_num - 3) & 0x3) ? 1 : 0);
+
+       return 0;
+}
+
+static int hclge_mac_update_stats(struct hclge_dev *hdev)
+{
+       u32 desc_num;
+       int ret;
+
+       ret = hclge_mac_query_reg_num(hdev, &desc_num);
+
+       /* The firmware supports the new statistics acquisition method */
+       if (!ret)
+               ret = hclge_mac_update_stats_complete(hdev, desc_num);
+       else if (ret == -EOPNOTSUPP)
+               ret = hclge_mac_update_stats_defective(hdev);
+       else
+               dev_err(&hdev->pdev->dev, "query mac reg num fail!\n");
+
+       return ret;
+}
+
 static int hclge_tqps_update_stats(struct hnae3_handle *handle)
 {
        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
index 279ed2d..b5a38fc 100644 (file)
@@ -16,6 +16,9 @@
 
 #define HCLGE_MAX_PF_NUM               8
 
+#define HCLGE_RD_FIRST_STATS_NUM        2
+#define HCLGE_RD_OTHER_STATS_NUM        4
+
 #define HCLGE_INVALID_VPORT 0xffff
 
 #define HCLGE_PF_CFG_BLOCK_SIZE                32
@@ -415,6 +418,10 @@ struct hclge_mac_stats {
        u64 mac_rx_fcs_err_pkt_num;
        u64 mac_rx_send_app_good_pkt_num;
        u64 mac_rx_send_app_bad_pkt_num;
+       u64 mac_tx_pfc_pause_pkt_num;
+       u64 mac_rx_pfc_pause_pkt_num;
+       u64 mac_tx_ctrl_pkt_num;
+       u64 mac_rx_ctrl_pkt_num;
 };
 
 #define HCLGE_STATS_TIMER_INTERVAL     (60 * 5)