134-net-mvneta-convert-to-phylink.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. From e268be0ddc666f4a98db462cbed2a97637e82b5c Mon Sep 17 00:00:00 2001
  2. From: Russell King <rmk+kernel@arm.linux.org.uk>
  3. Date: Wed, 16 Sep 2015 21:27:10 +0100
  4. Subject: [PATCH 722/744] net: mvneta: convert to phylink
  5. Convert mvneta to use phylink, which models the MAC to PHY link in
  6. a generic, reusable form.
  7. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  8. ---
  9. drivers/net/ethernet/marvell/Kconfig | 2 +-
  10. drivers/net/ethernet/marvell/mvneta.c | 451 +++++++++++++++++-----------------
  11. 2 files changed, 227 insertions(+), 226 deletions(-)
  12. --- a/drivers/net/ethernet/marvell/Kconfig
  13. +++ b/drivers/net/ethernet/marvell/Kconfig
  14. @@ -58,7 +58,7 @@ config MVNETA
  15. tristate "Marvell Armada 370/38x/XP network interface support"
  16. depends on PLAT_ORION
  17. select MVMDIO
  18. - select FIXED_PHY
  19. + select PHYLINK
  20. ---help---
  21. This driver supports the network interface units in the
  22. Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
  23. --- a/drivers/net/ethernet/marvell/mvneta.c
  24. +++ b/drivers/net/ethernet/marvell/mvneta.c
  25. @@ -28,6 +28,7 @@
  26. #include <linux/of_mdio.h>
  27. #include <linux/of_net.h>
  28. #include <linux/phy.h>
  29. +#include <linux/phylink.h>
  30. #include <linux/platform_device.h>
  31. #include <linux/skbuff.h>
  32. #include <net/hwbm.h>
  33. @@ -188,6 +189,7 @@
  34. #define MVNETA_GMAC_CTRL_0 0x2c00
  35. #define MVNETA_GMAC_MAX_RX_SIZE_SHIFT 2
  36. #define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
  37. +#define MVNETA_GMAC0_PORT_1000BASE_X BIT(1)
  38. #define MVNETA_GMAC0_PORT_ENABLE BIT(0)
  39. #define MVNETA_GMAC_CTRL_2 0x2c08
  40. #define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0)
  41. @@ -203,13 +205,19 @@
  42. #define MVNETA_GMAC_TX_FLOW_CTRL_ENABLE BIT(5)
  43. #define MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE BIT(6)
  44. #define MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE BIT(7)
  45. +#define MVNETA_GMAC_AN_COMPLETE BIT(11)
  46. +#define MVNETA_GMAC_SYNC_OK BIT(14)
  47. #define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
  48. #define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
  49. #define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
  50. #define MVNETA_GMAC_INBAND_AN_ENABLE BIT(2)
  51. +#define MVNETA_GMAC_AN_BYPASS_ENABLE BIT(3)
  52. +#define MVNETA_GMAC_INBAND_RESTART_AN BIT(4)
  53. #define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
  54. #define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
  55. #define MVNETA_GMAC_AN_SPEED_EN BIT(7)
  56. +#define MVNETA_GMAC_CONFIG_FLOW_CTRL BIT(8)
  57. +#define MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL BIT(9)
  58. #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11)
  59. #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
  60. #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
  61. @@ -396,15 +404,9 @@ struct mvneta_port {
  62. u16 tx_ring_size;
  63. u16 rx_ring_size;
  64. - struct mii_bus *mii_bus;
  65. - struct phy_device *phy_dev;
  66. - phy_interface_t phy_interface;
  67. - struct device_node *phy_node;
  68. - unsigned int link;
  69. - unsigned int duplex;
  70. - unsigned int speed;
  71. + struct device_node *dn;
  72. unsigned int tx_csum_limit;
  73. - unsigned int use_inband_status:1;
  74. + struct phylink *phylink;
  75. struct mvneta_bm *bm_priv;
  76. struct mvneta_bm_pool *pool_long;
  77. @@ -1178,10 +1180,6 @@ static void mvneta_port_disable(struct m
  78. val &= ~MVNETA_GMAC0_PORT_ENABLE;
  79. mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
  80. - pp->link = 0;
  81. - pp->duplex = -1;
  82. - pp->speed = 0;
  83. -
  84. udelay(200);
  85. }
  86. @@ -1241,44 +1239,6 @@ static void mvneta_set_other_mcast_table
  87. mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val);
  88. }
  89. -static void mvneta_set_autoneg(struct mvneta_port *pp, int enable)
  90. -{
  91. - u32 val;
  92. -
  93. - if (enable) {
  94. - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  95. - val &= ~(MVNETA_GMAC_FORCE_LINK_PASS |
  96. - MVNETA_GMAC_FORCE_LINK_DOWN |
  97. - MVNETA_GMAC_AN_FLOW_CTRL_EN);
  98. - val |= MVNETA_GMAC_INBAND_AN_ENABLE |
  99. - MVNETA_GMAC_AN_SPEED_EN |
  100. - MVNETA_GMAC_AN_DUPLEX_EN;
  101. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  102. -
  103. - val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
  104. - val |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
  105. - mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
  106. -
  107. - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
  108. - val |= MVNETA_GMAC2_INBAND_AN_ENABLE;
  109. - mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
  110. - } else {
  111. - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  112. - val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE |
  113. - MVNETA_GMAC_AN_SPEED_EN |
  114. - MVNETA_GMAC_AN_DUPLEX_EN);
  115. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  116. -
  117. - val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
  118. - val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
  119. - mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
  120. -
  121. - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
  122. - val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE;
  123. - mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
  124. - }
  125. -}
  126. -
  127. static void mvneta_percpu_unmask_interrupt(void *arg)
  128. {
  129. struct mvneta_port *pp = arg;
  130. @@ -1426,7 +1386,6 @@ static void mvneta_defaults_set(struct m
  131. val &= ~MVNETA_PHY_POLLING_ENABLE;
  132. mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
  133. - mvneta_set_autoneg(pp, pp->use_inband_status);
  134. mvneta_set_ucast_table(pp, -1);
  135. mvneta_set_special_mcast_table(pp, -1);
  136. mvneta_set_other_mcast_table(pp, -1);
  137. @@ -2619,26 +2578,11 @@ static irqreturn_t mvneta_isr(int irq, v
  138. return IRQ_HANDLED;
  139. }
  140. -static int mvneta_fixed_link_update(struct mvneta_port *pp,
  141. - struct phy_device *phy)
  142. +static void mvneta_link_change(struct mvneta_port *pp)
  143. {
  144. - struct fixed_phy_status status;
  145. - struct fixed_phy_status changed = {};
  146. u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
  147. - status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
  148. - if (gmac_stat & MVNETA_GMAC_SPEED_1000)
  149. - status.speed = SPEED_1000;
  150. - else if (gmac_stat & MVNETA_GMAC_SPEED_100)
  151. - status.speed = SPEED_100;
  152. - else
  153. - status.speed = SPEED_10;
  154. - status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
  155. - changed.link = 1;
  156. - changed.speed = 1;
  157. - changed.duplex = 1;
  158. - fixed_phy_update_state(phy, &status, &changed);
  159. - return 0;
  160. + phylink_mac_change(pp->phylink, !!(gmac_stat & MVNETA_GMAC_LINK_UP));
  161. }
  162. /* NAPI handler
  163. @@ -2667,12 +2611,11 @@ static int mvneta_poll(struct napi_struc
  164. u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE);
  165. mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
  166. - if (pp->use_inband_status && (cause_misc &
  167. - (MVNETA_CAUSE_PHY_STATUS_CHANGE |
  168. - MVNETA_CAUSE_LINK_CHANGE |
  169. - MVNETA_CAUSE_PSC_SYNC_CHANGE))) {
  170. - mvneta_fixed_link_update(pp, pp->phy_dev);
  171. - }
  172. +
  173. + if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE |
  174. + MVNETA_CAUSE_LINK_CHANGE |
  175. + MVNETA_CAUSE_PSC_SYNC_CHANGE))
  176. + mvneta_link_change(pp);
  177. }
  178. /* Release Tx descriptors */
  179. @@ -2988,7 +2931,7 @@ static void mvneta_start_dev(struct mvne
  180. MVNETA_CAUSE_LINK_CHANGE |
  181. MVNETA_CAUSE_PSC_SYNC_CHANGE);
  182. - phy_start(pp->phy_dev);
  183. + phylink_start(pp->phylink);
  184. netif_tx_start_all_queues(pp->dev);
  185. }
  186. @@ -2996,7 +2939,7 @@ static void mvneta_stop_dev(struct mvnet
  187. {
  188. unsigned int cpu;
  189. - phy_stop(pp->phy_dev);
  190. + phylink_stop(pp->phylink);
  191. for_each_online_cpu(cpu) {
  192. struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
  193. @@ -3165,99 +3108,219 @@ static int mvneta_set_mac_addr(struct ne
  194. return 0;
  195. }
  196. -static void mvneta_adjust_link(struct net_device *ndev)
  197. +static int mvneta_mac_support(struct net_device *ndev, unsigned int mode,
  198. + struct phylink_link_state *state)
  199. +{
  200. + switch (mode) {
  201. + case MLO_AN_8023Z:
  202. + state->supported = SUPPORTED_1000baseT_Full |
  203. + SUPPORTED_Autoneg | SUPPORTED_Pause;
  204. + state->advertising = ADVERTISED_1000baseT_Full |
  205. + ADVERTISED_Autoneg | ADVERTISED_Pause;
  206. + state->an_enabled = 1;
  207. + break;
  208. +
  209. + case MLO_AN_FIXED:
  210. + break;
  211. +
  212. + default:
  213. + state->supported = PHY_10BT_FEATURES |
  214. + PHY_100BT_FEATURES |
  215. + SUPPORTED_1000baseT_Full |
  216. + SUPPORTED_Autoneg;
  217. + state->advertising = ADVERTISED_10baseT_Half |
  218. + ADVERTISED_10baseT_Full |
  219. + ADVERTISED_100baseT_Half |
  220. + ADVERTISED_100baseT_Full |
  221. + ADVERTISED_1000baseT_Full |
  222. + ADVERTISED_Autoneg;
  223. + state->an_enabled = 1;
  224. + break;
  225. + }
  226. + return 0;
  227. +}
  228. +
  229. +static int mvneta_mac_link_state(struct net_device *ndev,
  230. + struct phylink_link_state *state)
  231. {
  232. struct mvneta_port *pp = netdev_priv(ndev);
  233. - struct phy_device *phydev = pp->phy_dev;
  234. - int status_change = 0;
  235. + u32 gmac_stat;
  236. - if (phydev->link) {
  237. - if ((pp->speed != phydev->speed) ||
  238. - (pp->duplex != phydev->duplex)) {
  239. - u32 val;
  240. -
  241. - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  242. - val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
  243. - MVNETA_GMAC_CONFIG_GMII_SPEED |
  244. - MVNETA_GMAC_CONFIG_FULL_DUPLEX);
  245. -
  246. - if (phydev->duplex)
  247. - val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
  248. -
  249. - if (phydev->speed == SPEED_1000)
  250. - val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
  251. - else if (phydev->speed == SPEED_100)
  252. - val |= MVNETA_GMAC_CONFIG_MII_SPEED;
  253. + gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
  254. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  255. + if (gmac_stat & MVNETA_GMAC_SPEED_1000)
  256. + state->speed = SPEED_1000;
  257. + else if (gmac_stat & MVNETA_GMAC_SPEED_100)
  258. + state->speed = SPEED_100;
  259. + else
  260. + state->speed = SPEED_10;
  261. - pp->duplex = phydev->duplex;
  262. - pp->speed = phydev->speed;
  263. - }
  264. + state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE);
  265. + state->sync = !!(gmac_stat & MVNETA_GMAC_SYNC_OK);
  266. + state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
  267. + state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
  268. +
  269. + state->pause = 0;
  270. + if (gmac_stat & MVNETA_GMAC_RX_FLOW_CTRL_ENABLE)
  271. + state->pause |= MLO_PAUSE_RX;
  272. + if (gmac_stat & MVNETA_GMAC_TX_FLOW_CTRL_ENABLE)
  273. + state->pause |= MLO_PAUSE_TX;
  274. +
  275. + return 1;
  276. +}
  277. +
  278. +static void mvneta_mac_an_restart(struct net_device *ndev, unsigned int mode)
  279. +{
  280. + struct mvneta_port *pp = netdev_priv(ndev);
  281. +
  282. + if (mode == MLO_AN_8023Z) {
  283. + u32 gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  284. +
  285. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
  286. + gmac_an | MVNETA_GMAC_INBAND_RESTART_AN);
  287. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
  288. + gmac_an & ~MVNETA_GMAC_INBAND_RESTART_AN);
  289. }
  290. +}
  291. - if (phydev->link != pp->link) {
  292. - if (!phydev->link) {
  293. - pp->duplex = -1;
  294. - pp->speed = 0;
  295. - }
  296. +static void mvneta_mac_config(struct net_device *ndev, unsigned int mode,
  297. + const struct phylink_link_state *state)
  298. +{
  299. + struct mvneta_port *pp = netdev_priv(ndev);
  300. + u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
  301. + u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
  302. + u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
  303. + u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  304. +
  305. + new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X;
  306. + new_ctrl2 = gmac_ctrl2 & ~MVNETA_GMAC2_INBAND_AN_ENABLE;
  307. + new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
  308. + new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE |
  309. + MVNETA_GMAC_INBAND_RESTART_AN |
  310. + MVNETA_GMAC_CONFIG_MII_SPEED |
  311. + MVNETA_GMAC_CONFIG_GMII_SPEED |
  312. + MVNETA_GMAC_AN_SPEED_EN |
  313. + MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL |
  314. + MVNETA_GMAC_CONFIG_FLOW_CTRL |
  315. + MVNETA_GMAC_AN_FLOW_CTRL_EN |
  316. + MVNETA_GMAC_CONFIG_FULL_DUPLEX |
  317. + MVNETA_GMAC_AN_DUPLEX_EN);
  318. +
  319. + if (state->advertising & ADVERTISED_Pause)
  320. + new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL;
  321. +
  322. + switch (mode) {
  323. + case MLO_AN_SGMII:
  324. + /* SGMII mode receives the state from the PHY */
  325. + new_ctrl2 |= MVNETA_GMAC2_INBAND_AN_ENABLE;
  326. + new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
  327. + new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
  328. + MVNETA_GMAC_FORCE_LINK_PASS)) |
  329. + MVNETA_GMAC_INBAND_AN_ENABLE |
  330. + MVNETA_GMAC_AN_SPEED_EN |
  331. + MVNETA_GMAC_AN_DUPLEX_EN;
  332. + break;
  333. +
  334. + case MLO_AN_8023Z:
  335. + /* 802.3z negotiation - only 1000base-X */
  336. + new_ctrl0 |= MVNETA_GMAC0_PORT_1000BASE_X;
  337. + new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
  338. + new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
  339. + MVNETA_GMAC_FORCE_LINK_PASS)) |
  340. + MVNETA_GMAC_INBAND_AN_ENABLE |
  341. + MVNETA_GMAC_CONFIG_GMII_SPEED |
  342. + /* The MAC only supports FD mode */
  343. + MVNETA_GMAC_CONFIG_FULL_DUPLEX;
  344. +
  345. + if (state->an_enabled)
  346. + new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN;
  347. + break;
  348. - pp->link = phydev->link;
  349. - status_change = 1;
  350. + default:
  351. + /* Phy or fixed speed */
  352. + if (state->duplex)
  353. + new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
  354. +
  355. + if (state->speed == SPEED_1000)
  356. + new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED;
  357. + else if (state->speed == SPEED_100)
  358. + new_an |= MVNETA_GMAC_CONFIG_MII_SPEED;
  359. + break;
  360. }
  361. - if (status_change) {
  362. - if (phydev->link) {
  363. - if (!pp->use_inband_status) {
  364. - u32 val = mvreg_read(pp,
  365. - MVNETA_GMAC_AUTONEG_CONFIG);
  366. - val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
  367. - val |= MVNETA_GMAC_FORCE_LINK_PASS;
  368. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
  369. - val);
  370. - }
  371. - mvneta_port_up(pp);
  372. - } else {
  373. - if (!pp->use_inband_status) {
  374. - u32 val = mvreg_read(pp,
  375. - MVNETA_GMAC_AUTONEG_CONFIG);
  376. - val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
  377. - val |= MVNETA_GMAC_FORCE_LINK_DOWN;
  378. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
  379. - val);
  380. - }
  381. - mvneta_port_down(pp);
  382. - }
  383. - phy_print_status(phydev);
  384. + /* Armada 370 documentation says we can only change the port mode
  385. + * and in-band enable when the link is down, so force it down
  386. + * while making these changes. We also do this for GMAC_CTRL2 */
  387. + if ((new_ctrl0 ^ gmac_ctrl0) & MVNETA_GMAC0_PORT_1000BASE_X ||
  388. + (new_ctrl2 ^ gmac_ctrl2) & MVNETA_GMAC2_INBAND_AN_ENABLE ||
  389. + (new_an ^ gmac_an) & MVNETA_GMAC_INBAND_AN_ENABLE) {
  390. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
  391. + (gmac_an & ~MVNETA_GMAC_FORCE_LINK_PASS) |
  392. + MVNETA_GMAC_FORCE_LINK_DOWN);
  393. + }
  394. +
  395. + if (new_ctrl0 != gmac_ctrl0)
  396. + mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
  397. + if (new_ctrl2 != gmac_ctrl2)
  398. + mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2);
  399. + if (new_clk != gmac_clk)
  400. + mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk);
  401. + if (new_an != gmac_an)
  402. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an);
  403. +}
  404. +
  405. +static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode)
  406. +{
  407. + struct mvneta_port *pp = netdev_priv(ndev);
  408. + u32 val;
  409. +
  410. + mvneta_port_down(pp);
  411. +
  412. + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
  413. + val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  414. + val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
  415. + val |= MVNETA_GMAC_FORCE_LINK_DOWN;
  416. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  417. }
  418. }
  419. -static int mvneta_mdio_probe(struct mvneta_port *pp)
  420. +static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode,
  421. + struct phy_device *phy)
  422. {
  423. - struct phy_device *phy_dev;
  424. + struct mvneta_port *pp = netdev_priv(ndev);
  425. + u32 val;
  426. +
  427. + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
  428. + val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  429. + val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
  430. + val |= MVNETA_GMAC_FORCE_LINK_PASS;
  431. + mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  432. + }
  433. - phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
  434. - pp->phy_interface);
  435. - if (!phy_dev) {
  436. - netdev_err(pp->dev, "could not find the PHY\n");
  437. - return -ENODEV;
  438. - }
  439. -
  440. - phy_dev->supported &= PHY_GBIT_FEATURES;
  441. - phy_dev->advertising = phy_dev->supported;
  442. -
  443. - pp->phy_dev = phy_dev;
  444. - pp->link = 0;
  445. - pp->duplex = 0;
  446. - pp->speed = 0;
  447. + mvneta_port_up(pp);
  448. +}
  449. - return 0;
  450. +static const struct phylink_mac_ops mvneta_phylink_ops = {
  451. + .mac_get_support = mvneta_mac_support,
  452. + .mac_link_state = mvneta_mac_link_state,
  453. + .mac_an_restart = mvneta_mac_an_restart,
  454. + .mac_config = mvneta_mac_config,
  455. + .mac_link_down = mvneta_mac_link_down,
  456. + .mac_link_up = mvneta_mac_link_up,
  457. +};
  458. +
  459. +static int mvneta_mdio_probe(struct mvneta_port *pp)
  460. +{
  461. + int err = phylink_of_phy_connect(pp->phylink, pp->dn);
  462. + if (err)
  463. + netdev_err(pp->dev, "could not attach PHY\n");
  464. +
  465. + return err;
  466. }
  467. static void mvneta_mdio_remove(struct mvneta_port *pp)
  468. {
  469. - phy_disconnect(pp->phy_dev);
  470. - pp->phy_dev = NULL;
  471. + phylink_disconnect_phy(pp->phylink);
  472. }
  473. /* Electing a CPU must be done in an atomic way: it should be done
  474. @@ -3505,10 +3568,7 @@ static int mvneta_ioctl(struct net_devic
  475. {
  476. struct mvneta_port *pp = netdev_priv(dev);
  477. - if (!pp->phy_dev)
  478. - return -ENOTSUPP;
  479. -
  480. - return phy_mii_ioctl(pp->phy_dev, ifr, cmd);
  481. + return phylink_mii_ioctl(pp->phylink, ifr, cmd);
  482. }
  483. /* Ethtool methods */
  484. @@ -3518,54 +3578,15 @@ int mvneta_ethtool_get_settings(struct n
  485. {
  486. struct mvneta_port *pp = netdev_priv(dev);
  487. - if (!pp->phy_dev)
  488. - return -ENODEV;
  489. -
  490. - return phy_ethtool_gset(pp->phy_dev, cmd);
  491. + return phylink_ethtool_get_settings(pp->phylink, cmd);
  492. }
  493. /* Set settings (phy address, speed) for ethtools */
  494. int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  495. {
  496. struct mvneta_port *pp = netdev_priv(dev);
  497. - struct phy_device *phydev = pp->phy_dev;
  498. -
  499. - if (!phydev)
  500. - return -ENODEV;
  501. - if ((cmd->autoneg == AUTONEG_ENABLE) != pp->use_inband_status) {
  502. - u32 val;
  503. -
  504. - mvneta_set_autoneg(pp, cmd->autoneg == AUTONEG_ENABLE);
  505. -
  506. - if (cmd->autoneg == AUTONEG_DISABLE) {
  507. - val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
  508. - val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
  509. - MVNETA_GMAC_CONFIG_GMII_SPEED |
  510. - MVNETA_GMAC_CONFIG_FULL_DUPLEX);
  511. -
  512. - if (phydev->duplex)
  513. - val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
  514. -
  515. - if (phydev->speed == SPEED_1000)
  516. - val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
  517. - else if (phydev->speed == SPEED_100)
  518. - val |= MVNETA_GMAC_CONFIG_MII_SPEED;
  519. -
  520. - mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
  521. - }
  522. -
  523. - pp->use_inband_status = (cmd->autoneg == AUTONEG_ENABLE);
  524. - netdev_info(pp->dev, "autoneg status set to %i\n",
  525. - pp->use_inband_status);
  526. -
  527. - if (netif_running(dev)) {
  528. - mvneta_port_down(pp);
  529. - mvneta_port_up(pp);
  530. - }
  531. - }
  532. -
  533. - return phy_ethtool_sset(pp->phy_dev, cmd);
  534. + return phylink_ethtool_set_settings(pp->phylink, cmd);
  535. }
  536. /* Set interrupt coalescing for ethtools */
  537. @@ -3673,7 +3694,8 @@ static void mvneta_ethtool_update_stats(
  538. {
  539. const struct mvneta_statistic *s;
  540. void __iomem *base = pp->base;
  541. - u32 high, low, val;
  542. + u32 high, low;
  543. + u64 val;
  544. u64 val64;
  545. int i;
  546. @@ -3968,14 +3990,13 @@ static int mvneta_probe(struct platform_
  547. const struct mbus_dram_target_info *dram_target_info;
  548. struct resource *res;
  549. struct device_node *dn = pdev->dev.of_node;
  550. - struct device_node *phy_node;
  551. struct device_node *bm_node;
  552. struct mvneta_port *pp;
  553. struct net_device *dev;
  554. + struct phylink *phylink;
  555. const char *dt_mac_addr;
  556. char hw_mac_addr[ETH_ALEN];
  557. const char *mac_from;
  558. - const char *managed;
  559. int tx_csum_limit;
  560. int phy_mode;
  561. int err;
  562. @@ -3991,31 +4012,11 @@ static int mvneta_probe(struct platform_
  563. goto err_free_netdev;
  564. }
  565. - phy_node = of_parse_phandle(dn, "phy", 0);
  566. - if (!phy_node) {
  567. - if (!of_phy_is_fixed_link(dn)) {
  568. - dev_err(&pdev->dev, "no PHY specified\n");
  569. - err = -ENODEV;
  570. - goto err_free_irq;
  571. - }
  572. -
  573. - err = of_phy_register_fixed_link(dn);
  574. - if (err < 0) {
  575. - dev_err(&pdev->dev, "cannot register fixed PHY\n");
  576. - goto err_free_irq;
  577. - }
  578. -
  579. - /* In the case of a fixed PHY, the DT node associated
  580. - * to the PHY is the Ethernet MAC DT node.
  581. - */
  582. - phy_node = of_node_get(dn);
  583. - }
  584. -
  585. phy_mode = of_get_phy_mode(dn);
  586. if (phy_mode < 0) {
  587. dev_err(&pdev->dev, "incorrect phy-mode\n");
  588. err = -EINVAL;
  589. - goto err_put_phy_node;
  590. + goto err_free_irq;
  591. }
  592. dev->tx_queue_len = MVNETA_MAX_TXD;
  593. @@ -4026,12 +4027,7 @@ static int mvneta_probe(struct platform_
  594. pp = netdev_priv(dev);
  595. spin_lock_init(&pp->lock);
  596. - pp->phy_node = phy_node;
  597. - pp->phy_interface = phy_mode;
  598. -
  599. - err = of_property_read_string(dn, "managed", &managed);
  600. - pp->use_inband_status = (err == 0 &&
  601. - strcmp(managed, "in-band-status") == 0);
  602. + pp->dn = dn;
  603. pp->cpu_notifier.notifier_call = mvneta_percpu_notifier;
  604. pp->rxq_def = rxq_def;
  605. @@ -4041,7 +4037,7 @@ static int mvneta_probe(struct platform_
  606. pp->clk = devm_clk_get(&pdev->dev, NULL);
  607. if (IS_ERR(pp->clk)) {
  608. err = PTR_ERR(pp->clk);
  609. - goto err_put_phy_node;
  610. + goto err_free_irq;
  611. }
  612. clk_prepare_enable(pp->clk);
  613. @@ -4144,6 +4140,14 @@ static int mvneta_probe(struct platform_
  614. dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
  615. dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
  616. + phylink = phylink_create(dev, dn, phy_mode, &mvneta_phylink_ops);
  617. + if (IS_ERR(phylink)) {
  618. + err = PTR_ERR(phylink);
  619. + goto err_free_stats;
  620. + }
  621. +
  622. + pp->phylink = phylink;
  623. +
  624. err = register_netdev(dev);
  625. if (err < 0) {
  626. dev_err(&pdev->dev, "failed to register\n");
  627. @@ -4155,13 +4159,6 @@ static int mvneta_probe(struct platform_
  628. platform_set_drvdata(pdev, pp->dev);
  629. - if (pp->use_inband_status) {
  630. - struct phy_device *phy = of_phy_find_device(dn);
  631. -
  632. - mvneta_fixed_link_update(pp, phy);
  633. -
  634. - put_device(&phy->dev);
  635. - }
  636. return 0;
  637. @@ -4173,13 +4170,13 @@ err_netdev:
  638. 1 << pp->id);
  639. }
  640. err_free_stats:
  641. + if (pp->phylink)
  642. + phylink_destroy(pp->phylink);
  643. free_percpu(pp->stats);
  644. err_free_ports:
  645. free_percpu(pp->ports);
  646. err_clk:
  647. clk_disable_unprepare(pp->clk);
  648. -err_put_phy_node:
  649. - of_node_put(phy_node);
  650. err_free_irq:
  651. irq_dispose_mapping(dev->irq);
  652. err_free_netdev:
  653. @@ -4198,7 +4195,7 @@ static int mvneta_remove(struct platform
  654. free_percpu(pp->ports);
  655. free_percpu(pp->stats);
  656. irq_dispose_mapping(dev->irq);
  657. - of_node_put(pp->phy_node);
  658. + phylink_destroy(pp->phylink);
  659. free_netdev(dev);
  660. if (pp->bm_priv) {