000-enable-alx-wol-5.15.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. --- a/drivers/net/ethernet/atheros/alx/ethtool.c
  2. +++ b/drivers/net/ethernet/atheros/alx/ethtool.c
  3. @@ -321,11 +321,47 @@ static int alx_get_sset_count(struct net_device *netdev, int sset)
  4. }
  5. }
  6. +static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
  7. +{
  8. + struct alx_priv *alx = netdev_priv(netdev);
  9. + struct alx_hw *hw = &alx->hw;
  10. +
  11. + wol->supported = WAKE_MAGIC | WAKE_PHY;
  12. + wol->wolopts = 0;
  13. +
  14. + if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC)
  15. + wol->wolopts |= WAKE_MAGIC;
  16. + if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY)
  17. + wol->wolopts |= WAKE_PHY;
  18. +}
  19. +
  20. +static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
  21. +{
  22. + struct alx_priv *alx = netdev_priv(netdev);
  23. + struct alx_hw *hw = &alx->hw;
  24. +
  25. + if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY))
  26. + return -EOPNOTSUPP;
  27. +
  28. + hw->sleep_ctrl = 0;
  29. +
  30. + if (wol->wolopts & WAKE_MAGIC)
  31. + hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC;
  32. + if (wol->wolopts & WAKE_PHY)
  33. + hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY;
  34. +
  35. + device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl);
  36. +
  37. + return 0;
  38. +}
  39. +
  40. const struct ethtool_ops alx_ethtool_ops = {
  41. .get_pauseparam = alx_get_pauseparam,
  42. .set_pauseparam = alx_set_pauseparam,
  43. .get_msglevel = alx_get_msglevel,
  44. .set_msglevel = alx_set_msglevel,
  45. + .get_wol = alx_get_wol,
  46. + .set_wol = alx_set_wol,
  47. .get_link = ethtool_op_get_link,
  48. .get_strings = alx_get_strings,
  49. .get_sset_count = alx_get_sset_count,
  50. --- a/drivers/net/ethernet/atheros/alx/hw.c
  51. +++ b/drivers/net/ethernet/atheros/alx/hw.c
  52. @@ -332,6 +332,16 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr)
  53. alx_write_mem32(hw, ALX_STAD1, val);
  54. }
  55. +static void alx_enable_osc(struct alx_hw *hw)
  56. +{
  57. + u32 val;
  58. +
  59. + /* rising edge */
  60. + val = alx_read_mem32(hw, ALX_MISC);
  61. + alx_write_mem32(hw, ALX_MISC, val & ~ALX_MISC_INTNLOSC_OPEN);
  62. + alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN);
  63. +}
  64. +
  65. static void alx_reset_osc(struct alx_hw *hw, u8 rev)
  66. {
  67. u32 val, val2;
  68. @@ -848,6 +858,66 @@ void alx_post_phy_link(struct alx_hw *hw)
  69. }
  70. }
  71. +
  72. +/* NOTE:
  73. + * 1. phy link must be established before calling this function
  74. + * 2. wol option (pattern,magic,link,etc.) is configed before call it.
  75. + */
  76. +int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex)
  77. +{
  78. + u32 master, mac, phy, val;
  79. + int err = 0;
  80. +
  81. + master = alx_read_mem32(hw, ALX_MASTER);
  82. + master &= ~ALX_MASTER_PCLKSEL_SRDS;
  83. + mac = hw->rx_ctrl;
  84. + /* 10/100 half */
  85. + ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, ALX_MAC_CTRL_SPEED_10_100);
  86. + mac &= ~(ALX_MAC_CTRL_FULLD | ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN);
  87. +
  88. + phy = alx_read_mem32(hw, ALX_PHY_CTRL);
  89. + phy &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_CLS);
  90. + phy |= ALX_PHY_CTRL_RST_ANALOG | ALX_PHY_CTRL_HIB_PULSE |
  91. + ALX_PHY_CTRL_HIB_EN;
  92. +
  93. + /* without any activity */
  94. + if (!(hw->sleep_ctrl & ALX_SLEEP_ACTIVE)) {
  95. + err = alx_write_phy_reg(hw, ALX_MII_IER, 0);
  96. + if (err)
  97. + return err;
  98. + phy |= ALX_PHY_CTRL_IDDQ | ALX_PHY_CTRL_POWER_DOWN;
  99. + } else {
  100. + if (hw->sleep_ctrl & (ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_CIFS))
  101. + mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN;
  102. + if (hw->sleep_ctrl & ALX_SLEEP_CIFS)
  103. + mac |= ALX_MAC_CTRL_TX_EN;
  104. + if (duplex == DUPLEX_FULL)
  105. + mac |= ALX_MAC_CTRL_FULLD;
  106. + if (speed == SPEED_1000)
  107. + ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED,
  108. + ALX_MAC_CTRL_SPEED_1000);
  109. + phy |= ALX_PHY_CTRL_DSPRST_OUT;
  110. + err = alx_write_phy_ext(hw, ALX_MIIEXT_ANEG,
  111. + ALX_MIIEXT_S3DIG10,
  112. + ALX_MIIEXT_S3DIG10_SL);
  113. + if (err)
  114. + return err;
  115. + }
  116. +
  117. + alx_enable_osc(hw);
  118. + hw->rx_ctrl = mac;
  119. + alx_write_mem32(hw, ALX_MASTER, master);
  120. + alx_write_mem32(hw, ALX_MAC_CTRL, mac);
  121. + alx_write_mem32(hw, ALX_PHY_CTRL, phy);
  122. +
  123. + /* set val of PDLL D3PLLOFF */
  124. + val = alx_read_mem32(hw, ALX_PDLL_TRNS1);
  125. + val |= ALX_PDLL_TRNS1_D3PLLOFF_EN;
  126. + alx_write_mem32(hw, ALX_PDLL_TRNS1, val);
  127. +
  128. + return 0;
  129. +}
  130. +
  131. bool alx_phy_configured(struct alx_hw *hw)
  132. {
  133. u32 cfg, hw_cfg;
  134. @@ -920,6 +990,26 @@ int alx_clear_phy_intr(struct alx_hw *hw)
  135. return alx_read_phy_reg(hw, ALX_MII_ISR, &isr);
  136. }
  137. +int alx_config_wol(struct alx_hw *hw)
  138. +{
  139. + u32 wol = 0;
  140. + int err = 0;
  141. +
  142. + /* turn on magic packet event */
  143. + if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC)
  144. + wol |= ALX_WOL0_MAGIC_EN | ALX_WOL0_PME_MAGIC_EN;
  145. +
  146. + /* turn on link up event */
  147. + if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) {
  148. + wol |= ALX_WOL0_LINK_EN | ALX_WOL0_PME_LINK;
  149. + /* only link up can wake up */
  150. + err = alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP);
  151. + }
  152. + alx_write_mem32(hw, ALX_WOL0, wol);
  153. +
  154. + return err;
  155. +}
  156. +
  157. void alx_disable_rss(struct alx_hw *hw)
  158. {
  159. u32 ctrl = alx_read_mem32(hw, ALX_RXQ0);
  160. @@ -1045,6 +1135,71 @@ void alx_mask_msix(struct alx_hw *hw, int index, bool mask)
  161. }
  162. +int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex)
  163. +{
  164. + int i, err;
  165. + u16 lpa;
  166. +
  167. + err = alx_read_phy_link(hw);
  168. + if (err)
  169. + return err;
  170. +
  171. + if (hw->link_speed == SPEED_UNKNOWN) {
  172. + *speed = SPEED_UNKNOWN;
  173. + *duplex = DUPLEX_UNKNOWN;
  174. + return 0;
  175. + }
  176. +
  177. + err = alx_read_phy_reg(hw, MII_LPA, &lpa);
  178. + if (err)
  179. + return err;
  180. +
  181. + if (!(lpa & LPA_LPACK)) {
  182. + *speed = hw->link_speed;
  183. + return 0;
  184. + }
  185. +
  186. + if (lpa & LPA_10FULL) {
  187. + *speed = SPEED_10;
  188. + *duplex = DUPLEX_FULL;
  189. + } else if (lpa & LPA_10HALF) {
  190. + *speed = SPEED_10;
  191. + *duplex = DUPLEX_HALF;
  192. + } else if (lpa & LPA_100FULL) {
  193. + *speed = SPEED_100;
  194. + *duplex = DUPLEX_FULL;
  195. + } else {
  196. + *speed = SPEED_100;
  197. + *duplex = DUPLEX_HALF;
  198. + }
  199. +
  200. + if (*speed == hw->link_speed && *duplex == hw->duplex)
  201. + return 0;
  202. + err = alx_write_phy_reg(hw, ALX_MII_IER, 0);
  203. + if (err)
  204. + return err;
  205. + err = alx_setup_speed_duplex(hw, alx_speed_to_ethadv(*speed, *duplex) |
  206. + ADVERTISED_Autoneg, ALX_FC_ANEG |
  207. + ALX_FC_RX | ALX_FC_TX);
  208. + if (err)
  209. + return err;
  210. +
  211. + /* wait for linkup */
  212. + for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) {
  213. + msleep(100);
  214. +
  215. + err = alx_read_phy_link(hw);
  216. + if (err < 0)
  217. + return err;
  218. + if (hw->link_speed != SPEED_UNKNOWN)
  219. + break;
  220. + }
  221. + if (i == ALX_MAX_SETUP_LNK_CYCLE)
  222. + return -ETIMEDOUT;
  223. +
  224. + return 0;
  225. +}
  226. +
  227. bool alx_get_phy_info(struct alx_hw *hw)
  228. {
  229. u16 devs1, devs2;
  230. --- a/drivers/net/ethernet/atheros/alx/hw.h
  231. +++ b/drivers/net/ethernet/atheros/alx/hw.h
  232. @@ -487,6 +487,8 @@ struct alx_hw {
  233. u8 flowctrl;
  234. u32 adv_cfg;
  235. + u32 sleep_ctrl;
  236. +
  237. spinlock_t mdio_lock;
  238. struct mdio_if_info mdio;
  239. u16 phy_id[2];
  240. @@ -549,12 +551,14 @@ void alx_reset_pcie(struct alx_hw *hw);
  241. void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en);
  242. int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl);
  243. void alx_post_phy_link(struct alx_hw *hw);
  244. +int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex);
  245. int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data);
  246. int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data);
  247. int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata);
  248. int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data);
  249. int alx_read_phy_link(struct alx_hw *hw);
  250. int alx_clear_phy_intr(struct alx_hw *hw);
  251. +int alx_config_wol(struct alx_hw *hw);
  252. void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc);
  253. void alx_start_mac(struct alx_hw *hw);
  254. int alx_reset_mac(struct alx_hw *hw);
  255. @@ -563,6 +567,7 @@ bool alx_phy_configured(struct alx_hw *hw);
  256. void alx_configure_basic(struct alx_hw *hw);
  257. void alx_mask_msix(struct alx_hw *hw, int index, bool mask);
  258. void alx_disable_rss(struct alx_hw *hw);
  259. +int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex);
  260. bool alx_get_phy_info(struct alx_hw *hw);
  261. void alx_update_hw_stats(struct alx_hw *hw);
  262. --- a/drivers/net/ethernet/atheros/alx/main.c
  263. +++ b/drivers/net/ethernet/atheros/alx/main.c
  264. @@ -1069,6 +1069,7 @@ static int alx_init_sw(struct alx_priv *alx)
  265. alx->dev->max_mtu = ALX_MAX_FRAME_LEN(ALX_MAX_FRAME_SIZE);
  266. alx->tx_ringsz = 256;
  267. alx->rx_ringsz = 512;
  268. + hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY;
  269. hw->imt = 200;
  270. alx->int_mask = ALX_ISR_MISC;
  271. hw->dma_chnl = hw->max_dma_chnl;
  272. @@ -1181,11 +1182,8 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
  273. alx->hw.mtu = mtu;
  274. alx->rxbuf_size = max(max_frame, ALX_DEF_RXBUF_SIZE);
  275. netdev_update_features(netdev);
  276. - if (netif_running(netdev)) {
  277. - mutex_lock(&alx->mtx);
  278. + if (netif_running(netdev))
  279. alx_reinit(alx);
  280. - mutex_unlock(&alx->mtx);
  281. - }
  282. return 0;
  283. }
  284. @@ -1371,6 +1369,66 @@ static int alx_stop(struct net_device *netdev)
  285. return 0;
  286. }
  287. +static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
  288. +{
  289. + struct alx_priv *alx = pci_get_drvdata(pdev);
  290. + struct net_device *netdev = alx->dev;
  291. + struct alx_hw *hw = &alx->hw;
  292. + int err, speed;
  293. + u8 duplex;
  294. +
  295. + netif_device_detach(netdev);
  296. +
  297. + if (netif_running(netdev))
  298. + __alx_stop(alx);
  299. +
  300. +#ifdef CONFIG_PM_SLEEP
  301. + err = pci_save_state(pdev);
  302. + if (err)
  303. + return err;
  304. +#endif
  305. +
  306. + err = alx_select_powersaving_speed(hw, &speed, &duplex);
  307. + if (err)
  308. + return err;
  309. + err = alx_clear_phy_intr(hw);
  310. + if (err)
  311. + return err;
  312. + err = alx_pre_suspend(hw, speed, duplex);
  313. + if (err)
  314. + return err;
  315. + err = alx_config_wol(hw);
  316. + if (err)
  317. + return err;
  318. +
  319. + *wol_en = false;
  320. + if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) {
  321. + netif_info(alx, wol, netdev,
  322. + "wol: ctrl=%X, speed=%X\n",
  323. + hw->sleep_ctrl, speed);
  324. + device_set_wakeup_enable(&pdev->dev, true);
  325. + *wol_en = true;
  326. + }
  327. +
  328. + pci_disable_device(pdev);
  329. +
  330. + return 0;
  331. +}
  332. +
  333. +static void alx_shutdown(struct pci_dev *pdev)
  334. +{
  335. + int err;
  336. + bool wol_en;
  337. +
  338. + err = __alx_shutdown(pdev, &wol_en);
  339. + if (!err) {
  340. + pci_wake_from_d3(pdev, wol_en);
  341. + pci_set_power_state(pdev, PCI_D3hot);
  342. + } else {
  343. + dev_err(&pdev->dev, "shutdown fail %d\n", err);
  344. + }
  345. +}
  346. +
  347. static void alx_link_check(struct work_struct *work)
  348. {
  349. struct alx_priv *alx;
  350. @@ -1865,6 +1923,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  351. goto out_unmap;
  352. }
  353. + device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl);
  354. netdev_info(netdev,
  355. "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n",
  356. netdev->dev_addr);
  357. @@ -1910,16 +1969,26 @@ static int alx_suspend(struct device *dev)
  358. {
  359. struct alx_priv *alx = dev_get_drvdata(dev);
  360. - if (!netif_running(alx->dev))
  361. - return 0;
  362. + struct pci_dev *pdev = alx->hw.pdev;
  363. + int err;
  364. + bool wol_en;
  365. - rtnl_lock();
  366. - netif_device_detach(alx->dev);
  367. + //if (!netif_running(alx->dev))
  368. + // return 0;
  369. + //netif_device_detach(alx->dev);
  370. + //__alx_stop(alx);
  371. + err = __alx_shutdown(pdev, &wol_en);
  372. + if (err) {
  373. + dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err);
  374. + return err;
  375. + }
  376. - mutex_lock(&alx->mtx);
  377. - __alx_stop(alx);
  378. - mutex_unlock(&alx->mtx);
  379. - rtnl_unlock();
  380. + if (wol_en) {
  381. + pci_prepare_to_sleep(pdev);
  382. + } else {
  383. + pci_wake_from_d3(pdev, false);
  384. + pci_set_power_state(pdev, PCI_D3hot);
  385. + }
  386. return 0;
  387. }
  388. @@ -1927,34 +1996,53 @@ static int alx_suspend(struct device *dev)
  389. static int alx_resume(struct device *dev)
  390. {
  391. struct alx_priv *alx = dev_get_drvdata(dev);
  392. + struct net_device *netdev = alx->dev;
  393. struct alx_hw *hw = &alx->hw;
  394. + struct pci_dev *pdev = hw->pdev;
  395. int err;
  396. - rtnl_lock();
  397. mutex_lock(&alx->mtx);
  398. +
  399. + pci_set_power_state(pdev, PCI_D0);
  400. + pci_restore_state(pdev);
  401. + pci_save_state(pdev);
  402. +
  403. + pci_enable_wake(pdev, PCI_D3hot, 0);
  404. + pci_enable_wake(pdev, PCI_D3cold, 0);
  405. +
  406. + hw->link_speed = SPEED_UNKNOWN;
  407. + alx->int_mask = ALX_ISR_MISC;
  408. +
  409. + alx_reset_pcie(hw);
  410. alx_reset_phy(hw);
  411. - if (!netif_running(alx->dev)) {
  412. - err = 0;
  413. - goto unlock;
  414. + //if (!netif_running(alx->dev)) {
  415. + // err = 0;
  416. + // goto unlock;
  417. + //}
  418. + err = alx_reset_mac(hw);
  419. + if (err) {
  420. + netif_err(alx, hw, alx->dev, "resume:reset_mac fail %d\n", err);
  421. + err = -EIO;
  422. + goto unlock;
  423. }
  424. - err = __alx_open(alx, true);
  425. - if (err)
  426. - goto unlock;
  427. + //err = __alx_open(alx, true);
  428. + //if (err)
  429. + // goto unlock;
  430. + if (netif_running(netdev)) {
  431. + err = __alx_open(alx, true);
  432. + if (err)
  433. + goto unlock;
  434. + }
  435. netif_device_attach(alx->dev);
  436. unlock:
  437. mutex_unlock(&alx->mtx);
  438. - rtnl_unlock();
  439. return err;
  440. }
  441. -static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
  442. -#define ALX_PM_OPS (&alx_pm_ops)
  443. -#else
  444. -#define ALX_PM_OPS NULL
  445. #endif
  446. @@ -2000,6 +2088,8 @@ static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
  447. }
  448. pci_set_master(pdev);
  449. + pci_enable_wake(pdev, PCI_D3hot, 0);
  450. + pci_enable_wake(pdev, PCI_D3cold, 0);
  451. alx_reset_pcie(hw);
  452. if (!alx_reset_mac(hw))
  453. @@ -2049,11 +2139,20 @@ static const struct pci_device_id alx_pci_tbl[] = {
  454. {}
  455. };
  456. +#ifdef CONFIG_PM_SLEEP
  457. +static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
  458. +#define ALX_PM_OPS (&alx_pm_ops)
  459. +#else
  460. +#define ALX_PM_OPS NULL
  461. +#endif
  462. +
  463. +
  464. static struct pci_driver alx_driver = {
  465. .name = alx_drv_name,
  466. .id_table = alx_pci_tbl,
  467. .probe = alx_probe,
  468. .remove = alx_remove,
  469. + .shutdown = alx_shutdown,
  470. .err_handler = &alx_err_handlers,
  471. .driver.pm = ALX_PM_OPS,
  472. };