733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Sun, 19 Mar 2023 12:58:02 +0000
  4. Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver
  5. Now that we got a PCS driver, use it and remove the now redundant
  6. PCS code and it's header macros from the Ethernet driver.
  7. Signed-off-by: Daniel Golle <[email protected]>
  8. Tested-by: Frank Wunderlich <[email protected]>
  9. Reviewed-by: Russell King (Oracle) <[email protected]>
  10. Signed-off-by: Jakub Kicinski <[email protected]>
  11. ---
  12. drivers/net/ethernet/mediatek/Kconfig | 2 +
  13. drivers/net/ethernet/mediatek/Makefile | 2 +-
  14. drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++-
  15. drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +--------
  16. drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 --------------------
  17. 5 files changed, 56 insertions(+), 319 deletions(-)
  18. delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
  19. --- a/drivers/net/ethernet/mediatek/Kconfig
  20. +++ b/drivers/net/ethernet/mediatek/Kconfig
  21. @@ -18,6 +18,8 @@ config NET_MEDIATEK_SOC
  22. select DIMLIB
  23. select PAGE_POOL
  24. select PAGE_POOL_STATS
  25. + select PCS_MTK_LYNXI
  26. + select REGMAP_MMIO
  27. help
  28. This driver supports the gigabit ethernet MACs in the
  29. MediaTek SoC family.
  30. --- a/drivers/net/ethernet/mediatek/Makefile
  31. +++ b/drivers/net/ethernet/mediatek/Makefile
  32. @@ -4,7 +4,7 @@
  33. #
  34. obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
  35. -mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
  36. +mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
  37. mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
  38. ifdef CONFIG_DEBUG_FS
  39. mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
  40. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  41. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  42. @@ -20,6 +20,7 @@
  43. #include <linux/interrupt.h>
  44. #include <linux/pinctrl/devinfo.h>
  45. #include <linux/phylink.h>
  46. +#include <linux/pcs/pcs-mtk-lynxi.h>
  47. #include <linux/jhash.h>
  48. #include <linux/bitfield.h>
  49. #include <net/dsa.h>
  50. @@ -357,7 +358,7 @@ static struct phylink_pcs *mtk_mac_selec
  51. sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
  52. 0 : mac->id;
  53. - return mtk_sgmii_select_pcs(eth->sgmii, sid);
  54. + return eth->sgmii_pcs[sid];
  55. }
  56. return NULL;
  57. @@ -3962,8 +3963,17 @@ static int mtk_unreg_dev(struct mtk_eth
  58. return 0;
  59. }
  60. +static void mtk_sgmii_destroy(struct mtk_eth *eth)
  61. +{
  62. + int i;
  63. +
  64. + for (i = 0; i < MTK_MAX_DEVS; i++)
  65. + mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
  66. +}
  67. +
  68. static int mtk_cleanup(struct mtk_eth *eth)
  69. {
  70. + mtk_sgmii_destroy(eth);
  71. mtk_unreg_dev(eth);
  72. mtk_free_dev(eth);
  73. cancel_work_sync(&eth->pending_work);
  74. @@ -4403,6 +4413,36 @@ void mtk_eth_set_dma_device(struct mtk_e
  75. rtnl_unlock();
  76. }
  77. +static int mtk_sgmii_init(struct mtk_eth *eth)
  78. +{
  79. + struct device_node *np;
  80. + struct regmap *regmap;
  81. + u32 flags;
  82. + int i;
  83. +
  84. + for (i = 0; i < MTK_MAX_DEVS; i++) {
  85. + np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
  86. + if (!np)
  87. + break;
  88. +
  89. + regmap = syscon_node_to_regmap(np);
  90. + flags = 0;
  91. + if (of_property_read_bool(np, "mediatek,pnswap"))
  92. + flags |= MTK_SGMII_FLAG_PN_SWAP;
  93. +
  94. + of_node_put(np);
  95. +
  96. + if (IS_ERR(regmap))
  97. + return PTR_ERR(regmap);
  98. +
  99. + eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap,
  100. + eth->soc->ana_rgc3,
  101. + flags);
  102. + }
  103. +
  104. + return 0;
  105. +}
  106. +
  107. static int mtk_probe(struct platform_device *pdev)
  108. {
  109. struct resource *res = NULL;
  110. @@ -4466,13 +4506,7 @@ static int mtk_probe(struct platform_dev
  111. }
  112. if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
  113. - eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
  114. - GFP_KERNEL);
  115. - if (!eth->sgmii)
  116. - return -ENOMEM;
  117. -
  118. - err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
  119. - eth->soc->ana_rgc3);
  120. + err = mtk_sgmii_init(eth);
  121. if (err)
  122. return err;
  123. @@ -4483,14 +4517,17 @@ static int mtk_probe(struct platform_dev
  124. "mediatek,pctl");
  125. if (IS_ERR(eth->pctl)) {
  126. dev_err(&pdev->dev, "no pctl regmap found\n");
  127. - return PTR_ERR(eth->pctl);
  128. + err = PTR_ERR(eth->pctl);
  129. + goto err_destroy_sgmii;
  130. }
  131. }
  132. if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
  133. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  134. - if (!res)
  135. - return -EINVAL;
  136. + if (!res) {
  137. + err = -EINVAL;
  138. + goto err_destroy_sgmii;
  139. + }
  140. }
  141. if (eth->soc->offload_version) {
  142. @@ -4651,6 +4688,8 @@ err_deinit_hw:
  143. mtk_hw_deinit(eth);
  144. err_wed_exit:
  145. mtk_wed_exit();
  146. +err_destroy_sgmii:
  147. + mtk_sgmii_destroy(eth);
  148. return err;
  149. }
  150. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  151. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  152. @@ -507,65 +507,6 @@
  153. #define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
  154. #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
  155. -/* SGMII subsystem config registers */
  156. -/* BMCR (low 16) BMSR (high 16) */
  157. -#define SGMSYS_PCS_CONTROL_1 0x0
  158. -#define SGMII_BMCR GENMASK(15, 0)
  159. -#define SGMII_BMSR GENMASK(31, 16)
  160. -#define SGMII_AN_RESTART BIT(9)
  161. -#define SGMII_ISOLATE BIT(10)
  162. -#define SGMII_AN_ENABLE BIT(12)
  163. -#define SGMII_LINK_STATYS BIT(18)
  164. -#define SGMII_AN_ABILITY BIT(19)
  165. -#define SGMII_AN_COMPLETE BIT(21)
  166. -#define SGMII_PCS_FAULT BIT(23)
  167. -#define SGMII_AN_EXPANSION_CLR BIT(30)
  168. -
  169. -#define SGMSYS_PCS_ADVERTISE 0x8
  170. -#define SGMII_ADVERTISE GENMASK(15, 0)
  171. -#define SGMII_LPA GENMASK(31, 16)
  172. -
  173. -/* Register to programmable link timer, the unit in 2 * 8ns */
  174. -#define SGMSYS_PCS_LINK_TIMER 0x18
  175. -#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
  176. -#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
  177. -
  178. -/* Register to control remote fault */
  179. -#define SGMSYS_SGMII_MODE 0x20
  180. -#define SGMII_IF_MODE_SGMII BIT(0)
  181. -#define SGMII_SPEED_DUPLEX_AN BIT(1)
  182. -#define SGMII_SPEED_MASK GENMASK(3, 2)
  183. -#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
  184. -#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
  185. -#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
  186. -#define SGMII_DUPLEX_HALF BIT(4)
  187. -#define SGMII_IF_MODE_BIT5 BIT(5)
  188. -#define SGMII_REMOTE_FAULT_DIS BIT(8)
  189. -#define SGMII_CODE_SYNC_SET_VAL BIT(9)
  190. -#define SGMII_CODE_SYNC_SET_EN BIT(10)
  191. -#define SGMII_SEND_AN_ERROR_EN BIT(11)
  192. -#define SGMII_IF_MODE_MASK GENMASK(5, 1)
  193. -
  194. -/* Register to reset SGMII design */
  195. -#define SGMII_RESERVED_0 0x34
  196. -#define SGMII_SW_RESET BIT(0)
  197. -
  198. -/* Register to set SGMII speed, ANA RG_ Control Signals III*/
  199. -#define SGMSYS_ANA_RG_CS3 0x2028
  200. -#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
  201. -#define RG_PHY_SPEED_1_25G 0x0
  202. -#define RG_PHY_SPEED_3_125G BIT(2)
  203. -
  204. -/* Register to power up QPHY */
  205. -#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
  206. -#define SGMII_PHYA_PWD BIT(4)
  207. -
  208. -/* Register to QPHY wrapper control */
  209. -#define SGMSYS_QPHY_WRAP_CTRL 0xec
  210. -#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
  211. -#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
  212. -#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
  213. -
  214. /* Infrasys subsystem config registers */
  215. #define INFRA_MISC2 0x70c
  216. #define CO_QPHY_SEL BIT(0)
  217. @@ -1099,31 +1040,6 @@ struct mtk_soc_data {
  218. /* currently no SoC has more than 2 macs */
  219. #define MTK_MAX_DEVS 2
  220. -/* struct mtk_pcs - This structure holds each sgmii regmap and associated
  221. - * data
  222. - * @regmap: The register map pointing at the range used to setup
  223. - * SGMII modes
  224. - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
  225. - * @interface: Currently configured interface mode
  226. - * @pcs: Phylink PCS structure
  227. - * @flags: Flags indicating hardware properties
  228. - */
  229. -struct mtk_pcs {
  230. - struct regmap *regmap;
  231. - u32 ana_rgc3;
  232. - phy_interface_t interface;
  233. - struct phylink_pcs pcs;
  234. - u32 flags;
  235. -};
  236. -
  237. -/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
  238. - * characteristics
  239. - * @pcs Array of individual PCS structures
  240. - */
  241. -struct mtk_sgmii {
  242. - struct mtk_pcs pcs[MTK_MAX_DEVS];
  243. -};
  244. -
  245. /* struct mtk_eth - This is the main datasructure for holding the state
  246. * of the driver
  247. * @dev: The device pointer
  248. @@ -1143,6 +1059,7 @@ struct mtk_sgmii {
  249. * MII modes
  250. * @infra: The register map pointing at the range used to setup
  251. * SGMII and GePHY path
  252. + * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
  253. * @pctl: The register map pointing at the range used to setup
  254. * GMAC port drive/slew values
  255. * @dma_refcnt: track how many netdevs are using the DMA engine
  256. @@ -1183,8 +1100,8 @@ struct mtk_eth {
  257. u32 msg_enable;
  258. unsigned long sysclk;
  259. struct regmap *ethsys;
  260. - struct regmap *infra;
  261. - struct mtk_sgmii *sgmii;
  262. + struct regmap *infra;
  263. + struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
  264. struct regmap *pctl;
  265. bool hwlro;
  266. refcount_t dma_refcnt;
  267. @@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac
  268. void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
  269. u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
  270. -struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
  271. -int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
  272. - u32 ana_rgc3);
  273. -
  274. int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
  275. int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
  276. int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
  277. --- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
  278. +++ /dev/null
  279. @@ -1,217 +0,0 @@
  280. -// SPDX-License-Identifier: GPL-2.0
  281. -// Copyright (c) 2018-2019 MediaTek Inc.
  282. -
  283. -/* A library for MediaTek SGMII circuit
  284. - *
  285. - * Author: Sean Wang <[email protected]>
  286. - *
  287. - */
  288. -
  289. -#include <linux/mfd/syscon.h>
  290. -#include <linux/of.h>
  291. -#include <linux/phylink.h>
  292. -#include <linux/regmap.h>
  293. -
  294. -#include "mtk_eth_soc.h"
  295. -
  296. -static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
  297. -{
  298. - return container_of(pcs, struct mtk_pcs, pcs);
  299. -}
  300. -
  301. -static void mtk_pcs_get_state(struct phylink_pcs *pcs,
  302. - struct phylink_link_state *state)
  303. -{
  304. - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
  305. - unsigned int bm, adv;
  306. -
  307. - /* Read the BMSR and LPA */
  308. - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
  309. - regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
  310. -
  311. - phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
  312. - FIELD_GET(SGMII_LPA, adv));
  313. -}
  314. -
  315. -static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
  316. - phy_interface_t interface,
  317. - const unsigned long *advertising,
  318. - bool permit_pause_to_mac)
  319. -{
  320. - bool mode_changed = false, changed, use_an;
  321. - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
  322. - unsigned int rgc3, sgm_mode, bmcr;
  323. - int advertise, link_timer;
  324. -
  325. - advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
  326. - advertising);
  327. - if (advertise < 0)
  328. - return advertise;
  329. -
  330. - /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
  331. - * we assume that fixes it's speed at bitrate = line rate (in
  332. - * other words, 1000Mbps or 2500Mbps).
  333. - */
  334. - if (interface == PHY_INTERFACE_MODE_SGMII) {
  335. - sgm_mode = SGMII_IF_MODE_SGMII;
  336. - if (phylink_autoneg_inband(mode)) {
  337. - sgm_mode |= SGMII_REMOTE_FAULT_DIS |
  338. - SGMII_SPEED_DUPLEX_AN;
  339. - use_an = true;
  340. - } else {
  341. - use_an = false;
  342. - }
  343. - } else if (phylink_autoneg_inband(mode)) {
  344. - /* 1000base-X or 2500base-X autoneg */
  345. - sgm_mode = SGMII_REMOTE_FAULT_DIS;
  346. - use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  347. - advertising);
  348. - } else {
  349. - /* 1000base-X or 2500base-X without autoneg */
  350. - sgm_mode = 0;
  351. - use_an = false;
  352. - }
  353. -
  354. - if (use_an) {
  355. - bmcr = SGMII_AN_ENABLE;
  356. - } else {
  357. - bmcr = 0;
  358. - }
  359. -
  360. - if (mpcs->interface != interface) {
  361. - link_timer = phylink_get_link_timer_ns(interface);
  362. - if (link_timer < 0)
  363. - return link_timer;
  364. -
  365. - /* PHYA power down */
  366. - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
  367. - SGMII_PHYA_PWD, SGMII_PHYA_PWD);
  368. -
  369. - if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
  370. - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
  371. - SGMII_PN_SWAP_MASK,
  372. - SGMII_PN_SWAP_TX_RX);
  373. -
  374. - /* Reset SGMII PCS state */
  375. - regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
  376. - SGMII_SW_RESET, SGMII_SW_RESET);
  377. -
  378. - if (interface == PHY_INTERFACE_MODE_2500BASEX)
  379. - rgc3 = RG_PHY_SPEED_3_125G;
  380. - else
  381. - rgc3 = 0;
  382. -
  383. - /* Configure the underlying interface speed */
  384. - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
  385. - RG_PHY_SPEED_3_125G, rgc3);
  386. -
  387. - /* Setup the link timer */
  388. - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
  389. -
  390. - mpcs->interface = interface;
  391. - mode_changed = true;
  392. - }
  393. -
  394. - /* Update the advertisement, noting whether it has changed */
  395. - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
  396. - SGMII_ADVERTISE, advertise, &changed);
  397. -
  398. - /* Update the sgmsys mode register */
  399. - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
  400. - SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
  401. - SGMII_IF_MODE_SGMII, sgm_mode);
  402. -
  403. - /* Update the BMCR */
  404. - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
  405. - SGMII_AN_ENABLE, bmcr);
  406. -
  407. - /* Release PHYA power down state
  408. - * Only removing bit SGMII_PHYA_PWD isn't enough.
  409. - * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
  410. - * prevents SGMII from working. The SGMII still shows link but no traffic
  411. - * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
  412. - * taken from a good working state of the SGMII interface.
  413. - * Unknown how much the QPHY needs but it is racy without a sleep.
  414. - * Tested on mt7622 & mt7986.
  415. - */
  416. - usleep_range(50, 100);
  417. - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
  418. -
  419. - return changed || mode_changed;
  420. -}
  421. -
  422. -static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
  423. -{
  424. - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
  425. -
  426. - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
  427. - SGMII_AN_RESTART, SGMII_AN_RESTART);
  428. -}
  429. -
  430. -static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
  431. - phy_interface_t interface, int speed, int duplex)
  432. -{
  433. - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
  434. - unsigned int sgm_mode;
  435. -
  436. - if (!phylink_autoneg_inband(mode)) {
  437. - /* Force the speed and duplex setting */
  438. - if (speed == SPEED_10)
  439. - sgm_mode = SGMII_SPEED_10;
  440. - else if (speed == SPEED_100)
  441. - sgm_mode = SGMII_SPEED_100;
  442. - else
  443. - sgm_mode = SGMII_SPEED_1000;
  444. -
  445. - if (duplex != DUPLEX_FULL)
  446. - sgm_mode |= SGMII_DUPLEX_HALF;
  447. -
  448. - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
  449. - SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
  450. - sgm_mode);
  451. - }
  452. -}
  453. -
  454. -static const struct phylink_pcs_ops mtk_pcs_ops = {
  455. - .pcs_get_state = mtk_pcs_get_state,
  456. - .pcs_config = mtk_pcs_config,
  457. - .pcs_an_restart = mtk_pcs_restart_an,
  458. - .pcs_link_up = mtk_pcs_link_up,
  459. -};
  460. -
  461. -int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
  462. -{
  463. - struct device_node *np;
  464. - int i;
  465. -
  466. - for (i = 0; i < MTK_MAX_DEVS; i++) {
  467. - np = of_parse_phandle(r, "mediatek,sgmiisys", i);
  468. - if (!np)
  469. - break;
  470. -
  471. - ss->pcs[i].ana_rgc3 = ana_rgc3;
  472. - ss->pcs[i].regmap = syscon_node_to_regmap(np);
  473. -
  474. - ss->pcs[i].flags = 0;
  475. - if (of_property_read_bool(np, "mediatek,pnswap"))
  476. - ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
  477. -
  478. - of_node_put(np);
  479. - if (IS_ERR(ss->pcs[i].regmap))
  480. - return PTR_ERR(ss->pcs[i].regmap);
  481. -
  482. - ss->pcs[i].pcs.ops = &mtk_pcs_ops;
  483. - ss->pcs[i].pcs.poll = true;
  484. - ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
  485. - }
  486. -
  487. - return 0;
  488. -}
  489. -
  490. -struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
  491. -{
  492. - if (!ss->pcs[id].regmap)
  493. - return NULL;
  494. -
  495. - return &ss->pcs[id].pcs;
  496. -}