amd-xgbe: Clear all state during a device restart
authorLendacky, Thomas <Thomas.Lendacky@amd.com>
Fri, 16 Jan 2015 18:46:45 +0000 (12:46 -0600)
committerDavid S. Miller <davem@davemloft.net>
Sat, 17 Jan 2015 03:24:20 +0000 (22:24 -0500)
When performing a device restart, like during an MTU change, sometimes
the device queues still have data and get hung up trying to flush
resulting in the device becoming unresponsive until brought down and
back up. To prevent this, always perform a device reset during a
restart.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-main.c

index 53f5f66ec2ee43fe5533697860f70d49a458b919..e424997afc55566607fa6b9783b3b163c3a63c40 100644 (file)
@@ -2107,6 +2107,23 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
        XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
 }
 
+static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata)
+{
+       switch (pdata->phy_speed) {
+       case SPEED_10000:
+               xgbe_set_xgmii_speed(pdata);
+               break;
+
+       case SPEED_2500:
+               xgbe_set_gmii_2500_speed(pdata);
+               break;
+
+       case SPEED_1000:
+               xgbe_set_gmii_speed(pdata);
+               break;
+       }
+}
+
 static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
 {
        if (pdata->netdev->features & NETIF_F_RXCSUM)
@@ -2757,6 +2774,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
        xgbe_config_mac_address(pdata);
        xgbe_config_jumbo_enable(pdata);
        xgbe_config_flow_control(pdata);
+       xgbe_config_mac_speed(pdata);
        xgbe_config_checksum_offload(pdata);
        xgbe_config_vlan_support(pdata);
        xgbe_config_mmc(pdata);
index e2e921768185476795e407bf23d766a1a2edd2b7..bdb373c87050c555df40899f9bcfefc99865cea5 100644 (file)
@@ -927,7 +927,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
        DBGPR("<--xgbe_stop\n");
 }
 
-static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset)
+static void xgbe_restart_dev(struct xgbe_prv_data *pdata)
 {
        struct xgbe_channel *channel;
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
@@ -950,9 +950,8 @@ static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset)
        xgbe_free_tx_data(pdata);
        xgbe_free_rx_data(pdata);
 
-       /* Issue software reset to device if requested */
-       if (reset)
-               hw_if->exit(pdata);
+       /* Issue software reset to device */
+       hw_if->exit(pdata);
 
        xgbe_start(pdata);
 
@@ -967,7 +966,7 @@ static void xgbe_restart(struct work_struct *work)
 
        rtnl_lock();
 
-       xgbe_restart_dev(pdata, 1);
+       xgbe_restart_dev(pdata);
 
        rtnl_unlock();
 }
@@ -1587,7 +1586,7 @@ static int xgbe_change_mtu(struct net_device *netdev, int mtu)
        pdata->rx_buf_size = ret;
        netdev->mtu = mtu;
 
-       xgbe_restart_dev(pdata, 0);
+       xgbe_restart_dev(pdata);
 
        DBGPR("<--xgbe_change_mtu\n");
 
index dbd3850b8b0a8f61053026a887e5a90f7a3aef53..a50dccd67de72f5f7e276b524237541cd7d759e3 100644 (file)
@@ -148,6 +148,7 @@ static void xgbe_default_config(struct xgbe_prv_data *pdata)
        pdata->pause_autoneg = 1;
        pdata->tx_pause = 1;
        pdata->rx_pause = 1;
+       pdata->phy_speed = SPEED_UNKNOWN;
        pdata->power_down = 0;
        pdata->default_autoneg = AUTONEG_ENABLE;
        pdata->default_speed = SPEED_10000;