]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
ethernet: eqos: fix EQOS controller timeout error
authorBhadram Varka <vbhadram@nvidia.com>
Tue, 17 Jan 2017 08:37:57 +0000 (14:07 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Wed, 1 Feb 2017 14:03:38 +0000 (06:03 -0800)
This will fix timeout error in below code path -

[14037.072191] [<ffffffc000304128>] ioread32+0x8c/0x98
[14037.077058] [<ffffffc00070be70>] read_phy_regs+0xe8/0x14c
[14037.082443] [<ffffffc000718684>] eqos_mdio_read+0x24/0x4c
[14037.087826] [<ffffffc000718e78>] eqos_phy_read_mmd_indirect+0x28/0x38
[14037.094249] [<ffffffc000718ffc>] eqos_eee_init+0xa8/0x1d8
[14037.099633] [<ffffffc0007184c0>] eqos_adjust_link+0x1a8/0x2f8
[14037.105365] [<ffffffc000538e2c>] phy_state_machine+0x118/0x450
[14037.111186] [<ffffffc0000b6ee8>] process_one_work+0x154/0x414
[14037.116920] [<ffffffc0000b79f8>] worker_thread+0x13c/0x474
[14037.122390] [<ffffffc0000bc238>] kthread+0xf8/0x110

Issue: While stopping the EQOS there is a chance of accessing
PHY registers through the worker thread by phy_state_machine.

Fix:Stop the PHY first before anything else in EQOS stop

Bug 200236154

Change-Id: I5defcf4954657c95082299460655db3415ba077a
Signed-off-by: Bhadram Varka <vbhadram@nvidia.com>
Reviewed-on: http://git-master/r/1286594
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Narayan Reddy <narayanr@nvidia.com>
Reviewed-by: Vijay Mishra <vijaym@nvidia.com>
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
drivers/net/ethernet/nvidia/eqos/drv.c

index edb436ff0ee15c3c9d5daefa6449f47d7260f0e1..ce34fad437e1dd6728102b538ebc33be2a73bf47 100644 (file)
@@ -5762,6 +5762,17 @@ void eqos_stop_dev(struct eqos_prv_data *pdata)
        tegra_unregister_hwtime_source();
 #endif
 
+       if (pdata->phydev && pdata->phydev->drv &&
+           pdata->phydev->drv->low_power_mode) {
+               pdata->phydev->drv->low_power_mode(pdata->phydev, true);
+               if (!pdata->suspended)
+                       phy_stop_interrupts(pdata->phydev);
+       } else if (pdata->phydev) {
+               /* stop the PHY */
+               phy_stop(pdata->phydev);
+               gpio_set_value(pdata->phy_reset_gpio, 0);
+       }
+
        /* turn off sources of data into dev */
        netif_tx_disable(pdata->dev);
 
@@ -5784,17 +5795,6 @@ void eqos_stop_dev(struct eqos_prv_data *pdata)
        /* disable MAC TX */
        hw_if->stop_mac_tx();
 
-       if (pdata->phydev && pdata->phydev->drv &&
-           pdata->phydev->drv->low_power_mode) {
-               pdata->phydev->drv->low_power_mode(pdata->phydev, true);
-               if (!pdata->suspended)
-                       phy_stop_interrupts(pdata->phydev);
-       } else if (pdata->phydev) {
-               /* stop the PHY */
-               phy_stop(pdata->phydev);
-               gpio_set_value(pdata->phy_reset_gpio, 0);
-       }
-
        /* stop DMA RX */
        eqos_stop_all_ch_rx_dma(pdata);