aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2014-02-18 08:49:04 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-18 16:40:01 -0500
commitaa66a5f1af163b6c90fca5a06c7fdab121b70cd2 (patch)
treeb4f4481d7b3c1120d0ee3c69b2aad2aa4801853c
parentf0cbe0ac87c123a80dac3b2df72ecb947ef63ad8 (diff)
r8152: combine PHY reset with set_speed
PHY reset is necessary after some hw settings. However, it would cause the linking down, and so does the set_speed function. Combine the PHY reset with set_speed function. That could reduce the frequency of linking down and accessing the PHY register. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/r8152.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7bae3920038..b3155da97f09 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -436,6 +436,7 @@ enum rtl8152_flags {
436 RTL8152_SET_RX_MODE, 436 RTL8152_SET_RX_MODE,
437 WORK_ENABLE, 437 WORK_ENABLE,
438 RTL8152_LINK_CHG, 438 RTL8152_LINK_CHG,
439 PHY_RESET,
439}; 440};
440 441
441/* Define these values to match your device */ 442/* Define these values to match your device */
@@ -1796,6 +1797,29 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
1796 1797
1797} 1798}
1798 1799
1800static void rtl_phy_reset(struct r8152 *tp)
1801{
1802 u16 data;
1803 int i;
1804
1805 clear_bit(PHY_RESET, &tp->flags);
1806
1807 data = r8152_mdio_read(tp, MII_BMCR);
1808
1809 /* don't reset again before the previous one complete */
1810 if (data & BMCR_RESET)
1811 return;
1812
1813 data |= BMCR_RESET;
1814 r8152_mdio_write(tp, MII_BMCR, data);
1815
1816 for (i = 0; i < 50; i++) {
1817 msleep(20);
1818 if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
1819 break;
1820 }
1821}
1822
1799static void rtl_clear_bp(struct r8152 *tp) 1823static void rtl_clear_bp(struct r8152 *tp)
1800{ 1824{
1801 ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0); 1825 ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
@@ -1854,6 +1878,7 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
1854 } 1878 }
1855 1879
1856 r8152b_disable_aldps(tp); 1880 r8152b_disable_aldps(tp);
1881 set_bit(PHY_RESET, &tp->flags);
1857} 1882}
1858 1883
1859static void r8152b_exit_oob(struct r8152 *tp) 1884static void r8152b_exit_oob(struct r8152 *tp)
@@ -2042,6 +2067,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
2042 data = sram_read(tp, SRAM_10M_AMP2); 2067 data = sram_read(tp, SRAM_10M_AMP2);
2043 data |= AMP_DN; 2068 data |= AMP_DN;
2044 sram_write(tp, SRAM_10M_AMP2, data); 2069 sram_write(tp, SRAM_10M_AMP2, data);
2070
2071 set_bit(PHY_RESET, &tp->flags);
2045} 2072}
2046 2073
2047static void r8153_u1u2en(struct r8152 *tp, bool enable) 2074static void r8153_u1u2en(struct r8152 *tp, bool enable)
@@ -2295,12 +2322,26 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
2295 bmcr = BMCR_ANENABLE | BMCR_ANRESTART; 2322 bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
2296 } 2323 }
2297 2324
2325 if (test_bit(PHY_RESET, &tp->flags))
2326 bmcr |= BMCR_RESET;
2327
2298 if (tp->mii.supports_gmii) 2328 if (tp->mii.supports_gmii)
2299 r8152_mdio_write(tp, MII_CTRL1000, gbcr); 2329 r8152_mdio_write(tp, MII_CTRL1000, gbcr);
2300 2330
2301 r8152_mdio_write(tp, MII_ADVERTISE, anar); 2331 r8152_mdio_write(tp, MII_ADVERTISE, anar);
2302 r8152_mdio_write(tp, MII_BMCR, bmcr); 2332 r8152_mdio_write(tp, MII_BMCR, bmcr);
2303 2333
2334 if (test_bit(PHY_RESET, &tp->flags)) {
2335 int i;
2336
2337 clear_bit(PHY_RESET, &tp->flags);
2338 for (i = 0; i < 50; i++) {
2339 msleep(20);
2340 if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
2341 break;
2342 }
2343 }
2344
2304out: 2345out:
2305 2346
2306 return ret; 2347 return ret;
@@ -2364,6 +2405,10 @@ static void rtl_work_func_t(struct work_struct *work)
2364 if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) 2405 if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
2365 _rtl8152_set_rx_mode(tp->netdev); 2406 _rtl8152_set_rx_mode(tp->netdev);
2366 2407
2408
2409 if (test_bit(PHY_RESET, &tp->flags))
2410 rtl_phy_reset(tp);
2411
2367out1: 2412out1:
2368 return; 2413 return;
2369} 2414}
@@ -2459,7 +2504,6 @@ static void r8152b_enable_fc(struct r8152 *tp)
2459static void r8152b_init(struct r8152 *tp) 2504static void r8152b_init(struct r8152 *tp)
2460{ 2505{
2461 u32 ocp_data; 2506 u32 ocp_data;
2462 int i;
2463 2507
2464 rtl_clear_bp(tp); 2508 rtl_clear_bp(tp);
2465 2509
@@ -2491,14 +2535,6 @@ static void r8152b_init(struct r8152 *tp)
2491 r8152b_enable_aldps(tp); 2535 r8152b_enable_aldps(tp);
2492 r8152b_enable_fc(tp); 2536 r8152b_enable_fc(tp);
2493 2537
2494 r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
2495 BMCR_ANRESTART);
2496 for (i = 0; i < 100; i++) {
2497 udelay(100);
2498 if (!(r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET))
2499 break;
2500 }
2501
2502 /* enable rx aggregation */ 2538 /* enable rx aggregation */
2503 ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); 2539 ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
2504 ocp_data &= ~RX_AGG_DISABLE; 2540 ocp_data &= ~RX_AGG_DISABLE;
@@ -2569,9 +2605,6 @@ static void r8153_init(struct r8152 *tp)
2569 r8153_enable_eee(tp); 2605 r8153_enable_eee(tp);
2570 r8153_enable_aldps(tp); 2606 r8153_enable_aldps(tp);
2571 r8152b_enable_fc(tp); 2607 r8152b_enable_fc(tp);
2572
2573 r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
2574 BMCR_ANRESTART);
2575} 2608}
2576 2609
2577static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) 2610static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)