lan7x.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2017 Microchip Technology Inc. All rights reserved.
  4. */
  5. #include <dm.h>
  6. #include <log.h>
  7. #include <malloc.h>
  8. #include <miiphy.h>
  9. #include <memalign.h>
  10. #include <net.h>
  11. #include <usb.h>
  12. #include <linux/ethtool.h>
  13. #include <linux/mii.h>
  14. #include "usb_ether.h"
  15. #include "lan7x.h"
  16. /*
  17. * Lan7x infrastructure commands
  18. */
  19. int lan7x_write_reg(struct usb_device *udev, u32 index, u32 data)
  20. {
  21. int len;
  22. ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
  23. cpu_to_le32s(&data);
  24. tmpbuf[0] = data;
  25. len = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26. USB_VENDOR_REQUEST_WRITE_REGISTER,
  27. USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  28. 0, index, tmpbuf, sizeof(data),
  29. USB_CTRL_SET_TIMEOUT_MS);
  30. if (len != sizeof(data)) {
  31. debug("%s failed: index=%d, data=%d, len=%d",
  32. __func__, index, data, len);
  33. return -EIO;
  34. }
  35. return 0;
  36. }
  37. int lan7x_read_reg(struct usb_device *udev, u32 index, u32 *data)
  38. {
  39. int len;
  40. ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
  41. len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  42. USB_VENDOR_REQUEST_READ_REGISTER,
  43. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  44. 0, index, tmpbuf, sizeof(*data),
  45. USB_CTRL_GET_TIMEOUT_MS);
  46. *data = tmpbuf[0];
  47. if (len != sizeof(*data)) {
  48. debug("%s failed: index=%d, len=%d", __func__, index, len);
  49. return -EIO;
  50. }
  51. le32_to_cpus(data);
  52. return 0;
  53. }
  54. static int lan7x_phy_wait_not_busy(struct usb_device *udev)
  55. {
  56. return lan7x_wait_for_bit(udev, __func__,
  57. MII_ACC, MII_ACC_MII_BUSY,
  58. false, 100, 0);
  59. }
  60. int lan7x_mdio_read(struct usb_device *udev, int phy_id, int idx)
  61. {
  62. u32 val, addr;
  63. /* confirm MII not busy */
  64. if (lan7x_phy_wait_not_busy(udev)) {
  65. debug("MII is busy in %s\n", __func__);
  66. return -ETIMEDOUT;
  67. }
  68. /* set the address, index & direction (read from PHY) */
  69. addr = (phy_id << 11) | (idx << 6) |
  70. MII_ACC_MII_READ | MII_ACC_MII_BUSY;
  71. lan7x_write_reg(udev, MII_ACC, addr);
  72. if (lan7x_phy_wait_not_busy(udev)) {
  73. debug("Timed out reading MII reg %02X\n", idx);
  74. return -ETIMEDOUT;
  75. }
  76. lan7x_read_reg(udev, MII_DATA, &val);
  77. return val & 0xFFFF;
  78. }
  79. void lan7x_mdio_write(struct usb_device *udev, int phy_id, int idx, int regval)
  80. {
  81. u32 addr;
  82. /* confirm MII not busy */
  83. if (lan7x_phy_wait_not_busy(udev)) {
  84. debug("MII is busy in %s\n", __func__);
  85. return;
  86. }
  87. lan7x_write_reg(udev, MII_DATA, regval);
  88. /* set the address, index & direction (write to PHY) */
  89. addr = (phy_id << 11) | (idx << 6) |
  90. MII_ACC_MII_WRITE | MII_ACC_MII_BUSY;
  91. lan7x_write_reg(udev, MII_ACC, addr);
  92. if (lan7x_phy_wait_not_busy(udev))
  93. debug("Timed out writing MII reg %02X\n", idx);
  94. }
  95. /*
  96. * Lan7x phylib wrappers
  97. */
  98. static int lan7x_phylib_mdio_read(struct mii_dev *bus,
  99. int addr, int devad, int reg)
  100. {
  101. struct usb_device *udev = dev_get_parent_priv(bus->priv);
  102. return lan7x_mdio_read(udev, addr, reg);
  103. }
  104. static int lan7x_phylib_mdio_write(struct mii_dev *bus,
  105. int addr, int devad, int reg, u16 val)
  106. {
  107. struct usb_device *udev = dev_get_parent_priv(bus->priv);
  108. lan7x_mdio_write(udev, addr, reg, (int)val);
  109. return 0;
  110. }
  111. /*
  112. * Lan7x eeprom functions
  113. */
  114. static int lan7x_eeprom_confirm_not_busy(struct usb_device *udev)
  115. {
  116. return lan7x_wait_for_bit(udev, __func__,
  117. E2P_CMD, E2P_CMD_EPC_BUSY,
  118. false, 100, 0);
  119. }
  120. static int lan7x_wait_eeprom(struct usb_device *udev)
  121. {
  122. return lan7x_wait_for_bit(udev, __func__,
  123. E2P_CMD,
  124. (E2P_CMD_EPC_BUSY | E2P_CMD_EPC_TIMEOUT),
  125. false, 100, 0);
  126. }
  127. static int lan7x_read_eeprom(struct usb_device *udev,
  128. u32 offset, u32 length, u8 *data)
  129. {
  130. u32 val;
  131. int i, ret;
  132. ret = lan7x_eeprom_confirm_not_busy(udev);
  133. if (ret)
  134. return ret;
  135. for (i = 0; i < length; i++) {
  136. val = E2P_CMD_EPC_BUSY | E2P_CMD_EPC_CMD_READ |
  137. (offset & E2P_CMD_EPC_ADDR_MASK);
  138. lan7x_write_reg(udev, E2P_CMD, val);
  139. ret = lan7x_wait_eeprom(udev);
  140. if (ret)
  141. return ret;
  142. lan7x_read_reg(udev, E2P_DATA, &val);
  143. data[i] = val & 0xFF;
  144. offset++;
  145. }
  146. return ret;
  147. }
  148. /*
  149. * Lan7x phylib functions
  150. */
  151. int lan7x_phylib_register(struct udevice *udev)
  152. {
  153. struct usb_device *usbdev = dev_get_parent_priv(udev);
  154. struct lan7x_private *priv = dev_get_priv(udev);
  155. int ret;
  156. priv->mdiobus = mdio_alloc();
  157. if (!priv->mdiobus) {
  158. printf("mdio_alloc failed\n");
  159. return -ENOMEM;
  160. }
  161. priv->mdiobus->read = lan7x_phylib_mdio_read;
  162. priv->mdiobus->write = lan7x_phylib_mdio_write;
  163. sprintf(priv->mdiobus->name,
  164. "lan7x_mdiobus-d%hu-p%hu", usbdev->devnum, usbdev->portnr);
  165. priv->mdiobus->priv = (void *)udev;
  166. ret = mdio_register(priv->mdiobus);
  167. if (ret) {
  168. printf("mdio_register failed\n");
  169. free(priv->mdiobus);
  170. return -ENOMEM;
  171. }
  172. return 0;
  173. }
  174. int lan7x_eth_phylib_connect(struct udevice *udev, struct ueth_data *dev)
  175. {
  176. struct lan7x_private *priv = dev_get_priv(udev);
  177. priv->phydev = phy_connect(priv->mdiobus, dev->phy_id,
  178. udev, PHY_INTERFACE_MODE_MII);
  179. if (!priv->phydev) {
  180. printf("phy_connect failed\n");
  181. return -ENODEV;
  182. }
  183. return 0;
  184. }
  185. int lan7x_eth_phylib_config_start(struct udevice *udev)
  186. {
  187. struct lan7x_private *priv = dev_get_priv(udev);
  188. int ret;
  189. /* configure supported modes */
  190. priv->phydev->supported = PHY_BASIC_FEATURES |
  191. SUPPORTED_1000baseT_Full |
  192. SUPPORTED_Pause |
  193. SUPPORTED_Asym_Pause;
  194. priv->phydev->advertising = ADVERTISED_10baseT_Half |
  195. ADVERTISED_10baseT_Full |
  196. ADVERTISED_100baseT_Half |
  197. ADVERTISED_100baseT_Full |
  198. ADVERTISED_1000baseT_Full |
  199. ADVERTISED_Pause |
  200. ADVERTISED_Asym_Pause |
  201. ADVERTISED_Autoneg;
  202. priv->phydev->autoneg = AUTONEG_ENABLE;
  203. ret = genphy_config_aneg(priv->phydev);
  204. if (ret) {
  205. printf("genphy_config_aneg failed\n");
  206. return ret;
  207. }
  208. ret = phy_startup(priv->phydev);
  209. if (ret) {
  210. printf("phy_startup failed\n");
  211. return ret;
  212. }
  213. debug("** %s() speed %i duplex %i adv %X supp %X\n", __func__,
  214. priv->phydev->speed, priv->phydev->duplex,
  215. priv->phydev->advertising, priv->phydev->supported);
  216. return 0;
  217. }
  218. int lan7x_update_flowcontrol(struct usb_device *udev,
  219. struct ueth_data *dev,
  220. uint32_t *flow, uint32_t *fct_flow)
  221. {
  222. uint32_t lcladv, rmtadv;
  223. u8 cap = 0;
  224. struct lan7x_private *priv = dev_get_priv(udev->dev);
  225. debug("** %s()\n", __func__);
  226. debug("** %s() priv->phydev->speed %i duplex %i\n", __func__,
  227. priv->phydev->speed, priv->phydev->duplex);
  228. if (priv->phydev->duplex == DUPLEX_FULL) {
  229. lcladv = lan7x_mdio_read(udev, dev->phy_id, MII_ADVERTISE);
  230. rmtadv = lan7x_mdio_read(udev, dev->phy_id, MII_LPA);
  231. cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
  232. debug("TX Flow ");
  233. if (cap & FLOW_CTRL_TX) {
  234. *flow = (FLOW_CR_TX_FCEN | 0xFFFF);
  235. /* set fct_flow thresholds to 20% and 80% */
  236. *fct_flow = ((MAX_RX_FIFO_SIZE * 2) / (10 * 512))
  237. & 0x7FUL;
  238. *fct_flow <<= 8UL;
  239. *fct_flow |= ((MAX_RX_FIFO_SIZE * 8) / (10 * 512))
  240. & 0x7FUL;
  241. debug("EN ");
  242. } else {
  243. debug("DIS ");
  244. }
  245. debug("RX Flow ");
  246. if (cap & FLOW_CTRL_RX) {
  247. *flow |= FLOW_CR_RX_FCEN;
  248. debug("EN");
  249. } else {
  250. debug("DIS");
  251. }
  252. }
  253. debug("\n");
  254. return 0;
  255. }
  256. int lan7x_read_eeprom_mac(unsigned char *enetaddr, struct usb_device *udev)
  257. {
  258. int ret;
  259. memset(enetaddr, 0, 6);
  260. ret = lan7x_read_eeprom(udev, 0, 1, enetaddr);
  261. if ((ret == 0) && (enetaddr[0] == EEPROM_INDICATOR)) {
  262. ret = lan7x_read_eeprom(udev,
  263. EEPROM_MAC_OFFSET, ETH_ALEN,
  264. enetaddr);
  265. if ((ret == 0) && is_valid_ethaddr(enetaddr)) {
  266. /* eeprom values are valid so use them */
  267. debug("MAC address read from EEPROM %pM\n",
  268. enetaddr);
  269. return 0;
  270. }
  271. }
  272. debug("MAC address read from EEPROM invalid %pM\n", enetaddr);
  273. memset(enetaddr, 0, 6);
  274. return -EINVAL;
  275. }
  276. int lan7x_pmt_phy_reset(struct usb_device *udev,
  277. struct ueth_data *dev)
  278. {
  279. int ret;
  280. u32 data;
  281. ret = lan7x_read_reg(udev, PMT_CTL, &data);
  282. if (ret)
  283. return ret;
  284. ret = lan7x_write_reg(udev, PMT_CTL, data | PMT_CTL_PHY_RST);
  285. if (ret)
  286. return ret;
  287. /* for LAN7x, we need to check PMT_CTL_READY asserted */
  288. ret = lan7x_wait_for_bit(udev, "PMT_CTL_PHY_RST",
  289. PMT_CTL, PMT_CTL_PHY_RST,
  290. false, 1000, 0); /* could take over 125mS */
  291. if (ret)
  292. return ret;
  293. return lan7x_wait_for_bit(udev, "PMT_CTL_READY",
  294. PMT_CTL, PMT_CTL_READY,
  295. true, 1000, 0);
  296. }
  297. int lan7x_basic_reset(struct usb_device *udev,
  298. struct ueth_data *dev)
  299. {
  300. int ret;
  301. dev->phy_id = LAN7X_INTERNAL_PHY_ID; /* fixed phy id */
  302. ret = lan7x_write_reg(udev, HW_CFG, HW_CFG_LRST);
  303. if (ret)
  304. return ret;
  305. ret = lan7x_wait_for_bit(udev, "HW_CFG_LRST",
  306. HW_CFG, HW_CFG_LRST,
  307. false, 1000, 0);
  308. if (ret)
  309. return ret;
  310. debug("USB devnum %d portnr %d\n", udev->devnum, udev->portnr);
  311. return lan7x_pmt_phy_reset(udev, dev);
  312. }
  313. void lan7x_eth_stop(struct udevice *dev)
  314. {
  315. debug("** %s()\n", __func__);
  316. }
  317. int lan7x_eth_send(struct udevice *dev, void *packet, int length)
  318. {
  319. struct lan7x_private *priv = dev_get_priv(dev);
  320. struct ueth_data *ueth = &priv->ueth;
  321. int err;
  322. int actual_len;
  323. u32 tx_cmd_a;
  324. u32 tx_cmd_b;
  325. ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
  326. PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
  327. debug("** %s(), len %d, buf %#x\n", __func__, length,
  328. (unsigned int)(ulong) msg);
  329. if (length > PKTSIZE)
  330. return -ENOSPC;
  331. /* LAN7x disable all TX offload features for u-boot */
  332. tx_cmd_a = (u32) (length & TX_CMD_A_LEN_MASK) | TX_CMD_A_FCS;
  333. tx_cmd_b = 0;
  334. cpu_to_le32s(&tx_cmd_a);
  335. cpu_to_le32s(&tx_cmd_b);
  336. /* prepend cmd_a and cmd_b */
  337. memcpy(msg, &tx_cmd_a, sizeof(tx_cmd_a));
  338. memcpy(msg + sizeof(tx_cmd_a), &tx_cmd_b, sizeof(tx_cmd_b));
  339. memcpy(msg + sizeof(tx_cmd_a) + sizeof(tx_cmd_b), (void *)packet,
  340. length);
  341. err = usb_bulk_msg(ueth->pusb_dev,
  342. usb_sndbulkpipe(ueth->pusb_dev, ueth->ep_out),
  343. (void *)msg,
  344. length + sizeof(tx_cmd_a) +
  345. sizeof(tx_cmd_b),
  346. &actual_len, USB_BULK_SEND_TIMEOUT_MS);
  347. debug("Tx: len = %u, actual = %u, err = %d\n",
  348. (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)),
  349. (unsigned int)actual_len, err);
  350. return err;
  351. }
  352. int lan7x_eth_recv(struct udevice *dev, int flags, uchar **packetp)
  353. {
  354. struct lan7x_private *priv = dev_get_priv(dev);
  355. struct ueth_data *ueth = &priv->ueth;
  356. uint8_t *ptr;
  357. int ret, len;
  358. u32 packet_len = 0;
  359. u32 rx_cmd_a = 0;
  360. len = usb_ether_get_rx_bytes(ueth, &ptr);
  361. debug("%s: first try, len=%d\n", __func__, len);
  362. if (!len) {
  363. if (!(flags & ETH_RECV_CHECK_DEVICE))
  364. return -EAGAIN;
  365. ret = usb_ether_receive(ueth, RX_URB_SIZE);
  366. if (ret == -EAGAIN)
  367. return ret;
  368. len = usb_ether_get_rx_bytes(ueth, &ptr);
  369. debug("%s: second try, len=%d\n", __func__, len);
  370. }
  371. /*
  372. * 1st 4 bytes contain the length of the actual data plus error info.
  373. * Extract data length.
  374. */
  375. if (len < sizeof(packet_len)) {
  376. debug("Rx: incomplete packet length\n");
  377. goto err;
  378. }
  379. memcpy(&rx_cmd_a, ptr, sizeof(rx_cmd_a));
  380. le32_to_cpus(&rx_cmd_a);
  381. if (rx_cmd_a & RX_CMD_A_RXE) {
  382. debug("Rx: Error header=%#x", rx_cmd_a);
  383. goto err;
  384. }
  385. packet_len = (u16) (rx_cmd_a & RX_CMD_A_LEN_MASK);
  386. if (packet_len > len - sizeof(packet_len)) {
  387. debug("Rx: too large packet: %d\n", packet_len);
  388. goto err;
  389. }
  390. /*
  391. * For LAN7x, the length in command A does not
  392. * include command A, B, and C length.
  393. * So use it as is.
  394. */
  395. *packetp = ptr + 10;
  396. return packet_len;
  397. err:
  398. usb_ether_advance_rxbuf(ueth, -1);
  399. return -EINVAL;
  400. }
  401. int lan7x_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
  402. {
  403. struct lan7x_private *priv = dev_get_priv(dev);
  404. packet_len = ALIGN(packet_len, 4);
  405. usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
  406. return 0;
  407. }
  408. int lan7x_eth_remove(struct udevice *dev)
  409. {
  410. struct lan7x_private *priv = dev_get_priv(dev);
  411. debug("** %s()\n", __func__);
  412. free(priv->phydev);
  413. mdio_unregister(priv->mdiobus);
  414. mdio_free(priv->mdiobus);
  415. return 0;
  416. }