sja1105_mdio.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright 2021 NXP
  3. */
  4. #include <linux/pcs/pcs-xpcs.h>
  5. #include <linux/of_mdio.h>
  6. #include "sja1105.h"
  7. #define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc)
  8. int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
  9. {
  10. struct sja1105_mdio_private *mdio_priv = bus->priv;
  11. struct sja1105_private *priv = mdio_priv->priv;
  12. u64 addr;
  13. u32 tmp;
  14. u16 mmd;
  15. int rc;
  16. if (!(reg & MII_ADDR_C45))
  17. return -EINVAL;
  18. mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  19. addr = (mmd << 16) | (reg & GENMASK(15, 0));
  20. if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
  21. return 0xffff;
  22. if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
  23. return NXP_SJA1105_XPCS_ID >> 16;
  24. if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
  25. return NXP_SJA1105_XPCS_ID & GENMASK(15, 0);
  26. rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
  27. if (rc < 0)
  28. return rc;
  29. return tmp & 0xffff;
  30. }
  31. int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
  32. {
  33. struct sja1105_mdio_private *mdio_priv = bus->priv;
  34. struct sja1105_private *priv = mdio_priv->priv;
  35. u64 addr;
  36. u32 tmp;
  37. u16 mmd;
  38. if (!(reg & MII_ADDR_C45))
  39. return -EINVAL;
  40. mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  41. addr = (mmd << 16) | (reg & GENMASK(15, 0));
  42. tmp = val;
  43. if (mmd != MDIO_MMD_VEND1 && mmd != MDIO_MMD_VEND2)
  44. return -EINVAL;
  45. return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
  46. }
  47. int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
  48. {
  49. struct sja1105_mdio_private *mdio_priv = bus->priv;
  50. struct sja1105_private *priv = mdio_priv->priv;
  51. const struct sja1105_regs *regs = priv->info->regs;
  52. int offset, bank;
  53. u64 addr;
  54. u32 tmp;
  55. u16 mmd;
  56. int rc;
  57. if (!(reg & MII_ADDR_C45))
  58. return -EINVAL;
  59. if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
  60. return -ENODEV;
  61. mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  62. addr = (mmd << 16) | (reg & GENMASK(15, 0));
  63. if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
  64. return NXP_SJA1110_XPCS_ID >> 16;
  65. if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
  66. return NXP_SJA1110_XPCS_ID & GENMASK(15, 0);
  67. bank = addr >> 8;
  68. offset = addr & GENMASK(7, 0);
  69. /* This addressing scheme reserves register 0xff for the bank address
  70. * register, so that can never be addressed.
  71. */
  72. if (WARN_ON(offset == 0xff))
  73. return -ENODEV;
  74. tmp = bank;
  75. rc = sja1105_xfer_u32(priv, SPI_WRITE,
  76. regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
  77. &tmp, NULL);
  78. if (rc < 0)
  79. return rc;
  80. rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset,
  81. &tmp, NULL);
  82. if (rc < 0)
  83. return rc;
  84. return tmp & 0xffff;
  85. }
  86. int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
  87. {
  88. struct sja1105_mdio_private *mdio_priv = bus->priv;
  89. struct sja1105_private *priv = mdio_priv->priv;
  90. const struct sja1105_regs *regs = priv->info->regs;
  91. int offset, bank;
  92. u64 addr;
  93. u32 tmp;
  94. u16 mmd;
  95. int rc;
  96. if (!(reg & MII_ADDR_C45))
  97. return -EINVAL;
  98. if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
  99. return -ENODEV;
  100. mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  101. addr = (mmd << 16) | (reg & GENMASK(15, 0));
  102. bank = addr >> 8;
  103. offset = addr & GENMASK(7, 0);
  104. /* This addressing scheme reserves register 0xff for the bank address
  105. * register, so that can never be addressed.
  106. */
  107. if (WARN_ON(offset == 0xff))
  108. return -ENODEV;
  109. tmp = bank;
  110. rc = sja1105_xfer_u32(priv, SPI_WRITE,
  111. regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
  112. &tmp, NULL);
  113. if (rc < 0)
  114. return rc;
  115. tmp = val;
  116. return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset,
  117. &tmp, NULL);
  118. }
  119. enum sja1105_mdio_opcode {
  120. SJA1105_C45_ADDR = 0,
  121. SJA1105_C22 = 1,
  122. SJA1105_C45_DATA = 2,
  123. SJA1105_C45_DATA_AUTOINC = 3,
  124. };
  125. static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv,
  126. int phy, enum sja1105_mdio_opcode op,
  127. int xad)
  128. {
  129. const struct sja1105_regs *regs = priv->info->regs;
  130. return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0);
  131. }
  132. static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg)
  133. {
  134. struct sja1105_mdio_private *mdio_priv = bus->priv;
  135. struct sja1105_private *priv = mdio_priv->priv;
  136. u64 addr;
  137. u32 tmp;
  138. int rc;
  139. if (reg & MII_ADDR_C45) {
  140. u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  141. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
  142. mmd);
  143. tmp = reg & MII_REGADDR_C45_MASK;
  144. rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
  145. if (rc < 0)
  146. return rc;
  147. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
  148. mmd);
  149. rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
  150. if (rc < 0)
  151. return rc;
  152. return tmp & 0xffff;
  153. }
  154. /* Clause 22 read */
  155. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
  156. rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL);
  157. if (rc < 0)
  158. return rc;
  159. return tmp & 0xffff;
  160. }
  161. static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg,
  162. u16 val)
  163. {
  164. struct sja1105_mdio_private *mdio_priv = bus->priv;
  165. struct sja1105_private *priv = mdio_priv->priv;
  166. u64 addr;
  167. u32 tmp;
  168. int rc;
  169. if (reg & MII_ADDR_C45) {
  170. u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
  171. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR,
  172. mmd);
  173. tmp = reg & MII_REGADDR_C45_MASK;
  174. rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
  175. if (rc < 0)
  176. return rc;
  177. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA,
  178. mmd);
  179. tmp = val & 0xffff;
  180. rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
  181. if (rc < 0)
  182. return rc;
  183. return 0;
  184. }
  185. /* Clause 22 write */
  186. addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f);
  187. tmp = val & 0xffff;
  188. return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
  189. }
  190. static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
  191. {
  192. struct sja1105_mdio_private *mdio_priv = bus->priv;
  193. struct sja1105_private *priv = mdio_priv->priv;
  194. const struct sja1105_regs *regs = priv->info->regs;
  195. u32 tmp;
  196. int rc;
  197. if (reg & MII_ADDR_C45)
  198. return -EOPNOTSUPP;
  199. rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
  200. &tmp, NULL);
  201. if (rc < 0)
  202. return rc;
  203. return tmp & 0xffff;
  204. }
  205. static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
  206. u16 val)
  207. {
  208. struct sja1105_mdio_private *mdio_priv = bus->priv;
  209. struct sja1105_private *priv = mdio_priv->priv;
  210. const struct sja1105_regs *regs = priv->info->regs;
  211. u32 tmp = val;
  212. if (reg & MII_ADDR_C45)
  213. return -EOPNOTSUPP;
  214. return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
  215. &tmp, NULL);
  216. }
  217. static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
  218. struct device_node *mdio_node)
  219. {
  220. struct sja1105_mdio_private *mdio_priv;
  221. struct device_node *np;
  222. struct mii_bus *bus;
  223. int rc = 0;
  224. np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio");
  225. if (!np)
  226. return 0;
  227. if (!of_device_is_available(np))
  228. goto out_put_np;
  229. bus = mdiobus_alloc_size(sizeof(*mdio_priv));
  230. if (!bus) {
  231. rc = -ENOMEM;
  232. goto out_put_np;
  233. }
  234. bus->name = "SJA1110 100base-TX MDIO bus";
  235. snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx",
  236. dev_name(priv->ds->dev));
  237. bus->read = sja1105_base_tx_mdio_read;
  238. bus->write = sja1105_base_tx_mdio_write;
  239. bus->parent = priv->ds->dev;
  240. mdio_priv = bus->priv;
  241. mdio_priv->priv = priv;
  242. rc = of_mdiobus_register(bus, np);
  243. if (rc) {
  244. mdiobus_free(bus);
  245. goto out_put_np;
  246. }
  247. priv->mdio_base_tx = bus;
  248. out_put_np:
  249. of_node_put(np);
  250. return rc;
  251. }
  252. static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv)
  253. {
  254. if (!priv->mdio_base_tx)
  255. return;
  256. mdiobus_unregister(priv->mdio_base_tx);
  257. mdiobus_free(priv->mdio_base_tx);
  258. priv->mdio_base_tx = NULL;
  259. }
  260. static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
  261. struct device_node *mdio_node)
  262. {
  263. struct sja1105_mdio_private *mdio_priv;
  264. struct device_node *np;
  265. struct mii_bus *bus;
  266. int rc = 0;
  267. np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio");
  268. if (!np)
  269. return 0;
  270. if (!of_device_is_available(np))
  271. goto out_put_np;
  272. bus = mdiobus_alloc_size(sizeof(*mdio_priv));
  273. if (!bus) {
  274. rc = -ENOMEM;
  275. goto out_put_np;
  276. }
  277. bus->name = "SJA1110 100base-T1 MDIO bus";
  278. snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1",
  279. dev_name(priv->ds->dev));
  280. bus->read = sja1105_base_t1_mdio_read;
  281. bus->write = sja1105_base_t1_mdio_write;
  282. bus->parent = priv->ds->dev;
  283. mdio_priv = bus->priv;
  284. mdio_priv->priv = priv;
  285. rc = of_mdiobus_register(bus, np);
  286. if (rc) {
  287. mdiobus_free(bus);
  288. goto out_put_np;
  289. }
  290. priv->mdio_base_t1 = bus;
  291. out_put_np:
  292. of_node_put(np);
  293. return rc;
  294. }
  295. static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv)
  296. {
  297. if (!priv->mdio_base_t1)
  298. return;
  299. mdiobus_unregister(priv->mdio_base_t1);
  300. mdiobus_free(priv->mdio_base_t1);
  301. priv->mdio_base_t1 = NULL;
  302. }
  303. static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
  304. {
  305. struct sja1105_mdio_private *mdio_priv;
  306. struct dsa_switch *ds = priv->ds;
  307. struct mii_bus *bus;
  308. int rc = 0;
  309. int port;
  310. if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write)
  311. return 0;
  312. bus = mdiobus_alloc_size(sizeof(*mdio_priv));
  313. if (!bus)
  314. return -ENOMEM;
  315. bus->name = "SJA1105 PCS MDIO bus";
  316. snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs",
  317. dev_name(ds->dev));
  318. bus->read = priv->info->pcs_mdio_read;
  319. bus->write = priv->info->pcs_mdio_write;
  320. bus->parent = ds->dev;
  321. /* There is no PHY on this MDIO bus => mask out all PHY addresses
  322. * from auto probing.
  323. */
  324. bus->phy_mask = ~0;
  325. mdio_priv = bus->priv;
  326. mdio_priv->priv = priv;
  327. rc = mdiobus_register(bus);
  328. if (rc) {
  329. mdiobus_free(bus);
  330. return rc;
  331. }
  332. for (port = 0; port < ds->num_ports; port++) {
  333. struct mdio_device *mdiodev;
  334. struct dw_xpcs *xpcs;
  335. if (dsa_is_unused_port(ds, port))
  336. continue;
  337. if (priv->phy_mode[port] != PHY_INTERFACE_MODE_SGMII &&
  338. priv->phy_mode[port] != PHY_INTERFACE_MODE_2500BASEX)
  339. continue;
  340. mdiodev = mdio_device_create(bus, port);
  341. if (IS_ERR(mdiodev)) {
  342. rc = PTR_ERR(mdiodev);
  343. goto out_pcs_free;
  344. }
  345. xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
  346. if (IS_ERR(xpcs)) {
  347. rc = PTR_ERR(xpcs);
  348. goto out_pcs_free;
  349. }
  350. priv->xpcs[port] = xpcs;
  351. }
  352. priv->mdio_pcs = bus;
  353. return 0;
  354. out_pcs_free:
  355. for (port = 0; port < ds->num_ports; port++) {
  356. if (!priv->xpcs[port])
  357. continue;
  358. mdio_device_free(priv->xpcs[port]->mdiodev);
  359. xpcs_destroy(priv->xpcs[port]);
  360. priv->xpcs[port] = NULL;
  361. }
  362. mdiobus_unregister(bus);
  363. mdiobus_free(bus);
  364. return rc;
  365. }
  366. static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv)
  367. {
  368. struct dsa_switch *ds = priv->ds;
  369. int port;
  370. if (!priv->mdio_pcs)
  371. return;
  372. for (port = 0; port < ds->num_ports; port++) {
  373. if (!priv->xpcs[port])
  374. continue;
  375. mdio_device_free(priv->xpcs[port]->mdiodev);
  376. xpcs_destroy(priv->xpcs[port]);
  377. priv->xpcs[port] = NULL;
  378. }
  379. mdiobus_unregister(priv->mdio_pcs);
  380. mdiobus_free(priv->mdio_pcs);
  381. priv->mdio_pcs = NULL;
  382. }
  383. int sja1105_mdiobus_register(struct dsa_switch *ds)
  384. {
  385. struct sja1105_private *priv = ds->priv;
  386. const struct sja1105_regs *regs = priv->info->regs;
  387. struct device_node *switch_node = ds->dev->of_node;
  388. struct device_node *mdio_node;
  389. int rc;
  390. rc = sja1105_mdiobus_pcs_register(priv);
  391. if (rc)
  392. return rc;
  393. mdio_node = of_get_child_by_name(switch_node, "mdios");
  394. if (!mdio_node)
  395. return 0;
  396. if (!of_device_is_available(mdio_node))
  397. goto out_put_mdio_node;
  398. if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) {
  399. rc = sja1105_mdiobus_base_tx_register(priv, mdio_node);
  400. if (rc)
  401. goto err_put_mdio_node;
  402. }
  403. if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) {
  404. rc = sja1105_mdiobus_base_t1_register(priv, mdio_node);
  405. if (rc)
  406. goto err_free_base_tx_mdiobus;
  407. }
  408. out_put_mdio_node:
  409. of_node_put(mdio_node);
  410. return 0;
  411. err_free_base_tx_mdiobus:
  412. sja1105_mdiobus_base_tx_unregister(priv);
  413. err_put_mdio_node:
  414. of_node_put(mdio_node);
  415. sja1105_mdiobus_pcs_unregister(priv);
  416. return rc;
  417. }
  418. void sja1105_mdiobus_unregister(struct dsa_switch *ds)
  419. {
  420. struct sja1105_private *priv = ds->priv;
  421. sja1105_mdiobus_base_t1_unregister(priv);
  422. sja1105_mdiobus_base_tx_unregister(priv);
  423. sja1105_mdiobus_pcs_unregister(priv);
  424. }