ax88180.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /*
  2. * ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver
  3. *
  4. * This program is free software; you can distribute it and/or modify
  5. * it under the terms of the GNU General Public License (Version 2) as
  6. * published by the Free Software Foundation.
  7. * This program is distributed in the hope it will be useful, but
  8. * WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. * See the GNU General Public License for more details.
  11. * You should have received a copy of the GNU General Public License
  12. * along with this program; if not, write to the Free Software
  13. * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
  14. * USA.
  15. */
  16. /*
  17. * ========================================================================
  18. * ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver
  19. *
  20. * The AX88180 Ethernet controller is a high performance and highly
  21. * integrated local CPU bus Ethernet controller with embedded 40K bytes
  22. * SRAM and supports both 16-bit and 32-bit SRAM-Like interfaces for any
  23. * embedded systems.
  24. * The AX88180 is a single chip 10/100/1000Mbps Gigabit Ethernet
  25. * controller that supports both MII and RGMII interfaces and is
  26. * compliant to IEEE 802.3, IEEE 802.3u and IEEE 802.3z standards.
  27. *
  28. * Please visit ASIX's web site (http://www.asix.com.tw) for more
  29. * details.
  30. *
  31. * Module Name : ax88180.c
  32. * Date : 2008-07-07
  33. * History
  34. * 09/06/2006 : New release for AX88180 US2 chip.
  35. * 07/07/2008 : Fix up the coding style and using inline functions
  36. * instead of macros
  37. * ========================================================================
  38. */
  39. #include <common.h>
  40. #include <command.h>
  41. #include <net.h>
  42. #include <malloc.h>
  43. #include <linux/mii.h>
  44. #include "ax88180.h"
  45. /*
  46. * ===========================================================================
  47. * Local SubProgram Declaration
  48. * ===========================================================================
  49. */
  50. static void ax88180_rx_handler (struct eth_device *dev);
  51. static int ax88180_phy_initial (struct eth_device *dev);
  52. static void ax88180_media_config (struct eth_device *dev);
  53. static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev);
  54. static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev);
  55. static unsigned short ax88180_mdio_read (struct eth_device *dev,
  56. unsigned long regaddr);
  57. static void ax88180_mdio_write (struct eth_device *dev,
  58. unsigned long regaddr, unsigned short regdata);
  59. /*
  60. * ===========================================================================
  61. * Local SubProgram Bodies
  62. * ===========================================================================
  63. */
  64. static int ax88180_mdio_check_complete (struct eth_device *dev)
  65. {
  66. int us_cnt = 10000;
  67. unsigned short tmpval;
  68. /* MDIO read/write should not take more than 10 ms */
  69. while (--us_cnt) {
  70. tmpval = INW (dev, MDIOCTRL);
  71. if (((tmpval & READ_PHY) == 0) && ((tmpval & WRITE_PHY) == 0))
  72. break;
  73. }
  74. return us_cnt;
  75. }
  76. static unsigned short
  77. ax88180_mdio_read (struct eth_device *dev, unsigned long regaddr)
  78. {
  79. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  80. unsigned long tmpval = 0;
  81. OUTW (dev, (READ_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
  82. if (ax88180_mdio_check_complete (dev))
  83. tmpval = INW (dev, MDIODP);
  84. else
  85. printf ("Failed to read PHY register!\n");
  86. return (unsigned short)(tmpval & 0xFFFF);
  87. }
  88. static void
  89. ax88180_mdio_write (struct eth_device *dev, unsigned long regaddr,
  90. unsigned short regdata)
  91. {
  92. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  93. OUTW (dev, regdata, MDIODP);
  94. OUTW (dev, (WRITE_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
  95. if (!ax88180_mdio_check_complete (dev))
  96. printf ("Failed to write PHY register!\n");
  97. }
  98. static int ax88180_phy_reset (struct eth_device *dev)
  99. {
  100. unsigned short delay_cnt = 500;
  101. ax88180_mdio_write (dev, MII_BMCR, (BMCR_RESET | BMCR_ANENABLE));
  102. /* Wait for the reset to complete, or time out (500 ms) */
  103. while (ax88180_mdio_read (dev, MII_BMCR) & BMCR_RESET) {
  104. udelay (1000);
  105. if (--delay_cnt == 0) {
  106. printf ("Failed to reset PHY!\n");
  107. return -1;
  108. }
  109. }
  110. return 0;
  111. }
  112. static void ax88180_mac_reset (struct eth_device *dev)
  113. {
  114. unsigned long tmpval;
  115. unsigned char i;
  116. struct {
  117. unsigned short offset, value;
  118. } program_seq[] = {
  119. {
  120. MISC, MISC_NORMAL}, {
  121. RXINDICATOR, DEFAULT_RXINDICATOR}, {
  122. TXCMD, DEFAULT_TXCMD}, {
  123. TXBS, DEFAULT_TXBS}, {
  124. TXDES0, DEFAULT_TXDES0}, {
  125. TXDES1, DEFAULT_TXDES1}, {
  126. TXDES2, DEFAULT_TXDES2}, {
  127. TXDES3, DEFAULT_TXDES3}, {
  128. TXCFG, DEFAULT_TXCFG}, {
  129. MACCFG2, DEFAULT_MACCFG2}, {
  130. MACCFG3, DEFAULT_MACCFG3}, {
  131. TXLEN, DEFAULT_TXLEN}, {
  132. RXBTHD0, DEFAULT_RXBTHD0}, {
  133. RXBTHD1, DEFAULT_RXBTHD1}, {
  134. RXFULTHD, DEFAULT_RXFULTHD}, {
  135. DOGTHD0, DEFAULT_DOGTHD0}, {
  136. DOGTHD1, DEFAULT_DOGTHD1},};
  137. OUTW (dev, MISC_RESET_MAC, MISC);
  138. tmpval = INW (dev, MISC);
  139. for (i = 0; i < (sizeof (program_seq) / sizeof (program_seq[0])); i++)
  140. OUTW (dev, program_seq[i].value, program_seq[i].offset);
  141. }
  142. static int ax88180_poll_tx_complete (struct eth_device *dev)
  143. {
  144. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  145. unsigned long tmpval, txbs_txdp;
  146. int TimeOutCnt = 10000;
  147. txbs_txdp = 1 << priv->NextTxDesc;
  148. while (TimeOutCnt--) {
  149. tmpval = INW (dev, TXBS);
  150. if ((tmpval & txbs_txdp) == 0)
  151. break;
  152. udelay (100);
  153. }
  154. if (TimeOutCnt)
  155. return 0;
  156. else
  157. return -TimeOutCnt;
  158. }
  159. static void ax88180_rx_handler (struct eth_device *dev)
  160. {
  161. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  162. unsigned long data_size;
  163. unsigned short rxcurt_ptr, rxbound_ptr, next_ptr;
  164. int i;
  165. #if defined (CONFIG_DRIVER_AX88180_16BIT)
  166. unsigned short *rxdata = (unsigned short *)NetRxPackets[0];
  167. #else
  168. unsigned long *rxdata = (unsigned long *)NetRxPackets[0];
  169. #endif
  170. unsigned short count;
  171. rxcurt_ptr = INW (dev, RXCURT);
  172. rxbound_ptr = INW (dev, RXBOUND);
  173. next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
  174. debug ("ax88180: RX original RXBOUND=0x%04x,"
  175. " RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
  176. while (next_ptr != rxcurt_ptr) {
  177. OUTW (dev, RX_START_READ, RXINDICATOR);
  178. data_size = READ_RXBUF (dev) & 0xFFFF;
  179. if ((data_size == 0) || (data_size > MAX_RX_SIZE)) {
  180. OUTW (dev, RX_STOP_READ, RXINDICATOR);
  181. ax88180_mac_reset (dev);
  182. printf ("ax88180: Invalid Rx packet length!"
  183. " (len=0x%04lx)\n", data_size);
  184. debug ("ax88180: RX RXBOUND=0x%04x,"
  185. "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
  186. return;
  187. }
  188. rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1;
  189. rxbound_ptr &= RX_PAGE_NUM_MASK;
  190. /* Comput access times */
  191. count = (data_size + priv->PadSize) >> priv->BusWidth;
  192. for (i = 0; i < count; i++) {
  193. *(rxdata + i) = READ_RXBUF (dev);
  194. }
  195. OUTW (dev, RX_STOP_READ, RXINDICATOR);
  196. /* Pass the packet up to the protocol layers. */
  197. NetReceive (NetRxPackets[0], data_size);
  198. OUTW (dev, rxbound_ptr, RXBOUND);
  199. rxcurt_ptr = INW (dev, RXCURT);
  200. rxbound_ptr = INW (dev, RXBOUND);
  201. next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
  202. debug ("ax88180: RX updated RXBOUND=0x%04x,"
  203. "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
  204. }
  205. return;
  206. }
  207. static int ax88180_phy_initial (struct eth_device *dev)
  208. {
  209. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  210. unsigned long tmp_regval;
  211. unsigned short phyaddr;
  212. /* Search for first avaliable PHY chipset */
  213. #ifdef CONFIG_PHY_ADDR
  214. phyaddr = CONFIG_PHY_ADDR;
  215. #else
  216. for (phyaddr = 0; phyaddr < 32; ++phyaddr)
  217. #endif
  218. {
  219. priv->PhyAddr = phyaddr;
  220. priv->PhyID0 = ax88180_mdio_read(dev, MII_PHYSID1);
  221. switch (priv->PhyID0) {
  222. case MARVELL_88E1111_PHYSID0:
  223. debug("ax88180: Found Marvell 88E1111 PHY."
  224. " (PHY Addr=0x%x)\n", priv->PhyAddr);
  225. tmp_regval = ax88180_mdio_read(dev, M88_EXT_SSR);
  226. if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE) {
  227. ax88180_mdio_write(dev, M88_EXT_SCR, DEFAULT_EXT_SCR);
  228. if (ax88180_phy_reset(dev) < 0)
  229. return 0;
  230. ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT);
  231. }
  232. return 1;
  233. case CICADA_CIS8201_PHYSID0:
  234. debug("ax88180: Found CICADA CIS8201 PHY"
  235. " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
  236. ax88180_mdio_write(dev, CIS_IMR,
  237. (CIS_INT_ENABLE | LINK_CHANGE_INT));
  238. /* Set CIS_SMI_PRIORITY bit before force the media mode */
  239. tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS);
  240. tmp_regval &= ~CIS_SMI_PRIORITY;
  241. ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval);
  242. return 1;
  243. case 0xffff:
  244. /* No PHY at this addr */
  245. break;
  246. default:
  247. printf("ax88180: Unknown PHY chipset %#x at addr %#x\n",
  248. priv->PhyID0, priv->PhyAddr);
  249. break;
  250. }
  251. }
  252. printf("ax88180: Unknown PHY chipset!!\n");
  253. return 0;
  254. }
  255. static void ax88180_media_config (struct eth_device *dev)
  256. {
  257. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  258. unsigned long bmcr_val, bmsr_val;
  259. unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
  260. unsigned long RealMediaMode;
  261. int i;
  262. /* Waiting 2 seconds for PHY link stable */
  263. for (i = 0; i < 20000; i++) {
  264. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  265. if (bmsr_val & BMSR_LSTATUS) {
  266. break;
  267. }
  268. udelay (100);
  269. }
  270. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  271. debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
  272. if (bmsr_val & BMSR_LSTATUS) {
  273. bmcr_val = ax88180_mdio_read (dev, MII_BMCR);
  274. if (bmcr_val & BMCR_ANENABLE) {
  275. /*
  276. * Waiting for Auto-negotiation completion, this may
  277. * take up to 5 seconds.
  278. */
  279. debug ("ax88180: Auto-negotiation is "
  280. "enabled. Waiting for NWay completion..\n");
  281. for (i = 0; i < 50000; i++) {
  282. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  283. if (bmsr_val & BMSR_ANEGCOMPLETE) {
  284. break;
  285. }
  286. udelay (100);
  287. }
  288. } else
  289. debug ("ax88180: Auto-negotiation is disabled.\n");
  290. debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
  291. (unsigned int)bmcr_val, (unsigned int)bmsr_val);
  292. /* Get real media mode here */
  293. switch (priv->PhyID0) {
  294. case MARVELL_88E1111_PHYSID0:
  295. RealMediaMode = get_MarvellPHY_media_mode(dev);
  296. break;
  297. case CICADA_CIS8201_PHYSID0:
  298. RealMediaMode = get_CicadaPHY_media_mode(dev);
  299. break;
  300. default:
  301. RealMediaMode = MEDIA_1000FULL;
  302. break;
  303. }
  304. priv->LinkState = INS_LINK_UP;
  305. switch (RealMediaMode) {
  306. case MEDIA_1000FULL:
  307. debug ("ax88180: 1000Mbps Full-duplex mode.\n");
  308. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  309. maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
  310. maccfg1_val = GIGA_MODE_EN | RXFLOW_EN |
  311. FULLDUPLEX | DEFAULT_MACCFG1;
  312. break;
  313. case MEDIA_1000HALF:
  314. debug ("ax88180: 1000Mbps Half-duplex mode.\n");
  315. rxcfg_val = DEFAULT_RXCFG;
  316. maccfg0_val = DEFAULT_MACCFG0;
  317. maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
  318. break;
  319. case MEDIA_100FULL:
  320. debug ("ax88180: 100Mbps Full-duplex mode.\n");
  321. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  322. maccfg0_val = SPEED100 | TXFLOW_ENABLE
  323. | DEFAULT_MACCFG0;
  324. maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
  325. break;
  326. case MEDIA_100HALF:
  327. debug ("ax88180: 100Mbps Half-duplex mode.\n");
  328. rxcfg_val = DEFAULT_RXCFG;
  329. maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
  330. maccfg1_val = DEFAULT_MACCFG1;
  331. break;
  332. case MEDIA_10FULL:
  333. debug ("ax88180: 10Mbps Full-duplex mode.\n");
  334. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  335. maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
  336. maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
  337. break;
  338. case MEDIA_10HALF:
  339. debug ("ax88180: 10Mbps Half-duplex mode.\n");
  340. rxcfg_val = DEFAULT_RXCFG;
  341. maccfg0_val = DEFAULT_MACCFG0;
  342. maccfg1_val = DEFAULT_MACCFG1;
  343. break;
  344. default:
  345. debug ("ax88180: Unknow media mode.\n");
  346. rxcfg_val = DEFAULT_RXCFG;
  347. maccfg0_val = DEFAULT_MACCFG0;
  348. maccfg1_val = DEFAULT_MACCFG1;
  349. priv->LinkState = INS_LINK_DOWN;
  350. break;
  351. }
  352. } else {
  353. rxcfg_val = DEFAULT_RXCFG;
  354. maccfg0_val = DEFAULT_MACCFG0;
  355. maccfg1_val = DEFAULT_MACCFG1;
  356. priv->LinkState = INS_LINK_DOWN;
  357. }
  358. OUTW (dev, rxcfg_val, RXCFG);
  359. OUTW (dev, maccfg0_val, MACCFG0);
  360. OUTW (dev, maccfg1_val, MACCFG1);
  361. return;
  362. }
  363. static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev)
  364. {
  365. unsigned long m88_ssr;
  366. unsigned long MediaMode;
  367. m88_ssr = ax88180_mdio_read (dev, M88_SSR);
  368. switch (m88_ssr & SSR_MEDIA_MASK) {
  369. case SSR_1000FULL:
  370. MediaMode = MEDIA_1000FULL;
  371. break;
  372. case SSR_1000HALF:
  373. MediaMode = MEDIA_1000HALF;
  374. break;
  375. case SSR_100FULL:
  376. MediaMode = MEDIA_100FULL;
  377. break;
  378. case SSR_100HALF:
  379. MediaMode = MEDIA_100HALF;
  380. break;
  381. case SSR_10FULL:
  382. MediaMode = MEDIA_10FULL;
  383. break;
  384. case SSR_10HALF:
  385. MediaMode = MEDIA_10HALF;
  386. break;
  387. default:
  388. MediaMode = MEDIA_UNKNOWN;
  389. break;
  390. }
  391. return MediaMode;
  392. }
  393. static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev)
  394. {
  395. unsigned long tmp_regval;
  396. unsigned long MediaMode;
  397. tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
  398. switch (tmp_regval & CIS_MEDIA_MASK) {
  399. case CIS_1000FULL:
  400. MediaMode = MEDIA_1000FULL;
  401. break;
  402. case CIS_1000HALF:
  403. MediaMode = MEDIA_1000HALF;
  404. break;
  405. case CIS_100FULL:
  406. MediaMode = MEDIA_100FULL;
  407. break;
  408. case CIS_100HALF:
  409. MediaMode = MEDIA_100HALF;
  410. break;
  411. case CIS_10FULL:
  412. MediaMode = MEDIA_10FULL;
  413. break;
  414. case CIS_10HALF:
  415. MediaMode = MEDIA_10HALF;
  416. break;
  417. default:
  418. MediaMode = MEDIA_UNKNOWN;
  419. break;
  420. }
  421. return MediaMode;
  422. }
  423. static void ax88180_halt (struct eth_device *dev)
  424. {
  425. /* Disable AX88180 TX/RX functions */
  426. OUTW (dev, WAKEMOD, CMD);
  427. }
  428. static int ax88180_init (struct eth_device *dev, bd_t * bd)
  429. {
  430. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  431. unsigned short tmp_regval;
  432. ax88180_mac_reset (dev);
  433. /* Disable interrupt */
  434. OUTW (dev, CLEAR_IMR, IMR);
  435. /* Disable AX88180 TX/RX functions */
  436. OUTW (dev, WAKEMOD, CMD);
  437. /* Fill the MAC address */
  438. tmp_regval =
  439. dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);
  440. OUTW (dev, tmp_regval, MACID0);
  441. tmp_regval =
  442. dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);
  443. OUTW (dev, tmp_regval, MACID1);
  444. tmp_regval =
  445. dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
  446. OUTW (dev, tmp_regval, MACID2);
  447. ax88180_media_config (dev);
  448. OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
  449. /* Initial variables here */
  450. priv->FirstTxDesc = TXDP0;
  451. priv->NextTxDesc = TXDP0;
  452. /* Check if there is any invalid interrupt status and clear it. */
  453. OUTW (dev, INW (dev, ISR), ISR);
  454. /* Start AX88180 TX/RX functions */
  455. OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);
  456. return 0;
  457. }
  458. /* Get a data block via Ethernet */
  459. static int ax88180_recv (struct eth_device *dev)
  460. {
  461. unsigned short ISR_Status;
  462. unsigned short tmp_regval;
  463. /* Read and check interrupt status here. */
  464. ISR_Status = INW (dev, ISR);
  465. while (ISR_Status) {
  466. /* Clear the interrupt status */
  467. OUTW (dev, ISR_Status, ISR);
  468. debug ("\nax88180: The interrupt status = 0x%04x\n",
  469. ISR_Status);
  470. if (ISR_Status & ISR_PHY) {
  471. /* Read ISR register once to clear PHY interrupt bit */
  472. tmp_regval = ax88180_mdio_read (dev, M88_ISR);
  473. ax88180_media_config (dev);
  474. }
  475. if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
  476. ax88180_rx_handler (dev);
  477. }
  478. /* Read and check interrupt status again */
  479. ISR_Status = INW (dev, ISR);
  480. }
  481. return 0;
  482. }
  483. /* Send a data block via Ethernet. */
  484. static int
  485. ax88180_send (struct eth_device *dev, volatile void *packet, int length)
  486. {
  487. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  488. unsigned short TXDES_addr;
  489. unsigned short txcmd_txdp, txbs_txdp;
  490. unsigned short tmp_data;
  491. int i;
  492. #if defined (CONFIG_DRIVER_AX88180_16BIT)
  493. volatile unsigned short *txdata = (volatile unsigned short *)packet;
  494. #else
  495. volatile unsigned long *txdata = (volatile unsigned long *)packet;
  496. #endif
  497. unsigned short count;
  498. if (priv->LinkState != INS_LINK_UP) {
  499. return 0;
  500. }
  501. priv->FirstTxDesc = priv->NextTxDesc;
  502. txbs_txdp = 1 << priv->FirstTxDesc;
  503. debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);
  504. txcmd_txdp = priv->FirstTxDesc << 13;
  505. TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);
  506. OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);
  507. /* Comput access times */
  508. count = (length + priv->PadSize) >> priv->BusWidth;
  509. for (i = 0; i < count; i++) {
  510. WRITE_TXBUF (dev, *(txdata + i));
  511. }
  512. OUTW (dev, txcmd_txdp | length, TXCMD);
  513. OUTW (dev, txbs_txdp, TXBS);
  514. OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);
  515. priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;
  516. /*
  517. * Check the available transmit descriptor, if we had exhausted all
  518. * transmit descriptor ,then we have to wait for at least one free
  519. * descriptor
  520. */
  521. txbs_txdp = 1 << priv->NextTxDesc;
  522. tmp_data = INW (dev, TXBS);
  523. if (tmp_data & txbs_txdp) {
  524. if (ax88180_poll_tx_complete (dev) < 0) {
  525. ax88180_mac_reset (dev);
  526. priv->FirstTxDesc = TXDP0;
  527. priv->NextTxDesc = TXDP0;
  528. printf ("ax88180: Transmit time out occurred!\n");
  529. }
  530. }
  531. return 0;
  532. }
  533. static void ax88180_read_mac_addr (struct eth_device *dev)
  534. {
  535. unsigned short macid0_val, macid1_val, macid2_val;
  536. unsigned short tmp_regval;
  537. unsigned short i;
  538. /* Reload MAC address from EEPROM */
  539. OUTW (dev, RELOAD_EEPROM, PROMCTRL);
  540. /* Waiting for reload eeprom completion */
  541. for (i = 0; i < 500; i++) {
  542. tmp_regval = INW (dev, PROMCTRL);
  543. if ((tmp_regval & RELOAD_EEPROM) == 0)
  544. break;
  545. udelay (1000);
  546. }
  547. /* Get MAC addresses */
  548. macid0_val = INW (dev, MACID0);
  549. macid1_val = INW (dev, MACID1);
  550. macid2_val = INW (dev, MACID2);
  551. if (((macid0_val | macid1_val | macid2_val) != 0) &&
  552. ((macid0_val & 0x01) == 0)) {
  553. dev->enetaddr[0] = (unsigned char)macid0_val;
  554. dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);
  555. dev->enetaddr[2] = (unsigned char)macid1_val;
  556. dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);
  557. dev->enetaddr[4] = (unsigned char)macid2_val;
  558. dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);
  559. }
  560. }
  561. /*
  562. ===========================================================================
  563. <<<<<< Exported SubProgram Bodies >>>>>>
  564. ===========================================================================
  565. */
  566. int ax88180_initialize (bd_t * bis)
  567. {
  568. struct eth_device *dev;
  569. struct ax88180_private *priv;
  570. dev = (struct eth_device *)malloc (sizeof *dev);
  571. if (NULL == dev)
  572. return 0;
  573. memset (dev, 0, sizeof *dev);
  574. priv = (struct ax88180_private *)malloc (sizeof (*priv));
  575. if (NULL == priv)
  576. return 0;
  577. memset (priv, 0, sizeof *priv);
  578. sprintf (dev->name, "ax88180");
  579. dev->iobase = AX88180_BASE;
  580. dev->priv = priv;
  581. dev->init = ax88180_init;
  582. dev->halt = ax88180_halt;
  583. dev->send = ax88180_send;
  584. dev->recv = ax88180_recv;
  585. priv->BusWidth = BUS_WIDTH_32;
  586. priv->PadSize = 3;
  587. #if defined (CONFIG_DRIVER_AX88180_16BIT)
  588. OUTW (dev, (START_BASE >> 8), BASE);
  589. OUTW (dev, DECODE_EN, DECODE);
  590. priv->BusWidth = BUS_WIDTH_16;
  591. priv->PadSize = 1;
  592. #endif
  593. ax88180_mac_reset (dev);
  594. /* Disable interrupt */
  595. OUTW (dev, CLEAR_IMR, IMR);
  596. /* Disable AX88180 TX/RX functions */
  597. OUTW (dev, WAKEMOD, CMD);
  598. ax88180_read_mac_addr (dev);
  599. eth_register (dev);
  600. return ax88180_phy_initial (dev);
  601. }