lkml.org 
[lkml]   [2021]   [Jun]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next v4 5/9] net: phy/dsa micrel/ksz886x add MDI-X support
    Date
    Add support for MDI-X status and configuration

    Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
    ---
    drivers/net/dsa/microchip/ksz8795.c | 5 ++
    drivers/net/phy/micrel.c | 88 +++++++++++++++++++++++++++++
    include/linux/micrel_phy.h | 2 +
    3 files changed, 95 insertions(+)

    diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
    index cfa2a5000cd3..690304c87b02 100644
    --- a/drivers/net/dsa/microchip/ksz8795.c
    +++ b/drivers/net/dsa/microchip/ksz8795.c
    @@ -816,6 +816,11 @@ static void ksz8_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val)
    if (data & ~LPA_SLCT)
    data |= LPA_LPACK;
    break;
    + case PHY_REG_PHY_CTRL:
    + ksz_pread8(dev, p, regs[P_LINK_STATUS], &link);
    + if (link & PORT_MDIX_STATUS)
    + data |= KSZ886X_CTRL_MDIX_STAT;
    + break;
    default:
    processed = false;
    break;
    diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
    index e462e718d68e..c421c1e7dd71 100644
    --- a/drivers/net/phy/micrel.c
    +++ b/drivers/net/phy/micrel.c
    @@ -1048,6 +1048,92 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
    return 0;
    }

    +static int ksz886x_config_mdix(struct phy_device *phydev, u8 ctrl)
    +{
    + u16 val;
    +
    + switch (ctrl) {
    + case ETH_TP_MDI:
    + val = KSZ886X_BMCR_DISABLE_AUTO_MDIX;
    + break;
    + case ETH_TP_MDI_X:
    + /* Note: The naming of the bit KSZ886X_BMCR_FORCE_MDI is bit
    + * counter intuitive, the "-X" in "1 = Force MDI" in the data
    + * sheet seems to be missing:
    + * 1 = Force MDI (sic!) (transmit on RX+/RX- pins)
    + * 0 = Normal operation (transmit on TX+/TX- pins)
    + */
    + val = KSZ886X_BMCR_DISABLE_AUTO_MDIX | KSZ886X_BMCR_FORCE_MDI;
    + break;
    + case ETH_TP_MDI_AUTO:
    + val = 0;
    + break;
    + default:
    + return 0;
    + }
    +
    + return phy_modify(phydev, MII_BMCR,
    + KSZ886X_BMCR_HP_MDIX | KSZ886X_BMCR_FORCE_MDI |
    + KSZ886X_BMCR_DISABLE_AUTO_MDIX,
    + KSZ886X_BMCR_HP_MDIX | val);
    +}
    +
    +static int ksz886x_config_aneg(struct phy_device *phydev)
    +{
    + int ret;
    +
    + ret = genphy_config_aneg(phydev);
    + if (ret)
    + return ret;
    +
    + /* The MDI-X configuration is automatically changed by the PHY after
    + * switching from autoneg off to on. So, take MDI-X configuration under
    + * own control and set it after autoneg configuration was done.
    + */
    + return ksz886x_config_mdix(phydev, phydev->mdix_ctrl);
    +}
    +
    +static int ksz886x_mdix_update(struct phy_device *phydev)
    +{
    + int ret;
    +
    + ret = phy_read(phydev, MII_BMCR);
    + if (ret < 0)
    + return ret;
    +
    + if (ret & KSZ886X_BMCR_DISABLE_AUTO_MDIX) {
    + if (ret & KSZ886X_BMCR_FORCE_MDI)
    + phydev->mdix_ctrl = ETH_TP_MDI_X;
    + else
    + phydev->mdix_ctrl = ETH_TP_MDI;
    + } else {
    + phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
    + }
    +
    + ret = phy_read(phydev, MII_KSZPHY_CTRL);
    + if (ret < 0)
    + return ret;
    +
    + /* Same reverse logic as KSZ886X_BMCR_FORCE_MDI */
    + if (ret & KSZ886X_CTRL_MDIX_STAT)
    + phydev->mdix = ETH_TP_MDI_X;
    + else
    + phydev->mdix = ETH_TP_MDI;
    +
    + return 0;
    +}
    +
    +static int ksz886x_read_status(struct phy_device *phydev)
    +{
    + int ret;
    +
    + ret = ksz886x_mdix_update(phydev);
    + if (ret < 0)
    + return ret;
    +
    + return genphy_read_status(phydev);
    +}
    +
    static int ksz886x_resume(struct phy_device *phydev)
    {
    int ret;
    @@ -1420,6 +1506,8 @@ static struct phy_driver ksphy_driver[] = {
    .name = "Micrel KSZ8851 Ethernet MAC or KSZ886X Switch",
    /* PHY_BASIC_FEATURES */
    .config_init = kszphy_config_init,
    + .config_aneg = ksz886x_config_aneg,
    + .read_status = ksz886x_read_status,
    .suspend = genphy_suspend,
    .resume = ksz886x_resume,
    }, {
    diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
    index b03e2afcb53f..58370abd9f4f 100644
    --- a/include/linux/micrel_phy.h
    +++ b/include/linux/micrel_phy.h
    @@ -58,4 +58,6 @@
    #define KSZ886X_BMCR_DISABLE_TRANSMIT BIT(1)
    #define KSZ886X_BMCR_DISABLE_LED BIT(0)

    +#define KSZ886X_CTRL_MDIX_STAT BIT(4)
    +
    #endif /* _MICREL_PHY_H */
    --
    2.29.2
    \
     
     \ /
      Last update: 2021-06-11 09:16    [W:4.449 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site