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 } 728