summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/r8152_shield.c
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2014-02-18 08:49:06 -0500
committerVladislav Zhurba <vzhurba@nvidia.com>2018-02-01 16:57:59 -0500
commit43510815800dac7be81a8899c6f339062ed72425 (patch)
tree329325b7c76f85e969c35fe1f27b62bf6288f1e8 /drivers/net/usb/r8152_shield.c
parentac120ff51aa6c15d0f1ca334b40762fdb6bb9b5f (diff)
r8152: support WOL
Support WOL for RTL8152 and RTL8153. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Preetham Chandru R <pchandru@nvidia.com> (cherry picked from commit 21ff2e8976b1be23eb0125ee83eb807ad40fb226) Conflicts: drivers/net/usb/r8152_shield.c Change-Id: Ia33c2ee113e7150c372c82d85becb811950b26f2 Reviewed-on: http://git-master/r/370022 Tested-by: Aly Hirani <ahirani@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Diffstat (limited to 'drivers/net/usb/r8152_shield.c')
-rw-r--r--drivers/net/usb/r8152_shield.c118
1 files changed, 105 insertions, 13 deletions
diff --git a/drivers/net/usb/r8152_shield.c b/drivers/net/usb/r8152_shield.c
index f2bf71f5c..237e8edb6 100644
--- a/drivers/net/usb/r8152_shield.c
+++ b/drivers/net/usb/r8152_shield.c
@@ -24,7 +24,7 @@
24#include <linux/ipv6.h> 24#include <linux/ipv6.h>
25 25
26/* Version Information */ 26/* Version Information */
27#define DRIVER_VERSION "v1.03.0 (2013/12/26)" 27#define DRIVER_VERSION "v1.05.0 (2014/02/18)"
28#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>" 28#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
29#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" 29#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
30#define MODULENAME "r8152" 30#define MODULENAME "r8152"
@@ -63,6 +63,8 @@
63#define PLA_RSTTELLY 0xe800 63#define PLA_RSTTELLY 0xe800
64#define PLA_CR 0xe813 64#define PLA_CR 0xe813
65#define PLA_CRWECR 0xe81c 65#define PLA_CRWECR 0xe81c
66#define PLA_CONFIG12 0xe81e /* CONFIG1, CONFIG2 */
67#define PLA_CONFIG34 0xe820 /* CONFIG3, CONFIG4 */
66#define PLA_CONFIG5 0xe822 68#define PLA_CONFIG5 0xe822
67#define PLA_PHY_PWR 0xe84c 69#define PLA_PHY_PWR 0xe84c
68#define PLA_OOB_CTRL 0xe84f 70#define PLA_OOB_CTRL 0xe84f
@@ -217,7 +219,14 @@
217/* PAL_BDC_CR */ 219/* PAL_BDC_CR */
218#define ALDPS_PROXY_MODE 0x0001 220#define ALDPS_PROXY_MODE 0x0001
219 221
222/* PLA_CONFIG34 */
223#define LINK_ON_WAKE_EN 0x0010
224#define LINK_OFF_WAKE_EN 0x0008
225
220/* PLA_CONFIG5 */ 226/* PLA_CONFIG5 */
227#define BWF_EN 0x0040
228#define MWF_EN 0x0020
229#define UWF_EN 0x0010
221#define LAN_WAKE_EN 0x0002 230#define LAN_WAKE_EN 0x0002
222 231
223/* PLA_LED_FEATURE */ 232/* PLA_LED_FEATURE */
@@ -519,6 +528,7 @@ struct r8152 {
519 } rtl_ops; 528 } rtl_ops;
520 529
521 int intr_interval; 530 int intr_interval;
531 u32 saved_wolopts;
522 u32 msg_enable; 532 u32 msg_enable;
523 u32 tx_qlen; 533 u32 tx_qlen;
524 u16 ocp_base; 534 u16 ocp_base;
@@ -1796,6 +1806,74 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
1796 1806
1797} 1807}
1798 1808
1809#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
1810
1811static u32 __rtl_get_wol(struct r8152 *tp)
1812{
1813 u32 ocp_data;
1814 u32 wolopts = 0;
1815
1816 ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5);
1817 if (!(ocp_data & LAN_WAKE_EN))
1818 return 0;
1819
1820 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
1821 if (ocp_data & LINK_ON_WAKE_EN)
1822 wolopts |= WAKE_PHY;
1823
1824 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
1825 if (ocp_data & UWF_EN)
1826 wolopts |= WAKE_UCAST;
1827 if (ocp_data & BWF_EN)
1828 wolopts |= WAKE_BCAST;
1829 if (ocp_data & MWF_EN)
1830 wolopts |= WAKE_MCAST;
1831
1832 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
1833 if (ocp_data & MAGIC_EN)
1834 wolopts |= WAKE_MAGIC;
1835
1836 return wolopts;
1837}
1838
1839static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
1840{
1841 u32 ocp_data;
1842
1843 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
1844
1845 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
1846 ocp_data &= ~LINK_ON_WAKE_EN;
1847 if (wolopts & WAKE_PHY)
1848 ocp_data |= LINK_ON_WAKE_EN;
1849 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data);
1850
1851 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
1852 ocp_data &= ~(UWF_EN | BWF_EN | MWF_EN | LAN_WAKE_EN);
1853 if (wolopts & WAKE_UCAST)
1854 ocp_data |= UWF_EN;
1855 if (wolopts & WAKE_BCAST)
1856 ocp_data |= BWF_EN;
1857 if (wolopts & WAKE_MCAST)
1858 ocp_data |= MWF_EN;
1859 if (wolopts & WAKE_ANY)
1860 ocp_data |= LAN_WAKE_EN;
1861 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data);
1862
1863 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
1864
1865 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
1866 ocp_data &= ~MAGIC_EN;
1867 if (wolopts & WAKE_MAGIC)
1868 ocp_data |= MAGIC_EN;
1869 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
1870
1871 if (wolopts & WAKE_ANY)
1872 device_set_wakeup_enable(&tp->udev->dev, true);
1873 else
1874 device_set_wakeup_enable(&tp->udev->dev, false);
1875}
1876
1799static void rtl_phy_reset(struct r8152 *tp) 1877static void rtl_phy_reset(struct r8152 *tp)
1800{ 1878{
1801 u16 data; 1879 u16 data;
@@ -2000,10 +2078,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
2000 2078
2001 ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); 2079 ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
2002 2080
2003 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
2004 ocp_data |= MAGIC_EN;
2005 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
2006
2007 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); 2081 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
2008 ocp_data |= CPCR_RX_VLAN; 2082 ocp_data |= CPCR_RX_VLAN;
2009 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); 2083 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
@@ -2016,8 +2090,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
2016 ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; 2090 ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
2017 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); 2091 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
2018 2092
2019 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
2020
2021 rxdy_gated_en(tp, false); 2093 rxdy_gated_en(tp, false);
2022 2094
2023 ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); 2095 ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -2215,10 +2287,6 @@ static void r8153_enter_oob(struct r8152 *tp)
2215 2287
2216 ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); 2288 ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
2217 2289
2218 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
2219 ocp_data |= MAGIC_EN;
2220 ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
2221
2222 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG); 2290 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
2223 ocp_data &= ~TEREDO_WAKE_MASK; 2291 ocp_data &= ~TEREDO_WAKE_MASK;
2224 ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); 2292 ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
@@ -2235,8 +2303,6 @@ static void r8153_enter_oob(struct r8152 *tp)
2235 ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; 2303 ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
2236 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); 2304 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
2237 2305
2238 ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
2239
2240 rxdy_gated_en(tp, false); 2306 rxdy_gated_en(tp, false);
2241 2307
2242 ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); 2308 ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -2650,6 +2716,24 @@ static int rtl8152_resume(struct usb_interface *intf)
2650 return 0; 2716 return 0;
2651} 2717}
2652 2718
2719static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2720{
2721 struct r8152 *tp = netdev_priv(dev);
2722
2723 wol->supported = WAKE_ANY;
2724 wol->wolopts = __rtl_get_wol(tp);
2725}
2726
2727static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2728{
2729 struct r8152 *tp = netdev_priv(dev);
2730
2731 __rtl_set_wol(tp, wol->wolopts);
2732 tp->saved_wolopts = wol->wolopts & WAKE_ANY;
2733
2734 return 0;
2735}
2736
2653static void rtl8152_get_drvinfo(struct net_device *netdev, 2737static void rtl8152_get_drvinfo(struct net_device *netdev,
2654 struct ethtool_drvinfo *info) 2738 struct ethtool_drvinfo *info)
2655{ 2739{
@@ -2683,6 +2767,8 @@ static struct ethtool_ops ops = {
2683 .get_settings = rtl8152_get_settings, 2767 .get_settings = rtl8152_get_settings,
2684 .set_settings = rtl8152_set_settings, 2768 .set_settings = rtl8152_set_settings,
2685 .get_link = ethtool_op_get_link, 2769 .get_link = ethtool_op_get_link,
2770 .get_wol = rtl8152_get_wol,
2771 .set_wol = rtl8152_set_wol,
2686}; 2772};
2687 2773
2688static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) 2774static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -2891,6 +2977,12 @@ static int rtl8152_probe(struct usb_interface *intf,
2891 goto out1; 2977 goto out1;
2892 } 2978 }
2893 2979
2980 tp->saved_wolopts = __rtl_get_wol(tp);
2981 if (tp->saved_wolopts)
2982 device_set_wakeup_enable(&udev->dev, true);
2983 else
2984 device_set_wakeup_enable(&udev->dev, false);
2985
2894 netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); 2986 netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
2895 2987
2896 return 0; 2988 return 0;