net: hns: fix the wrong speed for bond
authorQianqian Xie <xieqianqian@huawei.com>
Tue, 21 Jun 2016 03:56:29 +0000 (11:56 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 21 Jun 2016 08:51:55 +0000 (04:51 -0400)
For debug-ports,there are two non-synchronized processes:
Speed-Auto-Negotiation and Link-Update-Status. The two
processes are towed by two different state machines.
Bond reads the speed when link up, but the speed maybe
not update the right value at that time.That make for bond's
wrong speed. Thus only one state machine should be used and
if phy_state_machine is used, it does not need to do
hns_nic_update_link_status().

Signed-off-by: Qianqian Xie <xieqianqian@huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c

index 00e529f2f153674df7f95e6d4253d50c6040e57b..cef9d12f0d7ddcc409f3cbbd95975ecef96dbc94 100644 (file)
@@ -991,8 +991,26 @@ static void hns_nic_adjust_link(struct net_device *ndev)
 {
        struct hns_nic_priv *priv = netdev_priv(ndev);
        struct hnae_handle *h = priv->ae_handle;
+       int state = 1;
+
+       if (priv->phy) {
+               h->dev->ops->adjust_link(h, ndev->phydev->speed,
+                                        ndev->phydev->duplex);
+               state = priv->phy->link;
+       }
+       state = state && h->dev->ops->get_status(h);
 
-       h->dev->ops->adjust_link(h, ndev->phydev->speed, ndev->phydev->duplex);
+       if (state != priv->link) {
+               if (state) {
+                       netif_carrier_on(ndev);
+                       netif_tx_wake_all_queues(ndev);
+                       netdev_info(ndev, "link up\n");
+               } else {
+                       netif_carrier_off(ndev);
+                       netdev_info(ndev, "link down\n");
+               }
+               priv->link = state;
+       }
 }
 
 /**
@@ -1577,27 +1595,14 @@ static void hns_nic_update_link_status(struct net_device *netdev)
        struct hns_nic_priv *priv = netdev_priv(netdev);
 
        struct hnae_handle *h = priv->ae_handle;
-       int state = 1;
 
-       if (priv->phy) {
-               if (!genphy_update_link(priv->phy))
-                       state = priv->phy->link;
-               else
-                       state = 0;
-       }
-       state = state && h->dev->ops->get_status(h);
+       if (h->phy_dev) {
+               if (h->phy_if != PHY_INTERFACE_MODE_XGMII)
+                       return;
 
-       if (state != priv->link) {
-               if (state) {
-                       netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
-                       netdev_info(netdev, "link up\n");
-               } else {
-                       netif_carrier_off(netdev);
-                       netdev_info(netdev, "link down\n");
-               }
-               priv->link = state;
+               (void)genphy_read_status(h->phy_dev);
        }
+       hns_nic_adjust_link(netdev);
 }
 
 /* for dumping key regs*/
index 5b3dccb327751ebd7c08444702e97fd89d8595fb..564ae1ec6aa8813bfd9a96a78fb5d234690f640c 100644 (file)
@@ -49,7 +49,7 @@ static u32 hns_nic_get_link(struct net_device *net_dev)
        h = priv->ae_handle;
 
        if (priv->phy) {
-               if (!genphy_update_link(priv->phy))
+               if (!genphy_read_status(priv->phy))
                        link_stat = priv->phy->link;
                else
                        link_stat = 0;