micrel.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * drivers/net/phy/micrel.c
  3. *
  4. * Driver for Micrel PHYs
  5. *
  6. * Author: David J. Choi
  7. *
  8. * Copyright (c) 2010-2013 Micrel, Inc.
  9. * Copyright (c) 2014 Johan Hovold <johan@kernel.org>
  10. *
  11. * This program is free software; you can redistribute it and/or modify it
  12. * under the terms of the GNU General Public License as published by the
  13. * Free Software Foundation; either version 2 of the License, or (at your
  14. * option) any later version.
  15. *
  16. * Support : Micrel Phys:
  17. * Giga phys: ksz9021, ksz9031
  18. * 100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
  19. * ksz8021, ksz8031, ksz8051,
  20. * ksz8081, ksz8091,
  21. * ksz8061,
  22. * Switch : ksz8873, ksz886x
  23. */
  24. #include <linux/kernel.h>
  25. #include <linux/module.h>
  26. #include <linux/phy.h>
  27. #include <linux/micrel_phy.h>
  28. #include <linux/of.h>
  29. #include <linux/clk.h>
  30. /* Operation Mode Strap Override */
  31. #define MII_KSZPHY_OMSO 0x16
  32. #define KSZPHY_OMSO_B_CAST_OFF BIT(9)
  33. #define KSZPHY_OMSO_NAND_TREE_ON BIT(5)
  34. #define KSZPHY_OMSO_RMII_OVERRIDE BIT(1)
  35. #define KSZPHY_OMSO_MII_OVERRIDE BIT(0)
  36. /* general Interrupt control/status reg in vendor specific block. */
  37. #define MII_KSZPHY_INTCS 0x1B
  38. #define KSZPHY_INTCS_JABBER BIT(15)
  39. #define KSZPHY_INTCS_RECEIVE_ERR BIT(14)
  40. #define KSZPHY_INTCS_PAGE_RECEIVE BIT(13)
  41. #define KSZPHY_INTCS_PARELLEL BIT(12)
  42. #define KSZPHY_INTCS_LINK_PARTNER_ACK BIT(11)
  43. #define KSZPHY_INTCS_LINK_DOWN BIT(10)
  44. #define KSZPHY_INTCS_REMOTE_FAULT BIT(9)
  45. #define KSZPHY_INTCS_LINK_UP BIT(8)
  46. #define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\
  47. KSZPHY_INTCS_LINK_DOWN)
  48. /* PHY Control 1 */
  49. #define MII_KSZPHY_CTRL_1 0x1e
  50. /* PHY Control 2 / PHY Control (if no PHY Control 1) */
  51. #define MII_KSZPHY_CTRL_2 0x1f
  52. #define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2
  53. /* bitmap of PHY register to set interrupt mode */
  54. #define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9)
  55. #define KSZPHY_RMII_REF_CLK_SEL BIT(7)
  56. /* Write/read to/from extended registers */
  57. #define MII_KSZPHY_EXTREG 0x0b
  58. #define KSZPHY_EXTREG_WRITE 0x8000
  59. #define MII_KSZPHY_EXTREG_WRITE 0x0c
  60. #define MII_KSZPHY_EXTREG_READ 0x0d
  61. /* Extended registers */
  62. #define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104
  63. #define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105
  64. #define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106
  65. #define PS_TO_REG 200
  66. struct kszphy_hw_stat {
  67. const char *string;
  68. u8 reg;
  69. u8 bits;
  70. };
  71. static struct kszphy_hw_stat kszphy_hw_stats[] = {
  72. { "phy_receive_errors", 21, 16},
  73. { "phy_idle_errors", 10, 8 },
  74. };
  75. struct kszphy_type {
  76. u32 led_mode_reg;
  77. u16 interrupt_level_mask;
  78. bool has_broadcast_disable;
  79. bool has_nand_tree_disable;
  80. bool has_rmii_ref_clk_sel;
  81. };
  82. struct kszphy_priv {
  83. const struct kszphy_type *type;
  84. int led_mode;
  85. bool rmii_ref_clk_sel;
  86. bool rmii_ref_clk_sel_val;
  87. u64 stats[ARRAY_SIZE(kszphy_hw_stats)];
  88. };
  89. static const struct kszphy_type ksz8021_type = {
  90. .led_mode_reg = MII_KSZPHY_CTRL_2,
  91. .has_broadcast_disable = true,
  92. .has_nand_tree_disable = true,
  93. .has_rmii_ref_clk_sel = true,
  94. };
  95. static const struct kszphy_type ksz8041_type = {
  96. .led_mode_reg = MII_KSZPHY_CTRL_1,
  97. };
  98. static const struct kszphy_type ksz8051_type = {
  99. .led_mode_reg = MII_KSZPHY_CTRL_2,
  100. .has_nand_tree_disable = true,
  101. };
  102. static const struct kszphy_type ksz8081_type = {
  103. .led_mode_reg = MII_KSZPHY_CTRL_2,
  104. .has_broadcast_disable = true,
  105. .has_nand_tree_disable = true,
  106. .has_rmii_ref_clk_sel = true,
  107. };
  108. static const struct kszphy_type ks8737_type = {
  109. .interrupt_level_mask = BIT(14),
  110. };
  111. static const struct kszphy_type ksz9021_type = {
  112. .interrupt_level_mask = BIT(14),
  113. };
  114. static int kszphy_extended_write(struct phy_device *phydev,
  115. u32 regnum, u16 val)
  116. {
  117. phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum);
  118. return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val);
  119. }
  120. static int kszphy_extended_read(struct phy_device *phydev,
  121. u32 regnum)
  122. {
  123. phy_write(phydev, MII_KSZPHY_EXTREG, regnum);
  124. return phy_read(phydev, MII_KSZPHY_EXTREG_READ);
  125. }
  126. static int kszphy_ack_interrupt(struct phy_device *phydev)
  127. {
  128. /* bit[7..0] int status, which is a read and clear register. */
  129. int rc;
  130. rc = phy_read(phydev, MII_KSZPHY_INTCS);
  131. return (rc < 0) ? rc : 0;
  132. }
  133. static int kszphy_config_intr(struct phy_device *phydev)
  134. {
  135. const struct kszphy_type *type = phydev->drv->driver_data;
  136. int temp;
  137. u16 mask;
  138. if (type && type->interrupt_level_mask)
  139. mask = type->interrupt_level_mask;
  140. else
  141. mask = KSZPHY_CTRL_INT_ACTIVE_HIGH;
  142. /* set the interrupt pin active low */
  143. temp = phy_read(phydev, MII_KSZPHY_CTRL);
  144. if (temp < 0)
  145. return temp;
  146. temp &= ~mask;
  147. phy_write(phydev, MII_KSZPHY_CTRL, temp);
  148. /* enable / disable interrupts */
  149. if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  150. temp = KSZPHY_INTCS_ALL;
  151. else
  152. temp = 0;
  153. return phy_write(phydev, MII_KSZPHY_INTCS, temp);
  154. }
  155. static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val)
  156. {
  157. int ctrl;
  158. ctrl = phy_read(phydev, MII_KSZPHY_CTRL);
  159. if (ctrl < 0)
  160. return ctrl;
  161. if (val)
  162. ctrl |= KSZPHY_RMII_REF_CLK_SEL;
  163. else
  164. ctrl &= ~KSZPHY_RMII_REF_CLK_SEL;
  165. return phy_write(phydev, MII_KSZPHY_CTRL, ctrl);
  166. }
  167. static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
  168. {
  169. int rc, temp, shift;
  170. switch (reg) {
  171. case MII_KSZPHY_CTRL_1:
  172. shift = 14;
  173. break;
  174. case MII_KSZPHY_CTRL_2:
  175. shift = 4;
  176. break;
  177. default:
  178. return -EINVAL;
  179. }
  180. temp = phy_read(phydev, reg);
  181. if (temp < 0) {
  182. rc = temp;
  183. goto out;
  184. }
  185. temp &= ~(3 << shift);
  186. temp |= val << shift;
  187. rc = phy_write(phydev, reg, temp);
  188. out:
  189. if (rc < 0)
  190. phydev_err(phydev, "failed to set led mode\n");
  191. return rc;
  192. }
  193. /* Disable PHY address 0 as the broadcast address, so that it can be used as a
  194. * unique (non-broadcast) address on a shared bus.
  195. */
  196. static int kszphy_broadcast_disable(struct phy_device *phydev)
  197. {
  198. int ret;
  199. ret = phy_read(phydev, MII_KSZPHY_OMSO);
  200. if (ret < 0)
  201. goto out;
  202. ret = phy_write(phydev, MII_KSZPHY_OMSO, ret | KSZPHY_OMSO_B_CAST_OFF);
  203. out:
  204. if (ret)
  205. phydev_err(phydev, "failed to disable broadcast address\n");
  206. return ret;
  207. }
  208. static int kszphy_nand_tree_disable(struct phy_device *phydev)
  209. {
  210. int ret;
  211. ret = phy_read(phydev, MII_KSZPHY_OMSO);
  212. if (ret < 0)
  213. goto out;
  214. if (!(ret & KSZPHY_OMSO_NAND_TREE_ON))
  215. return 0;
  216. ret = phy_write(phydev, MII_KSZPHY_OMSO,
  217. ret & ~KSZPHY_OMSO_NAND_TREE_ON);
  218. out:
  219. if (ret)
  220. phydev_err(phydev, "failed to disable NAND tree mode\n");
  221. return ret;
  222. }
  223. static int kszphy_config_init(struct phy_device *phydev)
  224. {
  225. struct kszphy_priv *priv = phydev->priv;
  226. const struct kszphy_type *type;
  227. int ret;
  228. if (!priv)
  229. return 0;
  230. type = priv->type;
  231. if (type->has_broadcast_disable)
  232. kszphy_broadcast_disable(phydev);
  233. if (type->has_nand_tree_disable)
  234. kszphy_nand_tree_disable(phydev);
  235. if (priv->rmii_ref_clk_sel) {
  236. ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
  237. if (ret) {
  238. phydev_err(phydev,
  239. "failed to set rmii reference clock\n");
  240. return ret;
  241. }
  242. }
  243. if (priv->led_mode >= 0)
  244. kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
  245. return 0;
  246. }
  247. static int ksz8041_config_init(struct phy_device *phydev)
  248. {
  249. struct device_node *of_node = phydev->mdio.dev.of_node;
  250. /* Limit supported and advertised modes in fiber mode */
  251. if (of_property_read_bool(of_node, "micrel,fiber-mode")) {
  252. phydev->dev_flags |= MICREL_PHY_FXEN;
  253. phydev->supported &= SUPPORTED_100baseT_Full |
  254. SUPPORTED_100baseT_Half;
  255. phydev->supported |= SUPPORTED_FIBRE;
  256. phydev->advertising &= ADVERTISED_100baseT_Full |
  257. ADVERTISED_100baseT_Half;
  258. phydev->advertising |= ADVERTISED_FIBRE;
  259. phydev->autoneg = AUTONEG_DISABLE;
  260. }
  261. return kszphy_config_init(phydev);
  262. }
  263. static int ksz8041_config_aneg(struct phy_device *phydev)
  264. {
  265. /* Skip auto-negotiation in fiber mode */
  266. if (phydev->dev_flags & MICREL_PHY_FXEN) {
  267. phydev->speed = SPEED_100;
  268. return 0;
  269. }
  270. return genphy_config_aneg(phydev);
  271. }
  272. static int ksz9021_load_values_from_of(struct phy_device *phydev,
  273. const struct device_node *of_node,
  274. u16 reg,
  275. const char *field1, const char *field2,
  276. const char *field3, const char *field4)
  277. {
  278. int val1 = -1;
  279. int val2 = -2;
  280. int val3 = -3;
  281. int val4 = -4;
  282. int newval;
  283. int matches = 0;
  284. if (!of_property_read_u32(of_node, field1, &val1))
  285. matches++;
  286. if (!of_property_read_u32(of_node, field2, &val2))
  287. matches++;
  288. if (!of_property_read_u32(of_node, field3, &val3))
  289. matches++;
  290. if (!of_property_read_u32(of_node, field4, &val4))
  291. matches++;
  292. if (!matches)
  293. return 0;
  294. if (matches < 4)
  295. newval = kszphy_extended_read(phydev, reg);
  296. else
  297. newval = 0;
  298. if (val1 != -1)
  299. newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
  300. if (val2 != -2)
  301. newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
  302. if (val3 != -3)
  303. newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
  304. if (val4 != -4)
  305. newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
  306. return kszphy_extended_write(phydev, reg, newval);
  307. }
  308. static int ksz9021_config_init(struct phy_device *phydev)
  309. {
  310. const struct device *dev = &phydev->mdio.dev;
  311. const struct device_node *of_node = dev->of_node;
  312. const struct device *dev_walker;
  313. /* The Micrel driver has a deprecated option to place phy OF
  314. * properties in the MAC node. Walk up the tree of devices to
  315. * find a device with an OF node.
  316. */
  317. dev_walker = &phydev->mdio.dev;
  318. do {
  319. of_node = dev_walker->of_node;
  320. dev_walker = dev_walker->parent;
  321. } while (!of_node && dev_walker);
  322. if (of_node) {
  323. ksz9021_load_values_from_of(phydev, of_node,
  324. MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
  325. "txen-skew-ps", "txc-skew-ps",
  326. "rxdv-skew-ps", "rxc-skew-ps");
  327. ksz9021_load_values_from_of(phydev, of_node,
  328. MII_KSZPHY_RX_DATA_PAD_SKEW,
  329. "rxd0-skew-ps", "rxd1-skew-ps",
  330. "rxd2-skew-ps", "rxd3-skew-ps");
  331. ksz9021_load_values_from_of(phydev, of_node,
  332. MII_KSZPHY_TX_DATA_PAD_SKEW,
  333. "txd0-skew-ps", "txd1-skew-ps",
  334. "txd2-skew-ps", "txd3-skew-ps");
  335. }
  336. return 0;
  337. }
  338. #define MII_KSZ9031RN_MMD_CTRL_REG 0x0d
  339. #define MII_KSZ9031RN_MMD_REGDATA_REG 0x0e
  340. #define OP_DATA 1
  341. #define KSZ9031_PS_TO_REG 60
  342. /* Extended registers */
  343. /* MMD Address 0x0 */
  344. #define MII_KSZ9031RN_FLP_BURST_TX_LO 3
  345. #define MII_KSZ9031RN_FLP_BURST_TX_HI 4
  346. /* MMD Address 0x2 */
  347. #define MII_KSZ9031RN_CONTROL_PAD_SKEW 4
  348. #define MII_KSZ9031RN_RX_DATA_PAD_SKEW 5
  349. #define MII_KSZ9031RN_TX_DATA_PAD_SKEW 6
  350. #define MII_KSZ9031RN_CLK_PAD_SKEW 8
  351. /* MMD Address 0x1C */
  352. #define MII_KSZ9031RN_EDPD 0x23
  353. #define MII_KSZ9031RN_EDPD_ENABLE BIT(0)
  354. static int ksz9031_extended_write(struct phy_device *phydev,
  355. u8 mode, u32 dev_addr, u32 regnum, u16 val)
  356. {
  357. phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
  358. phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
  359. phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
  360. return phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, val);
  361. }
  362. static int ksz9031_extended_read(struct phy_device *phydev,
  363. u8 mode, u32 dev_addr, u32 regnum)
  364. {
  365. phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
  366. phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
  367. phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
  368. return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG);
  369. }
  370. static int ksz9031_of_load_skew_values(struct phy_device *phydev,
  371. const struct device_node *of_node,
  372. u16 reg, size_t field_sz,
  373. const char *field[], u8 numfields)
  374. {
  375. int val[4] = {-1, -2, -3, -4};
  376. int matches = 0;
  377. u16 mask;
  378. u16 maxval;
  379. u16 newval;
  380. int i;
  381. for (i = 0; i < numfields; i++)
  382. if (!of_property_read_u32(of_node, field[i], val + i))
  383. matches++;
  384. if (!matches)
  385. return 0;
  386. if (matches < numfields)
  387. newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
  388. else
  389. newval = 0;
  390. maxval = (field_sz == 4) ? 0xf : 0x1f;
  391. for (i = 0; i < numfields; i++)
  392. if (val[i] != -(i + 1)) {
  393. mask = 0xffff;
  394. mask ^= maxval << (field_sz * i);
  395. newval = (newval & mask) |
  396. (((val[i] / KSZ9031_PS_TO_REG) & maxval)
  397. << (field_sz * i));
  398. }
  399. return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
  400. }
  401. static int ksz9031_center_flp_timing(struct phy_device *phydev)
  402. {
  403. int result;
  404. /* Center KSZ9031RNX FLP timing at 16ms. */
  405. result = ksz9031_extended_write(phydev, OP_DATA, 0,
  406. MII_KSZ9031RN_FLP_BURST_TX_HI, 0x0006);
  407. result = ksz9031_extended_write(phydev, OP_DATA, 0,
  408. MII_KSZ9031RN_FLP_BURST_TX_LO, 0x1A80);
  409. if (result)
  410. return result;
  411. return genphy_restart_aneg(phydev);
  412. }
  413. /* Enable energy-detect power-down mode */
  414. static int ksz9031_enable_edpd(struct phy_device *phydev)
  415. {
  416. int reg;
  417. reg = ksz9031_extended_read(phydev, OP_DATA, 0x1C, MII_KSZ9031RN_EDPD);
  418. if (reg < 0)
  419. return reg;
  420. return ksz9031_extended_write(phydev, OP_DATA, 0x1C, MII_KSZ9031RN_EDPD,
  421. reg | MII_KSZ9031RN_EDPD_ENABLE);
  422. }
  423. static int ksz9031_config_init(struct phy_device *phydev)
  424. {
  425. const struct device *dev = &phydev->mdio.dev;
  426. const struct device_node *of_node = dev->of_node;
  427. static const char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
  428. static const char *rx_data_skews[4] = {
  429. "rxd0-skew-ps", "rxd1-skew-ps",
  430. "rxd2-skew-ps", "rxd3-skew-ps"
  431. };
  432. static const char *tx_data_skews[4] = {
  433. "txd0-skew-ps", "txd1-skew-ps",
  434. "txd2-skew-ps", "txd3-skew-ps"
  435. };
  436. static const char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
  437. const struct device *dev_walker;
  438. int result;
  439. result = ksz9031_enable_edpd(phydev);
  440. if (result < 0)
  441. return result;
  442. /* The Micrel driver has a deprecated option to place phy OF
  443. * properties in the MAC node. Walk up the tree of devices to
  444. * find a device with an OF node.
  445. */
  446. dev_walker = &phydev->mdio.dev;
  447. do {
  448. of_node = dev_walker->of_node;
  449. dev_walker = dev_walker->parent;
  450. } while (!of_node && dev_walker);
  451. if (of_node) {
  452. ksz9031_of_load_skew_values(phydev, of_node,
  453. MII_KSZ9031RN_CLK_PAD_SKEW, 5,
  454. clk_skews, 2);
  455. ksz9031_of_load_skew_values(phydev, of_node,
  456. MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
  457. control_skews, 2);
  458. ksz9031_of_load_skew_values(phydev, of_node,
  459. MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
  460. rx_data_skews, 4);
  461. ksz9031_of_load_skew_values(phydev, of_node,
  462. MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
  463. tx_data_skews, 4);
  464. }
  465. return ksz9031_center_flp_timing(phydev);
  466. }
  467. #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
  468. #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX BIT(6)
  469. #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED BIT(4)
  470. static int ksz8873mll_read_status(struct phy_device *phydev)
  471. {
  472. int regval;
  473. /* dummy read */
  474. regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
  475. regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
  476. if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX)
  477. phydev->duplex = DUPLEX_HALF;
  478. else
  479. phydev->duplex = DUPLEX_FULL;
  480. if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED)
  481. phydev->speed = SPEED_10;
  482. else
  483. phydev->speed = SPEED_100;
  484. phydev->link = 1;
  485. phydev->pause = phydev->asym_pause = 0;
  486. return 0;
  487. }
  488. static int ksz9031_read_status(struct phy_device *phydev)
  489. {
  490. int err;
  491. int regval;
  492. err = genphy_read_status(phydev);
  493. if (err)
  494. return err;
  495. /* Make sure the PHY is not broken. Read idle error count,
  496. * and reset the PHY if it is maxed out.
  497. */
  498. regval = phy_read(phydev, MII_STAT1000);
  499. if ((regval & 0xFF) == 0xFF) {
  500. phy_init_hw(phydev);
  501. phydev->link = 0;
  502. }
  503. return 0;
  504. }
  505. static int ksz8873mll_config_aneg(struct phy_device *phydev)
  506. {
  507. return 0;
  508. }
  509. /* This routine returns -1 as an indication to the caller that the
  510. * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
  511. * MMD extended PHY registers.
  512. */
  513. static int
  514. ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum)
  515. {
  516. return -1;
  517. }
  518. /* This routine does nothing since the Micrel ksz9021 does not support
  519. * standard IEEE MMD extended PHY registers.
  520. */
  521. static int
  522. ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum, u16 val)
  523. {
  524. return -1;
  525. }
  526. static int kszphy_get_sset_count(struct phy_device *phydev)
  527. {
  528. return ARRAY_SIZE(kszphy_hw_stats);
  529. }
  530. static void kszphy_get_strings(struct phy_device *phydev, u8 *data)
  531. {
  532. int i;
  533. for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
  534. memcpy(data + i * ETH_GSTRING_LEN,
  535. kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
  536. }
  537. }
  538. #ifndef UINT64_MAX
  539. #define UINT64_MAX (u64)(~((u64)0))
  540. #endif
  541. static u64 kszphy_get_stat(struct phy_device *phydev, int i)
  542. {
  543. struct kszphy_hw_stat stat = kszphy_hw_stats[i];
  544. struct kszphy_priv *priv = phydev->priv;
  545. int val;
  546. u64 ret;
  547. val = phy_read(phydev, stat.reg);
  548. if (val < 0) {
  549. ret = UINT64_MAX;
  550. } else {
  551. val = val & ((1 << stat.bits) - 1);
  552. priv->stats[i] += val;
  553. ret = priv->stats[i];
  554. }
  555. return ret;
  556. }
  557. static void kszphy_get_stats(struct phy_device *phydev,
  558. struct ethtool_stats *stats, u64 *data)
  559. {
  560. int i;
  561. for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++)
  562. data[i] = kszphy_get_stat(phydev, i);
  563. }
  564. static int kszphy_suspend(struct phy_device *phydev)
  565. {
  566. /* Disable PHY Interrupts */
  567. if (phy_interrupt_is_valid(phydev)) {
  568. phydev->interrupts = PHY_INTERRUPT_DISABLED;
  569. if (phydev->drv->config_intr)
  570. phydev->drv->config_intr(phydev);
  571. }
  572. return genphy_suspend(phydev);
  573. }
  574. static int kszphy_resume(struct phy_device *phydev)
  575. {
  576. genphy_resume(phydev);
  577. /* Enable PHY Interrupts */
  578. if (phy_interrupt_is_valid(phydev)) {
  579. phydev->interrupts = PHY_INTERRUPT_ENABLED;
  580. if (phydev->drv->config_intr)
  581. phydev->drv->config_intr(phydev);
  582. }
  583. return 0;
  584. }
  585. static int kszphy_probe(struct phy_device *phydev)
  586. {
  587. const struct kszphy_type *type = phydev->drv->driver_data;
  588. const struct device_node *np = phydev->mdio.dev.of_node;
  589. struct kszphy_priv *priv;
  590. struct clk *clk;
  591. int ret;
  592. priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
  593. if (!priv)
  594. return -ENOMEM;
  595. phydev->priv = priv;
  596. priv->type = type;
  597. if (type->led_mode_reg) {
  598. ret = of_property_read_u32(np, "micrel,led-mode",
  599. &priv->led_mode);
  600. if (ret)
  601. priv->led_mode = -1;
  602. if (priv->led_mode > 3) {
  603. phydev_err(phydev, "invalid led mode: 0x%02x\n",
  604. priv->led_mode);
  605. priv->led_mode = -1;
  606. }
  607. } else {
  608. priv->led_mode = -1;
  609. }
  610. clk = devm_clk_get(&phydev->mdio.dev, "rmii-ref");
  611. /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
  612. if (!IS_ERR_OR_NULL(clk)) {
  613. unsigned long rate = clk_get_rate(clk);
  614. bool rmii_ref_clk_sel_25_mhz;
  615. priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel;
  616. rmii_ref_clk_sel_25_mhz = of_property_read_bool(np,
  617. "micrel,rmii-reference-clock-select-25-mhz");
  618. if (rate > 24500000 && rate < 25500000) {
  619. priv->rmii_ref_clk_sel_val = rmii_ref_clk_sel_25_mhz;
  620. } else if (rate > 49500000 && rate < 50500000) {
  621. priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz;
  622. } else {
  623. phydev_err(phydev, "Clock rate out of range: %ld\n",
  624. rate);
  625. return -EINVAL;
  626. }
  627. }
  628. /* Support legacy board-file configuration */
  629. if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
  630. priv->rmii_ref_clk_sel = true;
  631. priv->rmii_ref_clk_sel_val = true;
  632. }
  633. return 0;
  634. }
  635. static struct phy_driver ksphy_driver[] = {
  636. {
  637. .phy_id = PHY_ID_KS8737,
  638. .phy_id_mask = MICREL_PHY_ID_MASK,
  639. .name = "Micrel KS8737",
  640. .features = PHY_BASIC_FEATURES,
  641. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  642. .driver_data = &ks8737_type,
  643. .config_init = kszphy_config_init,
  644. .config_aneg = genphy_config_aneg,
  645. .read_status = genphy_read_status,
  646. .ack_interrupt = kszphy_ack_interrupt,
  647. .config_intr = kszphy_config_intr,
  648. .suspend = genphy_suspend,
  649. .resume = genphy_resume,
  650. }, {
  651. .phy_id = PHY_ID_KSZ8021,
  652. .phy_id_mask = 0x00ffffff,
  653. .name = "Micrel KSZ8021 or KSZ8031",
  654. .features = PHY_BASIC_FEATURES,
  655. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  656. .driver_data = &ksz8021_type,
  657. .probe = kszphy_probe,
  658. .config_init = kszphy_config_init,
  659. .config_aneg = genphy_config_aneg,
  660. .read_status = genphy_read_status,
  661. .ack_interrupt = kszphy_ack_interrupt,
  662. .config_intr = kszphy_config_intr,
  663. .get_sset_count = kszphy_get_sset_count,
  664. .get_strings = kszphy_get_strings,
  665. .get_stats = kszphy_get_stats,
  666. .suspend = genphy_suspend,
  667. .resume = genphy_resume,
  668. }, {
  669. .phy_id = PHY_ID_KSZ8031,
  670. .phy_id_mask = 0x00ffffff,
  671. .name = "Micrel KSZ8031",
  672. .features = PHY_BASIC_FEATURES,
  673. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  674. .driver_data = &ksz8021_type,
  675. .probe = kszphy_probe,
  676. .config_init = kszphy_config_init,
  677. .config_aneg = genphy_config_aneg,
  678. .read_status = genphy_read_status,
  679. .ack_interrupt = kszphy_ack_interrupt,
  680. .config_intr = kszphy_config_intr,
  681. .get_sset_count = kszphy_get_sset_count,
  682. .get_strings = kszphy_get_strings,
  683. .get_stats = kszphy_get_stats,
  684. .suspend = genphy_suspend,
  685. .resume = genphy_resume,
  686. }, {
  687. .phy_id = PHY_ID_KSZ8041,
  688. .phy_id_mask = MICREL_PHY_ID_MASK,
  689. .name = "Micrel KSZ8041",
  690. .features = PHY_BASIC_FEATURES,
  691. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  692. .driver_data = &ksz8041_type,
  693. .probe = kszphy_probe,
  694. .config_init = ksz8041_config_init,
  695. .config_aneg = ksz8041_config_aneg,
  696. .read_status = genphy_read_status,
  697. .ack_interrupt = kszphy_ack_interrupt,
  698. .config_intr = kszphy_config_intr,
  699. .get_sset_count = kszphy_get_sset_count,
  700. .get_strings = kszphy_get_strings,
  701. .get_stats = kszphy_get_stats,
  702. .suspend = genphy_suspend,
  703. .resume = genphy_resume,
  704. }, {
  705. .phy_id = PHY_ID_KSZ8041RNLI,
  706. .phy_id_mask = MICREL_PHY_ID_MASK,
  707. .name = "Micrel KSZ8041RNLI",
  708. .features = PHY_BASIC_FEATURES,
  709. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  710. .driver_data = &ksz8041_type,
  711. .probe = kszphy_probe,
  712. .config_init = kszphy_config_init,
  713. .config_aneg = genphy_config_aneg,
  714. .read_status = genphy_read_status,
  715. .ack_interrupt = kszphy_ack_interrupt,
  716. .config_intr = kszphy_config_intr,
  717. .get_sset_count = kszphy_get_sset_count,
  718. .get_strings = kszphy_get_strings,
  719. .get_stats = kszphy_get_stats,
  720. .suspend = genphy_suspend,
  721. .resume = genphy_resume,
  722. }, {
  723. .phy_id = PHY_ID_KSZ8051,
  724. .phy_id_mask = MICREL_PHY_ID_MASK,
  725. .name = "Micrel KSZ8051",
  726. .features = PHY_BASIC_FEATURES,
  727. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  728. .driver_data = &ksz8051_type,
  729. .probe = kszphy_probe,
  730. .config_init = kszphy_config_init,
  731. .config_aneg = genphy_config_aneg,
  732. .read_status = genphy_read_status,
  733. .ack_interrupt = kszphy_ack_interrupt,
  734. .config_intr = kszphy_config_intr,
  735. .get_sset_count = kszphy_get_sset_count,
  736. .get_strings = kszphy_get_strings,
  737. .get_stats = kszphy_get_stats,
  738. .suspend = genphy_suspend,
  739. .resume = genphy_resume,
  740. }, {
  741. .phy_id = PHY_ID_KSZ8001,
  742. .name = "Micrel KSZ8001 or KS8721",
  743. .phy_id_mask = 0x00fffffc,
  744. .features = PHY_BASIC_FEATURES,
  745. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  746. .driver_data = &ksz8041_type,
  747. .probe = kszphy_probe,
  748. .config_init = kszphy_config_init,
  749. .config_aneg = genphy_config_aneg,
  750. .read_status = genphy_read_status,
  751. .ack_interrupt = kszphy_ack_interrupt,
  752. .config_intr = kszphy_config_intr,
  753. .get_sset_count = kszphy_get_sset_count,
  754. .get_strings = kszphy_get_strings,
  755. .get_stats = kszphy_get_stats,
  756. .suspend = genphy_suspend,
  757. .resume = genphy_resume,
  758. }, {
  759. .phy_id = PHY_ID_KSZ8081,
  760. .name = "Micrel KSZ8081 or KSZ8091",
  761. .phy_id_mask = MICREL_PHY_ID_MASK,
  762. .features = PHY_BASIC_FEATURES,
  763. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  764. .driver_data = &ksz8081_type,
  765. .probe = kszphy_probe,
  766. .config_init = kszphy_config_init,
  767. .config_aneg = genphy_config_aneg,
  768. .read_status = genphy_read_status,
  769. .ack_interrupt = kszphy_ack_interrupt,
  770. .config_intr = kszphy_config_intr,
  771. .get_sset_count = kszphy_get_sset_count,
  772. .get_strings = kszphy_get_strings,
  773. .get_stats = kszphy_get_stats,
  774. .suspend = kszphy_suspend,
  775. .resume = kszphy_resume,
  776. }, {
  777. .phy_id = PHY_ID_KSZ8061,
  778. .name = "Micrel KSZ8061",
  779. .phy_id_mask = MICREL_PHY_ID_MASK,
  780. .features = PHY_BASIC_FEATURES,
  781. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  782. .config_init = kszphy_config_init,
  783. .config_aneg = genphy_config_aneg,
  784. .read_status = genphy_read_status,
  785. .ack_interrupt = kszphy_ack_interrupt,
  786. .config_intr = kszphy_config_intr,
  787. .suspend = genphy_suspend,
  788. .resume = genphy_resume,
  789. }, {
  790. .phy_id = PHY_ID_KSZ9021,
  791. .phy_id_mask = 0x000ffffe,
  792. .name = "Micrel KSZ9021 Gigabit PHY",
  793. .features = PHY_GBIT_FEATURES,
  794. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  795. .driver_data = &ksz9021_type,
  796. .probe = kszphy_probe,
  797. .config_init = ksz9021_config_init,
  798. .config_aneg = genphy_config_aneg,
  799. .read_status = genphy_read_status,
  800. .ack_interrupt = kszphy_ack_interrupt,
  801. .config_intr = kszphy_config_intr,
  802. .get_sset_count = kszphy_get_sset_count,
  803. .get_strings = kszphy_get_strings,
  804. .get_stats = kszphy_get_stats,
  805. .suspend = genphy_suspend,
  806. .resume = genphy_resume,
  807. .read_mmd = ksz9021_rd_mmd_phyreg,
  808. .write_mmd = ksz9021_wr_mmd_phyreg,
  809. }, {
  810. .phy_id = PHY_ID_KSZ9031,
  811. .phy_id_mask = MICREL_PHY_ID_MASK,
  812. .name = "Micrel KSZ9031 Gigabit PHY",
  813. .features = PHY_GBIT_FEATURES,
  814. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  815. .driver_data = &ksz9021_type,
  816. .probe = kszphy_probe,
  817. .config_init = ksz9031_config_init,
  818. .config_aneg = genphy_config_aneg,
  819. .read_status = ksz9031_read_status,
  820. .ack_interrupt = kszphy_ack_interrupt,
  821. .config_intr = kszphy_config_intr,
  822. .get_sset_count = kszphy_get_sset_count,
  823. .get_strings = kszphy_get_strings,
  824. .get_stats = kszphy_get_stats,
  825. .suspend = genphy_suspend,
  826. .resume = kszphy_resume,
  827. }, {
  828. .phy_id = PHY_ID_KSZ8873MLL,
  829. .phy_id_mask = MICREL_PHY_ID_MASK,
  830. .name = "Micrel KSZ8873MLL Switch",
  831. .flags = PHY_HAS_MAGICANEG,
  832. .config_init = kszphy_config_init,
  833. .config_aneg = ksz8873mll_config_aneg,
  834. .read_status = ksz8873mll_read_status,
  835. .suspend = genphy_suspend,
  836. .resume = genphy_resume,
  837. }, {
  838. .phy_id = PHY_ID_KSZ886X,
  839. .phy_id_mask = MICREL_PHY_ID_MASK,
  840. .name = "Micrel KSZ886X Switch",
  841. .features = PHY_BASIC_FEATURES,
  842. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  843. .config_init = kszphy_config_init,
  844. .config_aneg = genphy_config_aneg,
  845. .read_status = genphy_read_status,
  846. .suspend = genphy_suspend,
  847. .resume = genphy_resume,
  848. }, {
  849. .phy_id = PHY_ID_KSZ8795,
  850. .phy_id_mask = MICREL_PHY_ID_MASK,
  851. .name = "Micrel KSZ8795",
  852. .features = PHY_BASIC_FEATURES,
  853. .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
  854. .config_init = kszphy_config_init,
  855. .config_aneg = ksz8873mll_config_aneg,
  856. .read_status = ksz8873mll_read_status,
  857. .suspend = genphy_suspend,
  858. .resume = genphy_resume,
  859. } };
  860. module_phy_driver(ksphy_driver);
  861. MODULE_DESCRIPTION("Micrel PHY driver");
  862. MODULE_AUTHOR("David J. Choi");
  863. MODULE_LICENSE("GPL");
  864. static struct mdio_device_id __maybe_unused micrel_tbl[] = {
  865. { PHY_ID_KSZ9021, 0x000ffffe },
  866. { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
  867. { PHY_ID_KSZ8001, 0x00fffffc },
  868. { PHY_ID_KS8737, MICREL_PHY_ID_MASK },
  869. { PHY_ID_KSZ8021, 0x00ffffff },
  870. { PHY_ID_KSZ8031, 0x00ffffff },
  871. { PHY_ID_KSZ8041, MICREL_PHY_ID_MASK },
  872. { PHY_ID_KSZ8051, MICREL_PHY_ID_MASK },
  873. { PHY_ID_KSZ8061, MICREL_PHY_ID_MASK },
  874. { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK },
  875. { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
  876. { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
  877. { }
  878. };
  879. MODULE_DEVICE_TABLE(mdio, micrel_tbl);