[PATCH net 5/5] net: hns3: fix init failure caused by lane_num contamination
From: Jijie Shao
Date: Wed Jun 17 2026 - 07:45:26 EST
From: Shuaisong Yang <yangshuaisong@xxxxxxxxxxxxxx>
Fix an initialization (probe) failure introduced when the driver
attempts to pre-query port settings from the firmware before link
setup.
To accurately implement the media-type differentiated autoneg
initialization (introduced in the previous patch), the driver queries
the firmware for preset autoneg configurations via
hclge_update_port_info() before invoking link setup. However, this
query also inadvertently pulls the stale 'lane_num' value from the last
active lifecycle (e.g., lane_num = 4 from a previous 100G link up state)
and overwrites the driver's runtime storage.
When the driver later tries to initialize the MAC with its default
speed (e.g., 25G, which requires 1 lane) but passes the stale
lane_num=4, the firmware rejects this invalid hardware parameter
combination (25G with 4 lanes) with -EINVAL, causing the entire driver
probe/initialization sequence to fail.
Fix this by introducing a new user-intent tracking variable
`req_lane_num`. Initialize `req_lane_num = 0` during probe, and pass it
into hclge_cfg_mac_speed_dup_hw(). According to the firmware
specification, passing a lane_num of 0 triggers the firmware's
automatic fallback mechanism to select the correct number of lanes
matching the speed, effectively neutralizing any cross-lifecycle
parameter contamination.
Fixes: 05eb60e9648c ("net: hns3: using user configure after hardware reset")
Signed-off-by: Shuaisong Yang <yangshuaisong@xxxxxxxxxxxxxx>
Signed-off-by: Jijie Shao <shaojijie@xxxxxxxxxx>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 8 +++++++-
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 853e97b0b6ff..50837d2c7998 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1577,6 +1577,11 @@ static int hclge_configure(struct hclge_dev *hdev)
hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
hdev->hw.mac.req_duplex = DUPLEX_FULL;
+ /* When lane_num is 0, the firmware will automatically
+ * select the appropriate lane_num based on the speed.
+ */
+ hdev->hw.mac.req_lane_num = 0;
+
hclge_parse_link_mode(hdev, cfg.speed_ability);
hdev->hw.mac.max_speed = hclge_get_max_speed(cfg.speed_ability);
@@ -2652,6 +2657,7 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed,
if (ret)
return ret;
+ hdev->hw.mac.req_lane_num = lane_num;
if (speed != SPEED_UNKNOWN)
hdev->hw.mac.req_speed = (u32)speed;
if (duplex != DUPLEX_UNKNOWN)
@@ -11747,7 +11753,7 @@ static int hclge_set_autoneg_speed_dup(struct hclge_dev *hdev)
if (!hdev->hw.mac.req_autoneg) {
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.req_speed,
hdev->hw.mac.req_duplex,
- hdev->hw.mac.lane_num);
+ hdev->hw.mac.req_lane_num);
if (ret)
return ret;
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 032b472d2368..4ca6458625a9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -287,6 +287,7 @@ struct hclge_mac {
u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */
u8 lane_num;
+ u8 req_lane_num;
u32 speed;
u32 req_speed;
u32 max_speed;
--
2.33.0