2 * ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver
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,
18 * ========================================================================
19 * ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver
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
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.
29 * Please visit ASIX's web site (http://www.asix.com.tw) for more
32 * Module Name : ax88180.c
35 * 09/06/2006 : New release for AX88180 US2 chip.
36 * 07/07/2008 : Fix up the coding style and using inline functions
38 * ========================================================================
47 * ===========================================================================
48 * Local SubProgram Declaration
49 * ===========================================================================
51 static void ax88180_rx_handler (struct eth_device *dev);
52 static int ax88180_phy_initial (struct eth_device *dev);
53 static void ax88180_media_config (struct eth_device *dev);
54 static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev);
55 static unsigned long get_MarvellPHY_media_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);
62 * ===========================================================================
63 * Local SubProgram Bodies
64 * ===========================================================================
66 static int ax88180_mdio_check_complete (struct eth_device *dev)
69 unsigned short tmpval;
71 /* MDIO read/write should not take more than 10 ms */
73 tmpval = INW (dev, MDIOCTRL);
74 if (((tmpval & READ_PHY) == 0) && ((tmpval & WRITE_PHY) == 0))
82 ax88180_mdio_read (struct eth_device *dev, unsigned long regaddr)
84 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
85 unsigned long tmpval = 0;
87 OUTW (dev, (READ_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
89 if (ax88180_mdio_check_complete (dev))
90 tmpval = INW (dev, MDIODP);
92 printf ("Failed to read PHY register!\n");
94 return (unsigned short)(tmpval & 0xFFFF);
98 ax88180_mdio_write (struct eth_device *dev, unsigned long regaddr,
99 unsigned short regdata)
101 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
103 OUTW (dev, regdata, MDIODP);
105 OUTW (dev, (WRITE_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
107 if (!ax88180_mdio_check_complete (dev))
108 printf ("Failed to write PHY register!\n");
111 static int ax88180_phy_reset (struct eth_device *dev)
113 unsigned short delay_cnt = 500;
115 ax88180_mdio_write (dev, BMCR, (PHY_RESET | AUTONEG_EN));
117 /* Wait for the reset to complete, or time out (500 ms) */
118 while (ax88180_mdio_read (dev, BMCR) & PHY_RESET) {
120 if (--delay_cnt == 0) {
121 printf ("Failed to reset PHY!\n");
129 static void ax88180_mac_reset (struct eth_device *dev)
131 unsigned long tmpval;
135 unsigned short offset, value;
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},};
156 OUTW (dev, MISC_RESET_MAC, MISC);
157 tmpval = INW (dev, MISC);
159 for (i = 0; i < (sizeof (program_seq) / sizeof (program_seq[0])); i++)
160 OUTW (dev, program_seq[i].value, program_seq[i].offset);
163 static int ax88180_poll_tx_complete (struct eth_device *dev)
165 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
166 unsigned long tmpval, txbs_txdp;
167 int TimeOutCnt = 10000;
169 txbs_txdp = 1 << priv->NextTxDesc;
171 while (TimeOutCnt--) {
173 tmpval = INW (dev, TXBS);
175 if ((tmpval & txbs_txdp) == 0)
187 static void ax88180_rx_handler (struct eth_device *dev)
189 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
190 unsigned long data_size;
191 unsigned short rxcurt_ptr, rxbound_ptr, next_ptr;
193 #if defined (CONFIG_DRIVER_AX88180_16BIT)
194 unsigned short *rxdata = (unsigned short *)NetRxPackets[0];
196 unsigned long *rxdata = (unsigned long *)NetRxPackets[0];
198 unsigned short count;
200 rxcurt_ptr = INW (dev, RXCURT);
201 rxbound_ptr = INW (dev, RXBOUND);
202 next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
204 debug ("ax88180: RX original RXBOUND=0x%04x,"
205 " RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
207 while (next_ptr != rxcurt_ptr) {
209 OUTW (dev, RX_START_READ, RXINDICATOR);
211 data_size = READ_RXBUF (dev) & 0xFFFF;
213 if ((data_size == 0) || (data_size > MAX_RX_SIZE)) {
215 OUTW (dev, RX_STOP_READ, RXINDICATOR);
217 ax88180_mac_reset (dev);
218 printf ("ax88180: Invalid Rx packet length!"
219 " (len=0x%04lx)\n", data_size);
221 debug ("ax88180: RX RXBOUND=0x%04x,"
222 "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
226 rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1;
227 rxbound_ptr &= RX_PAGE_NUM_MASK;
229 /* Comput access times */
230 count = (data_size + priv->PadSize) >> priv->BusWidth;
232 for (i = 0; i < count; i++) {
233 *(rxdata + i) = READ_RXBUF (dev);
236 OUTW (dev, RX_STOP_READ, RXINDICATOR);
238 /* Pass the packet up to the protocol layers. */
239 NetReceive (NetRxPackets[0], data_size);
241 OUTW (dev, rxbound_ptr, RXBOUND);
243 rxcurt_ptr = INW (dev, RXCURT);
244 rxbound_ptr = INW (dev, RXBOUND);
245 next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
247 debug ("ax88180: RX updated RXBOUND=0x%04x,"
248 "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
254 static int ax88180_phy_initial (struct eth_device *dev)
256 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
257 unsigned long tmp_regval;
258 unsigned short phyaddr;
260 /* Search for first avaliable PHY chipset */
261 #ifdef CONFIG_PHY_ADDR
262 phyaddr = CONFIG_PHY_ADDR;
264 for (phyaddr = 0; phyaddr < 32; ++phyaddr)
267 priv->PhyAddr = phyaddr;
268 priv->PhyID0 = ax88180_mdio_read(dev, PHYIDR0);
270 switch (priv->PhyID0) {
271 case MARVELL_88E1111_PHYIDR0:
272 debug("ax88180: Found Marvell 88E1111 PHY."
273 " (PHY Addr=0x%x)\n", priv->PhyAddr);
275 tmp_regval = ax88180_mdio_read(dev, M88_EXT_SSR);
276 if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE) {
277 ax88180_mdio_write(dev, M88_EXT_SCR, DEFAULT_EXT_SCR);
278 if (ax88180_phy_reset(dev) < 0)
280 ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT);
285 case CICADA_CIS8201_PHYIDR0:
286 debug("ax88180: Found CICADA CIS8201 PHY"
287 " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
289 ax88180_mdio_write(dev, CIS_IMR,
290 (CIS_INT_ENABLE | LINK_CHANGE_INT));
292 /* Set CIS_SMI_PRIORITY bit before force the media mode */
293 tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS);
294 tmp_regval &= ~CIS_SMI_PRIORITY;
295 ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval);
300 /* No PHY at this addr */
304 printf("ax88180: Unknown PHY chipset %#x at addr %#x\n",
305 priv->PhyID0, priv->PhyAddr);
310 printf("ax88180: Unknown PHY chipset!!\n");
314 static void ax88180_media_config (struct eth_device *dev)
316 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
317 unsigned long bmcr_val, bmsr_val;
318 unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
319 unsigned long RealMediaMode;
322 /* Waiting 2 seconds for PHY link stable */
323 for (i = 0; i < 20000; i++) {
324 bmsr_val = ax88180_mdio_read (dev, BMSR);
325 if (bmsr_val & LINKOK) {
331 bmsr_val = ax88180_mdio_read (dev, BMSR);
332 debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
334 if (bmsr_val & LINKOK) {
335 bmcr_val = ax88180_mdio_read (dev, BMCR);
337 if (bmcr_val & AUTONEG_EN) {
340 * Waiting for Auto-negotiation completion, this may
341 * take up to 5 seconds.
343 debug ("ax88180: Auto-negotiation is "
344 "enabled. Waiting for NWay completion..\n");
345 for (i = 0; i < 50000; i++) {
346 bmsr_val = ax88180_mdio_read (dev, BMSR);
347 if (bmsr_val & AUTONEG_COMPLETE) {
353 debug ("ax88180: Auto-negotiation is disabled.\n");
355 debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
356 (unsigned int)bmcr_val, (unsigned int)bmsr_val);
358 /* Get real media mode here */
359 switch (priv->PhyID0) {
360 case MARVELL_88E1111_PHYIDR0:
361 RealMediaMode = get_MarvellPHY_media_mode(dev);
363 case CICADA_CIS8201_PHYIDR0:
364 RealMediaMode = get_CicadaPHY_media_mode(dev);
367 RealMediaMode = MEDIA_1000FULL;
371 priv->LinkState = INS_LINK_UP;
373 switch (RealMediaMode) {
375 debug ("ax88180: 1000Mbps Full-duplex mode.\n");
376 rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
377 maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
378 maccfg1_val = GIGA_MODE_EN | RXFLOW_EN |
379 FULLDUPLEX | DEFAULT_MACCFG1;
383 debug ("ax88180: 1000Mbps Half-duplex mode.\n");
384 rxcfg_val = DEFAULT_RXCFG;
385 maccfg0_val = DEFAULT_MACCFG0;
386 maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
390 debug ("ax88180: 100Mbps Full-duplex mode.\n");
391 rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
392 maccfg0_val = SPEED100 | TXFLOW_ENABLE
394 maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
398 debug ("ax88180: 100Mbps Half-duplex mode.\n");
399 rxcfg_val = DEFAULT_RXCFG;
400 maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
401 maccfg1_val = DEFAULT_MACCFG1;
405 debug ("ax88180: 10Mbps Full-duplex mode.\n");
406 rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
407 maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
408 maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
412 debug ("ax88180: 10Mbps Half-duplex mode.\n");
413 rxcfg_val = DEFAULT_RXCFG;
414 maccfg0_val = DEFAULT_MACCFG0;
415 maccfg1_val = DEFAULT_MACCFG1;
418 debug ("ax88180: Unknow media mode.\n");
419 rxcfg_val = DEFAULT_RXCFG;
420 maccfg0_val = DEFAULT_MACCFG0;
421 maccfg1_val = DEFAULT_MACCFG1;
423 priv->LinkState = INS_LINK_DOWN;
428 rxcfg_val = DEFAULT_RXCFG;
429 maccfg0_val = DEFAULT_MACCFG0;
430 maccfg1_val = DEFAULT_MACCFG1;
432 priv->LinkState = INS_LINK_DOWN;
435 OUTW (dev, rxcfg_val, RXCFG);
436 OUTW (dev, maccfg0_val, MACCFG0);
437 OUTW (dev, maccfg1_val, MACCFG1);
442 static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev)
444 unsigned long m88_ssr;
445 unsigned long MediaMode;
447 m88_ssr = ax88180_mdio_read (dev, M88_SSR);
448 switch (m88_ssr & SSR_MEDIA_MASK) {
450 MediaMode = MEDIA_1000FULL;
453 MediaMode = MEDIA_1000HALF;
456 MediaMode = MEDIA_100FULL;
459 MediaMode = MEDIA_100HALF;
462 MediaMode = MEDIA_10FULL;
465 MediaMode = MEDIA_10HALF;
468 MediaMode = MEDIA_UNKNOWN;
475 static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev)
477 unsigned long tmp_regval;
478 unsigned long MediaMode;
480 tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
481 switch (tmp_regval & CIS_MEDIA_MASK) {
483 MediaMode = MEDIA_1000FULL;
486 MediaMode = MEDIA_1000HALF;
489 MediaMode = MEDIA_100FULL;
492 MediaMode = MEDIA_100HALF;
495 MediaMode = MEDIA_10FULL;
498 MediaMode = MEDIA_10HALF;
501 MediaMode = MEDIA_UNKNOWN;
508 static void ax88180_halt (struct eth_device *dev)
510 /* Disable AX88180 TX/RX functions */
511 OUTW (dev, WAKEMOD, CMD);
514 static int ax88180_init (struct eth_device *dev, bd_t * bd)
516 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
517 unsigned short tmp_regval;
519 ax88180_mac_reset (dev);
521 /* Disable interrupt */
522 OUTW (dev, CLEAR_IMR, IMR);
524 /* Disable AX88180 TX/RX functions */
525 OUTW (dev, WAKEMOD, CMD);
527 /* Fill the MAC address */
529 dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);
530 OUTW (dev, tmp_regval, MACID0);
533 dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);
534 OUTW (dev, tmp_regval, MACID1);
537 dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
538 OUTW (dev, tmp_regval, MACID2);
540 ax88180_media_config (dev);
542 OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
544 /* Initial variables here */
545 priv->FirstTxDesc = TXDP0;
546 priv->NextTxDesc = TXDP0;
548 /* Check if there is any invalid interrupt status and clear it. */
549 OUTW (dev, INW (dev, ISR), ISR);
551 /* Start AX88180 TX/RX functions */
552 OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);
557 /* Get a data block via Ethernet */
558 static int ax88180_recv (struct eth_device *dev)
560 unsigned short ISR_Status;
561 unsigned short tmp_regval;
563 /* Read and check interrupt status here. */
564 ISR_Status = INW (dev, ISR);
567 /* Clear the interrupt status */
568 OUTW (dev, ISR_Status, ISR);
570 debug ("\nax88180: The interrupt status = 0x%04x\n",
573 if (ISR_Status & ISR_PHY) {
574 /* Read ISR register once to clear PHY interrupt bit */
575 tmp_regval = ax88180_mdio_read (dev, M88_ISR);
576 ax88180_media_config (dev);
579 if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
580 ax88180_rx_handler (dev);
583 /* Read and check interrupt status again */
584 ISR_Status = INW (dev, ISR);
590 /* Send a data block via Ethernet. */
592 ax88180_send (struct eth_device *dev, volatile void *packet, int length)
594 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
595 unsigned short TXDES_addr;
596 unsigned short txcmd_txdp, txbs_txdp;
597 unsigned short tmp_data;
599 #if defined (CONFIG_DRIVER_AX88180_16BIT)
600 volatile unsigned short *txdata = (volatile unsigned short *)packet;
602 volatile unsigned long *txdata = (volatile unsigned long *)packet;
604 unsigned short count;
606 if (priv->LinkState != INS_LINK_UP) {
610 priv->FirstTxDesc = priv->NextTxDesc;
611 txbs_txdp = 1 << priv->FirstTxDesc;
613 debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);
615 txcmd_txdp = priv->FirstTxDesc << 13;
616 TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);
618 OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);
620 /* Comput access times */
621 count = (length + priv->PadSize) >> priv->BusWidth;
623 for (i = 0; i < count; i++) {
624 WRITE_TXBUF (dev, *(txdata + i));
627 OUTW (dev, txcmd_txdp | length, TXCMD);
628 OUTW (dev, txbs_txdp, TXBS);
629 OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);
631 priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;
634 * Check the available transmit descriptor, if we had exhausted all
635 * transmit descriptor ,then we have to wait for at least one free
638 txbs_txdp = 1 << priv->NextTxDesc;
639 tmp_data = INW (dev, TXBS);
641 if (tmp_data & txbs_txdp) {
642 if (ax88180_poll_tx_complete (dev) < 0) {
643 ax88180_mac_reset (dev);
644 priv->FirstTxDesc = TXDP0;
645 priv->NextTxDesc = TXDP0;
646 printf ("ax88180: Transmit time out occurred!\n");
653 static void ax88180_read_mac_addr (struct eth_device *dev)
655 unsigned short macid0_val, macid1_val, macid2_val;
656 unsigned short tmp_regval;
659 /* Reload MAC address from EEPROM */
660 OUTW (dev, RELOAD_EEPROM, PROMCTRL);
662 /* Waiting for reload eeprom completion */
663 for (i = 0; i < 500; i++) {
664 tmp_regval = INW (dev, PROMCTRL);
665 if ((tmp_regval & RELOAD_EEPROM) == 0)
670 /* Get MAC addresses */
671 macid0_val = INW (dev, MACID0);
672 macid1_val = INW (dev, MACID1);
673 macid2_val = INW (dev, MACID2);
675 if (((macid0_val | macid1_val | macid2_val) != 0) &&
676 ((macid0_val & 0x01) == 0)) {
677 dev->enetaddr[0] = (unsigned char)macid0_val;
678 dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);
679 dev->enetaddr[2] = (unsigned char)macid1_val;
680 dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);
681 dev->enetaddr[4] = (unsigned char)macid2_val;
682 dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);
687 ===========================================================================
688 <<<<<< Exported SubProgram Bodies >>>>>>
689 ===========================================================================
691 int ax88180_initialize (bd_t * bis)
693 struct eth_device *dev;
694 struct ax88180_private *priv;
696 dev = (struct eth_device *)malloc (sizeof *dev);
701 memset (dev, 0, sizeof *dev);
703 priv = (struct ax88180_private *)malloc (sizeof (*priv));
708 memset (priv, 0, sizeof *priv);
710 sprintf (dev->name, "ax88180");
711 dev->iobase = AX88180_BASE;
713 dev->init = ax88180_init;
714 dev->halt = ax88180_halt;
715 dev->send = ax88180_send;
716 dev->recv = ax88180_recv;
718 priv->BusWidth = BUS_WIDTH_32;
720 #if defined (CONFIG_DRIVER_AX88180_16BIT)
721 OUTW (dev, (START_BASE >> 8), BASE);
722 OUTW (dev, DECODE_EN, DECODE);
724 priv->BusWidth = BUS_WIDTH_16;
728 ax88180_mac_reset (dev);
730 /* Disable interrupt */
731 OUTW (dev, CLEAR_IMR, IMR);
733 /* Disable AX88180 TX/RX functions */
734 OUTW (dev, WAKEMOD, CMD);
736 ax88180_read_mac_addr (dev);
740 return ax88180_phy_initial (dev);