ftgmac100: Cleanup speed/duplex tracking and fix duplex config
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 5 Apr 2017 02:28:45 +0000 (12:28 +1000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 Apr 2017 19:38:04 +0000 (12:38 -0700)
Keep track of both the current speed and duplex settings
instead of only speed and properly apply the duplex setting
to the HW.

This reworks the adjust_link() function to also avoid trying
to reconfigure the HW when there is no link and to display
the link state to the user.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/faraday/ftgmac100.c

index 283edb1a7f7aff1d682a6adf38a306797831459d..69daf2a50573ccb84bb877b48872d42eeea63f7a 100644 (file)
@@ -79,7 +79,8 @@ struct ftgmac100 {
        struct mii_bus *mii_bus;
 
        /* Link management */
-       int old_speed;
+       int cur_speed;
+       int cur_duplex;
        bool use_ncsi;
 
        /* Misc */
@@ -212,16 +213,15 @@ static void ftgmac100_init_hw(struct ftgmac100 *priv)
                                 FTGMAC100_MACCR_RXDMA_EN       | \
                                 FTGMAC100_MACCR_TXMAC_EN       | \
                                 FTGMAC100_MACCR_RXMAC_EN       | \
-                                FTGMAC100_MACCR_FULLDUP        | \
                                 FTGMAC100_MACCR_CRC_APD        | \
                                 FTGMAC100_MACCR_RX_RUNT        | \
                                 FTGMAC100_MACCR_RX_BROADPKT)
 
-static void ftgmac100_start_hw(struct ftgmac100 *priv, int speed)
+static void ftgmac100_start_hw(struct ftgmac100 *priv)
 {
        int maccr = MACCR_ENABLE_ALL;
 
-       switch (speed) {
+       switch (priv->cur_speed) {
        default:
        case 10:
                break;
@@ -235,6 +235,9 @@ static void ftgmac100_start_hw(struct ftgmac100 *priv, int speed)
                break;
        }
 
+       if (priv->cur_duplex == DUPLEX_FULL)
+               maccr |= FTGMAC100_MACCR_FULLDUP;
+
        iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR);
 }
 
@@ -854,12 +857,31 @@ static void ftgmac100_adjust_link(struct net_device *netdev)
 {
        struct ftgmac100 *priv = netdev_priv(netdev);
        struct phy_device *phydev = netdev->phydev;
+       int new_speed;
        int ier;
 
-       if (phydev->speed == priv->old_speed)
+       /* We store "no link" as speed 0 */
+       if (!phydev->link)
+               new_speed = 0;
+       else
+               new_speed = phydev->speed;
+
+       if (phydev->speed == priv->cur_speed &&
+           phydev->duplex == priv->cur_duplex)
                return;
 
-       priv->old_speed = phydev->speed;
+       /* Print status if we have a link or we had one and just lost it,
+        * don't print otherwise.
+        */
+       if (new_speed || priv->cur_speed)
+               phy_print_status(phydev);
+
+       priv->cur_speed = new_speed;
+       priv->cur_duplex = phydev->duplex;
+
+       /* Link is down, do nothing else */
+       if (!new_speed)
+               return;
 
        ier = ioread32(priv->base + FTGMAC100_OFFSET_IER);
 
@@ -871,7 +893,7 @@ static void ftgmac100_adjust_link(struct net_device *netdev)
 
        netif_start_queue(netdev);
        ftgmac100_init_hw(priv);
-       ftgmac100_start_hw(priv, phydev->speed);
+       ftgmac100_start_hw(priv);
 
        /* re-enable interrupts */
        iowrite32(ier, priv->base + FTGMAC100_OFFSET_IER);
@@ -1091,6 +1113,20 @@ static int ftgmac100_open(struct net_device *netdev)
                goto err_irq;
        }
 
+       /* When using NC-SI we force the speed to 100Mbit/s full duplex,
+        *
+        * Otherwise we leave it set to 0 (no link), the link
+        * message from the PHY layer will handle setting it up to
+        * something else if needed.
+        */
+       if (priv->use_ncsi) {
+               priv->cur_duplex = DUPLEX_FULL;
+               priv->cur_speed = SPEED_100;
+       } else {
+               priv->cur_duplex = 0;
+               priv->cur_speed = 0;
+       }
+
        priv->rx_pointer = 0;
        priv->tx_clean_pointer = 0;
        priv->tx_pointer = 0;
@@ -1101,7 +1137,7 @@ static int ftgmac100_open(struct net_device *netdev)
                goto err_hw;
 
        ftgmac100_init_hw(priv);
-       ftgmac100_start_hw(priv, priv->use_ncsi ? 100 : 10);
+       ftgmac100_start_hw(priv);
 
        /* Clear stale interrupts */
        status = ioread32(priv->base + FTGMAC100_OFFSET_ISR);