mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
net: hns3: unify copper port ksettings configuration path
Refactor hns3_set_link_ksettings() and hclge_set_phy_link_ksettings() to unify the configuration path for copper ports. Previously, netdevs with a native kernel phy attached bypassed the main MAC parameter caching logic and returned early via phy_ethtool_ksettings_set(). This prevented the driver from updating hdev->hw.mac.req_xxx variables for kernel PHY setups, leaving them out-of-sync during reset recovery. Clean this up by routing all copper port configurations through ops->set_phy_link_ksettings(), and perform driver-level or kernel-level PHY arbitration inside hclge_set_phy_link_ksettings() via hnae3_dev_phy_imp_supported(). This ensures that the user's intended link profiles (req_speed, req_duplex, req_autoneg) are uniformly recorded across all copper and fiber deployment topologies, laying the groundwork for stable reset recovery. For copper ports where neither IMP firmware nor a kernel PHY is available (e.g. PHY_INEXISTENT), hclge_set_phy_link_ksettings() returns -ENODEV. In hns3_set_link_ksettings(), this is caught so the configuration falls through to the existing MAC-level path (check_ksettings_param -> cfg_mac_speed_dup_h), preserving compatibility with PHY-less copper deployments. Signed-off-by: Shuaisong Yang <yangshuaisong@h-partners.com> Signed-off-by: Jijie Shao <shaojijie@huawei.com> Link: https://patch.msgid.link/20260624141319.271439-2-shaojijie@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
5316394b17
commit
d77e98f8b2
|
|
@ -811,12 +811,11 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
|
|||
}
|
||||
|
||||
static int hns3_check_ksettings_param(const struct net_device *netdev,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
const struct ethtool_link_ksettings *cmd,
|
||||
u8 media_type)
|
||||
{
|
||||
struct hnae3_handle *handle = hns3_get_handle(netdev);
|
||||
const struct hnae3_ae_ops *ops = hns3_get_ops(handle);
|
||||
u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN;
|
||||
u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
|
||||
u32 lane_num;
|
||||
u8 autoneg;
|
||||
u32 speed;
|
||||
|
|
@ -836,9 +835,6 @@ static int hns3_check_ksettings_param(const struct net_device *netdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ops->get_media_type)
|
||||
ops->get_media_type(handle, &media_type, &module_type);
|
||||
|
||||
if (cmd->base.duplex == DUPLEX_HALF &&
|
||||
media_type != HNAE3_MEDIA_TYPE_COPPER) {
|
||||
netdev_err(netdev,
|
||||
|
|
@ -863,6 +859,8 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
|
|||
struct hnae3_handle *handle = hns3_get_handle(netdev);
|
||||
struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(handle);
|
||||
const struct hnae3_ae_ops *ops = hns3_get_ops(handle);
|
||||
u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN;
|
||||
u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
|
||||
int ret;
|
||||
|
||||
/* Chip don't support this mode. */
|
||||
|
|
@ -878,22 +876,23 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
|
|||
cmd->base.autoneg, cmd->base.speed, cmd->base.duplex,
|
||||
cmd->lanes);
|
||||
|
||||
/* Only support ksettings_set for netdev with phy attached for now */
|
||||
if (netdev->phydev) {
|
||||
if (cmd->base.speed == SPEED_1000 &&
|
||||
cmd->base.autoneg == AUTONEG_DISABLE)
|
||||
return -EINVAL;
|
||||
if (!ops->get_media_type)
|
||||
return -EOPNOTSUPP;
|
||||
ops->get_media_type(handle, &media_type, &module_type);
|
||||
|
||||
return phy_ethtool_ksettings_set(netdev->phydev, cmd);
|
||||
} else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
|
||||
ops->set_phy_link_ksettings) {
|
||||
return ops->set_phy_link_ksettings(handle, cmd);
|
||||
if (media_type == HNAE3_MEDIA_TYPE_COPPER) {
|
||||
if (!ops->set_phy_link_ksettings)
|
||||
return -EOPNOTSUPP;
|
||||
ret = ops->set_phy_link_ksettings(handle, cmd);
|
||||
if (ret != -ENODEV)
|
||||
return ret;
|
||||
/* PHY_INEXISTENT, use MAC-level configuration */
|
||||
}
|
||||
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = hns3_check_ksettings_param(netdev, cmd);
|
||||
ret = hns3_check_ksettings_param(netdev, cmd, media_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -3285,8 +3285,8 @@ static int hclge_get_phy_link_ksettings(struct hnae3_handle *handle,
|
|||
}
|
||||
|
||||
static int
|
||||
hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
hclge_ethtool_ksettings_set(struct hnae3_handle *handle,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct hclge_desc desc[HCLGE_PHY_LINK_SETTING_BD_NUM];
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
|
|
@ -3327,10 +3327,32 @@ hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
|
|||
return ret;
|
||||
}
|
||||
|
||||
linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (hnae3_dev_phy_imp_supported(hdev)) {
|
||||
ret = hclge_ethtool_ksettings_set(handle, cmd);
|
||||
} else if (handle->netdev->phydev) {
|
||||
if (cmd->base.speed == SPEED_1000 &&
|
||||
cmd->base.autoneg == AUTONEG_DISABLE)
|
||||
return -EINVAL;
|
||||
ret = phy_ethtool_ksettings_set(handle->netdev->phydev, cmd);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hdev->hw.mac.req_autoneg = cmd->base.autoneg;
|
||||
hdev->hw.mac.req_speed = cmd->base.speed;
|
||||
hdev->hw.mac.req_duplex = cmd->base.duplex;
|
||||
linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user