Preparing the phylink conversion, split the adjust_link callbaclk, by clearly separating the mac configuration, link_up and link_down phases.
Reviewed-by: Andrew Lunn <and...@lunn.ch> Signed-off-by: Maxime Chevallier <maxime.chevall...@bootlin.com> --- V3: No changes drivers/net/ethernet/freescale/ucc_geth.c | 180 +++++++++++----------- 1 file changed, 93 insertions(+), 87 deletions(-) diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index b023a1a1dc5c..bf9f5901b405 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -1548,105 +1548,111 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) __netdev_watchdog_up(ugeth->ndev); } -/* Called every time the controller might need to be made - * aware of new link state. The PHY code conveys this - * information through variables in the ugeth structure, and this - * function converts those variables into the appropriate - * register values, and can bring down the device if needed. - */ - -static void adjust_link(struct net_device *dev) +static void ugeth_link_up(struct ucc_geth_private *ugeth, + struct phy_device *phy, + phy_interface_t interface, int speed, int duplex) { - struct ucc_geth_private *ugeth = netdev_priv(dev); - struct ucc_geth __iomem *ug_regs; - struct ucc_fast __iomem *uf_regs; - struct phy_device *phydev = ugeth->phydev; + struct ucc_geth __iomem *ug_regs = ugeth->ug_regs; + struct ucc_fast __iomem *uf_regs = ugeth->uccf->uf_regs; + u32 tempval = in_be32(&ug_regs->maccfg2); + u32 upsmr = in_be32(&uf_regs->upsmr); int new_state = 0; - ug_regs = ugeth->ug_regs; - uf_regs = ugeth->uccf->uf_regs; - - if (phydev->link) { - u32 tempval = in_be32(&ug_regs->maccfg2); - u32 upsmr = in_be32(&uf_regs->upsmr); - /* Now we make sure that we can be in full duplex mode. - * If not, we operate in half-duplex mode. */ - if (phydev->duplex != ugeth->oldduplex) { - new_state = 1; - if (!(phydev->duplex)) - tempval &= ~(MACCFG2_FDX); - else - tempval |= MACCFG2_FDX; - ugeth->oldduplex = phydev->duplex; - } + /* Now we make sure that we can be in full duplex mode. + * If not, we operate in half-duplex mode. + */ + if (duplex != ugeth->oldduplex) { + new_state = 1; + if (duplex == DUPLEX_HALF) + tempval &= ~(MACCFG2_FDX); + else + tempval |= MACCFG2_FDX; + ugeth->oldduplex = duplex; + } - if (phydev->speed != ugeth->oldspeed) { - new_state = 1; - switch (phydev->speed) { - case SPEED_1000: - tempval = ((tempval & - ~(MACCFG2_INTERFACE_MODE_MASK)) | - MACCFG2_INTERFACE_MODE_BYTE); - break; - case SPEED_100: - case SPEED_10: - tempval = ((tempval & - ~(MACCFG2_INTERFACE_MODE_MASK)) | - MACCFG2_INTERFACE_MODE_NIBBLE); - /* if reduced mode, re-set UPSMR.R10M */ - if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) || - (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) || - (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) || - (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) || - (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) || - (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { - if (phydev->speed == SPEED_10) - upsmr |= UCC_GETH_UPSMR_R10M; - else - upsmr &= ~UCC_GETH_UPSMR_R10M; - } - break; - default: - if (netif_msg_link(ugeth)) - pr_warn( - "%s: Ack! Speed (%d) is not 10/100/1000!", - dev->name, phydev->speed); - break; + if (speed != ugeth->oldspeed) { + new_state = 1; + switch (speed) { + case SPEED_1000: + tempval = ((tempval & + ~(MACCFG2_INTERFACE_MODE_MASK)) | + MACCFG2_INTERFACE_MODE_BYTE); + break; + case SPEED_100: + case SPEED_10: + tempval = ((tempval & + ~(MACCFG2_INTERFACE_MODE_MASK)) | + MACCFG2_INTERFACE_MODE_NIBBLE); + /* if reduced mode, re-set UPSMR.R10M */ + if (interface == PHY_INTERFACE_MODE_RMII || + phy_interface_mode_is_rgmii(interface) || + interface == PHY_INTERFACE_MODE_RTBI) { + if (speed == SPEED_10) + upsmr |= UCC_GETH_UPSMR_R10M; + else + upsmr &= ~UCC_GETH_UPSMR_R10M; } - ugeth->oldspeed = phydev->speed; + break; + default: + if (netif_msg_link(ugeth)) + pr_warn("%s: Speed (%d) is not 10/100/1000!", + netdev_name(ugeth->ndev), speed); + break; } + ugeth->oldspeed = speed; + } - if (!ugeth->oldlink) { - new_state = 1; - ugeth->oldlink = 1; - } + if (!ugeth->oldlink) { + new_state = 1; + ugeth->oldlink = 1; + } - if (new_state) { - /* - * To change the MAC configuration we need to disable - * the controller. To do so, we have to either grab - * ugeth->lock, which is a bad idea since 'graceful - * stop' commands might take quite a while, or we can - * quiesce driver's activity. - */ - ugeth_quiesce(ugeth); - ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + if (new_state) { + /* + * To change the MAC configuration we need to disable + * the controller. To do so, we have to either grab + * ugeth->lock, which is a bad idea since 'graceful + * stop' commands might take quite a while, or we can + * quiesce driver's activity. + */ + ugeth_quiesce(ugeth); + ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - out_be32(&ug_regs->maccfg2, tempval); - out_be32(&uf_regs->upsmr, upsmr); + out_be32(&ug_regs->maccfg2, tempval); + out_be32(&uf_regs->upsmr, upsmr); - ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); - ugeth_activate(ugeth); - } - } else if (ugeth->oldlink) { - new_state = 1; - ugeth->oldlink = 0; - ugeth->oldspeed = 0; - ugeth->oldduplex = -1; + ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); + ugeth_activate(ugeth); } - if (new_state && netif_msg_link(ugeth)) - phy_print_status(phydev); + if (netif_msg_link(ugeth)) + phy_print_status(phy); +} + +static void ugeth_link_down(struct ucc_geth_private *ugeth) +{ + ugeth->oldlink = 0; + ugeth->oldspeed = 0; + ugeth->oldduplex = -1; +} + +/* Called every time the controller might need to be made + * aware of new link state. The PHY code conveys this + * information through variables in the ugeth structure, and this + * function converts those variables into the appropriate + * register values, and can bring down the device if needed. + */ + +static void adjust_link(struct net_device *dev) +{ + struct ucc_geth_private *ugeth = netdev_priv(dev); + struct phy_device *phydev = ugeth->phydev; + + if (phydev->link) + ugeth_link_up(ugeth, phydev, phydev->interface, + phydev->speed, phydev->duplex); + else + ugeth_link_down(ugeth); } /* Initialize TBI PHY interface for communicating with the -- 2.47.0