net: bcmgenet: use MAC link status for fixed phy
authorDoug Berger <opendmb@gmail.com>
Tue, 28 Aug 2018 19:33:15 +0000 (12:33 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 15 Sep 2018 07:40:37 +0000 (09:40 +0200)
[ Upstream commit c3c397c1f16c51601a3fac4fe0c63ad8aa85a904 ]

When using the fixed PHY with GENET (e.g. MOCA) the PHY link
status can be determined from the internal link status captured
by the MAC. This allows the PHY state machine to use the correct
link state with the fixed PHY even if MAC link event interrupts
are missed when the net device is opened.

Fixes: 8d88c6ebb34c ("net: bcmgenet: enable MoCA link state change detection")
Signed-off-by: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c

index cef53f2d9854f4483442566d58d900e3d71cd899..ce20bc939b38530ca91d9c953fee6f2047d5ad3a 100644 (file)
@@ -185,6 +185,9 @@ struct bcmgenet_mib_counters {
 #define UMAC_MAC1                      0x010
 #define UMAC_MAX_FRAME_LEN             0x014
 
+#define UMAC_MODE                      0x44
+#define  MODE_LINK_STATUS              (1 << 5)
+
 #define UMAC_EEE_CTRL                  0x064
 #define  EN_LPI_RX_PAUSE               (1 << 0)
 #define  EN_LPI_TX_PFC                 (1 << 1)
index e96d1f95bb47cc9d53ba0c6886e6cd54801d3dd7..4c73feca4842fe62e9e39535f40c99b854345593 100644 (file)
@@ -167,8 +167,14 @@ void bcmgenet_mii_setup(struct net_device *dev)
 static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
                                          struct fixed_phy_status *status)
 {
-       if (dev && dev->phydev && status)
-               status->link = dev->phydev->link;
+       struct bcmgenet_priv *priv;
+       u32 reg;
+
+       if (dev && dev->phydev && status) {
+               priv = netdev_priv(dev);
+               reg = bcmgenet_umac_readl(priv, UMAC_MODE);
+               status->link = !!(reg & MODE_LINK_STATUS);
+       }
 
        return 0;
 }