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_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);
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;
259 /* Check avaliable PHY chipset */
260 priv->PhyAddr = MARVELL_88E1111_PHYADDR;
261 priv->PhyID0 = ax88180_mdio_read (dev, PHYIDR0);
263 if (priv->PhyID0 == MARVELL_88E1111_PHYIDR0) {
265 debug ("ax88180: Found Marvell 88E1111 PHY."
266 " (PHY Addr=0x%x)\n", priv->PhyAddr);
268 tmp_regval = ax88180_mdio_read (dev, M88_EXT_SSR);
269 if ((tmp_regval & HWCFG_MODE_MASK) == RGMII_COPPER_MODE) {
271 ax88180_mdio_write (dev, M88_EXT_SCR, DEFAULT_EXT_SCR);
272 if (ax88180_phy_reset (dev) < 0)
274 ax88180_mdio_write (dev, M88_IER, LINK_CHANGE_INT);
278 priv->PhyAddr = CICADA_CIS8201_PHYADDR;
279 priv->PhyID0 = ax88180_mdio_read (dev, PHYIDR0);
281 if (priv->PhyID0 == CICADA_CIS8201_PHYIDR0) {
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));
288 /* Set CIS_SMI_PRIORITY bit before force the media mode */
290 ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
291 tmp_regval &= ~CIS_SMI_PRIORITY;
292 ax88180_mdio_write (dev, CIS_AUX_CTRL_STATUS,
295 printf ("ax88180: Unknown PHY chipset!!\n");
303 static void ax88180_meidia_config (struct eth_device *dev)
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;
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) {
320 bmsr_val = ax88180_mdio_read (dev, BMSR);
321 debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
323 if (bmsr_val & LINKOK) {
324 bmcr_val = ax88180_mdio_read (dev, BMCR);
326 if (bmcr_val & AUTONEG_EN) {
329 * Waiting for Auto-negotiation completion, this may
330 * take up to 5 seconds.
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) {
342 debug ("ax88180: Auto-negotiation is disabled.\n");
344 debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
345 (unsigned int)bmcr_val, (unsigned int)bmsr_val);
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);
353 RealMediaMode = MEDIA_1000FULL;
356 priv->LinkState = INS_LINK_UP;
358 switch (RealMediaMode) {
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;
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;
375 debug ("ax88180: 100Mbps Full-duplex mode.\n");
376 rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
377 maccfg0_val = SPEED100 | TXFLOW_ENABLE
379 maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
383 debug ("ax88180: 100Mbps Half-duplex mode.\n");
384 rxcfg_val = DEFAULT_RXCFG;
385 maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
386 maccfg1_val = DEFAULT_MACCFG1;
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;
397 debug ("ax88180: 10Mbps Half-duplex mode.\n");
398 rxcfg_val = DEFAULT_RXCFG;
399 maccfg0_val = DEFAULT_MACCFG0;
400 maccfg1_val = DEFAULT_MACCFG1;
403 debug ("ax88180: Unknow media mode.\n");
404 rxcfg_val = DEFAULT_RXCFG;
405 maccfg0_val = DEFAULT_MACCFG0;
406 maccfg1_val = DEFAULT_MACCFG1;
408 priv->LinkState = INS_LINK_DOWN;
413 rxcfg_val = DEFAULT_RXCFG;
414 maccfg0_val = DEFAULT_MACCFG0;
415 maccfg1_val = DEFAULT_MACCFG1;
417 priv->LinkState = INS_LINK_DOWN;
420 OUTW (dev, rxcfg_val, RXCFG);
421 OUTW (dev, maccfg0_val, MACCFG0);
422 OUTW (dev, maccfg1_val, MACCFG1);
427 static unsigned long get_MarvellPHY_meida_mode (struct eth_device *dev)
429 unsigned long m88_ssr;
430 unsigned long MediaMode;
432 m88_ssr = ax88180_mdio_read (dev, M88_SSR);
433 switch (m88_ssr & SSR_MEDIA_MASK) {
435 MediaMode = MEDIA_1000FULL;
438 MediaMode = MEDIA_1000HALF;
441 MediaMode = MEDIA_100FULL;
444 MediaMode = MEDIA_100HALF;
447 MediaMode = MEDIA_10FULL;
450 MediaMode = MEDIA_10HALF;
453 MediaMode = MEDIA_UNKNOWN;
460 static unsigned long get_CicadaPHY_meida_mode (struct eth_device *dev)
462 unsigned long tmp_regval;
463 unsigned long MediaMode;
465 tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
466 switch (tmp_regval & CIS_MEDIA_MASK) {
468 MediaMode = MEDIA_1000FULL;
471 MediaMode = MEDIA_1000HALF;
474 MediaMode = MEDIA_100FULL;
477 MediaMode = MEDIA_100HALF;
480 MediaMode = MEDIA_10FULL;
483 MediaMode = MEDIA_10HALF;
486 MediaMode = MEDIA_UNKNOWN;
493 static void ax88180_halt (struct eth_device *dev)
495 /* Disable AX88180 TX/RX functions */
496 OUTW (dev, WAKEMOD, CMD);
499 static int ax88180_init (struct eth_device *dev, bd_t * bd)
501 struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
502 unsigned short tmp_regval;
504 ax88180_mac_reset (dev);
506 /* Disable interrupt */
507 OUTW (dev, CLEAR_IMR, IMR);
509 /* Disable AX88180 TX/RX functions */
510 OUTW (dev, WAKEMOD, CMD);
512 /* Fill the MAC address */
514 dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);
515 OUTW (dev, tmp_regval, MACID0);
518 dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);
519 OUTW (dev, tmp_regval, MACID1);
522 dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
523 OUTW (dev, tmp_regval, MACID2);
525 ax88180_meidia_config (dev);
527 OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
529 /* Initial variables here */
530 priv->FirstTxDesc = TXDP0;
531 priv->NextTxDesc = TXDP0;
533 /* Check if there is any invalid interrupt status and clear it. */
534 OUTW (dev, INW (dev, ISR), ISR);
536 /* Start AX88180 TX/RX functions */
537 OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);
542 /* Get a data block via Ethernet */
543 static int ax88180_recv (struct eth_device *dev)
545 unsigned short ISR_Status;
546 unsigned short tmp_regval;
548 /* Read and check interrupt status here. */
549 ISR_Status = INW (dev, ISR);
552 /* Clear the interrupt status */
553 OUTW (dev, ISR_Status, ISR);
555 debug ("\nax88180: The interrupt status = 0x%04x\n",
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);
564 if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
565 ax88180_rx_handler (dev);
568 /* Read and check interrupt status again */
569 ISR_Status = INW (dev, ISR);
575 /* Send a data block via Ethernet. */
577 ax88180_send (struct eth_device *dev, volatile void *packet, int length)
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;
584 #if defined (CONFIG_DRIVER_AX88180_16BIT)
585 volatile unsigned short *txdata = (volatile unsigned short *)packet;
587 volatile unsigned long *txdata = (volatile unsigned long *)packet;
589 unsigned short count;
591 if (priv->LinkState != INS_LINK_UP) {
595 priv->FirstTxDesc = priv->NextTxDesc;
596 txbs_txdp = 1 << priv->FirstTxDesc;
598 debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);
600 txcmd_txdp = priv->FirstTxDesc << 13;
601 TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);
603 OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);
605 /* Comput access times */
606 count = (length + priv->PadSize) >> priv->BusWidth;
608 for (i = 0; i < count; i++) {
609 WRITE_TXBUF (dev, *(txdata + i));
612 OUTW (dev, txcmd_txdp | length, TXCMD);
613 OUTW (dev, txbs_txdp, TXBS);
614 OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);
616 priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;
619 * Check the available transmit descriptor, if we had exhausted all
620 * transmit descriptor ,then we have to wait for at least one free
623 txbs_txdp = 1 << priv->NextTxDesc;
624 tmp_data = INW (dev, TXBS);
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");
638 static void ax88180_read_mac_addr (struct eth_device *dev)
640 unsigned short macid0_val, macid1_val, macid2_val;
641 unsigned short tmp_regval;
644 /* Reload MAC address from EEPROM */
645 OUTW (dev, RELOAD_EEPROM, PROMCTRL);
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)
655 /* Get MAC addresses */
656 macid0_val = INW (dev, MACID0);
657 macid1_val = INW (dev, MACID1);
658 macid2_val = INW (dev, MACID2);
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);
672 ===========================================================================
673 <<<<<< Exported SubProgram Bodies >>>>>>
674 ===========================================================================
676 int ax88180_initialize (bd_t * bis)
678 struct eth_device *dev;
679 struct ax88180_private *priv;
681 dev = (struct eth_device *)malloc (sizeof *dev);
686 memset (dev, 0, sizeof *dev);
688 priv = (struct ax88180_private *)malloc (sizeof (*priv));
693 memset (priv, 0, sizeof *priv);
695 sprintf (dev->name, "ax88180");
696 dev->iobase = AX88180_BASE;
698 dev->init = ax88180_init;
699 dev->halt = ax88180_halt;
700 dev->send = ax88180_send;
701 dev->recv = ax88180_recv;
703 priv->BusWidth = BUS_WIDTH_32;
705 #if defined (CONFIG_DRIVER_AX88180_16BIT)
706 OUTW (dev, (START_BASE >> 8), BASE);
707 OUTW (dev, DECODE_EN, DECODE);
709 priv->BusWidth = BUS_WIDTH_16;
713 ax88180_mac_reset (dev);
715 /* Disable interrupt */
716 OUTW (dev, CLEAR_IMR, IMR);
718 /* Disable AX88180 TX/RX functions */
719 OUTW (dev, WAKEMOD, CMD);
721 ax88180_read_mac_addr (dev);
725 return ax88180_phy_initial (dev);