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