xilinx_emaclite.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /*
  2. * (C) Copyright 2007-2009 Michal Simek
  3. * (C) Copyright 2003 Xilinx Inc.
  4. *
  5. * Michal SIMEK <monstr@monstr.eu>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <net.h>
  11. #include <config.h>
  12. #include <console.h>
  13. #include <malloc.h>
  14. #include <asm/io.h>
  15. #include <phy.h>
  16. #include <miiphy.h>
  17. #include <fdtdec.h>
  18. #include <asm-generic/errno.h>
  19. #undef DEBUG
  20. #define ENET_ADDR_LENGTH 6
  21. /* EmacLite constants */
  22. #define XEL_BUFFER_OFFSET 0x0800 /* Next buffer's offset */
  23. #define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */
  24. #define XEL_TSR_OFFSET 0x07FC /* Tx status */
  25. #define XEL_RSR_OFFSET 0x17FC /* Rx status */
  26. #define XEL_RXBUFF_OFFSET 0x1000 /* Receive Buffer */
  27. /* Xmit complete */
  28. #define XEL_TSR_XMIT_BUSY_MASK 0x00000001UL
  29. /* Xmit interrupt enable bit */
  30. #define XEL_TSR_XMIT_IE_MASK 0x00000008UL
  31. /* Buffer is active, SW bit only */
  32. #define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000UL
  33. /* Program the MAC address */
  34. #define XEL_TSR_PROGRAM_MASK 0x00000002UL
  35. /* define for programming the MAC address into the EMAC Lite */
  36. #define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
  37. /* Transmit packet length upper byte */
  38. #define XEL_TPLR_LENGTH_MASK_HI 0x0000FF00UL
  39. /* Transmit packet length lower byte */
  40. #define XEL_TPLR_LENGTH_MASK_LO 0x000000FFUL
  41. /* Recv complete */
  42. #define XEL_RSR_RECV_DONE_MASK 0x00000001UL
  43. /* Recv interrupt enable bit */
  44. #define XEL_RSR_RECV_IE_MASK 0x00000008UL
  45. /* MDIO Address Register Bit Masks */
  46. #define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */
  47. #define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */
  48. #define XEL_MDIOADDR_PHYADR_SHIFT 5
  49. #define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */
  50. /* MDIO Write Data Register Bit Masks */
  51. #define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */
  52. /* MDIO Read Data Register Bit Masks */
  53. #define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */
  54. /* MDIO Control Register Bit Masks */
  55. #define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */
  56. #define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */
  57. struct emaclite_regs {
  58. u32 tx_ping; /* 0x0 - TX Ping buffer */
  59. u32 reserved1[504];
  60. u32 mdioaddr; /* 0x7e4 - MDIO Address Register */
  61. u32 mdiowr; /* 0x7e8 - MDIO Write Data Register */
  62. u32 mdiord;/* 0x7ec - MDIO Read Data Register */
  63. u32 mdioctrl; /* 0x7f0 - MDIO Control Register */
  64. u32 tx_ping_tplr; /* 0x7f4 - Tx packet length */
  65. u32 global_interrupt; /* 0x7f8 - Global interrupt enable */
  66. u32 tx_ping_tsr; /* 0x7fc - Tx status */
  67. u32 tx_pong; /* 0x800 - TX Pong buffer */
  68. u32 reserved2[508];
  69. u32 tx_pong_tplr; /* 0xff4 - Tx packet length */
  70. u32 reserved3; /* 0xff8 */
  71. u32 tx_pong_tsr; /* 0xffc - Tx status */
  72. u32 rx_ping; /* 0x1000 - Receive Buffer */
  73. u32 reserved4[510];
  74. u32 rx_ping_rsr; /* 0x17fc - Rx status */
  75. u32 rx_pong; /* 0x1800 - Receive Buffer */
  76. u32 reserved5[510];
  77. u32 rx_pong_rsr; /* 0x1ffc - Rx status */
  78. };
  79. struct xemaclite {
  80. u32 nexttxbuffertouse; /* Next TX buffer to write to */
  81. u32 nextrxbuffertouse; /* Next RX buffer to read from */
  82. u32 txpp; /* TX ping pong buffer */
  83. u32 rxpp; /* RX ping pong buffer */
  84. int phyaddr;
  85. struct emaclite_regs *regs;
  86. struct phy_device *phydev;
  87. struct mii_dev *bus;
  88. };
  89. static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
  90. static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount)
  91. {
  92. u32 i;
  93. u32 alignbuffer;
  94. u32 *to32ptr;
  95. u32 *from32ptr;
  96. u8 *to8ptr;
  97. u8 *from8ptr;
  98. from32ptr = (u32 *) srcptr;
  99. /* Word aligned buffer, no correction needed. */
  100. to32ptr = (u32 *) destptr;
  101. while (bytecount > 3) {
  102. *to32ptr++ = *from32ptr++;
  103. bytecount -= 4;
  104. }
  105. to8ptr = (u8 *) to32ptr;
  106. alignbuffer = *from32ptr++;
  107. from8ptr = (u8 *) &alignbuffer;
  108. for (i = 0; i < bytecount; i++)
  109. *to8ptr++ = *from8ptr++;
  110. }
  111. static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount)
  112. {
  113. u32 i;
  114. u32 alignbuffer;
  115. u32 *to32ptr = (u32 *) destptr;
  116. u32 *from32ptr;
  117. u8 *to8ptr;
  118. u8 *from8ptr;
  119. from32ptr = (u32 *) srcptr;
  120. while (bytecount > 3) {
  121. *to32ptr++ = *from32ptr++;
  122. bytecount -= 4;
  123. }
  124. alignbuffer = 0;
  125. to8ptr = (u8 *) &alignbuffer;
  126. from8ptr = (u8 *) from32ptr;
  127. for (i = 0; i < bytecount; i++)
  128. *to8ptr++ = *from8ptr++;
  129. *to32ptr++ = alignbuffer;
  130. }
  131. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  132. static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
  133. bool set, unsigned int timeout)
  134. {
  135. u32 val;
  136. unsigned long start = get_timer(0);
  137. while (1) {
  138. val = readl(reg);
  139. if (!set)
  140. val = ~val;
  141. if ((val & mask) == mask)
  142. return 0;
  143. if (get_timer(start) > timeout)
  144. break;
  145. if (ctrlc()) {
  146. puts("Abort\n");
  147. return -EINTR;
  148. }
  149. udelay(1);
  150. }
  151. debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
  152. func, reg, mask, set);
  153. return -ETIMEDOUT;
  154. }
  155. static int mdio_wait(struct emaclite_regs *regs)
  156. {
  157. return wait_for_bit(__func__, &regs->mdioctrl,
  158. XEL_MDIOCTRL_MDIOSTS_MASK, false, 2000);
  159. }
  160. static u32 phyread(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
  161. u16 *data)
  162. {
  163. struct emaclite_regs *regs = emaclite->regs;
  164. if (mdio_wait(regs))
  165. return 1;
  166. u32 ctrl_reg = in_be32(&regs->mdioctrl);
  167. out_be32(&regs->mdioaddr, XEL_MDIOADDR_OP_MASK |
  168. ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
  169. out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
  170. if (mdio_wait(regs))
  171. return 1;
  172. /* Read data */
  173. *data = in_be32(&regs->mdiord);
  174. return 0;
  175. }
  176. static u32 phywrite(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
  177. u16 data)
  178. {
  179. struct emaclite_regs *regs = emaclite->regs;
  180. if (mdio_wait(regs))
  181. return 1;
  182. /*
  183. * Write the PHY address, register number and clear the OP bit in the
  184. * MDIO Address register and then write the value into the MDIO Write
  185. * Data register. Finally, set the Status bit in the MDIO Control
  186. * register to start a MDIO write transaction.
  187. */
  188. u32 ctrl_reg = in_be32(&regs->mdioctrl);
  189. out_be32(&regs->mdioaddr, ~XEL_MDIOADDR_OP_MASK &
  190. ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
  191. out_be32(&regs->mdiowr, data);
  192. out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
  193. if (mdio_wait(regs))
  194. return 1;
  195. return 0;
  196. }
  197. #endif
  198. static void emaclite_halt(struct eth_device *dev)
  199. {
  200. debug("eth_halt\n");
  201. }
  202. /* Use MII register 1 (MII status register) to detect PHY */
  203. #define PHY_DETECT_REG 1
  204. /* Mask used to verify certain PHY features (or register contents)
  205. * in the register above:
  206. * 0x1000: 10Mbps full duplex support
  207. * 0x0800: 10Mbps half duplex support
  208. * 0x0008: Auto-negotiation support
  209. */
  210. #define PHY_DETECT_MASK 0x1808
  211. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  212. static int setup_phy(struct eth_device *dev)
  213. {
  214. int i;
  215. u16 phyreg;
  216. struct xemaclite *emaclite = dev->priv;
  217. struct phy_device *phydev;
  218. u32 supported = SUPPORTED_10baseT_Half |
  219. SUPPORTED_10baseT_Full |
  220. SUPPORTED_100baseT_Half |
  221. SUPPORTED_100baseT_Full;
  222. if (emaclite->phyaddr != -1) {
  223. phyread(emaclite, emaclite->phyaddr, PHY_DETECT_REG, &phyreg);
  224. if ((phyreg != 0xFFFF) &&
  225. ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
  226. /* Found a valid PHY address */
  227. debug("Default phy address %d is valid\n",
  228. emaclite->phyaddr);
  229. } else {
  230. debug("PHY address is not setup correctly %d\n",
  231. emaclite->phyaddr);
  232. emaclite->phyaddr = -1;
  233. }
  234. }
  235. if (emaclite->phyaddr == -1) {
  236. /* detect the PHY address */
  237. for (i = 31; i >= 0; i--) {
  238. phyread(emaclite, i, PHY_DETECT_REG, &phyreg);
  239. if ((phyreg != 0xFFFF) &&
  240. ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
  241. /* Found a valid PHY address */
  242. emaclite->phyaddr = i;
  243. debug("emaclite: Found valid phy address, %d\n",
  244. i);
  245. break;
  246. }
  247. }
  248. }
  249. /* interface - look at tsec */
  250. phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev,
  251. PHY_INTERFACE_MODE_MII);
  252. /*
  253. * Phy can support 1000baseT but device NOT that's why phydev->supported
  254. * must be setup for 1000baseT. phydev->advertising setups what speeds
  255. * will be used for autonegotiation where 1000baseT must be disabled.
  256. */
  257. phydev->supported = supported | SUPPORTED_1000baseT_Half |
  258. SUPPORTED_1000baseT_Full;
  259. phydev->advertising = supported;
  260. emaclite->phydev = phydev;
  261. phy_config(phydev);
  262. phy_startup(phydev);
  263. if (!phydev->link) {
  264. printf("%s: No link.\n", phydev->dev->name);
  265. return 0;
  266. }
  267. /* Do not setup anything */
  268. return 1;
  269. }
  270. #endif
  271. static int emaclite_init(struct eth_device *dev, bd_t *bis)
  272. {
  273. struct xemaclite *emaclite = dev->priv;
  274. struct emaclite_regs *regs = emaclite->regs;
  275. debug("EmacLite Initialization Started\n");
  276. /*
  277. * TX - TX_PING & TX_PONG initialization
  278. */
  279. /* Restart PING TX */
  280. out_be32(&regs->tx_ping_tsr, 0);
  281. /* Copy MAC address */
  282. xemaclite_alignedwrite(dev->enetaddr, (u32)&regs->tx_ping,
  283. ENET_ADDR_LENGTH);
  284. /* Set the length */
  285. out_be32(&regs->tx_ping_tplr, ENET_ADDR_LENGTH);
  286. /* Update the MAC address in the EMAC Lite */
  287. out_be32(&regs->tx_ping_tsr, XEL_TSR_PROG_MAC_ADDR);
  288. /* Wait for EMAC Lite to finish with the MAC address update */
  289. while ((in_be32 (&regs->tx_ping_tsr) &
  290. XEL_TSR_PROG_MAC_ADDR) != 0)
  291. ;
  292. if (emaclite->txpp) {
  293. /* The same operation with PONG TX */
  294. out_be32(&regs->tx_pong_tsr, 0);
  295. xemaclite_alignedwrite(dev->enetaddr, (u32)&regs->tx_pong,
  296. ENET_ADDR_LENGTH);
  297. out_be32(&regs->tx_pong_tplr, ENET_ADDR_LENGTH);
  298. out_be32(&regs->tx_pong_tsr, XEL_TSR_PROG_MAC_ADDR);
  299. while ((in_be32(&regs->tx_pong_tsr) &
  300. XEL_TSR_PROG_MAC_ADDR) != 0)
  301. ;
  302. }
  303. /*
  304. * RX - RX_PING & RX_PONG initialization
  305. */
  306. /* Write out the value to flush the RX buffer */
  307. out_be32(&regs->rx_ping_rsr, XEL_RSR_RECV_IE_MASK);
  308. if (emaclite->rxpp)
  309. out_be32(&regs->rx_pong_rsr, XEL_RSR_RECV_IE_MASK);
  310. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  311. out_be32(&regs->mdioctrl, XEL_MDIOCTRL_MDIOEN_MASK);
  312. if (in_be32(&regs->mdioctrl) & XEL_MDIOCTRL_MDIOEN_MASK)
  313. if (!setup_phy(dev))
  314. return -1;
  315. #endif
  316. debug("EmacLite Initialization complete\n");
  317. return 0;
  318. }
  319. static int xemaclite_txbufferavailable(struct eth_device *dev)
  320. {
  321. u32 reg;
  322. u32 txpingbusy;
  323. u32 txpongbusy;
  324. struct xemaclite *emaclite = dev->priv;
  325. /*
  326. * Read the other buffer register
  327. * and determine if the other buffer is available
  328. */
  329. reg = in_be32 (dev->iobase +
  330. emaclite->nexttxbuffertouse + 0);
  331. txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
  332. XEL_TSR_XMIT_BUSY_MASK);
  333. reg = in_be32 (dev->iobase +
  334. (emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0);
  335. txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
  336. XEL_TSR_XMIT_BUSY_MASK);
  337. return !(txpingbusy && txpongbusy);
  338. }
  339. static int emaclite_send(struct eth_device *dev, void *ptr, int len)
  340. {
  341. u32 reg;
  342. u32 baseaddress;
  343. struct xemaclite *emaclite = dev->priv;
  344. u32 maxtry = 1000;
  345. if (len > PKTSIZE)
  346. len = PKTSIZE;
  347. while (!xemaclite_txbufferavailable(dev) && maxtry) {
  348. udelay(10);
  349. maxtry--;
  350. }
  351. if (!maxtry) {
  352. printf("Error: Timeout waiting for ethernet TX buffer\n");
  353. /* Restart PING TX */
  354. out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
  355. if (emaclite->txpp) {
  356. out_be32 (dev->iobase + XEL_TSR_OFFSET +
  357. XEL_BUFFER_OFFSET, 0);
  358. }
  359. return -1;
  360. }
  361. /* Determine the expected TX buffer address */
  362. baseaddress = (dev->iobase + emaclite->nexttxbuffertouse);
  363. /* Determine if the expected buffer address is empty */
  364. reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
  365. if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
  366. && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
  367. & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
  368. if (emaclite->txpp)
  369. emaclite->nexttxbuffertouse ^= XEL_BUFFER_OFFSET;
  370. debug("Send packet from 0x%x\n", baseaddress);
  371. /* Write the frame to the buffer */
  372. xemaclite_alignedwrite(ptr, baseaddress, len);
  373. out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
  374. (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
  375. reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
  376. reg |= XEL_TSR_XMIT_BUSY_MASK;
  377. if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
  378. reg |= XEL_TSR_XMIT_ACTIVE_MASK;
  379. out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
  380. return 0;
  381. }
  382. if (emaclite->txpp) {
  383. /* Switch to second buffer */
  384. baseaddress ^= XEL_BUFFER_OFFSET;
  385. /* Determine if the expected buffer address is empty */
  386. reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
  387. if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
  388. && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
  389. & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
  390. debug("Send packet from 0x%x\n", baseaddress);
  391. /* Write the frame to the buffer */
  392. xemaclite_alignedwrite(ptr, baseaddress, len);
  393. out_be32 (baseaddress + XEL_TPLR_OFFSET, (len &
  394. (XEL_TPLR_LENGTH_MASK_HI |
  395. XEL_TPLR_LENGTH_MASK_LO)));
  396. reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
  397. reg |= XEL_TSR_XMIT_BUSY_MASK;
  398. if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
  399. reg |= XEL_TSR_XMIT_ACTIVE_MASK;
  400. out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
  401. return 0;
  402. }
  403. }
  404. puts("Error while sending frame\n");
  405. return -1;
  406. }
  407. static int emaclite_recv(struct eth_device *dev)
  408. {
  409. u32 length;
  410. u32 reg;
  411. u32 baseaddress;
  412. struct xemaclite *emaclite = dev->priv;
  413. baseaddress = dev->iobase + emaclite->nextrxbuffertouse;
  414. reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
  415. debug("Testing data at address 0x%x\n", baseaddress);
  416. if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
  417. if (emaclite->rxpp)
  418. emaclite->nextrxbuffertouse ^= XEL_BUFFER_OFFSET;
  419. } else {
  420. if (!emaclite->rxpp) {
  421. debug("No data was available - address 0x%x\n",
  422. baseaddress);
  423. return 0;
  424. } else {
  425. baseaddress ^= XEL_BUFFER_OFFSET;
  426. reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
  427. if ((reg & XEL_RSR_RECV_DONE_MASK) !=
  428. XEL_RSR_RECV_DONE_MASK) {
  429. debug("No data was available - address 0x%x\n",
  430. baseaddress);
  431. return 0;
  432. }
  433. }
  434. }
  435. /* Get the length of the frame that arrived */
  436. switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) &
  437. 0xFFFF0000 ) >> 16) {
  438. case 0x806:
  439. length = 42 + 20; /* FIXME size of ARP */
  440. debug("ARP Packet\n");
  441. break;
  442. case 0x800:
  443. length = 14 + 14 +
  444. (((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET +
  445. 0x10))) & 0xFFFF0000) >> 16);
  446. /* FIXME size of IP packet */
  447. debug ("IP Packet\n");
  448. break;
  449. default:
  450. debug("Other Packet\n");
  451. length = PKTSIZE;
  452. break;
  453. }
  454. xemaclite_alignedread((u32 *) (baseaddress + XEL_RXBUFF_OFFSET),
  455. etherrxbuff, length);
  456. /* Acknowledge the frame */
  457. reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
  458. reg &= ~XEL_RSR_RECV_DONE_MASK;
  459. out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
  460. debug("Packet receive from 0x%x, length %dB\n", baseaddress, length);
  461. net_process_received_packet((uchar *)etherrxbuff, length);
  462. return length;
  463. }
  464. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  465. static int emaclite_miiphy_read(const char *devname, uchar addr,
  466. uchar reg, ushort *val)
  467. {
  468. u32 ret;
  469. struct eth_device *dev = eth_get_dev();
  470. ret = phyread(dev->priv, addr, reg, val);
  471. debug("emaclite: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
  472. return ret;
  473. }
  474. static int emaclite_miiphy_write(const char *devname, uchar addr,
  475. uchar reg, ushort val)
  476. {
  477. struct eth_device *dev = eth_get_dev();
  478. debug("emaclite: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
  479. return phywrite(dev->priv, addr, reg, val);
  480. }
  481. #endif
  482. int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
  483. int txpp, int rxpp)
  484. {
  485. struct eth_device *dev;
  486. struct xemaclite *emaclite;
  487. struct emaclite_regs *regs;
  488. dev = calloc(1, sizeof(*dev));
  489. if (dev == NULL)
  490. return -1;
  491. emaclite = calloc(1, sizeof(struct xemaclite));
  492. if (emaclite == NULL) {
  493. free(dev);
  494. return -1;
  495. }
  496. dev->priv = emaclite;
  497. emaclite->txpp = txpp;
  498. emaclite->rxpp = rxpp;
  499. sprintf(dev->name, "Xelite.%lx", base_addr);
  500. emaclite->regs = (struct emaclite_regs *)base_addr;
  501. regs = emaclite->regs;
  502. dev->iobase = base_addr;
  503. dev->init = emaclite_init;
  504. dev->halt = emaclite_halt;
  505. dev->send = emaclite_send;
  506. dev->recv = emaclite_recv;
  507. #ifdef CONFIG_PHY_ADDR
  508. emaclite->phyaddr = CONFIG_PHY_ADDR;
  509. #else
  510. emaclite->phyaddr = -1;
  511. #endif
  512. eth_register(dev);
  513. #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
  514. miiphy_register(dev->name, emaclite_miiphy_read, emaclite_miiphy_write);
  515. emaclite->bus = miiphy_get_dev_by_name(dev->name);
  516. out_be32(&regs->mdioctrl, XEL_MDIOCTRL_MDIOEN_MASK);
  517. #endif
  518. return 1;
  519. }