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