smsc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * drivers/net/phy/smsc.c
  4. *
  5. * Driver for SMSC PHYs
  6. *
  7. * Author: Herbert Valerio Riedel
  8. *
  9. * Copyright (c) 2006 Herbert Valerio Riedel <[email protected]>
  10. *
  11. * Support added for SMSC LAN8187 and LAN8700 by [email protected]
  12. *
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/mii.h>
  18. #include <linux/ethtool.h>
  19. #include <linux/of.h>
  20. #include <linux/phy.h>
  21. #include <linux/netdevice.h>
  22. #include <linux/smscphy.h>
  23. /* Vendor-specific PHY Definitions */
  24. /* EDPD NLP / crossover time configuration */
  25. #define PHY_EDPD_CONFIG 16
  26. #define PHY_EDPD_CONFIG_EXT_CROSSOVER_ 0x0001
  27. /* Control/Status Indication Register */
  28. #define SPECIAL_CTRL_STS 27
  29. #define SPECIAL_CTRL_STS_OVRRD_AMDIX_ 0x8000
  30. #define SPECIAL_CTRL_STS_AMDIX_ENABLE_ 0x4000
  31. #define SPECIAL_CTRL_STS_AMDIX_STATE_ 0x2000
  32. struct smsc_hw_stat {
  33. const char *string;
  34. u8 reg;
  35. u8 bits;
  36. };
  37. static struct smsc_hw_stat smsc_hw_stats[] = {
  38. { "phy_symbol_errors", 26, 16},
  39. };
  40. struct smsc_phy_priv {
  41. bool energy_enable;
  42. };
  43. static int smsc_phy_ack_interrupt(struct phy_device *phydev)
  44. {
  45. int rc = phy_read(phydev, MII_LAN83C185_ISF);
  46. return rc < 0 ? rc : 0;
  47. }
  48. static int smsc_phy_config_intr(struct phy_device *phydev)
  49. {
  50. int rc;
  51. if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  52. rc = smsc_phy_ack_interrupt(phydev);
  53. if (rc)
  54. return rc;
  55. rc = phy_write(phydev, MII_LAN83C185_IM,
  56. MII_LAN83C185_ISF_INT_PHYLIB_EVENTS);
  57. } else {
  58. rc = phy_write(phydev, MII_LAN83C185_IM, 0);
  59. if (rc)
  60. return rc;
  61. rc = smsc_phy_ack_interrupt(phydev);
  62. }
  63. return rc < 0 ? rc : 0;
  64. }
  65. static irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
  66. {
  67. int irq_status;
  68. irq_status = phy_read(phydev, MII_LAN83C185_ISF);
  69. if (irq_status < 0) {
  70. if (irq_status != -ENODEV)
  71. phy_error(phydev);
  72. return IRQ_NONE;
  73. }
  74. if (!(irq_status & MII_LAN83C185_ISF_INT_PHYLIB_EVENTS))
  75. return IRQ_NONE;
  76. phy_trigger_machine(phydev);
  77. return IRQ_HANDLED;
  78. }
  79. static int smsc_phy_config_init(struct phy_device *phydev)
  80. {
  81. struct smsc_phy_priv *priv = phydev->priv;
  82. int rc;
  83. if (!priv->energy_enable || phydev->irq != PHY_POLL)
  84. return 0;
  85. rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
  86. if (rc < 0)
  87. return rc;
  88. /* Enable energy detect mode for this SMSC Transceivers */
  89. rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
  90. rc | MII_LAN83C185_EDPWRDOWN);
  91. return rc;
  92. }
  93. static int smsc_phy_reset(struct phy_device *phydev)
  94. {
  95. int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
  96. if (rc < 0)
  97. return rc;
  98. /* If the SMSC PHY is in power down mode, then set it
  99. * in all capable mode before using it.
  100. */
  101. if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) {
  102. /* set "all capable" mode */
  103. rc |= MII_LAN83C185_MODE_ALL;
  104. phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
  105. }
  106. /* reset the phy */
  107. return genphy_soft_reset(phydev);
  108. }
  109. static int lan87xx_config_aneg(struct phy_device *phydev)
  110. {
  111. int rc;
  112. int val;
  113. switch (phydev->mdix_ctrl) {
  114. case ETH_TP_MDI:
  115. val = SPECIAL_CTRL_STS_OVRRD_AMDIX_;
  116. break;
  117. case ETH_TP_MDI_X:
  118. val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
  119. SPECIAL_CTRL_STS_AMDIX_STATE_;
  120. break;
  121. case ETH_TP_MDI_AUTO:
  122. val = SPECIAL_CTRL_STS_AMDIX_ENABLE_;
  123. break;
  124. default:
  125. return genphy_config_aneg(phydev);
  126. }
  127. rc = phy_read(phydev, SPECIAL_CTRL_STS);
  128. if (rc < 0)
  129. return rc;
  130. rc &= ~(SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
  131. SPECIAL_CTRL_STS_AMDIX_ENABLE_ |
  132. SPECIAL_CTRL_STS_AMDIX_STATE_);
  133. rc |= val;
  134. phy_write(phydev, SPECIAL_CTRL_STS, rc);
  135. phydev->mdix = phydev->mdix_ctrl;
  136. return genphy_config_aneg(phydev);
  137. }
  138. static int lan95xx_config_aneg_ext(struct phy_device *phydev)
  139. {
  140. int rc;
  141. if (phydev->phy_id != 0x0007c0f0) /* not (LAN9500A or LAN9505A) */
  142. return lan87xx_config_aneg(phydev);
  143. /* Extend Manual AutoMDIX timer */
  144. rc = phy_read(phydev, PHY_EDPD_CONFIG);
  145. if (rc < 0)
  146. return rc;
  147. rc |= PHY_EDPD_CONFIG_EXT_CROSSOVER_;
  148. phy_write(phydev, PHY_EDPD_CONFIG, rc);
  149. return lan87xx_config_aneg(phydev);
  150. }
  151. /*
  152. * The LAN87xx suffers from rare absence of the ENERGYON-bit when Ethernet cable
  153. * plugs in while LAN87xx is in Energy Detect Power-Down mode. This leads to
  154. * unstable detection of plugging in Ethernet cable.
  155. * This workaround disables Energy Detect Power-Down mode and waiting for
  156. * response on link pulses to detect presence of plugged Ethernet cable.
  157. * The Energy Detect Power-Down mode is enabled again in the end of procedure to
  158. * save approximately 220 mW of power if cable is unplugged.
  159. * The workaround is only applicable to poll mode. Energy Detect Power-Down may
  160. * not be used in interrupt mode lest link change detection becomes unreliable.
  161. */
  162. static int lan87xx_read_status(struct phy_device *phydev)
  163. {
  164. struct smsc_phy_priv *priv = phydev->priv;
  165. int err;
  166. err = genphy_read_status(phydev);
  167. if (err)
  168. return err;
  169. if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) {
  170. /* Disable EDPD to wake up PHY */
  171. int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
  172. if (rc < 0)
  173. return rc;
  174. rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
  175. rc & ~MII_LAN83C185_EDPWRDOWN);
  176. if (rc < 0)
  177. return rc;
  178. /* Wait max 640 ms to detect energy and the timeout is not
  179. * an actual error.
  180. */
  181. read_poll_timeout(phy_read, rc,
  182. rc & MII_LAN83C185_ENERGYON || rc < 0,
  183. 10000, 640000, true, phydev,
  184. MII_LAN83C185_CTRL_STATUS);
  185. if (rc < 0)
  186. return rc;
  187. /* Re-enable EDPD */
  188. rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
  189. if (rc < 0)
  190. return rc;
  191. rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
  192. rc | MII_LAN83C185_EDPWRDOWN);
  193. if (rc < 0)
  194. return rc;
  195. }
  196. return err;
  197. }
  198. static int smsc_get_sset_count(struct phy_device *phydev)
  199. {
  200. return ARRAY_SIZE(smsc_hw_stats);
  201. }
  202. static void smsc_get_strings(struct phy_device *phydev, u8 *data)
  203. {
  204. int i;
  205. for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) {
  206. strncpy(data + i * ETH_GSTRING_LEN,
  207. smsc_hw_stats[i].string, ETH_GSTRING_LEN);
  208. }
  209. }
  210. static u64 smsc_get_stat(struct phy_device *phydev, int i)
  211. {
  212. struct smsc_hw_stat stat = smsc_hw_stats[i];
  213. int val;
  214. u64 ret;
  215. val = phy_read(phydev, stat.reg);
  216. if (val < 0)
  217. ret = U64_MAX;
  218. else
  219. ret = val;
  220. return ret;
  221. }
  222. static void smsc_get_stats(struct phy_device *phydev,
  223. struct ethtool_stats *stats, u64 *data)
  224. {
  225. int i;
  226. for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
  227. data[i] = smsc_get_stat(phydev, i);
  228. }
  229. static int smsc_phy_probe(struct phy_device *phydev)
  230. {
  231. struct device *dev = &phydev->mdio.dev;
  232. struct device_node *of_node = dev->of_node;
  233. struct smsc_phy_priv *priv;
  234. struct clk *refclk;
  235. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  236. if (!priv)
  237. return -ENOMEM;
  238. priv->energy_enable = true;
  239. if (of_property_read_bool(of_node, "smsc,disable-energy-detect"))
  240. priv->energy_enable = false;
  241. phydev->priv = priv;
  242. /* Make clk optional to keep DTB backward compatibility. */
  243. refclk = devm_clk_get_optional_enabled(dev, NULL);
  244. if (IS_ERR(refclk))
  245. return dev_err_probe(dev, PTR_ERR(refclk),
  246. "Failed to request clock\n");
  247. return clk_set_rate(refclk, 50 * 1000 * 1000);
  248. }
  249. static struct phy_driver smsc_phy_driver[] = {
  250. {
  251. .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
  252. .phy_id_mask = 0xfffffff0,
  253. .name = "SMSC LAN83C185",
  254. /* PHY_BASIC_FEATURES */
  255. .probe = smsc_phy_probe,
  256. /* basic functions */
  257. .config_init = smsc_phy_config_init,
  258. .soft_reset = smsc_phy_reset,
  259. /* IRQ related */
  260. .config_intr = smsc_phy_config_intr,
  261. .handle_interrupt = smsc_phy_handle_interrupt,
  262. .suspend = genphy_suspend,
  263. .resume = genphy_resume,
  264. }, {
  265. .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
  266. .phy_id_mask = 0xfffffff0,
  267. .name = "SMSC LAN8187",
  268. /* PHY_BASIC_FEATURES */
  269. .probe = smsc_phy_probe,
  270. /* basic functions */
  271. .config_init = smsc_phy_config_init,
  272. .soft_reset = smsc_phy_reset,
  273. /* IRQ related */
  274. .config_intr = smsc_phy_config_intr,
  275. .handle_interrupt = smsc_phy_handle_interrupt,
  276. /* Statistics */
  277. .get_sset_count = smsc_get_sset_count,
  278. .get_strings = smsc_get_strings,
  279. .get_stats = smsc_get_stats,
  280. .suspend = genphy_suspend,
  281. .resume = genphy_resume,
  282. }, {
  283. /* This covers internal PHY (phy_id: 0x0007C0C3) for
  284. * LAN9500 (PID: 0x9500), LAN9514 (PID: 0xec00), LAN9505 (PID: 0x9505)
  285. */
  286. .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
  287. .phy_id_mask = 0xfffffff0,
  288. .name = "SMSC LAN8700",
  289. /* PHY_BASIC_FEATURES */
  290. .probe = smsc_phy_probe,
  291. /* basic functions */
  292. .read_status = lan87xx_read_status,
  293. .config_init = smsc_phy_config_init,
  294. .soft_reset = smsc_phy_reset,
  295. .config_aneg = lan87xx_config_aneg,
  296. /* IRQ related */
  297. .config_intr = smsc_phy_config_intr,
  298. .handle_interrupt = smsc_phy_handle_interrupt,
  299. /* Statistics */
  300. .get_sset_count = smsc_get_sset_count,
  301. .get_strings = smsc_get_strings,
  302. .get_stats = smsc_get_stats,
  303. .suspend = genphy_suspend,
  304. .resume = genphy_resume,
  305. }, {
  306. .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
  307. .phy_id_mask = 0xfffffff0,
  308. .name = "SMSC LAN911x Internal PHY",
  309. /* PHY_BASIC_FEATURES */
  310. .probe = smsc_phy_probe,
  311. /* IRQ related */
  312. .config_intr = smsc_phy_config_intr,
  313. .handle_interrupt = smsc_phy_handle_interrupt,
  314. .suspend = genphy_suspend,
  315. .resume = genphy_resume,
  316. }, {
  317. /* This covers internal PHY (phy_id: 0x0007C0F0) for
  318. * LAN9500A (PID: 0x9E00), LAN9505A (PID: 0x9E01)
  319. */
  320. .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
  321. .phy_id_mask = 0xfffffff0,
  322. .name = "SMSC LAN8710/LAN8720",
  323. /* PHY_BASIC_FEATURES */
  324. .probe = smsc_phy_probe,
  325. /* basic functions */
  326. .read_status = lan87xx_read_status,
  327. .config_init = smsc_phy_config_init,
  328. .soft_reset = smsc_phy_reset,
  329. .config_aneg = lan95xx_config_aneg_ext,
  330. /* IRQ related */
  331. .config_intr = smsc_phy_config_intr,
  332. .handle_interrupt = smsc_phy_handle_interrupt,
  333. /* Statistics */
  334. .get_sset_count = smsc_get_sset_count,
  335. .get_strings = smsc_get_strings,
  336. .get_stats = smsc_get_stats,
  337. .suspend = genphy_suspend,
  338. .resume = genphy_resume,
  339. }, {
  340. .phy_id = 0x0007c110,
  341. .phy_id_mask = 0xfffffff0,
  342. .name = "SMSC LAN8740",
  343. /* PHY_BASIC_FEATURES */
  344. .flags = PHY_RST_AFTER_CLK_EN,
  345. .probe = smsc_phy_probe,
  346. /* basic functions */
  347. .read_status = lan87xx_read_status,
  348. .config_init = smsc_phy_config_init,
  349. .soft_reset = smsc_phy_reset,
  350. /* IRQ related */
  351. .config_intr = smsc_phy_config_intr,
  352. .handle_interrupt = smsc_phy_handle_interrupt,
  353. /* Statistics */
  354. .get_sset_count = smsc_get_sset_count,
  355. .get_strings = smsc_get_strings,
  356. .get_stats = smsc_get_stats,
  357. .suspend = genphy_suspend,
  358. .resume = genphy_resume,
  359. }, {
  360. .phy_id = 0x0007c130, /* 0x0007c130 and 0x0007c131 */
  361. /* This mask (0xfffffff2) is to differentiate from
  362. * LAN88xx (phy_id 0x0007c132)
  363. * and allows future phy_id revisions.
  364. */
  365. .phy_id_mask = 0xfffffff2,
  366. .name = "Microchip LAN8742",
  367. /* PHY_BASIC_FEATURES */
  368. .flags = PHY_RST_AFTER_CLK_EN,
  369. .probe = smsc_phy_probe,
  370. /* basic functions */
  371. .read_status = lan87xx_read_status,
  372. .config_init = smsc_phy_config_init,
  373. .soft_reset = smsc_phy_reset,
  374. /* IRQ related */
  375. .config_intr = smsc_phy_config_intr,
  376. .handle_interrupt = smsc_phy_handle_interrupt,
  377. /* Statistics */
  378. .get_sset_count = smsc_get_sset_count,
  379. .get_strings = smsc_get_strings,
  380. .get_stats = smsc_get_stats,
  381. .suspend = genphy_suspend,
  382. .resume = genphy_resume,
  383. } };
  384. module_phy_driver(smsc_phy_driver);
  385. MODULE_DESCRIPTION("SMSC PHY driver");
  386. MODULE_AUTHOR("Herbert Valerio Riedel");
  387. MODULE_LICENSE("GPL");
  388. static struct mdio_device_id __maybe_unused smsc_tbl[] = {
  389. { 0x0007c0a0, 0xfffffff0 },
  390. { 0x0007c0b0, 0xfffffff0 },
  391. { 0x0007c0c0, 0xfffffff0 },
  392. { 0x0007c0d0, 0xfffffff0 },
  393. { 0x0007c0f0, 0xfffffff0 },
  394. { 0x0007c110, 0xfffffff0 },
  395. { 0x0007c130, 0xfffffff2 },
  396. { }
  397. };
  398. MODULE_DEVICE_TABLE(mdio, smsc_tbl);