1 /* 2 Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> 3 4 Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and 5 eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world 6 are GPL, so this is, of course, GPL. 7 8 ========================================================================== 9 10 dev/if_dp83902a.c 11 12 Ethernet device driver for NS DP83902a ethernet controller 13 14 ========================================================================== 15 ####ECOSGPLCOPYRIGHTBEGIN#### 16 ------------------------------------------- 17 This file is part of eCos, the Embedded Configurable Operating System. 18 Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 19 20 eCos is free software; you can redistribute it and/or modify it under 21 the terms of the GNU General Public License as published by the Free 22 Software Foundation; either version 2 or (at your option) any later version. 23 24 eCos is distributed in the hope that it will be useful, but WITHOUT ANY 25 WARRANTY; without even the implied warranty of MERCHANTABILITY or 26 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27 for more details. 28 29 You should have received a copy of the GNU General Public License along 30 with eCos; if not, write to the Free Software Foundation, Inc., 31 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 32 33 As a special exception, if other files instantiate templates or use macros 34 or inline functions from this file, or you compile this file and link it 35 with other works to produce a work based on this file, this file does not 36 by itself cause the resulting work to be covered by the GNU General Public 37 License. However the source code for this file must still be made available 38 in accordance with section (3) of the GNU General Public License. 39 40 This exception does not invalidate any other reasons why a work based on 41 this file might be covered by the GNU General Public License. 42 43 Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. 44 at http://sources.redhat.com/ecos/ecos-license/ 45 ------------------------------------------- 46 ####ECOSGPLCOPYRIGHTEND#### 47 ####BSDCOPYRIGHTBEGIN#### 48 49 ------------------------------------------- 50 51 Portions of this software may have been derived from OpenBSD or other sources, 52 and are covered by the appropriate copyright disclaimers included herein. 53 54 ------------------------------------------- 55 56 ####BSDCOPYRIGHTEND#### 57 ========================================================================== 58 #####DESCRIPTIONBEGIN#### 59 60 Author(s): gthomas 61 Contributors: gthomas, jskov, rsandifo 62 Date: 2001-06-13 63 Purpose: 64 Description: 65 66 FIXME: Will fail if pinged with large packets (1520 bytes) 67 Add promisc config 68 Add SNMP 69 70 ####DESCRIPTIONEND#### 71 72 ========================================================================== 73 */ 74 75 #include <common.h> 76 #include <command.h> 77 #include <net.h> 78 #include <malloc.h> 79 80 #define mdelay(n) udelay((n)*1000) 81 /* forward definition of function used for the uboot interface */ 82 void uboot_push_packet_len(int len); 83 void uboot_push_tx_done(int key, int val); 84 85 /* 86 * Debugging details 87 * 88 * Set to perms of: 89 * 0 disables all debug output 90 * 1 for process debug output 91 * 2 for added data IO output: get_reg, put_reg 92 * 4 for packet allocation/free output 93 * 8 for only startup status, so we can tell we're installed OK 94 */ 95 #if 0 96 #define DEBUG 0xf 97 #else 98 #define DEBUG 0 99 #endif 100 101 #if DEBUG & 1 102 #define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0) 103 #define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0) 104 #define PRINTK(args...) printf(args) 105 #else 106 #define DEBUG_FUNCTION() do {} while(0) 107 #define DEBUG_LINE() do {} while(0) 108 #define PRINTK(args...) 109 #endif 110 111 /* NE2000 base header file */ 112 #include "ne2000_base.h" 113 114 #if defined(CONFIG_DRIVER_AX88796L) 115 /* AX88796L support */ 116 #include "ax88796.h" 117 #else 118 /* Basic NE2000 chip support */ 119 #include "ne2000.h" 120 #endif 121 122 static dp83902a_priv_data_t nic; /* just one instance of the card supported */ 123 124 static bool 125 dp83902a_init(void) 126 { 127 dp83902a_priv_data_t *dp = &nic; 128 u8* base; 129 #if defined(NE2000_BASIC_INIT) 130 int i; 131 #endif 132 133 DEBUG_FUNCTION(); 134 135 base = dp->base; 136 if (!base) 137 return false; /* No device found */ 138 139 DEBUG_LINE(); 140 141 #if defined(NE2000_BASIC_INIT) 142 /* AX88796L doesn't need */ 143 /* Prepare ESA */ 144 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */ 145 /* Use the address from the serial EEPROM */ 146 for (i = 0; i < 6; i++) 147 DP_IN(base, DP_P1_PAR0+i, dp->esa[i]); 148 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */ 149 150 printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", 151 "eeprom", 152 dp->esa[0], 153 dp->esa[1], 154 dp->esa[2], 155 dp->esa[3], 156 dp->esa[4], 157 dp->esa[5] ); 158 159 #endif /* NE2000_BASIC_INIT */ 160 return true; 161 } 162 163 static void 164 dp83902a_stop(void) 165 { 166 dp83902a_priv_data_t *dp = &nic; 167 u8 *base = dp->base; 168 169 DEBUG_FUNCTION(); 170 171 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ 172 DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ 173 DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */ 174 175 dp->running = false; 176 } 177 178 /* 179 * This function is called to "start up" the interface. It may be called 180 * multiple times, even when the hardware is already running. It will be 181 * called whenever something "hardware oriented" changes and should leave 182 * the hardware ready to send/receive packets. 183 */ 184 static void 185 dp83902a_start(u8 * enaddr) 186 { 187 dp83902a_priv_data_t *dp = &nic; 188 u8 *base = dp->base; 189 int i; 190 191 DEBUG_FUNCTION(); 192 193 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ 194 DP_OUT(base, DP_DCR, DP_DCR_INIT); 195 DP_OUT(base, DP_RBCH, 0); /* Remote byte count */ 196 DP_OUT(base, DP_RBCL, 0); 197 DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */ 198 DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */ 199 DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */ 200 dp->tx1 = dp->tx2 = 0; 201 dp->tx_next = dp->tx_buf1; 202 dp->tx_started = false; 203 dp->running = true; 204 DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ 205 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */ 206 DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */ 207 dp->rx_next = dp->rx_buf_start - 1; 208 dp->running = true; 209 DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ 210 DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */ 211 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */ 212 DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */ 213 dp->running = true; 214 for (i = 0; i < ETHER_ADDR_LEN; i++) { 215 /* FIXME */ 216 /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) + 217 * 0x1400)) = enaddr[i];*/ 218 DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); 219 } 220 /* Enable and start device */ 221 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 222 DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */ 223 DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */ 224 dp->running = true; 225 } 226 227 /* 228 * This routine is called to start the transmitter. It is split out from the 229 * data handling routine so it may be called either when data becomes first 230 * available or when an Tx interrupt occurs 231 */ 232 233 static void 234 dp83902a_start_xmit(int start_page, int len) 235 { 236 dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; 237 u8 *base = dp->base; 238 239 DEBUG_FUNCTION(); 240 241 #if DEBUG & 1 242 printf("Tx pkt %d len %d\n", start_page, len); 243 if (dp->tx_started) 244 printf("TX already started?!?\n"); 245 #endif 246 247 DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE)); 248 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 249 DP_OUT(base, DP_TBCL, len & 0xFF); 250 DP_OUT(base, DP_TBCH, len >> 8); 251 DP_OUT(base, DP_TPSR, start_page); 252 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); 253 254 dp->tx_started = true; 255 } 256 257 /* 258 * This routine is called to send data to the hardware. It is known a-priori 259 * that there is free buffer space (dp->tx_next). 260 */ 261 static void 262 dp83902a_send(u8 *data, int total_len, u32 key) 263 { 264 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 265 u8 *base = dp->base; 266 int len, start_page, pkt_len, i, isr; 267 #if DEBUG & 4 268 int dx; 269 #endif 270 271 DEBUG_FUNCTION(); 272 273 len = pkt_len = total_len; 274 if (pkt_len < IEEE_8023_MIN_FRAME) 275 pkt_len = IEEE_8023_MIN_FRAME; 276 277 start_page = dp->tx_next; 278 if (dp->tx_next == dp->tx_buf1) { 279 dp->tx1 = start_page; 280 dp->tx1_len = pkt_len; 281 dp->tx1_key = key; 282 dp->tx_next = dp->tx_buf2; 283 } else { 284 dp->tx2 = start_page; 285 dp->tx2_len = pkt_len; 286 dp->tx2_key = key; 287 dp->tx_next = dp->tx_buf1; 288 } 289 290 #if DEBUG & 5 291 printf("TX prep page %d len %d\n", start_page, pkt_len); 292 #endif 293 294 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 295 { 296 /* 297 * Dummy read. The manual sez something slightly different, 298 * but the code is extended a bit to do what Hitachi's monitor 299 * does (i.e., also read data). 300 */ 301 302 u16 tmp; 303 int len = 1; 304 305 DP_OUT(base, DP_RSAL, 0x100 - len); 306 DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff); 307 DP_OUT(base, DP_RBCL, len); 308 DP_OUT(base, DP_RBCH, 0); 309 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); 310 DP_IN_DATA(dp->data, tmp); 311 } 312 313 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 314 /* 315 * Stall for a bit before continuing to work around random data 316 * corruption problems on some platforms. 317 */ 318 CYGACC_CALL_IF_DELAY_US(1); 319 #endif 320 321 /* Send data to device buffer(s) */ 322 DP_OUT(base, DP_RSAL, 0); 323 DP_OUT(base, DP_RSAH, start_page); 324 DP_OUT(base, DP_RBCL, pkt_len & 0xFF); 325 DP_OUT(base, DP_RBCH, pkt_len >> 8); 326 DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); 327 328 /* Put data into buffer */ 329 #if DEBUG & 4 330 printf(" sg buf %08lx len %08x\n ", (u32)data, len); 331 dx = 0; 332 #endif 333 while (len > 0) { 334 #if DEBUG & 4 335 printf(" %02x", *data); 336 if (0 == (++dx % 16)) printf("\n "); 337 #endif 338 339 DP_OUT_DATA(dp->data, *data++); 340 len--; 341 } 342 #if DEBUG & 4 343 printf("\n"); 344 #endif 345 if (total_len < pkt_len) { 346 #if DEBUG & 4 347 printf(" + %d bytes of padding\n", pkt_len - total_len); 348 #endif 349 /* Padding to 802.3 length was required */ 350 for (i = total_len; i < pkt_len;) { 351 i++; 352 DP_OUT_DATA(dp->data, 0); 353 } 354 } 355 356 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 357 /* 358 * After last data write, delay for a bit before accessing the 359 * device again, or we may get random data corruption in the last 360 * datum (on some platforms). 361 */ 362 CYGACC_CALL_IF_DELAY_US(1); 363 #endif 364 365 /* Wait for DMA to complete */ 366 do { 367 DP_IN(base, DP_ISR, isr); 368 } while ((isr & DP_ISR_RDC) == 0); 369 370 /* Then disable DMA */ 371 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 372 373 /* Start transmit if not already going */ 374 if (!dp->tx_started) { 375 if (start_page == dp->tx1) { 376 dp->tx_int = 1; /* Expecting interrupt from BUF1 */ 377 } else { 378 dp->tx_int = 2; /* Expecting interrupt from BUF2 */ 379 } 380 dp83902a_start_xmit(start_page, pkt_len); 381 } 382 } 383 384 /* 385 * This function is called when a packet has been received. It's job is 386 * to prepare to unload the packet from the hardware. Once the length of 387 * the packet is known, the upper layer of the driver can be told. When 388 * the upper layer is ready to unload the packet, the internal function 389 * 'dp83902a_recv' will be called to actually fetch it from the hardware. 390 */ 391 static void 392 dp83902a_RxEvent(void) 393 { 394 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 395 u8 *base = dp->base; 396 u8 rsr; 397 u8 rcv_hdr[4]; 398 int i, len, pkt, cur; 399 400 DEBUG_FUNCTION(); 401 402 DP_IN(base, DP_RSR, rsr); 403 while (true) { 404 /* Read incoming packet header */ 405 DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); 406 DP_IN(base, DP_P1_CURP, cur); 407 DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 408 DP_IN(base, DP_BNDRY, pkt); 409 410 pkt += 1; 411 if (pkt == dp->rx_buf_end) 412 pkt = dp->rx_buf_start; 413 414 if (pkt == cur) { 415 break; 416 } 417 DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); 418 DP_OUT(base, DP_RBCH, 0); 419 DP_OUT(base, DP_RSAL, 0); 420 DP_OUT(base, DP_RSAH, pkt); 421 if (dp->rx_next == pkt) { 422 if (cur == dp->rx_buf_start) 423 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); 424 else 425 DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */ 426 return; 427 } 428 dp->rx_next = pkt; 429 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 430 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); 431 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA 432 CYGACC_CALL_IF_DELAY_US(10); 433 #endif 434 435 /* read header (get data size)*/ 436 for (i = 0; i < sizeof(rcv_hdr);) { 437 DP_IN_DATA(dp->data, rcv_hdr[i++]); 438 } 439 440 #if DEBUG & 5 441 printf("rx hdr %02x %02x %02x %02x\n", 442 rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); 443 #endif 444 len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); 445 446 /* data read */ 447 uboot_push_packet_len(len); 448 449 if (rcv_hdr[1] == dp->rx_buf_start) 450 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); 451 else 452 DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */ 453 } 454 } 455 456 /* 457 * This function is called as a result of the "eth_drv_recv()" call above. 458 * It's job is to actually fetch data for a packet from the hardware once 459 * memory buffers have been allocated for the packet. Note that the buffers 460 * may come in pieces, using a scatter-gather list. This allows for more 461 * efficient processing in the upper layers of the stack. 462 */ 463 static void 464 dp83902a_recv(u8 *data, int len) 465 { 466 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 467 u8 *base = dp->base; 468 int i, mlen; 469 u8 saved_char = 0; 470 bool saved; 471 #if DEBUG & 4 472 int dx; 473 #endif 474 475 DEBUG_FUNCTION(); 476 477 #if DEBUG & 5 478 printf("Rx packet %d length %d\n", dp->rx_next, len); 479 #endif 480 481 /* Read incoming packet data */ 482 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 483 DP_OUT(base, DP_RBCL, len & 0xFF); 484 DP_OUT(base, DP_RBCH, len >> 8); 485 DP_OUT(base, DP_RSAL, 4); /* Past header */ 486 DP_OUT(base, DP_RSAH, dp->rx_next); 487 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 488 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); 489 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA 490 CYGACC_CALL_IF_DELAY_US(10); 491 #endif 492 493 saved = false; 494 for (i = 0; i < 1; i++) { 495 if (data) { 496 mlen = len; 497 #if DEBUG & 4 498 printf(" sg buf %08lx len %08x \n", (u32) data, mlen); 499 dx = 0; 500 #endif 501 while (0 < mlen) { 502 /* Saved byte from previous loop? */ 503 if (saved) { 504 *data++ = saved_char; 505 mlen--; 506 saved = false; 507 continue; 508 } 509 510 { 511 u8 tmp; 512 DP_IN_DATA(dp->data, tmp); 513 #if DEBUG & 4 514 printf(" %02x", tmp); 515 if (0 == (++dx % 16)) printf("\n "); 516 #endif 517 *data++ = tmp;; 518 mlen--; 519 } 520 } 521 #if DEBUG & 4 522 printf("\n"); 523 #endif 524 } 525 } 526 } 527 528 static void 529 dp83902a_TxEvent(void) 530 { 531 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 532 u8 *base = dp->base; 533 u8 tsr; 534 u32 key; 535 536 DEBUG_FUNCTION(); 537 538 DP_IN(base, DP_TSR, tsr); 539 if (dp->tx_int == 1) { 540 key = dp->tx1_key; 541 dp->tx1 = 0; 542 } else { 543 key = dp->tx2_key; 544 dp->tx2 = 0; 545 } 546 /* Start next packet if one is ready */ 547 dp->tx_started = false; 548 if (dp->tx1) { 549 dp83902a_start_xmit(dp->tx1, dp->tx1_len); 550 dp->tx_int = 1; 551 } else if (dp->tx2) { 552 dp83902a_start_xmit(dp->tx2, dp->tx2_len); 553 dp->tx_int = 2; 554 } else { 555 dp->tx_int = 0; 556 } 557 /* Tell higher level we sent this packet */ 558 uboot_push_tx_done(key, 0); 559 } 560 561 /* 562 * Read the tally counters to clear them. Called in response to a CNT 563 * interrupt. 564 */ 565 static void 566 dp83902a_ClearCounters(void) 567 { 568 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 569 u8 *base = dp->base; 570 u8 cnt1, cnt2, cnt3; 571 572 DP_IN(base, DP_FER, cnt1); 573 DP_IN(base, DP_CER, cnt2); 574 DP_IN(base, DP_MISSED, cnt3); 575 DP_OUT(base, DP_ISR, DP_ISR_CNT); 576 } 577 578 /* 579 * Deal with an overflow condition. This code follows the procedure set 580 * out in section 7.0 of the datasheet. 581 */ 582 static void 583 dp83902a_Overflow(void) 584 { 585 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; 586 u8 *base = dp->base; 587 u8 isr; 588 589 /* Issue a stop command and wait 1.6ms for it to complete. */ 590 DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); 591 CYGACC_CALL_IF_DELAY_US(1600); 592 593 /* Clear the remote byte counter registers. */ 594 DP_OUT(base, DP_RBCL, 0); 595 DP_OUT(base, DP_RBCH, 0); 596 597 /* Enter loopback mode while we clear the buffer. */ 598 DP_OUT(base, DP_TCR, DP_TCR_LOCAL); 599 DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); 600 601 /* 602 * Read in as many packets as we can and acknowledge any and receive 603 * interrupts. Since the buffer has overflowed, a receive event of 604 * some kind will have occured. 605 */ 606 dp83902a_RxEvent(); 607 DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); 608 609 /* Clear the overflow condition and leave loopback mode. */ 610 DP_OUT(base, DP_ISR, DP_ISR_OFLW); 611 DP_OUT(base, DP_TCR, DP_TCR_NORMAL); 612 613 /* 614 * If a transmit command was issued, but no transmit event has occured, 615 * restart it here. 616 */ 617 DP_IN(base, DP_ISR, isr); 618 if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { 619 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); 620 } 621 } 622 623 static void 624 dp83902a_poll(void) 625 { 626 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 627 u8 *base = dp->base; 628 u8 isr; 629 630 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); 631 DP_IN(base, DP_ISR, isr); 632 while (0 != isr) { 633 /* 634 * The CNT interrupt triggers when the MSB of one of the error 635 * counters is set. We don't much care about these counters, but 636 * we should read their values to reset them. 637 */ 638 if (isr & DP_ISR_CNT) { 639 dp83902a_ClearCounters(); 640 } 641 /* 642 * Check for overflow. It's a special case, since there's a 643 * particular procedure that must be followed to get back into 644 * a running state.a 645 */ 646 if (isr & DP_ISR_OFLW) { 647 dp83902a_Overflow(); 648 } else { 649 /* 650 * Other kinds of interrupts can be acknowledged simply by 651 * clearing the relevant bits of the ISR. Do that now, then 652 * handle the interrupts we care about. 653 */ 654 DP_OUT(base, DP_ISR, isr); /* Clear set bits */ 655 if (!dp->running) break; /* Is this necessary? */ 656 /* 657 * Check for tx_started on TX event since these may happen 658 * spuriously it seems. 659 */ 660 if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) { 661 dp83902a_TxEvent(); 662 } 663 if (isr & (DP_ISR_RxP|DP_ISR_RxE)) { 664 dp83902a_RxEvent(); 665 } 666 } 667 DP_IN(base, DP_ISR, isr); 668 } 669 } 670 671 /* find prom (taken from pc_net_cs.c from Linux) */ 672 673 #include "8390.h" 674 /* 675 typedef struct hw_info_t { 676 u_int offset; 677 u_char a0, a1, a2; 678 u_int flags; 679 } hw_info_t; 680 */ 681 #define DELAY_OUTPUT 0x01 682 #define HAS_MISC_REG 0x02 683 #define USE_BIG_BUF 0x04 684 #define HAS_IBM_MISC 0x08 685 #define IS_DL10019 0x10 686 #define IS_DL10022 0x20 687 #define HAS_MII 0x40 688 #define USE_SHMEM 0x80 /* autodetected */ 689 690 #define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */ 691 #define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */ 692 #define MII_PHYID_REV_MASK 0xfffffff0 693 #define MII_PHYID_REG1 0x02 694 #define MII_PHYID_REG2 0x03 695 696 static hw_info_t hw_info[] = { 697 { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, 698 { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, 699 { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, 700 { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, 701 DELAY_OUTPUT | HAS_IBM_MISC }, 702 { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, 703 { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, 704 { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, 705 { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, 706 { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, 707 { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, 708 { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, 709 HAS_MISC_REG | HAS_IBM_MISC }, 710 { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, 711 { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, 712 { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, 713 HAS_MISC_REG | HAS_IBM_MISC }, 714 { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, 715 HAS_MISC_REG | HAS_IBM_MISC }, 716 { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, 717 HAS_MISC_REG | HAS_IBM_MISC }, 718 { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, 719 HAS_MISC_REG | HAS_IBM_MISC }, 720 { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, 721 HAS_MISC_REG | HAS_IBM_MISC }, 722 { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, 723 HAS_MISC_REG | HAS_IBM_MISC }, 724 { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, 725 HAS_MISC_REG | HAS_IBM_MISC }, 726 { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, 727 HAS_MISC_REG | HAS_IBM_MISC }, 728 { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, 729 HAS_MISC_REG | HAS_IBM_MISC }, 730 { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, 731 HAS_MISC_REG | HAS_IBM_MISC }, 732 { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, 733 { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, 734 { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, 735 HAS_MISC_REG | HAS_IBM_MISC }, 736 { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, 737 HAS_MISC_REG | HAS_IBM_MISC }, 738 { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, 739 { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, 740 { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, 741 { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, 742 { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, 743 HAS_MISC_REG | HAS_IBM_MISC }, 744 { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, 745 HAS_MISC_REG | HAS_IBM_MISC }, 746 { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, 747 { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, 748 { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, 749 { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, 750 DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, 751 { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, 752 { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, 753 { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, 754 { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, 755 { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }, 756 { /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 } 757 }; 758 759 #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) 760 761 #define PCNET_CMD 0x00 762 #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ 763 #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ 764 #define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ 765 766 static void pcnet_reset_8390(void) 767 { 768 int i, r; 769 770 PRINTK("nic base is %lx\n", nic.base); 771 772 n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD); 773 PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); 774 n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); 775 PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); 776 n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); 777 PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); 778 n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); 779 780 n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); 781 782 for (i = 0; i < 100; i++) { 783 if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) 784 break; 785 PRINTK("got %x in reset\n", r); 786 udelay(100); 787 } 788 n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ 789 790 if (i == 100) 791 printf("pcnet_reset_8390() did not complete.\n"); 792 } /* pcnet_reset_8390 */ 793 794 int get_prom(u8* mac_addr) __attribute__ ((weak, alias ("__get_prom"))); 795 int __get_prom(u8* mac_addr) 796 { 797 u8 prom[32]; 798 int i, j; 799 struct { 800 u_char value, offset; 801 } program_seq[] = { 802 {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ 803 {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ 804 {0x00, EN0_RCNTLO}, /* Clear the count regs. */ 805 {0x00, EN0_RCNTHI}, 806 {0x00, EN0_IMR}, /* Mask completion irq. */ 807 {0xFF, EN0_ISR}, 808 {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ 809 {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ 810 {32, EN0_RCNTLO}, 811 {0x00, EN0_RCNTHI}, 812 {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ 813 {0x00, EN0_RSARHI}, 814 {E8390_RREAD+E8390_START, E8390_CMD}, 815 }; 816 817 PRINTK ("trying to get MAC via prom reading\n"); 818 819 pcnet_reset_8390 (); 820 821 mdelay (10); 822 823 for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++) 824 n2k_outb (program_seq[i].value, program_seq[i].offset); 825 826 PRINTK ("PROM:"); 827 for (i = 0; i < 32; i++) { 828 prom[i] = n2k_inb (PCNET_DATAPORT); 829 PRINTK (" %02x", prom[i]); 830 } 831 PRINTK ("\n"); 832 for (i = 0; i < NR_INFO; i++) { 833 if ((prom[0] == hw_info[i].a0) && 834 (prom[2] == hw_info[i].a1) && 835 (prom[4] == hw_info[i].a2)) { 836 PRINTK ("matched board %d\n", i); 837 break; 838 } 839 } 840 if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { 841 PRINTK ("on exit i is %d/%ld\n", i, NR_INFO); 842 PRINTK ("MAC address is "); 843 for (j = 0; j < 6; j++) { 844 mac_addr[j] = prom[j << 1]; 845 PRINTK ("%02x:", mac_addr[i]); 846 } 847 PRINTK ("\n"); 848 return (i < NR_INFO) ? i : 0; 849 } 850 return 0; 851 } 852 853 /* U-boot specific routines */ 854 static u8 *pbuf = NULL; 855 856 static int pkey = -1; 857 static int initialized = 0; 858 859 void uboot_push_packet_len(int len) { 860 PRINTK("pushed len = %d\n", len); 861 if (len >= 2000) { 862 printf("NE2000: packet too big\n"); 863 return; 864 } 865 dp83902a_recv(&pbuf[0], len); 866 867 /*Just pass it to the upper layer*/ 868 NetReceive(&pbuf[0], len); 869 } 870 871 void uboot_push_tx_done(int key, int val) { 872 PRINTK("pushed key = %d\n", key); 873 pkey = key; 874 } 875 876 int eth_init(bd_t *bd) { 877 int r; 878 u8 dev_addr[6]; 879 char ethaddr[20]; 880 881 PRINTK("### eth_init\n"); 882 883 if (!pbuf) { 884 pbuf = malloc(2000); 885 if (!pbuf) { 886 printf("Cannot allocate rx buffer\n"); 887 return -1; 888 } 889 } 890 891 #ifdef CONFIG_DRIVER_NE2000_CCR 892 { 893 vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR; 894 895 PRINTK("CCR before is %x\n", *p); 896 *p = CONFIG_DRIVER_NE2000_VAL; 897 PRINTK("CCR after is %x\n", *p); 898 } 899 #endif 900 901 nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; 902 903 r = get_prom(dev_addr); 904 if (!r) 905 return -1; 906 907 sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", 908 dev_addr[0], dev_addr[1], 909 dev_addr[2], dev_addr[3], 910 dev_addr[4], dev_addr[5]) ; 911 PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr); 912 setenv ("ethaddr", ethaddr); 913 914 nic.data = nic.base + DP_DATA; 915 nic.tx_buf1 = START_PG; 916 nic.tx_buf2 = START_PG2; 917 nic.rx_buf_start = RX_START; 918 nic.rx_buf_end = RX_END; 919 920 if (dp83902a_init() == false) 921 return -1; 922 923 dp83902a_start(dev_addr); 924 initialized = 1; 925 926 return 0; 927 } 928 929 void eth_halt() { 930 931 PRINTK("### eth_halt\n"); 932 if(initialized) 933 dp83902a_stop(); 934 initialized = 0; 935 } 936 937 int eth_rx() { 938 dp83902a_poll(); 939 return 1; 940 } 941 942 int eth_send(volatile void *packet, int length) { 943 int tmo; 944 945 PRINTK("### eth_send\n"); 946 947 pkey = -1; 948 949 dp83902a_send((u8 *) packet, length, 666); 950 tmo = get_timer (0) + TOUT * CFG_HZ; 951 while(1) { 952 dp83902a_poll(); 953 if (pkey != -1) { 954 PRINTK("Packet sucesfully sent\n"); 955 return 0; 956 } 957 if (get_timer (0) >= tmo) { 958 printf("transmission error (timoeut)\n"); 959 return 0; 960 } 961 962 } 963 return 0; 964 } 965