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 /* NE2000 base header file */ 86 #include "ne2000_base.h" 87 88 #if defined(CONFIG_DRIVER_AX88796L) 89 /* AX88796L support */ 90 #include "ax88796.h" 91 #else 92 /* Basic NE2000 chip support */ 93 #include "ne2000.h" 94 #endif 95 96 static dp83902a_priv_data_t nic; /* just one instance of the card supported */ 97 98 static bool 99 dp83902a_init(void) 100 { 101 dp83902a_priv_data_t *dp = &nic; 102 u8* base; 103 #if defined(NE2000_BASIC_INIT) 104 int i; 105 #endif 106 107 DEBUG_FUNCTION(); 108 109 base = dp->base; 110 if (!base) 111 return false; /* No device found */ 112 113 DEBUG_LINE(); 114 115 #if defined(NE2000_BASIC_INIT) 116 /* AX88796L doesn't need */ 117 /* Prepare ESA */ 118 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */ 119 /* Use the address from the serial EEPROM */ 120 for (i = 0; i < 6; i++) 121 DP_IN(base, DP_P1_PAR0+i, dp->esa[i]); 122 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */ 123 124 printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", 125 "eeprom", 126 dp->esa[0], 127 dp->esa[1], 128 dp->esa[2], 129 dp->esa[3], 130 dp->esa[4], 131 dp->esa[5] ); 132 133 #endif /* NE2000_BASIC_INIT */ 134 return true; 135 } 136 137 static void 138 dp83902a_stop(void) 139 { 140 dp83902a_priv_data_t *dp = &nic; 141 u8 *base = dp->base; 142 143 DEBUG_FUNCTION(); 144 145 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ 146 DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ 147 DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */ 148 149 dp->running = false; 150 } 151 152 /* 153 * This function is called to "start up" the interface. It may be called 154 * multiple times, even when the hardware is already running. It will be 155 * called whenever something "hardware oriented" changes and should leave 156 * the hardware ready to send/receive packets. 157 */ 158 static void 159 dp83902a_start(u8 * enaddr) 160 { 161 dp83902a_priv_data_t *dp = &nic; 162 u8 *base = dp->base; 163 int i; 164 165 DEBUG_FUNCTION(); 166 167 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ 168 DP_OUT(base, DP_DCR, DP_DCR_INIT); 169 DP_OUT(base, DP_RBCH, 0); /* Remote byte count */ 170 DP_OUT(base, DP_RBCL, 0); 171 DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */ 172 DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */ 173 DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */ 174 dp->tx1 = dp->tx2 = 0; 175 dp->tx_next = dp->tx_buf1; 176 dp->tx_started = false; 177 dp->running = true; 178 DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ 179 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */ 180 DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */ 181 dp->rx_next = dp->rx_buf_start - 1; 182 dp->running = true; 183 DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ 184 DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */ 185 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */ 186 DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */ 187 dp->running = true; 188 for (i = 0; i < ETHER_ADDR_LEN; i++) { 189 /* FIXME */ 190 /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) + 191 * 0x1400)) = enaddr[i];*/ 192 DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); 193 } 194 /* Enable and start device */ 195 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 196 DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */ 197 DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */ 198 dp->running = true; 199 } 200 201 /* 202 * This routine is called to start the transmitter. It is split out from the 203 * data handling routine so it may be called either when data becomes first 204 * available or when an Tx interrupt occurs 205 */ 206 207 static void 208 dp83902a_start_xmit(int start_page, int len) 209 { 210 dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; 211 u8 *base = dp->base; 212 213 DEBUG_FUNCTION(); 214 215 #if DEBUG & 1 216 printf("Tx pkt %d len %d\n", start_page, len); 217 if (dp->tx_started) 218 printf("TX already started?!?\n"); 219 #endif 220 221 DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE)); 222 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 223 DP_OUT(base, DP_TBCL, len & 0xFF); 224 DP_OUT(base, DP_TBCH, len >> 8); 225 DP_OUT(base, DP_TPSR, start_page); 226 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); 227 228 dp->tx_started = true; 229 } 230 231 /* 232 * This routine is called to send data to the hardware. It is known a-priori 233 * that there is free buffer space (dp->tx_next). 234 */ 235 static void 236 dp83902a_send(u8 *data, int total_len, u32 key) 237 { 238 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 239 u8 *base = dp->base; 240 int len, start_page, pkt_len, i, isr; 241 #if DEBUG & 4 242 int dx; 243 #endif 244 245 DEBUG_FUNCTION(); 246 247 len = pkt_len = total_len; 248 if (pkt_len < IEEE_8023_MIN_FRAME) 249 pkt_len = IEEE_8023_MIN_FRAME; 250 251 start_page = dp->tx_next; 252 if (dp->tx_next == dp->tx_buf1) { 253 dp->tx1 = start_page; 254 dp->tx1_len = pkt_len; 255 dp->tx1_key = key; 256 dp->tx_next = dp->tx_buf2; 257 } else { 258 dp->tx2 = start_page; 259 dp->tx2_len = pkt_len; 260 dp->tx2_key = key; 261 dp->tx_next = dp->tx_buf1; 262 } 263 264 #if DEBUG & 5 265 printf("TX prep page %d len %d\n", start_page, pkt_len); 266 #endif 267 268 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 269 { 270 /* 271 * Dummy read. The manual sez something slightly different, 272 * but the code is extended a bit to do what Hitachi's monitor 273 * does (i.e., also read data). 274 */ 275 276 u16 tmp; 277 int len = 1; 278 279 DP_OUT(base, DP_RSAL, 0x100 - len); 280 DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff); 281 DP_OUT(base, DP_RBCL, len); 282 DP_OUT(base, DP_RBCH, 0); 283 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); 284 DP_IN_DATA(dp->data, tmp); 285 } 286 287 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 288 /* 289 * Stall for a bit before continuing to work around random data 290 * corruption problems on some platforms. 291 */ 292 CYGACC_CALL_IF_DELAY_US(1); 293 #endif 294 295 /* Send data to device buffer(s) */ 296 DP_OUT(base, DP_RSAL, 0); 297 DP_OUT(base, DP_RSAH, start_page); 298 DP_OUT(base, DP_RBCL, pkt_len & 0xFF); 299 DP_OUT(base, DP_RBCH, pkt_len >> 8); 300 DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); 301 302 /* Put data into buffer */ 303 #if DEBUG & 4 304 printf(" sg buf %08lx len %08x\n ", (u32)data, len); 305 dx = 0; 306 #endif 307 while (len > 0) { 308 #if DEBUG & 4 309 printf(" %02x", *data); 310 if (0 == (++dx % 16)) printf("\n "); 311 #endif 312 313 DP_OUT_DATA(dp->data, *data++); 314 len--; 315 } 316 #if DEBUG & 4 317 printf("\n"); 318 #endif 319 if (total_len < pkt_len) { 320 #if DEBUG & 4 321 printf(" + %d bytes of padding\n", pkt_len - total_len); 322 #endif 323 /* Padding to 802.3 length was required */ 324 for (i = total_len; i < pkt_len;) { 325 i++; 326 DP_OUT_DATA(dp->data, 0); 327 } 328 } 329 330 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 331 /* 332 * After last data write, delay for a bit before accessing the 333 * device again, or we may get random data corruption in the last 334 * datum (on some platforms). 335 */ 336 CYGACC_CALL_IF_DELAY_US(1); 337 #endif 338 339 /* Wait for DMA to complete */ 340 do { 341 DP_IN(base, DP_ISR, isr); 342 } while ((isr & DP_ISR_RDC) == 0); 343 344 /* Then disable DMA */ 345 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 346 347 /* Start transmit if not already going */ 348 if (!dp->tx_started) { 349 if (start_page == dp->tx1) { 350 dp->tx_int = 1; /* Expecting interrupt from BUF1 */ 351 } else { 352 dp->tx_int = 2; /* Expecting interrupt from BUF2 */ 353 } 354 dp83902a_start_xmit(start_page, pkt_len); 355 } 356 } 357 358 /* 359 * This function is called when a packet has been received. It's job is 360 * to prepare to unload the packet from the hardware. Once the length of 361 * the packet is known, the upper layer of the driver can be told. When 362 * the upper layer is ready to unload the packet, the internal function 363 * 'dp83902a_recv' will be called to actually fetch it from the hardware. 364 */ 365 static void 366 dp83902a_RxEvent(void) 367 { 368 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 369 u8 *base = dp->base; 370 u8 rsr; 371 u8 rcv_hdr[4]; 372 int i, len, pkt, cur; 373 374 DEBUG_FUNCTION(); 375 376 DP_IN(base, DP_RSR, rsr); 377 while (true) { 378 /* Read incoming packet header */ 379 DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); 380 DP_IN(base, DP_P1_CURP, cur); 381 DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 382 DP_IN(base, DP_BNDRY, pkt); 383 384 pkt += 1; 385 if (pkt == dp->rx_buf_end) 386 pkt = dp->rx_buf_start; 387 388 if (pkt == cur) { 389 break; 390 } 391 DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); 392 DP_OUT(base, DP_RBCH, 0); 393 DP_OUT(base, DP_RSAL, 0); 394 DP_OUT(base, DP_RSAH, pkt); 395 if (dp->rx_next == pkt) { 396 if (cur == dp->rx_buf_start) 397 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); 398 else 399 DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */ 400 return; 401 } 402 dp->rx_next = pkt; 403 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 404 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); 405 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA 406 CYGACC_CALL_IF_DELAY_US(10); 407 #endif 408 409 /* read header (get data size)*/ 410 for (i = 0; i < sizeof(rcv_hdr);) { 411 DP_IN_DATA(dp->data, rcv_hdr[i++]); 412 } 413 414 #if DEBUG & 5 415 printf("rx hdr %02x %02x %02x %02x\n", 416 rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); 417 #endif 418 len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); 419 420 /* data read */ 421 uboot_push_packet_len(len); 422 423 if (rcv_hdr[1] == dp->rx_buf_start) 424 DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); 425 else 426 DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */ 427 } 428 } 429 430 /* 431 * This function is called as a result of the "eth_drv_recv()" call above. 432 * It's job is to actually fetch data for a packet from the hardware once 433 * memory buffers have been allocated for the packet. Note that the buffers 434 * may come in pieces, using a scatter-gather list. This allows for more 435 * efficient processing in the upper layers of the stack. 436 */ 437 static void 438 dp83902a_recv(u8 *data, int len) 439 { 440 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 441 u8 *base = dp->base; 442 int i, mlen; 443 u8 saved_char = 0; 444 bool saved; 445 #if DEBUG & 4 446 int dx; 447 #endif 448 449 DEBUG_FUNCTION(); 450 451 #if DEBUG & 5 452 printf("Rx packet %d length %d\n", dp->rx_next, len); 453 #endif 454 455 /* Read incoming packet data */ 456 DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); 457 DP_OUT(base, DP_RBCL, len & 0xFF); 458 DP_OUT(base, DP_RBCH, len >> 8); 459 DP_OUT(base, DP_RSAL, 4); /* Past header */ 460 DP_OUT(base, DP_RSAH, dp->rx_next); 461 DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ 462 DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); 463 #ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA 464 CYGACC_CALL_IF_DELAY_US(10); 465 #endif 466 467 saved = false; 468 for (i = 0; i < 1; i++) { 469 if (data) { 470 mlen = len; 471 #if DEBUG & 4 472 printf(" sg buf %08lx len %08x \n", (u32) data, mlen); 473 dx = 0; 474 #endif 475 while (0 < mlen) { 476 /* Saved byte from previous loop? */ 477 if (saved) { 478 *data++ = saved_char; 479 mlen--; 480 saved = false; 481 continue; 482 } 483 484 { 485 u8 tmp; 486 DP_IN_DATA(dp->data, tmp); 487 #if DEBUG & 4 488 printf(" %02x", tmp); 489 if (0 == (++dx % 16)) printf("\n "); 490 #endif 491 *data++ = tmp;; 492 mlen--; 493 } 494 } 495 #if DEBUG & 4 496 printf("\n"); 497 #endif 498 } 499 } 500 } 501 502 static void 503 dp83902a_TxEvent(void) 504 { 505 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 506 u8 *base = dp->base; 507 u8 tsr; 508 u32 key; 509 510 DEBUG_FUNCTION(); 511 512 DP_IN(base, DP_TSR, tsr); 513 if (dp->tx_int == 1) { 514 key = dp->tx1_key; 515 dp->tx1 = 0; 516 } else { 517 key = dp->tx2_key; 518 dp->tx2 = 0; 519 } 520 /* Start next packet if one is ready */ 521 dp->tx_started = false; 522 if (dp->tx1) { 523 dp83902a_start_xmit(dp->tx1, dp->tx1_len); 524 dp->tx_int = 1; 525 } else if (dp->tx2) { 526 dp83902a_start_xmit(dp->tx2, dp->tx2_len); 527 dp->tx_int = 2; 528 } else { 529 dp->tx_int = 0; 530 } 531 /* Tell higher level we sent this packet */ 532 uboot_push_tx_done(key, 0); 533 } 534 535 /* 536 * Read the tally counters to clear them. Called in response to a CNT 537 * interrupt. 538 */ 539 static void 540 dp83902a_ClearCounters(void) 541 { 542 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 543 u8 *base = dp->base; 544 u8 cnt1, cnt2, cnt3; 545 546 DP_IN(base, DP_FER, cnt1); 547 DP_IN(base, DP_CER, cnt2); 548 DP_IN(base, DP_MISSED, cnt3); 549 DP_OUT(base, DP_ISR, DP_ISR_CNT); 550 } 551 552 /* 553 * Deal with an overflow condition. This code follows the procedure set 554 * out in section 7.0 of the datasheet. 555 */ 556 static void 557 dp83902a_Overflow(void) 558 { 559 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; 560 u8 *base = dp->base; 561 u8 isr; 562 563 /* Issue a stop command and wait 1.6ms for it to complete. */ 564 DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); 565 CYGACC_CALL_IF_DELAY_US(1600); 566 567 /* Clear the remote byte counter registers. */ 568 DP_OUT(base, DP_RBCL, 0); 569 DP_OUT(base, DP_RBCH, 0); 570 571 /* Enter loopback mode while we clear the buffer. */ 572 DP_OUT(base, DP_TCR, DP_TCR_LOCAL); 573 DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); 574 575 /* 576 * Read in as many packets as we can and acknowledge any and receive 577 * interrupts. Since the buffer has overflowed, a receive event of 578 * some kind will have occured. 579 */ 580 dp83902a_RxEvent(); 581 DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); 582 583 /* Clear the overflow condition and leave loopback mode. */ 584 DP_OUT(base, DP_ISR, DP_ISR_OFLW); 585 DP_OUT(base, DP_TCR, DP_TCR_NORMAL); 586 587 /* 588 * If a transmit command was issued, but no transmit event has occured, 589 * restart it here. 590 */ 591 DP_IN(base, DP_ISR, isr); 592 if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { 593 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); 594 } 595 } 596 597 static void 598 dp83902a_poll(void) 599 { 600 struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; 601 u8 *base = dp->base; 602 u8 isr; 603 604 DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); 605 DP_IN(base, DP_ISR, isr); 606 while (0 != isr) { 607 /* 608 * The CNT interrupt triggers when the MSB of one of the error 609 * counters is set. We don't much care about these counters, but 610 * we should read their values to reset them. 611 */ 612 if (isr & DP_ISR_CNT) { 613 dp83902a_ClearCounters(); 614 } 615 /* 616 * Check for overflow. It's a special case, since there's a 617 * particular procedure that must be followed to get back into 618 * a running state.a 619 */ 620 if (isr & DP_ISR_OFLW) { 621 dp83902a_Overflow(); 622 } else { 623 /* 624 * Other kinds of interrupts can be acknowledged simply by 625 * clearing the relevant bits of the ISR. Do that now, then 626 * handle the interrupts we care about. 627 */ 628 DP_OUT(base, DP_ISR, isr); /* Clear set bits */ 629 if (!dp->running) break; /* Is this necessary? */ 630 /* 631 * Check for tx_started on TX event since these may happen 632 * spuriously it seems. 633 */ 634 if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) { 635 dp83902a_TxEvent(); 636 } 637 if (isr & (DP_ISR_RxP|DP_ISR_RxE)) { 638 dp83902a_RxEvent(); 639 } 640 } 641 DP_IN(base, DP_ISR, isr); 642 } 643 } 644 645 646 /* U-boot specific routines */ 647 static u8 *pbuf = NULL; 648 649 static int pkey = -1; 650 static int initialized = 0; 651 652 void uboot_push_packet_len(int len) { 653 PRINTK("pushed len = %d\n", len); 654 if (len >= 2000) { 655 printf("NE2000: packet too big\n"); 656 return; 657 } 658 dp83902a_recv(&pbuf[0], len); 659 660 /*Just pass it to the upper layer*/ 661 NetReceive(&pbuf[0], len); 662 } 663 664 void uboot_push_tx_done(int key, int val) { 665 PRINTK("pushed key = %d\n", key); 666 pkey = key; 667 } 668 669 int eth_init(bd_t *bd) { 670 int r; 671 u8 dev_addr[6]; 672 char ethaddr[20]; 673 674 PRINTK("### eth_init\n"); 675 676 if (!pbuf) { 677 pbuf = malloc(2000); 678 if (!pbuf) { 679 printf("Cannot allocate rx buffer\n"); 680 return -1; 681 } 682 } 683 684 #ifdef CONFIG_DRIVER_NE2000_CCR 685 { 686 vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR; 687 688 PRINTK("CCR before is %x\n", *p); 689 *p = CONFIG_DRIVER_NE2000_VAL; 690 PRINTK("CCR after is %x\n", *p); 691 } 692 #endif 693 694 nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; 695 696 r = get_prom(dev_addr, nic.base); 697 if (!r) 698 return -1; 699 700 sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", 701 dev_addr[0], dev_addr[1], 702 dev_addr[2], dev_addr[3], 703 dev_addr[4], dev_addr[5]) ; 704 PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr); 705 setenv ("ethaddr", ethaddr); 706 707 nic.data = nic.base + DP_DATA; 708 nic.tx_buf1 = START_PG; 709 nic.tx_buf2 = START_PG2; 710 nic.rx_buf_start = RX_START; 711 nic.rx_buf_end = RX_END; 712 713 if (dp83902a_init() == false) 714 return -1; 715 716 dp83902a_start(dev_addr); 717 initialized = 1; 718 719 return 0; 720 } 721 722 void eth_halt() { 723 724 PRINTK("### eth_halt\n"); 725 if(initialized) 726 dp83902a_stop(); 727 initialized = 0; 728 } 729 730 int eth_rx() { 731 dp83902a_poll(); 732 return 1; 733 } 734 735 int eth_send(volatile void *packet, int length) { 736 int tmo; 737 738 PRINTK("### eth_send\n"); 739 740 pkey = -1; 741 742 dp83902a_send((u8 *) packet, length, 666); 743 tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ; 744 while(1) { 745 dp83902a_poll(); 746 if (pkey != -1) { 747 PRINTK("Packet sucesfully sent\n"); 748 return 0; 749 } 750 if (get_timer (0) >= tmo) { 751 printf("transmission error (timoeut)\n"); 752 return 0; 753 } 754 755 } 756 return 0; 757 } 758