ax88180.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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 < ARRAY_SIZE(program_seq); 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 *)net_rx_packets[0];
  167. #else
  168. unsigned long *rxdata = (unsigned long *)net_rx_packets[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. net_process_received_packet(net_rx_packets[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. priv->PhyID1 = ax88180_mdio_read(dev, MII_PHYSID2);
  222. switch (priv->PhyID0) {
  223. case MARVELL_ALASKA_PHYSID0:
  224. debug("ax88180: Found Marvell Alaska PHY family."
  225. " (PHY Addr=0x%x)\n", priv->PhyAddr);
  226. switch (priv->PhyID1) {
  227. case MARVELL_88E1118_PHYSID1:
  228. ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 2);
  229. ax88180_mdio_write(dev, M88E1118_CR,
  230. M88E1118_CR_DEFAULT);
  231. ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 3);
  232. ax88180_mdio_write(dev, M88E1118_LEDCTL,
  233. M88E1118_LEDCTL_DEFAULT);
  234. ax88180_mdio_write(dev, M88E1118_LEDMIX,
  235. M88E1118_LEDMIX_LED050 | M88E1118_LEDMIX_LED150 | 0x15);
  236. ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 0);
  237. default: /* Default to 88E1111 Phy */
  238. tmp_regval = ax88180_mdio_read(dev, M88E1111_EXT_SSR);
  239. if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE)
  240. ax88180_mdio_write(dev, M88E1111_EXT_SCR,
  241. DEFAULT_EXT_SCR);
  242. }
  243. if (ax88180_phy_reset(dev) < 0)
  244. return 0;
  245. ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT);
  246. return 1;
  247. case CICADA_CIS8201_PHYSID0:
  248. debug("ax88180: Found CICADA CIS8201 PHY"
  249. " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
  250. ax88180_mdio_write(dev, CIS_IMR,
  251. (CIS_INT_ENABLE | LINK_CHANGE_INT));
  252. /* Set CIS_SMI_PRIORITY bit before force the media mode */
  253. tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS);
  254. tmp_regval &= ~CIS_SMI_PRIORITY;
  255. ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval);
  256. return 1;
  257. case 0xffff:
  258. /* No PHY at this addr */
  259. break;
  260. default:
  261. printf("ax88180: Unknown PHY chipset %#x at addr %#x\n",
  262. priv->PhyID0, priv->PhyAddr);
  263. break;
  264. }
  265. }
  266. printf("ax88180: Unknown PHY chipset!!\n");
  267. return 0;
  268. }
  269. static void ax88180_media_config (struct eth_device *dev)
  270. {
  271. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  272. unsigned long bmcr_val, bmsr_val;
  273. unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
  274. unsigned long RealMediaMode;
  275. int i;
  276. /* Waiting 2 seconds for PHY link stable */
  277. for (i = 0; i < 20000; i++) {
  278. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  279. if (bmsr_val & BMSR_LSTATUS) {
  280. break;
  281. }
  282. udelay (100);
  283. }
  284. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  285. debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
  286. if (bmsr_val & BMSR_LSTATUS) {
  287. bmcr_val = ax88180_mdio_read (dev, MII_BMCR);
  288. if (bmcr_val & BMCR_ANENABLE) {
  289. /*
  290. * Waiting for Auto-negotiation completion, this may
  291. * take up to 5 seconds.
  292. */
  293. debug ("ax88180: Auto-negotiation is "
  294. "enabled. Waiting for NWay completion..\n");
  295. for (i = 0; i < 50000; i++) {
  296. bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
  297. if (bmsr_val & BMSR_ANEGCOMPLETE) {
  298. break;
  299. }
  300. udelay (100);
  301. }
  302. } else
  303. debug ("ax88180: Auto-negotiation is disabled.\n");
  304. debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
  305. (unsigned int)bmcr_val, (unsigned int)bmsr_val);
  306. /* Get real media mode here */
  307. switch (priv->PhyID0) {
  308. case MARVELL_ALASKA_PHYSID0:
  309. RealMediaMode = get_MarvellPHY_media_mode(dev);
  310. break;
  311. case CICADA_CIS8201_PHYSID0:
  312. RealMediaMode = get_CicadaPHY_media_mode(dev);
  313. break;
  314. default:
  315. RealMediaMode = MEDIA_1000FULL;
  316. break;
  317. }
  318. priv->LinkState = INS_LINK_UP;
  319. switch (RealMediaMode) {
  320. case MEDIA_1000FULL:
  321. debug ("ax88180: 1000Mbps Full-duplex mode.\n");
  322. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  323. maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
  324. maccfg1_val = GIGA_MODE_EN | RXFLOW_EN |
  325. FULLDUPLEX | DEFAULT_MACCFG1;
  326. break;
  327. case MEDIA_1000HALF:
  328. debug ("ax88180: 1000Mbps Half-duplex mode.\n");
  329. rxcfg_val = DEFAULT_RXCFG;
  330. maccfg0_val = DEFAULT_MACCFG0;
  331. maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
  332. break;
  333. case MEDIA_100FULL:
  334. debug ("ax88180: 100Mbps Full-duplex mode.\n");
  335. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  336. maccfg0_val = SPEED100 | TXFLOW_ENABLE
  337. | DEFAULT_MACCFG0;
  338. maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
  339. break;
  340. case MEDIA_100HALF:
  341. debug ("ax88180: 100Mbps Half-duplex mode.\n");
  342. rxcfg_val = DEFAULT_RXCFG;
  343. maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
  344. maccfg1_val = DEFAULT_MACCFG1;
  345. break;
  346. case MEDIA_10FULL:
  347. debug ("ax88180: 10Mbps Full-duplex mode.\n");
  348. rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
  349. maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
  350. maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
  351. break;
  352. case MEDIA_10HALF:
  353. debug ("ax88180: 10Mbps Half-duplex mode.\n");
  354. rxcfg_val = DEFAULT_RXCFG;
  355. maccfg0_val = DEFAULT_MACCFG0;
  356. maccfg1_val = DEFAULT_MACCFG1;
  357. break;
  358. default:
  359. debug ("ax88180: Unknow media mode.\n");
  360. rxcfg_val = DEFAULT_RXCFG;
  361. maccfg0_val = DEFAULT_MACCFG0;
  362. maccfg1_val = DEFAULT_MACCFG1;
  363. priv->LinkState = INS_LINK_DOWN;
  364. break;
  365. }
  366. } else {
  367. rxcfg_val = DEFAULT_RXCFG;
  368. maccfg0_val = DEFAULT_MACCFG0;
  369. maccfg1_val = DEFAULT_MACCFG1;
  370. priv->LinkState = INS_LINK_DOWN;
  371. }
  372. OUTW (dev, rxcfg_val, RXCFG);
  373. OUTW (dev, maccfg0_val, MACCFG0);
  374. OUTW (dev, maccfg1_val, MACCFG1);
  375. return;
  376. }
  377. static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev)
  378. {
  379. unsigned long m88_ssr;
  380. unsigned long MediaMode;
  381. m88_ssr = ax88180_mdio_read (dev, M88_SSR);
  382. switch (m88_ssr & SSR_MEDIA_MASK) {
  383. case SSR_1000FULL:
  384. MediaMode = MEDIA_1000FULL;
  385. break;
  386. case SSR_1000HALF:
  387. MediaMode = MEDIA_1000HALF;
  388. break;
  389. case SSR_100FULL:
  390. MediaMode = MEDIA_100FULL;
  391. break;
  392. case SSR_100HALF:
  393. MediaMode = MEDIA_100HALF;
  394. break;
  395. case SSR_10FULL:
  396. MediaMode = MEDIA_10FULL;
  397. break;
  398. case SSR_10HALF:
  399. MediaMode = MEDIA_10HALF;
  400. break;
  401. default:
  402. MediaMode = MEDIA_UNKNOWN;
  403. break;
  404. }
  405. return MediaMode;
  406. }
  407. static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev)
  408. {
  409. unsigned long tmp_regval;
  410. unsigned long MediaMode;
  411. tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
  412. switch (tmp_regval & CIS_MEDIA_MASK) {
  413. case CIS_1000FULL:
  414. MediaMode = MEDIA_1000FULL;
  415. break;
  416. case CIS_1000HALF:
  417. MediaMode = MEDIA_1000HALF;
  418. break;
  419. case CIS_100FULL:
  420. MediaMode = MEDIA_100FULL;
  421. break;
  422. case CIS_100HALF:
  423. MediaMode = MEDIA_100HALF;
  424. break;
  425. case CIS_10FULL:
  426. MediaMode = MEDIA_10FULL;
  427. break;
  428. case CIS_10HALF:
  429. MediaMode = MEDIA_10HALF;
  430. break;
  431. default:
  432. MediaMode = MEDIA_UNKNOWN;
  433. break;
  434. }
  435. return MediaMode;
  436. }
  437. static void ax88180_halt (struct eth_device *dev)
  438. {
  439. /* Disable AX88180 TX/RX functions */
  440. OUTW (dev, WAKEMOD, CMD);
  441. }
  442. static int ax88180_init (struct eth_device *dev, bd_t * bd)
  443. {
  444. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  445. unsigned short tmp_regval;
  446. ax88180_mac_reset (dev);
  447. /* Disable interrupt */
  448. OUTW (dev, CLEAR_IMR, IMR);
  449. /* Disable AX88180 TX/RX functions */
  450. OUTW (dev, WAKEMOD, CMD);
  451. /* Fill the MAC address */
  452. tmp_regval =
  453. dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);
  454. OUTW (dev, tmp_regval, MACID0);
  455. tmp_regval =
  456. dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);
  457. OUTW (dev, tmp_regval, MACID1);
  458. tmp_regval =
  459. dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
  460. OUTW (dev, tmp_regval, MACID2);
  461. ax88180_media_config (dev);
  462. OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
  463. /* Initial variables here */
  464. priv->FirstTxDesc = TXDP0;
  465. priv->NextTxDesc = TXDP0;
  466. /* Check if there is any invalid interrupt status and clear it. */
  467. OUTW (dev, INW (dev, ISR), ISR);
  468. /* Start AX88180 TX/RX functions */
  469. OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);
  470. return 0;
  471. }
  472. /* Get a data block via Ethernet */
  473. static int ax88180_recv (struct eth_device *dev)
  474. {
  475. unsigned short ISR_Status;
  476. unsigned short tmp_regval;
  477. /* Read and check interrupt status here. */
  478. ISR_Status = INW (dev, ISR);
  479. while (ISR_Status) {
  480. /* Clear the interrupt status */
  481. OUTW (dev, ISR_Status, ISR);
  482. debug ("\nax88180: The interrupt status = 0x%04x\n",
  483. ISR_Status);
  484. if (ISR_Status & ISR_PHY) {
  485. /* Read ISR register once to clear PHY interrupt bit */
  486. tmp_regval = ax88180_mdio_read (dev, M88_ISR);
  487. ax88180_media_config (dev);
  488. }
  489. if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
  490. ax88180_rx_handler (dev);
  491. }
  492. /* Read and check interrupt status again */
  493. ISR_Status = INW (dev, ISR);
  494. }
  495. return 0;
  496. }
  497. /* Send a data block via Ethernet. */
  498. static int ax88180_send(struct eth_device *dev, void *packet, int length)
  499. {
  500. struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
  501. unsigned short TXDES_addr;
  502. unsigned short txcmd_txdp, txbs_txdp;
  503. unsigned short tmp_data;
  504. int i;
  505. #if defined (CONFIG_DRIVER_AX88180_16BIT)
  506. volatile unsigned short *txdata = (volatile unsigned short *)packet;
  507. #else
  508. volatile unsigned long *txdata = (volatile unsigned long *)packet;
  509. #endif
  510. unsigned short count;
  511. if (priv->LinkState != INS_LINK_UP) {
  512. return 0;
  513. }
  514. priv->FirstTxDesc = priv->NextTxDesc;
  515. txbs_txdp = 1 << priv->FirstTxDesc;
  516. debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);
  517. txcmd_txdp = priv->FirstTxDesc << 13;
  518. TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);
  519. OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);
  520. /* Comput access times */
  521. count = (length + priv->PadSize) >> priv->BusWidth;
  522. for (i = 0; i < count; i++) {
  523. WRITE_TXBUF (dev, *(txdata + i));
  524. }
  525. OUTW (dev, txcmd_txdp | length, TXCMD);
  526. OUTW (dev, txbs_txdp, TXBS);
  527. OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);
  528. priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;
  529. /*
  530. * Check the available transmit descriptor, if we had exhausted all
  531. * transmit descriptor ,then we have to wait for at least one free
  532. * descriptor
  533. */
  534. txbs_txdp = 1 << priv->NextTxDesc;
  535. tmp_data = INW (dev, TXBS);
  536. if (tmp_data & txbs_txdp) {
  537. if (ax88180_poll_tx_complete (dev) < 0) {
  538. ax88180_mac_reset (dev);
  539. priv->FirstTxDesc = TXDP0;
  540. priv->NextTxDesc = TXDP0;
  541. printf ("ax88180: Transmit time out occurred!\n");
  542. }
  543. }
  544. return 0;
  545. }
  546. static void ax88180_read_mac_addr (struct eth_device *dev)
  547. {
  548. unsigned short macid0_val, macid1_val, macid2_val;
  549. unsigned short tmp_regval;
  550. unsigned short i;
  551. /* Reload MAC address from EEPROM */
  552. OUTW (dev, RELOAD_EEPROM, PROMCTRL);
  553. /* Waiting for reload eeprom completion */
  554. for (i = 0; i < 500; i++) {
  555. tmp_regval = INW (dev, PROMCTRL);
  556. if ((tmp_regval & RELOAD_EEPROM) == 0)
  557. break;
  558. udelay (1000);
  559. }
  560. /* Get MAC addresses */
  561. macid0_val = INW (dev, MACID0);
  562. macid1_val = INW (dev, MACID1);
  563. macid2_val = INW (dev, MACID2);
  564. if (((macid0_val | macid1_val | macid2_val) != 0) &&
  565. ((macid0_val & 0x01) == 0)) {
  566. dev->enetaddr[0] = (unsigned char)macid0_val;
  567. dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);
  568. dev->enetaddr[2] = (unsigned char)macid1_val;
  569. dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);
  570. dev->enetaddr[4] = (unsigned char)macid2_val;
  571. dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);
  572. }
  573. }
  574. /*
  575. ===========================================================================
  576. <<<<<< Exported SubProgram Bodies >>>>>>
  577. ===========================================================================
  578. */
  579. int ax88180_initialize (bd_t * bis)
  580. {
  581. struct eth_device *dev;
  582. struct ax88180_private *priv;
  583. dev = (struct eth_device *)malloc (sizeof *dev);
  584. if (NULL == dev)
  585. return 0;
  586. memset (dev, 0, sizeof *dev);
  587. priv = (struct ax88180_private *)malloc (sizeof (*priv));
  588. if (NULL == priv)
  589. return 0;
  590. memset (priv, 0, sizeof *priv);
  591. strcpy(dev->name, "ax88180");
  592. dev->iobase = AX88180_BASE;
  593. dev->priv = priv;
  594. dev->init = ax88180_init;
  595. dev->halt = ax88180_halt;
  596. dev->send = ax88180_send;
  597. dev->recv = ax88180_recv;
  598. priv->BusWidth = BUS_WIDTH_32;
  599. priv->PadSize = 3;
  600. #if defined (CONFIG_DRIVER_AX88180_16BIT)
  601. OUTW (dev, (START_BASE >> 8), BASE);
  602. OUTW (dev, DECODE_EN, DECODE);
  603. priv->BusWidth = BUS_WIDTH_16;
  604. priv->PadSize = 1;
  605. #endif
  606. ax88180_mac_reset (dev);
  607. /* Disable interrupt */
  608. OUTW (dev, CLEAR_IMR, IMR);
  609. /* Disable AX88180 TX/RX functions */
  610. OUTW (dev, WAKEMOD, CMD);
  611. ax88180_read_mac_addr (dev);
  612. eth_register (dev);
  613. return ax88180_phy_initial (dev);
  614. }