kernel/patches/0570-net-hns3-PF-supports-to-set-and-query-lane_num-by-sy.patch
2023-11-17 14:19:46 +08:00

306 lines
10 KiB
Diff

From 032dc6157f90eabc76f47b5a655ba7c356955c37 Mon Sep 17 00:00:00 2001
From: Hao Chen <chenhao418@huawei.com>
Date: Wed, 30 Nov 2022 18:23:35 +0800
Subject: [PATCH 209/283] net: hns3: PF supports to set and query lane_num by
sysfs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
driver inclusion
category:feature
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EN49
----------------------------------------------------------------------
When serdes lane support setting 25Gb/s、50Gb/s speed and user wants to
set port speed as 50Gb/s, it can be setted as one 50Gb/s serdes lane or
two 25Gb/s serdes lanes.
So, this patch adds support to query and set lane number by sysfs
to satisfy this scenario.
Signed-off-by: Hao Chen <chenhao418@huawei.com>
Signed-off-by: Jiantao Xiao <xiaojiantao1@h-partners.com>
Reviewed-by: Yue Haibing <yuehaibing@huawei.com>
Reviewed-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
Conflicts:
drivers/net/ethernet/hisilicon/hns3/Makefile
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/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
---
drivers/net/ethernet/hisilicon/hns3/Makefile | 1 +
.../hisilicon/hns3/hns3pf/hclge_cmd.h | 7 +-
.../hisilicon/hns3/hns3pf/hclge_main.c | 24 +++--
.../hisilicon/hns3/hns3pf/hclge_main.h | 4 +-
.../hisilicon/hns3/hns3pf/hclge_sysfs.c | 91 +++++++++++++++++++
5 files changed, 118 insertions(+), 9 deletions(-)
create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c
diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile
index d0f56781b558..8a9c53f86dce 100644
--- a/drivers/net/ethernet/hisilicon/hns3/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/Makefile
@@ -36,6 +36,7 @@ HCLGE_OBJ = hns3pf/hclge_main.o \
hns3pf/hclge_mdio.o \
hns3pf/hclge_debugfs.o \
hns3pf/hclge_tm.o \
+ hns3pf/hclge_sysfs.o \
hns3pf/hclge_mbx.o \
hns3pf/hclge_err.o \
hns3pf/hclge_ptp.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index a4599f717da5..38b82f87ec76 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -671,7 +671,9 @@ struct hclge_config_mac_speed_dup_cmd {
#define HCLGE_CFG_MAC_SPEED_CHANGE_EN_B 0
u8 mac_change_fec_en;
- u8 rsv[22];
+ u8 rsv[4];
+ u8 lane_num;
+ u8 rsv1[17];
};
#define HCLGE_RING_ID_MASK GENMASK(9, 0)
@@ -699,7 +701,8 @@ struct hclge_sfp_info_cmd {
__le32 speed_ability; /* speed ability for current media */
__le32 module_type;
u8 fec_ability;
- u8 rsv[7];
+ u8 lane_num;
+ u8 rsv[6];
};
struct hclge_port_fault_cmd {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 68158219e8c6..898c724a53b8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2631,7 +2631,7 @@ static u8 hclge_check_speed_dup(u8 duplex, int speed)
}
int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed,
- u8 duplex)
+ u8 duplex, u8 lane_num)
{
struct hclge_config_mac_speed_dup_cmd *req;
struct hclge_desc desc;
@@ -2688,6 +2688,7 @@ int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed,
hnae3_set_bit(req->mac_change_fec_en, HCLGE_CFG_MAC_SPEED_CHANGE_EN_B,
1);
+ req->lane_num = lane_num;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
@@ -2709,7 +2710,7 @@ int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex)
mac->duplex == duplex)
return 0;
- ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex);
+ ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex, 0);
if (ret)
return ret;
@@ -2874,7 +2875,8 @@ static int hclge_mac_init(struct hclge_dev *hdev)
hdev->support_sfp_query = true;
hdev->hw.mac.duplex = HCLGE_MAC_FULL;
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
- hdev->hw.mac.duplex);
+ hdev->hw.mac.duplex,
+ hdev->hw.mac.lane_num);
if (ret)
return ret;
@@ -3202,6 +3204,7 @@ static int hclge_get_sfp_info(struct hclge_dev *hdev, struct hclge_mac *mac)
mac->autoneg = resp->autoneg;
mac->support_autoneg = resp->autoneg_ability;
mac->speed_type = QUERY_ACTIVE_SPEED;
+ mac->lane_num = resp->lane_num;
if (!resp->active_fec)
mac->fec_mode = 0;
else
@@ -7592,7 +7595,7 @@ static int hclge_set_phy_loopback(struct hclge_dev *hdev, bool en)
}
duplex = en ? DUPLEX_FULL : hdev->hw.mac.duplex;
- ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, duplex);
+ ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, duplex, hdev->hw.mac.lane_num);
if (ret)
return ret;
@@ -11470,13 +11473,19 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
goto err_mdiobus_unreg;
}
+ ret = hclge_register_sysfs(hdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register sysfs, ret = %d\n", ret);
+ goto err_mdiobus_unreg;
+ }
+
ret = hclge_ptp_init(hdev);
if (ret)
- goto err_mdiobus_unreg;
+ goto err_sysfs_unregister;
ret = hclge_update_port_info(hdev);
if (ret)
- goto err_mdiobus_unreg;
+ goto err_sysfs_unregister;
INIT_KFIFO(hdev->mac_tnl_log);
@@ -11529,6 +11538,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return 0;
+err_sysfs_unregister:
+ hclge_unregister_sysfs(hdev);
err_mdiobus_unreg:
if (hdev->hw.mac.phydev)
mdiobus_unregister(hdev->hw.mac.mdio_bus);
@@ -11912,6 +11923,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
struct hclge_dev *hdev = ae_dev->priv;
struct hclge_mac *mac = &hdev->hw.mac;
+ hclge_unregister_sysfs(hdev);
hclge_reset_vf_rate(hdev);
hclge_clear_vf_vlan(hdev);
hclge_misc_affinity_teardown(hdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index c2fcbf658bfa..df2b56b83084 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -296,6 +296,7 @@ struct hclge_mac {
u8 duplex_last;
u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */
+ u8 lane_num;
u32 speed;
u32 max_speed;
u32 speed_ability; /* speed ability supported by current media */
@@ -1168,7 +1169,6 @@ int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
int hclge_mac_update_stats(struct hclge_dev *hdev);
int hclge_register_sysfs(struct hclge_dev *hdev);
void hclge_unregister_sysfs(struct hclge_dev *hdev);
-int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, u8 duplex);
int hclge_get_wol_supported_mode(struct hclge_dev *hdev, u32 *wol_supported);
int hclge_get_wol_cfg(struct hclge_dev *hdev, u32 *mode);
struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf);
@@ -1177,4 +1177,6 @@ void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle);
void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type,
u8 *module_type);
int hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable);
+int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, u8 duplex,
+ u8 lane_num);
#endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c
new file mode 100644
index 000000000000..b7cc89c3f6d8
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_sysfs.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+
+#include "hnae3.h"
+#include "hclge_main.h"
+
+static ssize_t lane_num_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
+ struct hclge_dev *hdev = ae_dev->priv;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", hdev->hw.mac.lane_num);
+}
+
+static ssize_t lane_num_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+#define HCLGE_CONVERSION_NUM 10 /* Convert string to decimal number */
+
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
+ struct hclge_dev *hdev = ae_dev->priv;
+ u8 lane_num, duplex;
+ u32 speed;
+ int ret;
+
+ ret = kstrtou8(buf, HCLGE_CONVERSION_NUM, &lane_num);
+ if (ret) {
+ dev_err(dev, "input params of lane number format unmatch.\n");
+ return -EINVAL;
+ }
+
+ if (!lane_num || lane_num > 8 || !is_power_of_2(lane_num)) {
+ dev_err(dev, "lane number only supports setting 1, 2, 4, 8.\n");
+ return -EINVAL;
+ }
+
+ rtnl_lock();
+
+ if (hdev->hw.mac.support_autoneg && hdev->hw.mac.autoneg) {
+ ret = count;
+ goto out;
+ }
+
+ if (lane_num == hdev->hw.mac.lane_num) {
+ dev_info(dev, "setting lane number not changed.\n");
+ ret = count;
+ goto out;
+ }
+
+ speed = hdev->hw.mac.speed;
+ duplex = hdev->hw.mac.duplex;
+
+ ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex, lane_num);
+ if (!ret)
+ ret = count;
+
+out:
+ rtnl_unlock();
+ return ret;
+}
+
+static DEVICE_ATTR_RW(lane_num);
+
+static const struct device_attribute *hclge_hw_attrs_list[] = {
+ &dev_attr_lane_num,
+};
+
+int hclge_register_sysfs(struct hclge_dev *hdev)
+{
+ int ret;
+
+ if (!hnae3_ae_dev_lane_num_supported(hdev->ae_dev))
+ return 0;
+
+ ret = device_create_file(&hdev->pdev->dev, hclge_hw_attrs_list[0]);
+ if (ret)
+ dev_err(&hdev->pdev->dev,
+ "failed to create node %s, ret = %d.\n",
+ hclge_hw_attrs_list[0]->attr.name, ret);
+
+ return ret;
+}
+
+void hclge_unregister_sysfs(struct hclge_dev *hdev)
+{
+ device_remove_file(&hdev->pdev->dev, hclge_hw_attrs_list[0]);
+}
--
2.34.1