]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: hns3: add support to query scc version by devlink info
authorHao Chen <chenhao418@huawei.com>
Wed, 10 Apr 2024 12:53:54 +0000 (20:53 +0800)
committerJakub Kicinski <kuba@kernel.org>
Sat, 13 Apr 2024 01:58:46 +0000 (18:58 -0700)
Add support to query scc version by devlink info for device V3.

Signed-off-by: Hao Chen <chenhao418@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Link: https://lore.kernel.org/r/20240410125354.2177067-5-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/devlink/hns3.rst
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

index 4562a6e4782f9d2583be2bb418294bf222e33cee..72bc1b9f3785deb8c78a744e85967e30fc082602 100644 (file)
@@ -23,3 +23,8 @@ The ``hns3`` driver reports the following versions
    * - ``fw``
      - running
      - Used to represent the firmware version.
+   * - ``fw.scc``
+     - running
+     - Used to represent the Soft Congestion Control (SSC) firmware version.
+       SCC is a firmware component which provides multiple RDMA congestion
+       control algorithms, including DCQCN.
index e9266c65b331b95c3338338cc5fb74d6d3e37505..7c2c8bea4c065708911b6b16e79b622f21f4d1a8 100644 (file)
@@ -366,6 +366,15 @@ struct hnae3_vector_info {
 #define HNAE3_FW_VERSION_BYTE0_SHIFT   0
 #define HNAE3_FW_VERSION_BYTE0_MASK    GENMASK(7, 0)
 
+#define HNAE3_SCC_VERSION_BYTE3_SHIFT  24
+#define HNAE3_SCC_VERSION_BYTE3_MASK   GENMASK(31, 24)
+#define HNAE3_SCC_VERSION_BYTE2_SHIFT  16
+#define HNAE3_SCC_VERSION_BYTE2_MASK   GENMASK(23, 16)
+#define HNAE3_SCC_VERSION_BYTE1_SHIFT  8
+#define HNAE3_SCC_VERSION_BYTE1_MASK   GENMASK(15, 8)
+#define HNAE3_SCC_VERSION_BYTE0_SHIFT  0
+#define HNAE3_SCC_VERSION_BYTE0_MASK   GENMASK(7, 0)
+
 struct hnae3_ring_chain_node {
        struct hnae3_ring_chain_node *next;
        u32 tqp_index;
index a2bc5a9adaa3868cf48df2172c723080241da081..2c2a2f1e0d7a662b57384496962b75cee939858c 100644 (file)
@@ -247,6 +247,9 @@ enum hclge_opcode_type {
        HCLGE_OPC_QCN_AJUST_INIT        = 0x1A07,
        HCLGE_OPC_QCN_DFX_CNT_STATUS    = 0x1A08,
 
+       /* SCC commands */
+       HCLGE_OPC_QUERY_SCC_VER         = 0x1A84,
+
        /* Mailbox command */
        HCLGEVF_OPC_MBX_PF_TO_VF        = 0x2000,
        HCLGEVF_OPC_MBX_VF_TO_PF        = 0x2001,
@@ -394,6 +397,11 @@ struct hclge_comm_query_version_cmd {
        __le32 caps[HCLGE_COMM_QUERY_CAP_LENGTH]; /* capabilities of device */
 };
 
+struct hclge_comm_query_scc_cmd {
+       __le32 scc_version;
+       u8 rsv[20];
+};
+
 #define HCLGE_DESC_DATA_LEN            6
 struct hclge_desc {
        __le16 opcode;
index 9a939c0b217f717746924af4f651e384e2f0035a..a1571c1086788b434f19363b095ce00baa71cae9 100644 (file)
@@ -5,6 +5,34 @@
 
 #include "hclge_devlink.h"
 
+static int hclge_devlink_scc_info_get(struct devlink *devlink,
+                                     struct devlink_info_req *req)
+{
+       struct hclge_devlink_priv *priv = devlink_priv(devlink);
+       char scc_version[HCLGE_DEVLINK_FW_SCC_LEN];
+       struct hclge_dev *hdev = priv->hdev;
+       u32 scc_version_tmp;
+       int ret;
+
+       ret = hclge_query_scc_version(hdev, &scc_version_tmp);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "failed to get scc version, ret = %d\n", ret);
+               return ret;
+       }
+
+       snprintf(scc_version, sizeof(scc_version), "%lu.%lu.%lu.%lu",
+                hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE3_MASK,
+                                HNAE3_FW_VERSION_BYTE3_SHIFT),
+                hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE2_MASK,
+                                HNAE3_FW_VERSION_BYTE2_SHIFT),
+                hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE1_MASK,
+                                HNAE3_FW_VERSION_BYTE1_SHIFT),
+                hnae3_get_field(scc_version_tmp, HNAE3_SCC_VERSION_BYTE0_MASK,
+                                HNAE3_FW_VERSION_BYTE0_SHIFT));
+       return devlink_info_version_running_put(req, "fw.scc", scc_version);
+}
+
 static int hclge_devlink_info_get(struct devlink *devlink,
                                  struct devlink_info_req *req,
                                  struct netlink_ext_ack *extack)
@@ -13,6 +41,7 @@ static int hclge_devlink_info_get(struct devlink *devlink,
        struct hclge_devlink_priv *priv = devlink_priv(devlink);
        char version_str[HCLGE_DEVLINK_FW_STRING_LEN];
        struct hclge_dev *hdev = priv->hdev;
+       int ret;
 
        snprintf(version_str, sizeof(version_str), "%lu.%lu.%lu.%lu",
                 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE3_MASK,
@@ -24,9 +53,18 @@ static int hclge_devlink_info_get(struct devlink *devlink,
                 hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
                                 HNAE3_FW_VERSION_BYTE0_SHIFT));
 
-       return devlink_info_version_running_put(req,
-                                               DEVLINK_INFO_VERSION_GENERIC_FW,
-                                               version_str);
+       ret = devlink_info_version_running_put(req,
+                                              DEVLINK_INFO_VERSION_GENERIC_FW,
+                                              version_str);
+       if (ret) {
+               dev_err(&hdev->pdev->dev, "failed to set running version of fw\n");
+               return ret;
+       }
+
+       if (hdev->pdev->revision > HNAE3_DEVICE_VERSION_V2)
+               ret = hclge_devlink_scc_info_get(devlink, req);
+
+       return ret;
 }
 
 static int hclge_devlink_reload_down(struct devlink *devlink, bool netns_change,
index 918be04507a59b38b63cf9d003b6a75b102df53c..148effa5ea897217949c0abf09e3ecd672e21304 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "hclge_main.h"
 
+#define        HCLGE_DEVLINK_FW_SCC_LEN        32
+
 struct hclge_devlink_priv {
        struct hclge_dev *hdev;
 };
index eb31a7e9c8fc8c6a8809db26658820e386c56938..28336cf171704aac56cbf39138a302621fdc6737 100644 (file)
@@ -10883,6 +10883,24 @@ static u32 hclge_get_fw_version(struct hnae3_handle *handle)
        return hdev->fw_version;
 }
 
+int hclge_query_scc_version(struct hclge_dev *hdev, u32 *scc_version)
+{
+       struct hclge_comm_query_scc_cmd *resp;
+       struct hclge_desc desc;
+       int ret;
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_SCC_VER, 1);
+       resp = (struct hclge_comm_query_scc_cmd *)desc.data;
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret)
+               return ret;
+
+       *scc_version = le32_to_cpu(resp->scc_version);
+
+       return 0;
+}
+
 static void hclge_set_flowctrl_adv(struct hclge_dev *hdev, u32 rx_en, u32 tx_en)
 {
        struct phy_device *phydev = hdev->hw.mac.phydev;
index e821dd2f15289012651bb5a4d0ac5cfb6cfbec3a..df3c10098349904af904f22c5c493814bf402e1c 100644 (file)
@@ -1169,4 +1169,5 @@ int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
 int hclge_mac_update_stats(struct hclge_dev *hdev);
 struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf);
 int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type);
+int hclge_query_scc_version(struct hclge_dev *hdev, u32 *scc_version);
 #endif