lkml.org 
[lkml]   [2022]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] phy: aquantia: Configure SERDES mode by default
    Date
    When autonegotiation completes, the phy interface will be set based on
    the global config register for that speed. If the SERDES mode is set to
    something which the MAC does not support, then the link will not come
    up. The register reference says that the SERDES mode should default to
    XFI, but for some phys lower speeds default to XFI/2 (5G XFI). To ensure
    the link comes up correctly, configure the SERDES mode.

    We use the same configuration for all interfaces. We don't advertise
    any speeds faster than the interface mode, so they won't be selected.
    We default to pause-based rate adaptation, but enable USXGMII rate
    adaptation for USXGMII. I'm not sure if this is correct for
    SGMII; it might need USXGMII adaptation instead.

    This effectively disables switching interface mode depending on the
    speed, in favor of using rate adaptation. If this is not desired, we
    would need some kind of API to configure things.

    Signed-off-by: Sean Anderson <sean.anderson@seco.com>
    ---

    drivers/net/phy/aquantia_main.c | 65 +++++++++++++++++++++++++++++++++
    1 file changed, 65 insertions(+)

    diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
    index 47a76df36b74..88a3defb632c 100644
    --- a/drivers/net/phy/aquantia_main.c
    +++ b/drivers/net/phy/aquantia_main.c
    @@ -109,6 +109,10 @@
    #define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
    #define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
    #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
    +#define VEND1_GLOBAL_CFG_SERDES_MODE GENMASK(2, 0)
    +#define VEND1_GLOBAL_CFG_SERDES_MODE_XFI 0
    +#define VEND1_GLOBAL_CFG_SERDES_MODE_SGMII 3
    +#define VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII 4

    #define VEND1_GLOBAL_RSVD_STAT1 0xc885
    #define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
    @@ -558,6 +562,63 @@ static void aqr107_chip_info(struct phy_device *phydev)
    fw_major, fw_minor, build_id, prov_id);
    }

    +static int aqr107_global_config_init(struct phy_device *phydev)
    +{
    + u16 mask = VEND1_GLOBAL_CFG_RATE_ADAPT | VEND1_GLOBAL_CFG_SERDES_MODE;
    + u16 val, serdes_mode, rate_adapt = VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE;
    + u16 config_regs[] = {
    + VEND1_GLOBAL_CFG_10M,
    + VEND1_GLOBAL_CFG_100M,
    + VEND1_GLOBAL_CFG_1G,
    + VEND1_GLOBAL_CFG_2_5G,
    + VEND1_GLOBAL_CFG_5G,
    + VEND1_GLOBAL_CFG_10G,
    + };
    + int i, ret;
    +
    + switch (phydev->interface) {
    + case PHY_INTERFACE_MODE_SGMII:
    + case PHY_INTERFACE_MODE_1000BASEKX:
    + rate_adapt = VEND1_GLOBAL_CFG_RATE_ADAPT_USX;
    + serdes_mode = VEND1_GLOBAL_CFG_SERDES_MODE_SGMII;
    + break;
    +
    + case PHY_INTERFACE_MODE_2500BASEX:
    + serdes_mode = VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII;
    + break;
    +
    + case PHY_INTERFACE_MODE_USXGMII:
    + rate_adapt = VEND1_GLOBAL_CFG_RATE_ADAPT_USX;
    + fallthrough;
    + case PHY_INTERFACE_MODE_XGMII:
    + case PHY_INTERFACE_MODE_10GKR:
    + case PHY_INTERFACE_MODE_10GBASER:
    + case PHY_INTERFACE_MODE_XAUI:
    + case PHY_INTERFACE_MODE_RXAUI:
    + serdes_mode = VEND1_GLOBAL_CFG_SERDES_MODE_XFI;
    + break;
    +
    + default:
    + WARN_ON_ONCE(1);
    + return -EINVAL;
    + }
    +
    + val = FIELD_PREP(VEND1_GLOBAL_CFG_RATE_ADAPT, rate_adapt);
    + val |= FIELD_PREP(VEND1_GLOBAL_CFG_SERDES_MODE, serdes_mode);
    +
    + for (i = 0; i < ARRAY_SIZE(config_regs); i++) {
    + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, config_regs[i],
    + mask, val);
    + if (ret) {
    + phydev_err(phydev, "could not initialize register %x\n",
    + config_regs[i]);
    + return ret;
    + }
    + }
    +
    + return 0;
    +}
    +
    static int aqr107_config_init(struct phy_device *phydev)
    {
    int ret;
    @@ -581,6 +642,10 @@ static int aqr107_config_init(struct phy_device *phydev)
    if (!ret)
    aqr107_chip_info(phydev);

    + ret = aqr107_global_config_init(phydev);
    + if (ret)
    + return ret;
    +
    return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
    }

    --
    2.35.1.1320.gc452695387.dirty
    \
     
     \ /
      Last update: 2022-11-14 22:08    [W:3.169 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site