From 8e732f1c6f2dc5e18f766d0f1b11df9db2dd044a Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 14 Dec 2023 01:44:31 +0100 Subject: [PATCH 1/2] net: phy: at803x: move specific qca808x config_aneg to dedicated function Move specific qca808x config_aneg to dedicated function to permit easier split of qca808x portion from at803x driver. Signed-off-by: Christian Marangi Signed-off-by: David S. Miller --- drivers/net/phy/at803x.c | 68 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index b9d3a26cf6dc..03f945cc7626 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -1045,9 +1045,8 @@ static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); } -static int at803x_config_aneg(struct phy_device *phydev) +static int at803x_prepare_config_aneg(struct phy_device *phydev) { - struct at803x_priv *priv = phydev->priv; int ret; ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); @@ -1064,33 +1063,22 @@ static int at803x_config_aneg(struct phy_device *phydev) return ret; } + return 0; +} + +static int at803x_config_aneg(struct phy_device *phydev) +{ + struct at803x_priv *priv = phydev->priv; + int ret; + + ret = at803x_prepare_config_aneg(phydev); + if (ret) + return ret; + if (priv->is_1000basex) return genphy_c37_config_aneg(phydev); - /* Do not restart auto-negotiation by setting ret to 0 defautly, - * when calling __genphy_config_aneg later. - */ - ret = 0; - - if (phydev->drv->phy_id == QCA8081_PHY_ID) { - int phy_ctrl = 0; - - /* The reg MII_BMCR also needs to be configured for force mode, the - * genphy_config_aneg is also needed. - */ - if (phydev->autoneg == AUTONEG_DISABLE) - genphy_c45_pma_setup_forced(phydev); - - if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) - phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; - - ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); - if (ret < 0) - return ret; - } - - return __genphy_config_aneg(phydev, ret); + return genphy_config_aneg(phydev); } static int at803x_get_downshift(struct phy_device *phydev, u8 *d) @@ -2118,6 +2106,32 @@ static int qca808x_get_features(struct phy_device *phydev) return 0; } +static int qca808x_config_aneg(struct phy_device *phydev) +{ + int phy_ctrl = 0; + int ret; + + ret = at803x_prepare_config_aneg(phydev); + if (ret) + return ret; + + /* The reg MII_BMCR also needs to be configured for force mode, the + * genphy_config_aneg is also needed. + */ + if (phydev->autoneg == AUTONEG_DISABLE) + genphy_c45_pma_setup_forced(phydev); + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) + phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; + + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); + if (ret < 0) + return ret; + + return __genphy_config_aneg(phydev, ret); +} + static void qca808x_link_change_notify(struct phy_device *phydev) { /* Assert interface sgmii fifo on link down, deassert it on link up, @@ -2295,7 +2309,7 @@ static struct phy_driver at803x_driver[] = { .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, .get_features = qca808x_get_features, - .config_aneg = at803x_config_aneg, + .config_aneg = qca808x_config_aneg, .suspend = genphy_suspend, .resume = genphy_resume, .read_status = qca808x_read_status, From 38eb804e8458ba181a03a0498ce4bf84eebd1931 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 14 Dec 2023 01:44:32 +0100 Subject: [PATCH 2/2] net: phy: at803x: make read specific status function more generic Rework read specific status function to be more generic. The function apply different speed mask based on the PHY ID. Make it more generic by adding an additional arg to pass the specific speed (ss) mask and use the provided mask to parse the speed value. This is needed to permit an easier deatch of qca808x code from the at803x driver. Signed-off-by: Christian Marangi Signed-off-by: David S. Miller --- drivers/net/phy/at803x.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 03f945cc7626..a7d28848ee93 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -301,6 +301,11 @@ static struct at803x_hw_stat qca83xx_hw_stats[] = { { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, }; +struct at803x_ss_mask { + u16 speed_mask; + u8 speed_shift; +}; + struct at803x_priv { int flags; u16 clk_25m_reg; @@ -921,7 +926,8 @@ static void at803x_link_change_notify(struct phy_device *phydev) } } -static int at803x_read_specific_status(struct phy_device *phydev) +static int at803x_read_specific_status(struct phy_device *phydev, + struct at803x_ss_mask ss_mask) { int ss; @@ -940,11 +946,8 @@ static int at803x_read_specific_status(struct phy_device *phydev) if (sfc < 0) return sfc; - /* qca8081 takes the different bits for speed value from at803x */ - if (phydev->drv->phy_id == QCA8081_PHY_ID) - speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss); - else - speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss); + speed = ss & ss_mask.speed_mask; + speed >>= ss_mask.speed_shift; switch (speed) { case AT803X_SS_SPEED_10: @@ -989,6 +992,7 @@ static int at803x_read_specific_status(struct phy_device *phydev) static int at803x_read_status(struct phy_device *phydev) { struct at803x_priv *priv = phydev->priv; + struct at803x_ss_mask ss_mask = { 0 }; int err, old_link = phydev->link; if (priv->is_1000basex) @@ -1012,7 +1016,9 @@ static int at803x_read_status(struct phy_device *phydev) if (err < 0) return err; - err = at803x_read_specific_status(phydev); + ss_mask.speed_mask = AT803X_SS_SPEED_MASK; + ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); + err = at803x_read_specific_status(phydev, ss_mask); if (err < 0) return err; @@ -1869,6 +1875,7 @@ static int qca808x_config_init(struct phy_device *phydev) static int qca808x_read_status(struct phy_device *phydev) { + struct at803x_ss_mask ss_mask = { 0 }; int ret; ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); @@ -1882,7 +1889,10 @@ static int qca808x_read_status(struct phy_device *phydev) if (ret) return ret; - ret = at803x_read_specific_status(phydev); + /* qca8081 takes the different bits for speed value from at803x */ + ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; + ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); + ret = at803x_read_specific_status(phydev, ss_mask); if (ret < 0) return ret;