mxl-gpy.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /* Copyright (C) 2021 Maxlinear Corporation
  3. * Copyright (C) 2020 Intel Corporation
  4. *
  5. * Drivers for Maxlinear Ethernet GPY
  6. *
  7. */
  8. #include <linux/module.h>
  9. #include <linux/bitfield.h>
  10. #include <linux/hwmon.h>
  11. #include <linux/mutex.h>
  12. #include <linux/phy.h>
  13. #include <linux/polynomial.h>
  14. #include <linux/property.h>
  15. #include <linux/netdevice.h>
  16. /* PHY ID */
  17. #define PHY_ID_GPYx15B_MASK 0xFFFFFFFC
  18. #define PHY_ID_GPY21xB_MASK 0xFFFFFFF9
  19. #define PHY_ID_GPY2xx 0x67C9DC00
  20. #define PHY_ID_GPY115B 0x67C9DF00
  21. #define PHY_ID_GPY115C 0x67C9DF10
  22. #define PHY_ID_GPY211B 0x67C9DE08
  23. #define PHY_ID_GPY211C 0x67C9DE10
  24. #define PHY_ID_GPY212B 0x67C9DE09
  25. #define PHY_ID_GPY212C 0x67C9DE20
  26. #define PHY_ID_GPY215B 0x67C9DF04
  27. #define PHY_ID_GPY215C 0x67C9DF20
  28. #define PHY_ID_GPY241B 0x67C9DE40
  29. #define PHY_ID_GPY241BM 0x67C9DE80
  30. #define PHY_ID_GPY245B 0x67C9DEC0
  31. #define PHY_ID_MXL86211C 0xC1335400
  32. #define PHY_ID_MXL86252 0xC1335520
  33. #define PHY_ID_MXL86282 0xC1335500
  34. #define PHY_CTL1 0x13
  35. #define PHY_CTL1_MDICD BIT(3)
  36. #define PHY_CTL1_MDIAB BIT(2)
  37. #define PHY_CTL1_AMDIX BIT(0)
  38. #define PHY_MIISTAT 0x18 /* MII state */
  39. #define PHY_IMASK 0x19 /* interrupt mask */
  40. #define PHY_ISTAT 0x1A /* interrupt status */
  41. #define PHY_LED 0x1B /* LEDs */
  42. #define PHY_FWV 0x1E /* firmware version */
  43. #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0)
  44. #define PHY_MIISTAT_DPX BIT(3)
  45. #define PHY_MIISTAT_LS BIT(10)
  46. #define PHY_MIISTAT_SPD_10 0
  47. #define PHY_MIISTAT_SPD_100 1
  48. #define PHY_MIISTAT_SPD_1000 2
  49. #define PHY_MIISTAT_SPD_2500 4
  50. #define PHY_IMASK_WOL BIT(15) /* Wake-on-LAN */
  51. #define PHY_IMASK_ANC BIT(10) /* Auto-Neg complete */
  52. #define PHY_IMASK_ADSC BIT(5) /* Link auto-downspeed detect */
  53. #define PHY_IMASK_DXMC BIT(2) /* Duplex mode change */
  54. #define PHY_IMASK_LSPC BIT(1) /* Link speed change */
  55. #define PHY_IMASK_LSTC BIT(0) /* Link state change */
  56. #define PHY_IMASK_MASK (PHY_IMASK_LSTC | \
  57. PHY_IMASK_LSPC | \
  58. PHY_IMASK_DXMC | \
  59. PHY_IMASK_ADSC | \
  60. PHY_IMASK_ANC)
  61. #define GPY_MAX_LEDS 4
  62. #define PHY_LED_POLARITY(idx) BIT(12 + (idx))
  63. #define PHY_LED_HWCONTROL(idx) BIT(8 + (idx))
  64. #define PHY_LED_ON(idx) BIT(idx)
  65. #define PHY_FWV_REL_MASK BIT(15)
  66. #define PHY_FWV_MAJOR_MASK GENMASK(11, 8)
  67. #define PHY_FWV_MINOR_MASK GENMASK(7, 0)
  68. #define PHY_PMA_MGBT_POLARITY 0x82
  69. #define PHY_MDI_MDI_X_MASK GENMASK(1, 0)
  70. #define PHY_MDI_MDI_X_NORMAL 0x3
  71. #define PHY_MDI_MDI_X_AB 0x2
  72. #define PHY_MDI_MDI_X_CD 0x1
  73. #define PHY_MDI_MDI_X_CROSS 0x0
  74. /* LED */
  75. #define VSPEC1_LED(idx) (1 + (idx))
  76. #define VSPEC1_LED_BLINKS GENMASK(15, 12)
  77. #define VSPEC1_LED_PULSE GENMASK(11, 8)
  78. #define VSPEC1_LED_CON GENMASK(7, 4)
  79. #define VSPEC1_LED_BLINKF GENMASK(3, 0)
  80. #define VSPEC1_LED_LINK10 BIT(0)
  81. #define VSPEC1_LED_LINK100 BIT(1)
  82. #define VSPEC1_LED_LINK1000 BIT(2)
  83. #define VSPEC1_LED_LINK2500 BIT(3)
  84. #define VSPEC1_LED_TXACT BIT(0)
  85. #define VSPEC1_LED_RXACT BIT(1)
  86. #define VSPEC1_LED_COL BIT(2)
  87. #define VSPEC1_LED_NO_CON BIT(3)
  88. /* SGMII */
  89. #define VSPEC1_SGMII_CTRL 0x08
  90. #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */
  91. #define VSPEC1_SGMII_CTRL_ANRS BIT(9) /* Restart Aneg */
  92. #define VSPEC1_SGMII_ANEN_ANRS (VSPEC1_SGMII_CTRL_ANEN | \
  93. VSPEC1_SGMII_CTRL_ANRS)
  94. /* Temperature sensor */
  95. #define VSPEC1_TEMP_STA 0x0E
  96. #define VSPEC1_TEMP_STA_DATA GENMASK(9, 0)
  97. /* Mailbox */
  98. #define VSPEC1_MBOX_DATA 0x5
  99. #define VSPEC1_MBOX_ADDRLO 0x6
  100. #define VSPEC1_MBOX_CMD 0x7
  101. #define VSPEC1_MBOX_CMD_ADDRHI GENMASK(7, 0)
  102. #define VSPEC1_MBOX_CMD_RD (0 << 8)
  103. #define VSPEC1_MBOX_CMD_READY BIT(15)
  104. /* WoL */
  105. #define VPSPEC2_WOL_CTL 0x0E06
  106. #define VPSPEC2_WOL_AD01 0x0E08
  107. #define VPSPEC2_WOL_AD23 0x0E09
  108. #define VPSPEC2_WOL_AD45 0x0E0A
  109. #define WOL_EN BIT(0)
  110. /* Internal registers, access via mbox */
  111. #define REG_GPIO0_OUT 0xd3ce00
  112. struct gpy_priv {
  113. /* serialize mailbox acesses */
  114. struct mutex mbox_lock;
  115. u8 fw_major;
  116. u8 fw_minor;
  117. u32 wolopts;
  118. /* It takes 3 seconds to fully switch out of loopback mode before
  119. * it can safely re-enter loopback mode. Record the time when
  120. * loopback is disabled. Check and wait if necessary before loopback
  121. * is enabled.
  122. */
  123. u64 lb_dis_to;
  124. };
  125. static const struct {
  126. int major;
  127. int minor;
  128. } ver_need_sgmii_reaneg[] = {
  129. {7, 0x6D},
  130. {8, 0x6D},
  131. {9, 0x73},
  132. };
  133. #if IS_ENABLED(CONFIG_HWMON)
  134. /* The original translation formulae of the temperature (in degrees of Celsius)
  135. * are as follows:
  136. *
  137. * T = -2.5761e-11*(N^4) + 9.7332e-8*(N^3) + -1.9165e-4*(N^2) +
  138. * 3.0762e-1*(N^1) + -5.2156e1
  139. *
  140. * where [-52.156, 137.961]C and N = [0, 1023].
  141. *
  142. * They must be accordingly altered to be suitable for the integer arithmetics.
  143. * The technique is called 'factor redistribution', which just makes sure the
  144. * multiplications and divisions are made so to have a result of the operations
  145. * within the integer numbers limit. In addition we need to translate the
  146. * formulae to accept millidegrees of Celsius. Here what it looks like after
  147. * the alterations:
  148. *
  149. * T = -25761e-12*(N^4) + 97332e-9*(N^3) + -191650e-6*(N^2) +
  150. * 307620e-3*(N^1) + -52156
  151. *
  152. * where T = [-52156, 137961]mC and N = [0, 1023].
  153. */
  154. static const struct polynomial poly_N_to_temp = {
  155. .terms = {
  156. {4, -25761, 1000, 1},
  157. {3, 97332, 1000, 1},
  158. {2, -191650, 1000, 1},
  159. {1, 307620, 1000, 1},
  160. {0, -52156, 1, 1}
  161. }
  162. };
  163. static int gpy_hwmon_read(struct device *dev,
  164. enum hwmon_sensor_types type,
  165. u32 attr, int channel, long *value)
  166. {
  167. struct phy_device *phydev = dev_get_drvdata(dev);
  168. int ret;
  169. ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_TEMP_STA);
  170. if (ret < 0)
  171. return ret;
  172. if (!ret)
  173. return -ENODATA;
  174. *value = polynomial_calc(&poly_N_to_temp,
  175. FIELD_GET(VSPEC1_TEMP_STA_DATA, ret));
  176. return 0;
  177. }
  178. static int mxl862x2_hwmon_read(struct device *dev,
  179. enum hwmon_sensor_types type,
  180. u32 attr, int channel, long *value)
  181. {
  182. struct phy_device *phydev = dev_get_drvdata(dev);
  183. long tmp;
  184. int ret;
  185. ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_TEMP_STA);
  186. if (ret < 0)
  187. return ret;
  188. if (!ret)
  189. return -ENODATA;
  190. tmp = (s16)ret;
  191. tmp *= 78125;
  192. tmp /= 10000;
  193. *value = tmp;
  194. return 0;
  195. }
  196. static umode_t gpy_hwmon_is_visible(const void *data,
  197. enum hwmon_sensor_types type,
  198. u32 attr, int channel)
  199. {
  200. return 0444;
  201. }
  202. static const struct hwmon_channel_info * const gpy_hwmon_info[] = {
  203. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
  204. NULL
  205. };
  206. static const struct hwmon_ops gpy_hwmon_hwmon_ops = {
  207. .is_visible = gpy_hwmon_is_visible,
  208. .read = gpy_hwmon_read,
  209. };
  210. static const struct hwmon_ops mxl862x2_hwmon_hwmon_ops = {
  211. .is_visible = gpy_hwmon_is_visible,
  212. .read = mxl862x2_hwmon_read,
  213. };
  214. static const struct hwmon_chip_info gpy_hwmon_chip_info = {
  215. .ops = &gpy_hwmon_hwmon_ops,
  216. .info = gpy_hwmon_info,
  217. };
  218. static const struct hwmon_chip_info mxl862x2_hwmon_chip_info = {
  219. .ops = &mxl862x2_hwmon_hwmon_ops,
  220. .info = gpy_hwmon_info,
  221. };
  222. static int gpy_hwmon_register(struct phy_device *phydev)
  223. {
  224. struct device *dev = &phydev->mdio.dev;
  225. const struct hwmon_chip_info *info;
  226. struct device *hwmon_dev;
  227. if (phy_id_compare_model(phydev->phy_id, PHY_ID_MXL86252) ||
  228. phy_id_compare_model(phydev->phy_id, PHY_ID_MXL86282))
  229. info = &mxl862x2_hwmon_chip_info;
  230. else
  231. info = &gpy_hwmon_chip_info;
  232. hwmon_dev = devm_hwmon_device_register_with_info(dev, NULL, phydev,
  233. info, NULL);
  234. return PTR_ERR_OR_ZERO(hwmon_dev);
  235. }
  236. #else
  237. static int gpy_hwmon_register(struct phy_device *phydev)
  238. {
  239. return 0;
  240. }
  241. #endif
  242. static int gpy_ack_interrupt(struct phy_device *phydev)
  243. {
  244. int ret;
  245. /* Clear all pending interrupts */
  246. ret = phy_read(phydev, PHY_ISTAT);
  247. return ret < 0 ? ret : 0;
  248. }
  249. static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
  250. {
  251. struct gpy_priv *priv = phydev->priv;
  252. int val, ret;
  253. u16 cmd;
  254. mutex_lock(&priv->mbox_lock);
  255. ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_ADDRLO,
  256. addr);
  257. if (ret)
  258. goto out;
  259. cmd = VSPEC1_MBOX_CMD_RD;
  260. cmd |= FIELD_PREP(VSPEC1_MBOX_CMD_ADDRHI, addr >> 16);
  261. ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_CMD, cmd);
  262. if (ret)
  263. goto out;
  264. /* The mbox read is used in the interrupt workaround. It was observed
  265. * that a read might take up to 2.5ms. This is also the time for which
  266. * the interrupt line is stuck low. To be on the safe side, poll the
  267. * ready bit for 10ms.
  268. */
  269. ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
  270. VSPEC1_MBOX_CMD, val,
  271. (val & VSPEC1_MBOX_CMD_READY),
  272. 500, 10000, false);
  273. if (ret)
  274. goto out;
  275. ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_DATA);
  276. out:
  277. mutex_unlock(&priv->mbox_lock);
  278. return ret;
  279. }
  280. static int gpy_config_init(struct phy_device *phydev)
  281. {
  282. /* Nothing to configure. Configuration Requirement Placeholder */
  283. return 0;
  284. }
  285. static int gpy21x_config_init(struct phy_device *phydev)
  286. {
  287. __set_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces);
  288. __set_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces);
  289. return gpy_config_init(phydev);
  290. }
  291. static int gpy_probe(struct phy_device *phydev)
  292. {
  293. struct device *dev = &phydev->mdio.dev;
  294. struct gpy_priv *priv;
  295. int fw_version;
  296. int ret;
  297. if (!phydev->is_c45) {
  298. ret = phy_get_c45_ids(phydev);
  299. if (ret < 0)
  300. return ret;
  301. }
  302. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  303. if (!priv)
  304. return -ENOMEM;
  305. phydev->priv = priv;
  306. mutex_init(&priv->mbox_lock);
  307. if (!device_property_present(dev, "maxlinear,use-broken-interrupts"))
  308. phydev->dev_flags |= PHY_F_NO_IRQ;
  309. fw_version = phy_read(phydev, PHY_FWV);
  310. if (fw_version < 0)
  311. return fw_version;
  312. priv->fw_major = FIELD_GET(PHY_FWV_MAJOR_MASK, fw_version);
  313. priv->fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_version);
  314. ret = gpy_hwmon_register(phydev);
  315. if (ret)
  316. return ret;
  317. /* Show GPY PHY FW version in dmesg */
  318. phydev_info(phydev, "Firmware Version: %d.%d (0x%04X%s)\n",
  319. priv->fw_major, priv->fw_minor, fw_version,
  320. fw_version & PHY_FWV_REL_MASK ? "" : " test version");
  321. return 0;
  322. }
  323. static bool gpy_sgmii_need_reaneg(struct phy_device *phydev)
  324. {
  325. struct gpy_priv *priv = phydev->priv;
  326. size_t i;
  327. for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) {
  328. if (priv->fw_major != ver_need_sgmii_reaneg[i].major)
  329. continue;
  330. if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor)
  331. return true;
  332. break;
  333. }
  334. return false;
  335. }
  336. static bool gpy_2500basex_chk(struct phy_device *phydev)
  337. {
  338. int ret;
  339. ret = phy_read(phydev, PHY_MIISTAT);
  340. if (ret < 0) {
  341. phydev_err(phydev, "Error: MDIO register access failed: %d\n",
  342. ret);
  343. return false;
  344. }
  345. if (!(ret & PHY_MIISTAT_LS) ||
  346. FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500)
  347. return false;
  348. phydev->speed = SPEED_2500;
  349. phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
  350. phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
  351. VSPEC1_SGMII_CTRL_ANEN, 0);
  352. return true;
  353. }
  354. static bool gpy_sgmii_aneg_en(struct phy_device *phydev)
  355. {
  356. int ret;
  357. ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL);
  358. if (ret < 0) {
  359. phydev_err(phydev, "Error: MMD register access failed: %d\n",
  360. ret);
  361. return true;
  362. }
  363. return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false;
  364. }
  365. static int gpy_config_mdix(struct phy_device *phydev, u8 ctrl)
  366. {
  367. int ret;
  368. u16 val;
  369. switch (ctrl) {
  370. case ETH_TP_MDI_AUTO:
  371. val = PHY_CTL1_AMDIX;
  372. break;
  373. case ETH_TP_MDI_X:
  374. val = (PHY_CTL1_MDIAB | PHY_CTL1_MDICD);
  375. break;
  376. case ETH_TP_MDI:
  377. val = 0;
  378. break;
  379. default:
  380. return 0;
  381. }
  382. ret = phy_modify(phydev, PHY_CTL1, PHY_CTL1_AMDIX | PHY_CTL1_MDIAB |
  383. PHY_CTL1_MDICD, val);
  384. if (ret < 0)
  385. return ret;
  386. return genphy_c45_restart_aneg(phydev);
  387. }
  388. static int gpy_config_aneg(struct phy_device *phydev)
  389. {
  390. bool changed = false;
  391. u32 adv;
  392. int ret;
  393. if (phydev->autoneg == AUTONEG_DISABLE) {
  394. /* Configure half duplex with genphy_setup_forced,
  395. * because genphy_c45_pma_setup_forced does not support.
  396. */
  397. return phydev->duplex != DUPLEX_FULL
  398. ? genphy_setup_forced(phydev)
  399. : genphy_c45_pma_setup_forced(phydev);
  400. }
  401. ret = gpy_config_mdix(phydev, phydev->mdix_ctrl);
  402. if (ret < 0)
  403. return ret;
  404. ret = genphy_c45_an_config_aneg(phydev);
  405. if (ret < 0)
  406. return ret;
  407. if (ret > 0)
  408. changed = true;
  409. adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
  410. ret = phy_modify_changed(phydev, MII_CTRL1000,
  411. ADVERTISE_1000FULL | ADVERTISE_1000HALF,
  412. adv);
  413. if (ret < 0)
  414. return ret;
  415. if (ret > 0)
  416. changed = true;
  417. ret = genphy_c45_check_and_restart_aneg(phydev, changed);
  418. if (ret < 0)
  419. return ret;
  420. if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
  421. phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
  422. return 0;
  423. /* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is
  424. * disabled.
  425. */
  426. if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) ||
  427. !gpy_sgmii_aneg_en(phydev))
  428. return 0;
  429. /* There is a design constraint in GPY2xx device where SGMII AN is
  430. * only triggered when there is change of speed. If, PHY link
  431. * partner`s speed is still same even after PHY TPI is down and up
  432. * again, SGMII AN is not triggered and hence no new in-band message
  433. * from GPY to MAC side SGMII.
  434. * This could cause an issue during power up, when PHY is up prior to
  435. * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII
  436. * wouldn`t receive new in-band message from GPY with correct link
  437. * status, speed and duplex info.
  438. *
  439. * 1) If PHY is already up and TPI link status is still down (such as
  440. * hard reboot), TPI link status is polled for 4 seconds before
  441. * retriggerring SGMII AN.
  442. * 2) If PHY is already up and TPI link status is also up (such as soft
  443. * reboot), polling of TPI link status is not needed and SGMII AN is
  444. * immediately retriggered.
  445. * 3) Other conditions such as PHY is down, speed change etc, skip
  446. * retriggering SGMII AN. Note: in case of speed change, GPY FW will
  447. * initiate SGMII AN.
  448. */
  449. if (phydev->state != PHY_UP)
  450. return 0;
  451. ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS,
  452. 20000, 4000000, false);
  453. if (ret == -ETIMEDOUT)
  454. return 0;
  455. else if (ret < 0)
  456. return ret;
  457. /* Trigger SGMII AN. */
  458. return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
  459. VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS);
  460. }
  461. static int gpy_update_mdix(struct phy_device *phydev)
  462. {
  463. int ret;
  464. ret = phy_read(phydev, PHY_CTL1);
  465. if (ret < 0)
  466. return ret;
  467. if (ret & PHY_CTL1_AMDIX)
  468. phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
  469. else
  470. if (ret & PHY_CTL1_MDICD || ret & PHY_CTL1_MDIAB)
  471. phydev->mdix_ctrl = ETH_TP_MDI_X;
  472. else
  473. phydev->mdix_ctrl = ETH_TP_MDI;
  474. ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, PHY_PMA_MGBT_POLARITY);
  475. if (ret < 0)
  476. return ret;
  477. if ((ret & PHY_MDI_MDI_X_MASK) < PHY_MDI_MDI_X_NORMAL)
  478. phydev->mdix = ETH_TP_MDI_X;
  479. else
  480. phydev->mdix = ETH_TP_MDI;
  481. return 0;
  482. }
  483. static int gpy_update_interface(struct phy_device *phydev)
  484. {
  485. int ret;
  486. /* Interface mode is fixed for USXGMII and integrated PHY */
  487. if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
  488. phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
  489. return 0;
  490. /* Automatically switch SERDES interface between SGMII and 2500-BaseX
  491. * according to speed. Disable ANEG in 2500-BaseX mode.
  492. */
  493. switch (phydev->speed) {
  494. case SPEED_2500:
  495. phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
  496. ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
  497. VSPEC1_SGMII_CTRL_ANEN, 0);
  498. if (ret < 0) {
  499. phydev_err(phydev,
  500. "Error: Disable of SGMII ANEG failed: %d\n",
  501. ret);
  502. return ret;
  503. }
  504. break;
  505. case SPEED_1000:
  506. case SPEED_100:
  507. case SPEED_10:
  508. phydev->interface = PHY_INTERFACE_MODE_SGMII;
  509. break;
  510. }
  511. return 0;
  512. }
  513. static int gpy_read_status(struct phy_device *phydev)
  514. {
  515. int ret;
  516. ret = genphy_update_link(phydev);
  517. if (ret)
  518. return ret;
  519. phydev->speed = SPEED_UNKNOWN;
  520. phydev->duplex = DUPLEX_UNKNOWN;
  521. phydev->pause = 0;
  522. phydev->asym_pause = 0;
  523. if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
  524. ret = genphy_c45_read_lpa(phydev);
  525. if (ret < 0)
  526. return ret;
  527. /* Read the link partner's 1G advertisement */
  528. ret = phy_read(phydev, MII_STAT1000);
  529. if (ret < 0)
  530. return ret;
  531. mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
  532. } else if (phydev->autoneg == AUTONEG_DISABLE) {
  533. linkmode_zero(phydev->lp_advertising);
  534. }
  535. ret = phy_read(phydev, PHY_MIISTAT);
  536. if (ret < 0)
  537. return ret;
  538. phydev->link = (ret & PHY_MIISTAT_LS) ? 1 : 0;
  539. phydev->duplex = (ret & PHY_MIISTAT_DPX) ? DUPLEX_FULL : DUPLEX_HALF;
  540. switch (FIELD_GET(PHY_MIISTAT_SPD_MASK, ret)) {
  541. case PHY_MIISTAT_SPD_10:
  542. phydev->speed = SPEED_10;
  543. break;
  544. case PHY_MIISTAT_SPD_100:
  545. phydev->speed = SPEED_100;
  546. break;
  547. case PHY_MIISTAT_SPD_1000:
  548. phydev->speed = SPEED_1000;
  549. break;
  550. case PHY_MIISTAT_SPD_2500:
  551. phydev->speed = SPEED_2500;
  552. break;
  553. }
  554. if (phydev->link) {
  555. ret = gpy_update_interface(phydev);
  556. if (ret < 0)
  557. return ret;
  558. if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) {
  559. ret = genphy_read_master_slave(phydev);
  560. if (ret < 0)
  561. return ret;
  562. }
  563. ret = gpy_update_mdix(phydev);
  564. if (ret < 0)
  565. return ret;
  566. }
  567. return 0;
  568. }
  569. static int gpy_config_intr(struct phy_device *phydev)
  570. {
  571. struct gpy_priv *priv = phydev->priv;
  572. u16 mask = 0;
  573. int ret;
  574. ret = gpy_ack_interrupt(phydev);
  575. if (ret)
  576. return ret;
  577. if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  578. mask = PHY_IMASK_MASK;
  579. if (priv->wolopts & WAKE_MAGIC)
  580. mask |= PHY_IMASK_WOL;
  581. if (priv->wolopts & WAKE_PHY)
  582. mask |= PHY_IMASK_LSTC;
  583. return phy_write(phydev, PHY_IMASK, mask);
  584. }
  585. static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)
  586. {
  587. int reg;
  588. reg = phy_read(phydev, PHY_ISTAT);
  589. if (reg < 0) {
  590. phy_error(phydev);
  591. return IRQ_NONE;
  592. }
  593. if (!(reg & PHY_IMASK_MASK))
  594. return IRQ_NONE;
  595. /* The PHY might leave the interrupt line asserted even after PHY_ISTAT
  596. * is read. To avoid interrupt storms, delay the interrupt handling as
  597. * long as the PHY drives the interrupt line. An internal bus read will
  598. * stall as long as the interrupt line is asserted, thus just read a
  599. * random register here.
  600. * Because we cannot access the internal bus at all while the interrupt
  601. * is driven by the PHY, there is no way to make the interrupt line
  602. * unstuck (e.g. by changing the pinmux to GPIO input) during that time
  603. * frame. Therefore, polling is the best we can do and won't do any more
  604. * harm.
  605. * It was observed that this bug happens on link state and link speed
  606. * changes independent of the firmware version.
  607. */
  608. if (reg & (PHY_IMASK_LSTC | PHY_IMASK_LSPC)) {
  609. reg = gpy_mbox_read(phydev, REG_GPIO0_OUT);
  610. if (reg < 0) {
  611. phy_error(phydev);
  612. return IRQ_NONE;
  613. }
  614. }
  615. phy_trigger_machine(phydev);
  616. return IRQ_HANDLED;
  617. }
  618. static int gpy_set_wol(struct phy_device *phydev,
  619. struct ethtool_wolinfo *wol)
  620. {
  621. struct net_device *attach_dev = phydev->attached_dev;
  622. struct gpy_priv *priv = phydev->priv;
  623. int ret;
  624. if (wol->wolopts & WAKE_MAGIC) {
  625. /* MAC address - Byte0:Byte1:Byte2:Byte3:Byte4:Byte5
  626. * VPSPEC2_WOL_AD45 = Byte0:Byte1
  627. * VPSPEC2_WOL_AD23 = Byte2:Byte3
  628. * VPSPEC2_WOL_AD01 = Byte4:Byte5
  629. */
  630. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
  631. VPSPEC2_WOL_AD45,
  632. ((attach_dev->dev_addr[0] << 8) |
  633. attach_dev->dev_addr[1]));
  634. if (ret < 0)
  635. return ret;
  636. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
  637. VPSPEC2_WOL_AD23,
  638. ((attach_dev->dev_addr[2] << 8) |
  639. attach_dev->dev_addr[3]));
  640. if (ret < 0)
  641. return ret;
  642. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
  643. VPSPEC2_WOL_AD01,
  644. ((attach_dev->dev_addr[4] << 8) |
  645. attach_dev->dev_addr[5]));
  646. if (ret < 0)
  647. return ret;
  648. /* Enable the WOL interrupt */
  649. ret = phy_write(phydev, PHY_IMASK, PHY_IMASK_WOL);
  650. if (ret < 0)
  651. return ret;
  652. /* Enable magic packet matching */
  653. ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
  654. VPSPEC2_WOL_CTL,
  655. WOL_EN);
  656. if (ret < 0)
  657. return ret;
  658. /* Clear the interrupt status register.
  659. * Only WoL is enabled so clear all.
  660. */
  661. ret = phy_read(phydev, PHY_ISTAT);
  662. if (ret < 0)
  663. return ret;
  664. priv->wolopts |= WAKE_MAGIC;
  665. } else {
  666. /* Disable magic packet matching */
  667. ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
  668. VPSPEC2_WOL_CTL,
  669. WOL_EN);
  670. if (ret < 0)
  671. return ret;
  672. /* Disable the WOL interrupt */
  673. ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL);
  674. if (ret < 0)
  675. return ret;
  676. priv->wolopts &= ~WAKE_MAGIC;
  677. }
  678. if (wol->wolopts & WAKE_PHY) {
  679. /* Enable the link state change interrupt */
  680. ret = phy_set_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
  681. if (ret < 0)
  682. return ret;
  683. /* Clear the interrupt status register */
  684. ret = phy_read(phydev, PHY_ISTAT);
  685. if (ret < 0)
  686. return ret;
  687. if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC))
  688. phy_trigger_machine(phydev);
  689. priv->wolopts |= WAKE_PHY;
  690. return 0;
  691. }
  692. priv->wolopts &= ~WAKE_PHY;
  693. /* Disable the link state change interrupt */
  694. return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
  695. }
  696. static void gpy_get_wol(struct phy_device *phydev,
  697. struct ethtool_wolinfo *wol)
  698. {
  699. struct gpy_priv *priv = phydev->priv;
  700. wol->supported = WAKE_MAGIC | WAKE_PHY;
  701. wol->wolopts = priv->wolopts;
  702. }
  703. static int gpy_loopback(struct phy_device *phydev, bool enable, int speed)
  704. {
  705. struct gpy_priv *priv = phydev->priv;
  706. u16 set = 0;
  707. int ret;
  708. if (enable) {
  709. u64 now = get_jiffies_64();
  710. if (speed)
  711. return -EOPNOTSUPP;
  712. /* wait until 3 seconds from last disable */
  713. if (time_before64(now, priv->lb_dis_to))
  714. msleep(jiffies64_to_msecs(priv->lb_dis_to - now));
  715. set = BMCR_LOOPBACK;
  716. }
  717. ret = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, set);
  718. if (ret <= 0)
  719. return ret;
  720. if (enable) {
  721. /* It takes some time for PHY device to switch into
  722. * loopback mode.
  723. */
  724. msleep(100);
  725. } else {
  726. priv->lb_dis_to = get_jiffies_64() + HZ * 3;
  727. }
  728. return 0;
  729. }
  730. static int gpy115_loopback(struct phy_device *phydev, bool enable, int speed)
  731. {
  732. struct gpy_priv *priv = phydev->priv;
  733. if (enable)
  734. return gpy_loopback(phydev, enable, speed);
  735. if (priv->fw_minor > 0x76)
  736. return gpy_loopback(phydev, 0, 0);
  737. return genphy_soft_reset(phydev);
  738. }
  739. static int gpy_led_brightness_set(struct phy_device *phydev,
  740. u8 index, enum led_brightness value)
  741. {
  742. int ret;
  743. if (index >= GPY_MAX_LEDS)
  744. return -EINVAL;
  745. /* clear HWCONTROL and set manual LED state */
  746. ret = phy_modify(phydev, PHY_LED,
  747. ((value == LED_OFF) ? PHY_LED_HWCONTROL(index) : 0) |
  748. PHY_LED_ON(index),
  749. (value == LED_OFF) ? 0 : PHY_LED_ON(index));
  750. if (ret)
  751. return ret;
  752. /* ToDo: set PWM brightness */
  753. /* clear HW LED setup */
  754. if (value == LED_OFF)
  755. return phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), 0);
  756. else
  757. return 0;
  758. }
  759. static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
  760. BIT(TRIGGER_NETDEV_LINK_10) |
  761. BIT(TRIGGER_NETDEV_LINK_100) |
  762. BIT(TRIGGER_NETDEV_LINK_1000) |
  763. BIT(TRIGGER_NETDEV_LINK_2500) |
  764. BIT(TRIGGER_NETDEV_RX) |
  765. BIT(TRIGGER_NETDEV_TX));
  766. static int gpy_led_hw_is_supported(struct phy_device *phydev, u8 index,
  767. unsigned long rules)
  768. {
  769. if (index >= GPY_MAX_LEDS)
  770. return -EINVAL;
  771. /* All combinations of the supported triggers are allowed */
  772. if (rules & ~supported_triggers)
  773. return -EOPNOTSUPP;
  774. return 0;
  775. }
  776. static int gpy_led_hw_control_get(struct phy_device *phydev, u8 index,
  777. unsigned long *rules)
  778. {
  779. int val;
  780. if (index >= GPY_MAX_LEDS)
  781. return -EINVAL;
  782. val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index));
  783. if (val < 0)
  784. return val;
  785. if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK10)
  786. *rules |= BIT(TRIGGER_NETDEV_LINK_10);
  787. if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK100)
  788. *rules |= BIT(TRIGGER_NETDEV_LINK_100);
  789. if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK1000)
  790. *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
  791. if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK2500)
  792. *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
  793. if (FIELD_GET(VSPEC1_LED_CON, val) == (VSPEC1_LED_LINK10 |
  794. VSPEC1_LED_LINK100 |
  795. VSPEC1_LED_LINK1000 |
  796. VSPEC1_LED_LINK2500))
  797. *rules |= BIT(TRIGGER_NETDEV_LINK);
  798. if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_TXACT)
  799. *rules |= BIT(TRIGGER_NETDEV_TX);
  800. if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_RXACT)
  801. *rules |= BIT(TRIGGER_NETDEV_RX);
  802. return 0;
  803. }
  804. static int gpy_led_hw_control_set(struct phy_device *phydev, u8 index,
  805. unsigned long rules)
  806. {
  807. u16 val = 0;
  808. int ret;
  809. if (index >= GPY_MAX_LEDS)
  810. return -EINVAL;
  811. if (rules & BIT(TRIGGER_NETDEV_LINK) ||
  812. rules & BIT(TRIGGER_NETDEV_LINK_10))
  813. val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK10);
  814. if (rules & BIT(TRIGGER_NETDEV_LINK) ||
  815. rules & BIT(TRIGGER_NETDEV_LINK_100))
  816. val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK100);
  817. if (rules & BIT(TRIGGER_NETDEV_LINK) ||
  818. rules & BIT(TRIGGER_NETDEV_LINK_1000))
  819. val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK1000);
  820. if (rules & BIT(TRIGGER_NETDEV_LINK) ||
  821. rules & BIT(TRIGGER_NETDEV_LINK_2500))
  822. val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK2500);
  823. if (rules & BIT(TRIGGER_NETDEV_TX))
  824. val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_TXACT);
  825. if (rules & BIT(TRIGGER_NETDEV_RX))
  826. val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_RXACT);
  827. /* allow RX/TX pulse without link indication */
  828. if ((rules & BIT(TRIGGER_NETDEV_TX) || rules & BIT(TRIGGER_NETDEV_RX)) &&
  829. !(val & VSPEC1_LED_CON))
  830. val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_NO_CON) | VSPEC1_LED_CON;
  831. ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), val);
  832. if (ret)
  833. return ret;
  834. return phy_set_bits(phydev, PHY_LED, PHY_LED_HWCONTROL(index));
  835. }
  836. static int gpy_led_polarity_set(struct phy_device *phydev, int index,
  837. unsigned long modes)
  838. {
  839. bool force_active_low = false, force_active_high = false;
  840. u32 mode;
  841. if (index >= GPY_MAX_LEDS)
  842. return -EINVAL;
  843. for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
  844. switch (mode) {
  845. case PHY_LED_ACTIVE_LOW:
  846. force_active_low = true;
  847. break;
  848. case PHY_LED_ACTIVE_HIGH:
  849. force_active_high = true;
  850. break;
  851. default:
  852. return -EINVAL;
  853. }
  854. }
  855. if (force_active_low)
  856. return phy_set_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
  857. if (force_active_high)
  858. return phy_clear_bits(phydev, PHY_LED, PHY_LED_POLARITY(index));
  859. return -EINVAL;
  860. }
  861. static unsigned int gpy_inband_caps(struct phy_device *phydev,
  862. phy_interface_t interface)
  863. {
  864. switch (interface) {
  865. case PHY_INTERFACE_MODE_SGMII:
  866. return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
  867. case PHY_INTERFACE_MODE_2500BASEX:
  868. return LINK_INBAND_DISABLE;
  869. default:
  870. return 0;
  871. }
  872. }
  873. static int gpy_config_inband(struct phy_device *phydev, unsigned int modes)
  874. {
  875. return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
  876. VSPEC1_SGMII_ANEN_ANRS,
  877. (modes == LINK_INBAND_DISABLE) ? 0 :
  878. VSPEC1_SGMII_ANEN_ANRS);
  879. }
  880. static struct phy_driver gpy_drivers[] = {
  881. {
  882. PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx),
  883. .name = "Maxlinear Ethernet GPY2xx",
  884. .get_features = genphy_c45_pma_read_abilities,
  885. .config_init = gpy_config_init,
  886. .probe = gpy_probe,
  887. .inband_caps = gpy_inband_caps,
  888. .config_inband = gpy_config_inband,
  889. .suspend = genphy_suspend,
  890. .resume = genphy_resume,
  891. .config_aneg = gpy_config_aneg,
  892. .aneg_done = genphy_c45_aneg_done,
  893. .read_status = gpy_read_status,
  894. .config_intr = gpy_config_intr,
  895. .handle_interrupt = gpy_handle_interrupt,
  896. .set_wol = gpy_set_wol,
  897. .get_wol = gpy_get_wol,
  898. .set_loopback = gpy_loopback,
  899. .led_brightness_set = gpy_led_brightness_set,
  900. .led_hw_is_supported = gpy_led_hw_is_supported,
  901. .led_hw_control_get = gpy_led_hw_control_get,
  902. .led_hw_control_set = gpy_led_hw_control_set,
  903. .led_polarity_set = gpy_led_polarity_set,
  904. },
  905. {
  906. .phy_id = PHY_ID_GPY115B,
  907. .phy_id_mask = PHY_ID_GPYx15B_MASK,
  908. .name = "Maxlinear Ethernet GPY115B",
  909. .get_features = genphy_c45_pma_read_abilities,
  910. .config_init = gpy_config_init,
  911. .probe = gpy_probe,
  912. .inband_caps = gpy_inband_caps,
  913. .config_inband = gpy_config_inband,
  914. .suspend = genphy_suspend,
  915. .resume = genphy_resume,
  916. .config_aneg = gpy_config_aneg,
  917. .aneg_done = genphy_c45_aneg_done,
  918. .read_status = gpy_read_status,
  919. .config_intr = gpy_config_intr,
  920. .handle_interrupt = gpy_handle_interrupt,
  921. .set_wol = gpy_set_wol,
  922. .get_wol = gpy_get_wol,
  923. .set_loopback = gpy115_loopback,
  924. .led_brightness_set = gpy_led_brightness_set,
  925. .led_hw_is_supported = gpy_led_hw_is_supported,
  926. .led_hw_control_get = gpy_led_hw_control_get,
  927. .led_hw_control_set = gpy_led_hw_control_set,
  928. .led_polarity_set = gpy_led_polarity_set,
  929. },
  930. {
  931. PHY_ID_MATCH_MODEL(PHY_ID_GPY115C),
  932. .name = "Maxlinear Ethernet GPY115C",
  933. .get_features = genphy_c45_pma_read_abilities,
  934. .config_init = gpy_config_init,
  935. .probe = gpy_probe,
  936. .inband_caps = gpy_inband_caps,
  937. .config_inband = gpy_config_inband,
  938. .suspend = genphy_suspend,
  939. .resume = genphy_resume,
  940. .config_aneg = gpy_config_aneg,
  941. .aneg_done = genphy_c45_aneg_done,
  942. .read_status = gpy_read_status,
  943. .config_intr = gpy_config_intr,
  944. .handle_interrupt = gpy_handle_interrupt,
  945. .set_wol = gpy_set_wol,
  946. .get_wol = gpy_get_wol,
  947. .set_loopback = gpy115_loopback,
  948. .led_brightness_set = gpy_led_brightness_set,
  949. .led_hw_is_supported = gpy_led_hw_is_supported,
  950. .led_hw_control_get = gpy_led_hw_control_get,
  951. .led_hw_control_set = gpy_led_hw_control_set,
  952. .led_polarity_set = gpy_led_polarity_set,
  953. },
  954. {
  955. .phy_id = PHY_ID_GPY211B,
  956. .phy_id_mask = PHY_ID_GPY21xB_MASK,
  957. .name = "Maxlinear Ethernet GPY211B",
  958. .get_features = genphy_c45_pma_read_abilities,
  959. .config_init = gpy21x_config_init,
  960. .probe = gpy_probe,
  961. .inband_caps = gpy_inband_caps,
  962. .config_inband = gpy_config_inband,
  963. .suspend = genphy_suspend,
  964. .resume = genphy_resume,
  965. .config_aneg = gpy_config_aneg,
  966. .aneg_done = genphy_c45_aneg_done,
  967. .read_status = gpy_read_status,
  968. .config_intr = gpy_config_intr,
  969. .handle_interrupt = gpy_handle_interrupt,
  970. .set_wol = gpy_set_wol,
  971. .get_wol = gpy_get_wol,
  972. .set_loopback = gpy_loopback,
  973. .led_brightness_set = gpy_led_brightness_set,
  974. .led_hw_is_supported = gpy_led_hw_is_supported,
  975. .led_hw_control_get = gpy_led_hw_control_get,
  976. .led_hw_control_set = gpy_led_hw_control_set,
  977. .led_polarity_set = gpy_led_polarity_set,
  978. },
  979. {
  980. PHY_ID_MATCH_MODEL(PHY_ID_GPY211C),
  981. .name = "Maxlinear Ethernet GPY211C",
  982. .get_features = genphy_c45_pma_read_abilities,
  983. .config_init = gpy21x_config_init,
  984. .probe = gpy_probe,
  985. .inband_caps = gpy_inband_caps,
  986. .config_inband = gpy_config_inband,
  987. .suspend = genphy_suspend,
  988. .resume = genphy_resume,
  989. .config_aneg = gpy_config_aneg,
  990. .aneg_done = genphy_c45_aneg_done,
  991. .read_status = gpy_read_status,
  992. .config_intr = gpy_config_intr,
  993. .handle_interrupt = gpy_handle_interrupt,
  994. .set_wol = gpy_set_wol,
  995. .get_wol = gpy_get_wol,
  996. .set_loopback = gpy_loopback,
  997. .led_brightness_set = gpy_led_brightness_set,
  998. .led_hw_is_supported = gpy_led_hw_is_supported,
  999. .led_hw_control_get = gpy_led_hw_control_get,
  1000. .led_hw_control_set = gpy_led_hw_control_set,
  1001. .led_polarity_set = gpy_led_polarity_set,
  1002. },
  1003. {
  1004. .phy_id = PHY_ID_GPY212B,
  1005. .phy_id_mask = PHY_ID_GPY21xB_MASK,
  1006. .name = "Maxlinear Ethernet GPY212B",
  1007. .get_features = genphy_c45_pma_read_abilities,
  1008. .config_init = gpy21x_config_init,
  1009. .inband_caps = gpy_inband_caps,
  1010. .config_inband = gpy_config_inband,
  1011. .probe = gpy_probe,
  1012. .suspend = genphy_suspend,
  1013. .resume = genphy_resume,
  1014. .config_aneg = gpy_config_aneg,
  1015. .aneg_done = genphy_c45_aneg_done,
  1016. .read_status = gpy_read_status,
  1017. .config_intr = gpy_config_intr,
  1018. .handle_interrupt = gpy_handle_interrupt,
  1019. .set_wol = gpy_set_wol,
  1020. .get_wol = gpy_get_wol,
  1021. .set_loopback = gpy_loopback,
  1022. .led_brightness_set = gpy_led_brightness_set,
  1023. .led_hw_is_supported = gpy_led_hw_is_supported,
  1024. .led_hw_control_get = gpy_led_hw_control_get,
  1025. .led_hw_control_set = gpy_led_hw_control_set,
  1026. .led_polarity_set = gpy_led_polarity_set,
  1027. },
  1028. {
  1029. PHY_ID_MATCH_MODEL(PHY_ID_GPY212C),
  1030. .name = "Maxlinear Ethernet GPY212C",
  1031. .get_features = genphy_c45_pma_read_abilities,
  1032. .config_init = gpy21x_config_init,
  1033. .probe = gpy_probe,
  1034. .inband_caps = gpy_inband_caps,
  1035. .config_inband = gpy_config_inband,
  1036. .suspend = genphy_suspend,
  1037. .resume = genphy_resume,
  1038. .config_aneg = gpy_config_aneg,
  1039. .aneg_done = genphy_c45_aneg_done,
  1040. .read_status = gpy_read_status,
  1041. .config_intr = gpy_config_intr,
  1042. .handle_interrupt = gpy_handle_interrupt,
  1043. .set_wol = gpy_set_wol,
  1044. .get_wol = gpy_get_wol,
  1045. .set_loopback = gpy_loopback,
  1046. .led_brightness_set = gpy_led_brightness_set,
  1047. .led_hw_is_supported = gpy_led_hw_is_supported,
  1048. .led_hw_control_get = gpy_led_hw_control_get,
  1049. .led_hw_control_set = gpy_led_hw_control_set,
  1050. .led_polarity_set = gpy_led_polarity_set,
  1051. },
  1052. {
  1053. .phy_id = PHY_ID_GPY215B,
  1054. .phy_id_mask = PHY_ID_GPYx15B_MASK,
  1055. .name = "Maxlinear Ethernet GPY215B",
  1056. .get_features = genphy_c45_pma_read_abilities,
  1057. .config_init = gpy21x_config_init,
  1058. .probe = gpy_probe,
  1059. .inband_caps = gpy_inband_caps,
  1060. .config_inband = gpy_config_inband,
  1061. .suspend = genphy_suspend,
  1062. .resume = genphy_resume,
  1063. .config_aneg = gpy_config_aneg,
  1064. .aneg_done = genphy_c45_aneg_done,
  1065. .read_status = gpy_read_status,
  1066. .config_intr = gpy_config_intr,
  1067. .handle_interrupt = gpy_handle_interrupt,
  1068. .set_wol = gpy_set_wol,
  1069. .get_wol = gpy_get_wol,
  1070. .set_loopback = gpy_loopback,
  1071. .led_brightness_set = gpy_led_brightness_set,
  1072. .led_hw_is_supported = gpy_led_hw_is_supported,
  1073. .led_hw_control_get = gpy_led_hw_control_get,
  1074. .led_hw_control_set = gpy_led_hw_control_set,
  1075. .led_polarity_set = gpy_led_polarity_set,
  1076. },
  1077. {
  1078. PHY_ID_MATCH_MODEL(PHY_ID_GPY215C),
  1079. .name = "Maxlinear Ethernet GPY215C",
  1080. .get_features = genphy_c45_pma_read_abilities,
  1081. .config_init = gpy21x_config_init,
  1082. .probe = gpy_probe,
  1083. .inband_caps = gpy_inband_caps,
  1084. .config_inband = gpy_config_inband,
  1085. .suspend = genphy_suspend,
  1086. .resume = genphy_resume,
  1087. .config_aneg = gpy_config_aneg,
  1088. .aneg_done = genphy_c45_aneg_done,
  1089. .read_status = gpy_read_status,
  1090. .config_intr = gpy_config_intr,
  1091. .handle_interrupt = gpy_handle_interrupt,
  1092. .set_wol = gpy_set_wol,
  1093. .get_wol = gpy_get_wol,
  1094. .set_loopback = gpy_loopback,
  1095. .led_brightness_set = gpy_led_brightness_set,
  1096. .led_hw_is_supported = gpy_led_hw_is_supported,
  1097. .led_hw_control_get = gpy_led_hw_control_get,
  1098. .led_hw_control_set = gpy_led_hw_control_set,
  1099. .led_polarity_set = gpy_led_polarity_set,
  1100. },
  1101. {
  1102. PHY_ID_MATCH_MODEL(PHY_ID_GPY241B),
  1103. .name = "Maxlinear Ethernet GPY241B",
  1104. .get_features = genphy_c45_pma_read_abilities,
  1105. .config_init = gpy_config_init,
  1106. .probe = gpy_probe,
  1107. .inband_caps = gpy_inband_caps,
  1108. .config_inband = gpy_config_inband,
  1109. .suspend = genphy_suspend,
  1110. .resume = genphy_resume,
  1111. .config_aneg = gpy_config_aneg,
  1112. .aneg_done = genphy_c45_aneg_done,
  1113. .read_status = gpy_read_status,
  1114. .config_intr = gpy_config_intr,
  1115. .handle_interrupt = gpy_handle_interrupt,
  1116. .set_wol = gpy_set_wol,
  1117. .get_wol = gpy_get_wol,
  1118. .set_loopback = gpy_loopback,
  1119. },
  1120. {
  1121. PHY_ID_MATCH_MODEL(PHY_ID_GPY241BM),
  1122. .name = "Maxlinear Ethernet GPY241BM",
  1123. .get_features = genphy_c45_pma_read_abilities,
  1124. .config_init = gpy_config_init,
  1125. .probe = gpy_probe,
  1126. .inband_caps = gpy_inband_caps,
  1127. .config_inband = gpy_config_inband,
  1128. .suspend = genphy_suspend,
  1129. .resume = genphy_resume,
  1130. .config_aneg = gpy_config_aneg,
  1131. .aneg_done = genphy_c45_aneg_done,
  1132. .read_status = gpy_read_status,
  1133. .config_intr = gpy_config_intr,
  1134. .handle_interrupt = gpy_handle_interrupt,
  1135. .set_wol = gpy_set_wol,
  1136. .get_wol = gpy_get_wol,
  1137. .set_loopback = gpy_loopback,
  1138. },
  1139. {
  1140. PHY_ID_MATCH_MODEL(PHY_ID_GPY245B),
  1141. .name = "Maxlinear Ethernet GPY245B",
  1142. .get_features = genphy_c45_pma_read_abilities,
  1143. .config_init = gpy_config_init,
  1144. .probe = gpy_probe,
  1145. .inband_caps = gpy_inband_caps,
  1146. .config_inband = gpy_config_inband,
  1147. .suspend = genphy_suspend,
  1148. .resume = genphy_resume,
  1149. .config_aneg = gpy_config_aneg,
  1150. .aneg_done = genphy_c45_aneg_done,
  1151. .read_status = gpy_read_status,
  1152. .config_intr = gpy_config_intr,
  1153. .handle_interrupt = gpy_handle_interrupt,
  1154. .set_wol = gpy_set_wol,
  1155. .get_wol = gpy_get_wol,
  1156. .set_loopback = gpy_loopback,
  1157. },
  1158. {
  1159. PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C),
  1160. .name = "Maxlinear Ethernet MxL86211C",
  1161. .get_features = genphy_c45_pma_read_abilities,
  1162. .config_init = gpy_config_init,
  1163. .probe = gpy_probe,
  1164. .inband_caps = gpy_inband_caps,
  1165. .config_inband = gpy_config_inband,
  1166. .suspend = genphy_suspend,
  1167. .resume = genphy_resume,
  1168. .config_aneg = gpy_config_aneg,
  1169. .aneg_done = genphy_c45_aneg_done,
  1170. .read_status = gpy_read_status,
  1171. .config_intr = gpy_config_intr,
  1172. .handle_interrupt = gpy_handle_interrupt,
  1173. .set_wol = gpy_set_wol,
  1174. .get_wol = gpy_get_wol,
  1175. .set_loopback = gpy_loopback,
  1176. .led_brightness_set = gpy_led_brightness_set,
  1177. .led_hw_is_supported = gpy_led_hw_is_supported,
  1178. .led_hw_control_get = gpy_led_hw_control_get,
  1179. .led_hw_control_set = gpy_led_hw_control_set,
  1180. .led_polarity_set = gpy_led_polarity_set,
  1181. },
  1182. {
  1183. PHY_ID_MATCH_MODEL(PHY_ID_MXL86252),
  1184. .name = "MaxLinear Ethernet MxL86252",
  1185. .get_features = genphy_c45_pma_read_abilities,
  1186. .config_init = gpy_config_init,
  1187. .probe = gpy_probe,
  1188. .suspend = genphy_suspend,
  1189. .resume = genphy_resume,
  1190. .config_aneg = gpy_config_aneg,
  1191. .aneg_done = genphy_c45_aneg_done,
  1192. .read_status = gpy_read_status,
  1193. .config_intr = gpy_config_intr,
  1194. .handle_interrupt = gpy_handle_interrupt,
  1195. .set_wol = gpy_set_wol,
  1196. .get_wol = gpy_get_wol,
  1197. .set_loopback = gpy_loopback,
  1198. .led_brightness_set = gpy_led_brightness_set,
  1199. .led_hw_is_supported = gpy_led_hw_is_supported,
  1200. .led_hw_control_get = gpy_led_hw_control_get,
  1201. .led_hw_control_set = gpy_led_hw_control_set,
  1202. .led_polarity_set = gpy_led_polarity_set,
  1203. },
  1204. {
  1205. PHY_ID_MATCH_MODEL(PHY_ID_MXL86282),
  1206. .name = "MaxLinear Ethernet MxL86282",
  1207. .get_features = genphy_c45_pma_read_abilities,
  1208. .config_init = gpy_config_init,
  1209. .probe = gpy_probe,
  1210. .suspend = genphy_suspend,
  1211. .resume = genphy_resume,
  1212. .config_aneg = gpy_config_aneg,
  1213. .aneg_done = genphy_c45_aneg_done,
  1214. .read_status = gpy_read_status,
  1215. .config_intr = gpy_config_intr,
  1216. .handle_interrupt = gpy_handle_interrupt,
  1217. .set_wol = gpy_set_wol,
  1218. .get_wol = gpy_get_wol,
  1219. .set_loopback = gpy_loopback,
  1220. .led_brightness_set = gpy_led_brightness_set,
  1221. .led_hw_is_supported = gpy_led_hw_is_supported,
  1222. .led_hw_control_get = gpy_led_hw_control_get,
  1223. .led_hw_control_set = gpy_led_hw_control_set,
  1224. .led_polarity_set = gpy_led_polarity_set,
  1225. },
  1226. };
  1227. module_phy_driver(gpy_drivers);
  1228. static const struct mdio_device_id __maybe_unused gpy_tbl[] = {
  1229. {PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx)},
  1230. {PHY_ID_GPY115B, PHY_ID_GPYx15B_MASK},
  1231. {PHY_ID_MATCH_MODEL(PHY_ID_GPY115C)},
  1232. {PHY_ID_GPY211B, PHY_ID_GPY21xB_MASK},
  1233. {PHY_ID_MATCH_MODEL(PHY_ID_GPY211C)},
  1234. {PHY_ID_GPY212B, PHY_ID_GPY21xB_MASK},
  1235. {PHY_ID_MATCH_MODEL(PHY_ID_GPY212C)},
  1236. {PHY_ID_GPY215B, PHY_ID_GPYx15B_MASK},
  1237. {PHY_ID_MATCH_MODEL(PHY_ID_GPY215C)},
  1238. {PHY_ID_MATCH_MODEL(PHY_ID_GPY241B)},
  1239. {PHY_ID_MATCH_MODEL(PHY_ID_GPY241BM)},
  1240. {PHY_ID_MATCH_MODEL(PHY_ID_GPY245B)},
  1241. {PHY_ID_MATCH_MODEL(PHY_ID_MXL86211C)},
  1242. {PHY_ID_MATCH_MODEL(PHY_ID_MXL86252)},
  1243. {PHY_ID_MATCH_MODEL(PHY_ID_MXL86282)},
  1244. { }
  1245. };
  1246. MODULE_DEVICE_TABLE(mdio, gpy_tbl);
  1247. MODULE_DESCRIPTION("Maxlinear Ethernet GPY Driver");
  1248. MODULE_AUTHOR("Xu Liang");
  1249. MODULE_LICENSE("GPL");