1 /* 2 * Copyright (c) 1998, 1999, Be Incorporated. All Rights Reserved. 3 * This file may be used under the terms of the Be Sample Code License. 4 */ 5 6 /*! Ethernet driver: handles PCI NE2000 cards */ 7 8 #include "etherpci_private.h" 9 #include <ether_driver.h> 10 11 #include <OS.h> 12 #include <KernelExport.h> 13 #include <Drivers.h> 14 #include <PCI.h> 15 16 #include <stdlib.h> 17 #include <stdio.h> 18 #include <string.h> 19 #include <stdarg.h> 20 21 #define kDevName "etherpci" 22 #define kDevDir "net/" kDevName "/" 23 #define DEVNAME_LENGTH 64 24 #define MAX_CARDS 4 /* maximum number of driver instances */ 25 26 int32 api_version = B_CUR_DRIVER_API_VERSION; 27 28 /* debug flags */ 29 #define ERR 0x0001 30 #define INFO 0x0002 31 #define RX 0x0004 /* dump received frames */ 32 #define TX 0x0008 /* dump transmitted frames */ 33 #define INTERRUPT 0x0010 /* interrupt calls */ 34 #define FUNCTION 0x0020 /* function calls */ 35 #define PCI_IO 0x0040 /* pci reads and writes */ 36 #define SEQ 0x0080 /* trasnmit & receive TCP/IP sequence sequence numbers */ 37 #define WARN 0x0100 /* Warnings - off on final release */ 38 39 /* diagnostic debug flags - compile in here or set while running with debugger "AcmeRoadRunner" command */ 40 #define DEFAULT_DEBUG_FLAGS ( ERR | INFO | WARN | FUNCTION ) 41 42 //#define TRACE_ETHERPCI 43 #ifdef TRACE_ETHERPCI 44 # define ETHER_DEBUG(mask, enabled, format, args...) \ 45 do { if (mask & enabled) \ 46 dprintf(format , ##args); } while (0) 47 #else 48 # define ETHER_DEBUG(mask, enabled, format, args...) ; 49 #endif 50 51 52 static pci_module_info *gPCIModInfo; 53 static char *gDevNameList[MAX_CARDS+1]; 54 static pci_info *gDevList[MAX_CARDS+1]; 55 static int32 gOpenMask = 0; 56 57 58 /* Driver Entry Points */ 59 status_t init_hardware(void); 60 status_t init_driver(void); 61 void uninit_driver(void); 62 const char** publish_devices(void); 63 device_hooks *find_device(const char *name); 64 65 66 67 /* 68 * Define STAY_ON_PAGE_0 if you want the driver to stay on page 0 all the 69 * time. This is faster than if it has to switch to page 1 to get the 70 * current register to see if there are any more packets. Reason: the 71 * interrupt handler does not have to do any locking if it knows it is 72 * always on page 0. I'm not sure why the speed difference is so dramatic, 73 * so perhaps there is actually a bug in page-changing version. 74 * 75 * STAY_ON_PAGE_0 uses a rather dubious technique to avoid changing the 76 * register page and it may not be 100% reliable. The technique used is to 77 * make sure all ring headers are zeroed out before packets are received 78 * into them. Then, if you detect a non-zero ring header, you can be pretty 79 * sure that it is another packet. 80 * 81 * We never read the "might-be-a-packet" immediately. Instead, we just 82 * release a semaphore so that the next read will occur later on enough 83 * so that the ring header information should be completely filled in. 84 * 85 */ 86 #define STAY_ON_PAGE_0 0 87 88 89 /* 90 * We only care about these interrupts in our driver 91 */ 92 #define INTS_WE_CARE_ABOUT (ISR_RECEIVE | ISR_RECEIVE_ERROR |\ 93 ISR_TRANSMIT | ISR_TRANSMIT_ERROR | ISR_COUNTER) 94 95 typedef struct etherpci_private { 96 int32 devID; /* device identifier: 0-n */ 97 pci_info *pciInfo; 98 uint16 irq; /* IRQ line */ 99 uint32 reg_base; /* hardware register base address */ 100 area_id ioarea; /* Area used for MMIO of hostRegs */ 101 int boundary; /* boundary register value (mirrored) */ 102 ether_address_t myaddr; /* my ethernet address */ 103 unsigned nmulti; /* number of multicast addresses */ 104 ether_address_t multi[MAX_MULTI]; /* multicast addresses */ 105 sem_id iolock; /* ethercard io, except interrupt handler */ 106 int nonblocking; /* non-blocking mode */ 107 #if !STAY_ON_PAGE_0 108 spinlock intrlock; /* ethercard io, including interrupt handler */ 109 #endif /* !STAY_ON_PAGE_0 */ 110 volatile int interrupted; /* interrupted system call */ 111 sem_id inrw; /* in read or write function */ 112 sem_id ilock; /* waiting for input */ 113 sem_id olock; /* waiting to output */ 114 115 /* 116 * Various statistics 117 */ 118 volatile int ints; /* total number of interrupts */ 119 volatile int rints; /* read interrupts */ 120 volatile int wints; /* write interrupts */ 121 volatile int reads; /* reads */ 122 volatile int writes; /* writes */ 123 volatile int resets; /* resets */ 124 volatile int rerrs; /* read errors */ 125 volatile int werrs; /* write errors */ 126 volatile int interrs;/* unknown interrupts */ 127 volatile int frame_errs; /* frame alignment errors */ 128 volatile int crc_errs; /* crc errors */ 129 volatile int frames_lost;/* frames lost due to buffer problems */ 130 131 /* 132 * Most recent values of the error statistics to detect any changes in them 133 */ 134 int rerrs_last; 135 int werrs_last; 136 int interrs_last; 137 int frame_errs_last; 138 int crc_errs_last; 139 int frames_lost_last; 140 141 /* stats from the hardware */ 142 int chip_rx_frame_errors; 143 int chip_rx_crc_errors; 144 int chip_rx_missed_errors; 145 /* 146 * These values are set once and never looked at again. They are 147 * almost as good as constants, but they differ for the various 148 * cards, so we can't set them now. 149 */ 150 int ETHER_BUF_START; 151 int ETHER_BUF_SIZE; 152 int EC_VMEM_PAGE; 153 int EC_VMEM_NPAGES; 154 int EC_RXBUF_START_PAGE; 155 int EC_RXBUF_END_PAGE; 156 int EC_RINGSTART; 157 int EC_RINGSIZE; 158 159 uint32 debug; 160 161 } etherpci_private_t; 162 163 164 #if __POWERPC__ 165 166 #define ether_inb(device, offset) (*((volatile uint8*)(device->reg_base + (offset)))); __eieio() 167 #define ether_inw(device, offset) (*((volatile uint16*)(device->reg_base + (offset)))); __eieio() 168 #define ether_outb(device, offset, value) (*((volatile uint8 *)(device->reg_base + (offset))) = (value)); __eieio() 169 #define ether_outw(device, offset, value) (*((volatile uint16*)(device->reg_base + (offset))) = (value)); __eieio() 170 171 #else /* !PPC */ 172 173 #define ether_outb(device, offset, value) (*gPCIModInfo->write_io_8)((device->reg_base + (offset)), (value)) 174 #define ether_outw(device, offset, value) (*gPCIModInfo->write_io_16)((device->reg_base + (offset)), (value)) 175 #define ether_inb(device, offset) ((*gPCIModInfo->read_io_8)(device->reg_base + (offset))) 176 #define ether_inw(device, offset) ((*gPCIModInfo->read_io_16)(device->reg_base + (offset))) 177 178 #endif 179 180 #if 0 181 #if __i386__ 182 183 uint8 ether_inb(etherpci_private_t *device, uint32 offset) { 184 uint8 result; 185 result = ((*gPCIModInfo->read_io_8)(device->reg_base + (offset))); 186 ETHER_DEBUG(PCI_IO, device->debug, " inb(%x) %x \n", offset, result); 187 return result; 188 }; 189 uint16 ether_inw(etherpci_private_t *device, uint32 offset) { 190 uint16 result; 191 result = ((*gPCIModInfo->read_io_16)(device->reg_base + (offset))); 192 ETHER_DEBUG(PCI_IO, device->debug, " inw(%x) %x \n", offset, result); 193 return result; 194 }; 195 void ether_outb(etherpci_private_t *device, uint32 offset, uint8 value) { 196 (*gPCIModInfo->write_io_8)((device->reg_base + (offset)), (value)); 197 ETHER_DEBUG(PCI_IO, device->debug, " outb(%x) %x \n", offset, value); 198 }; 199 void ether_outw(etherpci_private_t *device, uint32 offset, uint16 value) { 200 (*gPCIModInfo->write_io_16)((device->reg_base + (offset)), (value)); 201 ETHER_DEBUG(PCI_IO, device->debug, " outb(%x) %x \n", offset, value); 202 }; 203 204 205 #else /* PPC */ 206 207 uint8 ether_inb(etherpci_private_t *device, uint32 offset) { 208 uint8 result; 209 result = (*((volatile uint8*) (device->reg_base + (offset)))); __eieio(); 210 ETHER_DEBUG(PCI_IO, device->debug, " inb(%x) %x \n", offset, result); 211 return result; 212 }; 213 214 uint16 ether_inw(etherpci_private_t *device, uint32 offset) { 215 uint16 result; 216 result = (*((volatile uint16*) (device->reg_base + (offset)))); __eieio(); 217 ETHER_DEBUG(PCI_IO, device->debug, " inw(%x) %x \n", offset, result); 218 return result; 219 }; 220 221 void ether_outb(etherpci_private_t *device, uint32 offset, uint8 value) { 222 (*((volatile uint8 *)(device->reg_base + (offset))) = (value)); __eieio(); 223 ETHER_DEBUG(PCI_IO, device->debug, " outb(%x) %x \n", offset, value); 224 }; 225 void ether_outw(etherpci_private_t *device, uint32 offset, uint16 value) { 226 (*((volatile uint16 *)(device->reg_base + (offset))) = (value)); __eieio(); 227 ETHER_DEBUG(PCI_IO, device->debug, " outb(%x) %x \n", offset, value); 228 }; 229 230 #endif 231 #endif 232 233 234 235 236 237 /* for serial debug command*/ 238 #define DEBUGGER_COMMAND true 239 #if DEBUGGER_COMMAND 240 etherpci_private_t * gdev; 241 static int etherpci(int argc, char **argv); 242 /* serial debug command */ 243 #endif 244 245 /* 246 * io_lock gets you exclusive access to the card, except that 247 * the interrupt handler can still run. 248 * There is probably no need to io_lock() a 3com card, so look into 249 * removing it for that case. 250 */ 251 #define io_lock(data) acquire_sem(data->iolock) 252 #define io_unlock(data) release_sem_etc(data->iolock, 1, B_DO_NOT_RESCHEDULE) 253 254 /* 255 * output_wait wakes up when the card is ready to transmit another packet 256 */ 257 #define output_wait(data, t) acquire_sem_etc(data->olock, 1, B_TIMEOUT, t) 258 #define output_unwait(data, c) release_sem_etc(data->olock, c, B_DO_NOT_RESCHEDULE) 259 260 /* 261 * input_wait wakes up when the card has at least one packet on it 262 */ 263 #define input_wait(data) acquire_sem_etc(data->ilock ,1, B_CAN_INTERRUPT, 0) 264 #define input_unwait(data, c) release_sem_etc(data->ilock, c, B_DO_NOT_RESCHEDULE) 265 266 267 /* prototypes */ 268 static status_t open_hook(const char *name, uint32 flags, void **cookie); 269 static status_t close_hook(void *); 270 static status_t free_hook(void *); 271 static status_t control_hook(void * cookie,uint32 msg,void *buf,size_t len); 272 static status_t read_hook(void *data, off_t pos, void *buf, size_t *len); 273 static status_t write_hook(void *data, off_t pos, const void *buf, size_t *len); 274 //static int32 etherpci_interrupt(void *data); /* interrupt handler */ 275 //static int32 get_pci_list(pci_info *info[], int32 maxEntries); /* Get pci_info for each device */ 276 //static status_t free_pci_list(pci_info *info[]); /* Free storage used by pci_info list */ 277 //static void dump_packet(const char * msg, unsigned char * buf, uint16 size); /* diagnostic packet trace */ 278 //static status_t enable_addressing(etherpci_private_t *data); /* enable pci io address space for device */ 279 //static int domulti(etherpci_private_t *data,char *addr); 280 281 static device_hooks gDeviceHooks = { 282 open_hook, /* -> open entry point */ 283 close_hook, /* -> close entry point */ 284 free_hook, /* -> free entry point */ 285 control_hook, /* -> control entry point */ 286 read_hook, /* -> read entry point */ 287 write_hook, /* -> write entry point */ 288 NULL, /* -> select entry point */ 289 NULL, /* -> deselect entry point */ 290 NULL, /* -> readv */ 291 NULL /* -> writev */ 292 }; 293 294 295 static int32 296 get_pci_list(pci_info *info[], int32 maxEntries) 297 { 298 int32 i, entries; 299 pci_info *item; 300 301 item = (pci_info *)malloc(sizeof(pci_info)); 302 if (item == NULL) 303 return 0; 304 305 for (i = 0, entries = 0; entries < maxEntries; i++) { 306 if (gPCIModInfo->get_nth_pci_info(i, item) != B_OK) 307 break; 308 309 if ((item->vendor_id == 0x10ec && item->device_id == 0x8029) // RealTek 8029 310 || (item->vendor_id == 0x1106 && item->device_id == 0x0926) // VIA 311 || (item->vendor_id == 0x4a14 && item->device_id == 0x5000) // NetVin 5000 312 || (item->vendor_id == 0x1050 && item->device_id == 0x0940) // ProLAN 313 || (item->vendor_id == 0x11f6 && item->device_id == 0x1401) // Compex 314 || (item->vendor_id == 0x8e2e && item->device_id == 0x3000)) { // KTI 315 /* check if the device really has an IRQ */ 316 if (item->u.h0.interrupt_line == 0 || item->u.h0.interrupt_line == 0xFF) { 317 dprintf(kDevName " found with invalid IRQ - check IRQ assignement"); 318 continue; 319 } 320 321 dprintf(kDevName " found at IRQ %x ", item->u.h0.interrupt_line); 322 info[entries++] = item; 323 item = (pci_info *)malloc(sizeof(pci_info)); 324 if (item == NULL) 325 break; 326 } 327 } 328 info[entries] = NULL; 329 free(item); 330 return entries; 331 } 332 333 334 static status_t 335 free_pci_list(pci_info *info[]) 336 { 337 pci_info *item; 338 int32 i; 339 340 for (i = 0; (item = info[i]) != NULL; i++) { 341 free(item); 342 } 343 return B_OK; 344 } 345 346 347 #if 0 348 /*! How many waiting for io? */ 349 static long 350 io_count(etherpci_private_t *data) 351 { 352 long count; 353 354 get_sem_count(data->iolock, &count); 355 return (count); 356 } 357 358 359 /*! How many waiting for output? */ 360 static long 361 output_count(etherpci_private_t *data) 362 { 363 long count; 364 365 get_sem_count(data->olock, &count); 366 return (count); 367 } 368 #endif 369 370 /* 371 * How many waiting for input? 372 */ 373 static int32 374 input_count(etherpci_private_t *data) 375 { 376 int32 count; 377 378 get_sem_count(data->ilock, &count); 379 return (count); 380 } 381 382 #if STAY_ON_PAGE_0 383 384 #define INTR_LOCK(data, expression) (expression) 385 386 #else /* STAY_ON_PAGE_0 */ 387 388 /* 389 * Spinlock for negotiating access to card with interrupt handler 390 */ 391 #define intr_lock(data) acquire_spinlock(&data->intrlock) 392 #define intr_unlock(data) release_spinlock(&data->intrlock) 393 394 /* 395 * The interrupt handler must lock all calls to the card 396 * This macro is useful for that purpose. 397 */ 398 #define INTR_LOCK(data, expression) (intr_lock(data), (expression), intr_unlock(data)) 399 400 #endif /* STAY_ON_PAGE_0 */ 401 402 403 /* 404 * Calculate various constants 405 * These must be done at runtime, since 3com and ne2000 cards have different 406 * values. 407 */ 408 static void 409 calc_constants(etherpci_private_t *data) 410 { 411 data->EC_VMEM_PAGE = (data->ETHER_BUF_START >> EC_PAGE_SHIFT); 412 data->EC_VMEM_NPAGES = (data->ETHER_BUF_SIZE >> EC_PAGE_SHIFT); 413 414 data->EC_RXBUF_START_PAGE = (data->EC_VMEM_PAGE + 6); 415 data->EC_RXBUF_END_PAGE = (data->EC_VMEM_PAGE + data->EC_VMEM_NPAGES); 416 417 data->EC_RINGSTART = (data->EC_RXBUF_START_PAGE << EC_PAGE_SHIFT); 418 data->EC_RINGSIZE = ((data->EC_VMEM_NPAGES - 6) << EC_PAGE_SHIFT); 419 } 420 421 422 /*! Print an ethernet address */ 423 static void 424 print_address(ether_address_t *addr) 425 { 426 int i; 427 char buf[3 * 6 + 1]; 428 429 for (i = 0; i < 5; i++) { 430 sprintf(&buf[3*i], "%02x:", addr->ebyte[i]); 431 } 432 sprintf(&buf[3*5], "%02x", addr->ebyte[5]); 433 dprintf("%s\n", buf); 434 } 435 436 437 /*! Get the isr register */ 438 static unsigned char 439 getisr(etherpci_private_t *data) 440 { 441 return ether_inb(data, EN0_ISR); 442 } 443 444 445 /*! Set the isr register */ 446 static void 447 setisr(etherpci_private_t *data, unsigned char isr) 448 { 449 ether_outb(data, EN0_ISR, isr); 450 } 451 452 453 /*! Wait for the DMA to complete */ 454 static int 455 wait_for_dma_complete(etherpci_private_t *data, unsigned short addr, 456 unsigned short size) 457 { 458 unsigned short hi, low; 459 unsigned short where; 460 int bogus; 461 462 #define MAXBOGUS 20 463 464 /* 465 * This is the expected way to wait for DMA completion, which 466 * is in fact incorrect. I think ISR_DMADONE gets set too early. 467 */ 468 bogus = 0; 469 while (!(getisr(data) & ISR_DMADONE) && ++bogus < MAXBOGUS) { 470 /* keep waiting */ 471 } 472 if (bogus >= MAXBOGUS) 473 dprintf("Bogus alert: waiting for ISR\n"); 474 475 /* 476 * This is the workaround 477 */ 478 bogus = 0; 479 do { 480 hi = ether_inb(data, EN0_RADDRHI); 481 low = ether_inb(data, EN0_RADDRLO); 482 where = (hi << 8) | low; 483 } while (where < addr + size && ++bogus < MAXBOGUS); 484 485 if (bogus >= MAXBOGUS * 2) { 486 /* 487 * On some cards, the counters will never clear. 488 * So only print this message when debugging. 489 */ 490 dprintf("Bogus alert: waiting for counters to zero\n"); 491 return -1; 492 } 493 494 setisr(data, ISR_DMADONE); 495 ether_outb(data, EN_CCMD, ENC_NODMA); 496 return 0; 497 } 498 499 500 /*! Check the status of the last packet transmitted */ 501 static void 502 check_transmit_status(etherpci_private_t *data) 503 { 504 unsigned char status; 505 506 status = ether_inb(data, EN0_TPSR); 507 if (status & (TSR_ABORTED | TSR_UNDERRUN)) { 508 dprintf("transmit error: %02x\n", status); 509 } 510 #if 0 511 if (data->wints + data->werrs != data->writes) { 512 dprintf("Write interrupts %d, errors %d, transmits %d\n", 513 data->wints, data->werrs, data->writes); 514 } 515 #endif 516 } 517 518 519 static long 520 inrw(etherpci_private_t *data) 521 { 522 return data->inrw; 523 } 524 525 526 static status_t 527 create_sems(etherpci_private_t *data) 528 { 529 data->iolock = create_sem(1, "ethercard io"); 530 if (data->iolock < B_OK) 531 return data->iolock; 532 533 data->olock = create_sem(1, "ethercard output"); 534 if (data->olock < B_OK) { 535 delete_sem(data->iolock); 536 return data->olock; 537 } 538 539 data->ilock = create_sem(0, "ethercard input"); 540 if (data->ilock < B_OK) { 541 delete_sem(data->iolock); 542 delete_sem(data->olock); 543 return data->ilock; 544 } 545 546 return B_OK; 547 } 548 549 550 /*! Get data from the ne2000 card */ 551 static void 552 etherpci_min(etherpci_private_t *data, unsigned char *dst, 553 unsigned src, unsigned len) 554 { 555 unsigned int i; 556 557 if (len & 1) 558 len++; 559 560 ether_outb(data, EN0_RCNTLO, len & 0xff); 561 ether_outb(data, EN0_RCNTHI, len >> 8); 562 ether_outb(data, EN0_RADDRLO, src & 0xff); 563 ether_outb(data, EN0_RADDRHI, src >> 8); 564 ether_outb(data, EN_CCMD, ENC_DMAREAD); 565 566 for (i = 0; i < len; i += 2) { 567 unsigned short word; 568 569 word = ether_inw(data, NE_DATA); 570 #if __i386__ 571 dst[i + 1] = word >> 8; 572 dst[i + 0] = word & 0xff; 573 #else 574 dst[i] = word >> 8; 575 dst[i + 1] = word & 0xff; 576 #endif 577 } 578 wait_for_dma_complete(data, src, len); 579 } 580 581 582 /*! Put data on the ne2000 card */ 583 static void 584 etherpci_mout(etherpci_private_t *data, unsigned dst, 585 const unsigned char *src, unsigned len) 586 { 587 unsigned int i; 588 int tries = 1; 589 590 // This loop is for a bug that showed up with the old ISA 3com cards 591 // that were in the original BeBox. Sometimes the dma status would just 592 // stop on some part of the buffer, never finishing. 593 // If we notice this error, we redo the dma transfer. 594 again: 595 #define MAXTRIES 2 596 if (tries > MAXTRIES) { 597 dprintf("ether_mout : tried %d times, stopping\n", tries); 598 return; 599 } 600 601 if (len & 1) 602 len++; 603 604 ether_outb(data, EN0_RCNTHI, len >> 8); 605 ether_outb(data, EN0_RADDRLO, dst & 0xff); 606 ether_outb(data, EN0_RADDRHI, dst >> 8); 607 608 /* 609 * The 8390 hardware has documented bugs in it related to DMA write. 610 * So, we follow the documentation on how to work around them. 611 */ 612 613 /* 614 * Step 1: You must put a non-zero value in this register. We use 2. 615 */ 616 if ((len & 0xff) == 0) { 617 ether_outb(data, EN0_RCNTLO, 2); 618 } else { 619 ether_outb(data, EN0_RCNTLO, len & 0xff); 620 } 621 622 #if you_want_to_follow_step2_even_though_it_hangs 623 ether_outb(data, EN_CCMD, ENC_DMAREAD); /* Step 2 */ 624 #endif 625 626 ether_outb(data, EN_CCMD, ENC_DMAWRITE); 627 628 for (i = 0; i < len; i += 2) { 629 unsigned short word; 630 631 #if __i386__ 632 word = (src[i + 1] << 8) | src[i + 0]; 633 #else 634 word = (src[i] << 8) | src[i + 1]; 635 #endif 636 ether_outw(data, NE_DATA, word); 637 } 638 639 if ((len & 0xff) == 0) { 640 /* 641 * Write out the two extra bytes 642 */ 643 ether_outw(data, NE_DATA, 0); 644 len += 2; 645 } 646 if (wait_for_dma_complete(data, dst, len) != 0) { 647 tries++; 648 goto again; 649 } 650 //if (tries != 1) { dprintf("wait_for_dma worked after %d tries\n", tries); } 651 } 652 653 654 #if STAY_ON_PAGE_0 655 /*! Zero out the headers in the ring buffer */ 656 static void 657 ringzero(etherpci_private_t *data, unsigned boundary, 658 unsigned next_boundary) 659 { 660 ring_header ring; 661 int i; 662 int pages; 663 unsigned offset; 664 665 ring.count = 0; 666 ring.next_packet = 0; 667 ring.status = 0; 668 669 if (data->boundary < next_boundary) { 670 pages = next_boundary - data->boundary; 671 } else { 672 pages = (data->EC_RINGSIZE >> EC_PAGE_SHIFT) - (data->boundary - next_boundary); 673 } 674 675 for (i = 0; i < pages; i++) { 676 offset = data->boundary << EC_PAGE_SHIFT; 677 etherpci_mout(data, offset, (unsigned char *)&ring, sizeof(ring)); 678 data->boundary++; 679 if (data->boundary >= data->EC_RXBUF_END_PAGE) { 680 data->boundary = data->EC_RXBUF_START_PAGE; 681 } 682 } 683 } 684 #endif /* STAY_ON_PAGE_0 */ 685 686 687 /*! Determine if we have an ne2000 PCI card */ 688 static int 689 probe(etherpci_private_t *data) 690 { 691 unsigned int i; 692 int reg; 693 unsigned char test[EC_PAGE_SIZE]; 694 short waddr[ETHER_ADDR_LEN]; 695 uint8 reg_val; 696 697 data->ETHER_BUF_START = ETHER_BUF_START_NE2000; 698 data->ETHER_BUF_SIZE = ETHER_BUF_SIZE_NE2000; 699 calc_constants(data); 700 701 reg = ether_inb(data, NE_RESET); 702 snooze(2000); 703 ether_outb(data, NE_RESET, reg); 704 snooze(2000); 705 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_STOP | ENC_PAGE0); 706 707 i = 10000; 708 while ( i-- > 0) { 709 reg_val = ether_inb(data, EN0_ISR); 710 if (reg_val & ISR_RESET) break; 711 } 712 if (i < 0) 713 dprintf("reset failed -- ignoring\n"); 714 715 ether_outb(data, EN0_ISR, 0xff); 716 ether_outb(data, EN0_DCFG, DCFG_BM16); 717 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_STOP | ENC_PAGE0); 718 719 snooze(2000); 720 721 reg = ether_inb(data, EN_CCMD); 722 if (reg != (ENC_NODMA|ENC_STOP|ENC_PAGE0)) { 723 dprintf("command register failed: %02x != %02x\n", reg, ENC_NODMA|ENC_STOP); 724 return 0; 725 } 726 727 ether_outb(data, EN0_TXCR, 0); 728 ether_outb(data, EN0_RXCR, ENRXCR_MON); 729 ether_outb(data, EN0_STARTPG, data->EC_RXBUF_START_PAGE); 730 ether_outb(data, EN0_STOPPG, data->EC_RXBUF_END_PAGE); 731 ether_outb(data, EN0_BOUNDARY, data->EC_RXBUF_END_PAGE); 732 ether_outb(data, EN0_IMR, 0); 733 ether_outb(data, EN0_ISR, 0); 734 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_PAGE1 | ENC_STOP); 735 ether_outb(data, EN1_CURPAG, data->EC_RXBUF_START_PAGE); 736 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_PAGE0 | ENC_STOP); 737 738 /* stop chip */ 739 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_PAGE0); 740 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_STOP); 741 742 memset(&waddr[0], 0, sizeof(waddr)); 743 etherpci_min(data, (unsigned char *)&waddr[0], 0, sizeof(waddr)); 744 745 for (i = 0; i < ETHER_ADDR_LEN; i++) { 746 data->myaddr.ebyte[i] = ((unsigned char *)&waddr[0])[2*i]; 747 } 748 749 /* test memory */ 750 for (i = 0; i < sizeof(test); i++) { 751 test[i] = i; 752 } 753 754 etherpci_mout(data, data->ETHER_BUF_START, (unsigned char *)&test[0], sizeof(test)); 755 memset(&test, 0, sizeof(test)); 756 etherpci_min(data, (unsigned char *)&test[0], data->ETHER_BUF_START, sizeof(test)); 757 758 for (i = 0; i < sizeof(test); i++) { 759 if (test[i] != i) { 760 dprintf("memory test failed: %02x %02x\n", i, test[i]); 761 return 0; 762 } 763 } 764 765 dprintf("ne2000 pci ethernet card found - "); 766 print_address(&data->myaddr); 767 return 1; 768 } 769 770 771 /*! Initialize the ethernet card */ 772 static void 773 init(etherpci_private_t *data) 774 { 775 int i; 776 777 #if STAY_ON_PAGE_0 778 /* 779 * Set all the ring headers to zero 780 */ 781 ringzero(data, data->EC_RXBUF_START_PAGE, data->EC_RXBUF_END_PAGE); 782 #endif /* STAY_ON_PAGE_0 */ 783 784 /* initialize data configuration register */ 785 ether_outb(data, EN0_DCFG, DCFG_BM16); 786 787 /* clear remote byte count registers */ 788 ether_outb(data, EN0_RCNTLO, 0x0); 789 ether_outb(data, EN0_RCNTHI, 0x0); 790 791 /* initialize receive configuration register */ 792 ether_outb(data, EN0_RXCR, ENRXCR_BCST); 793 794 /* get into loopback mode */ 795 ether_outb(data, EN0_TXCR, TXCR_LOOPBACK); 796 797 /* set boundary, page start and page stop */ 798 ether_outb(data, EN0_BOUNDARY, data->EC_RXBUF_END_PAGE); 799 data->boundary = data->EC_RXBUF_START_PAGE; 800 ether_outb(data, EN0_STARTPG, data->EC_RXBUF_START_PAGE); 801 ether_outb(data, EN0_STOPPG, data->EC_RXBUF_END_PAGE); 802 803 /* set transmit page start register */ 804 ether_outb(data, EN0_TPSR, data->EC_VMEM_PAGE); 805 806 /* clear interrupt status register */ 807 ether_outb(data, EN0_ISR, 0xff); 808 809 /* initialize interrupt mask register */ 810 ether_outb(data, EN0_IMR, INTS_WE_CARE_ABOUT); 811 812 /* set page 1 */ 813 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_PAGE1); 814 815 /* set physical address */ 816 for (i = 0; i < 6; i++) { 817 ether_outb(data, EN1_PHYS + i, data->myaddr.ebyte[i]); 818 } 819 820 /* set multicast address */ 821 for (i = 0; i < 8; i++) { 822 ether_outb(data, EN1_MULT+i, 0xff); 823 } 824 data->nmulti = 0; 825 826 /* set current pointer */ 827 ether_outb(data, EN1_CURPAG, data->EC_RXBUF_START_PAGE); 828 829 /* start chip */ 830 ether_outb(data, EN_CCMD, ENC_START | ENC_PAGE0 | ENC_NODMA); 831 832 /* initialize transmit configuration register */ 833 ether_outb(data, EN0_TXCR, 0x00); 834 } 835 836 837 /*! Copy data from the card's ring buffer */ 838 static void 839 ringcopy(etherpci_private_t *data, unsigned char *ether_buf, 840 int offset, int len) 841 { 842 int roffset; 843 int rem; 844 845 roffset = offset - data->EC_RINGSTART; 846 rem = data->EC_RINGSIZE - roffset; 847 if (len > rem) { 848 etherpci_min(data, ðer_buf[0], offset, rem); 849 etherpci_min(data, ðer_buf[rem], data->EC_RINGSTART, len - rem); 850 } else { 851 etherpci_min(data, ðer_buf[0], offset, len); 852 } 853 } 854 855 856 /*! 857 Set the boundary register, both on the card and internally 858 NOTE: you cannot make the boundary = current register on the card, 859 so we actually set it one behind. 860 */ 861 static void 862 setboundary(etherpci_private_t *data, unsigned char nextboundary) 863 { 864 if (nextboundary != data->EC_RXBUF_START_PAGE) { 865 ether_outb(data, EN0_BOUNDARY, nextboundary - 1); 866 } else { 867 /* since it's a ring buffer */ 868 ether_outb(data, EN0_BOUNDARY, data->EC_RXBUF_END_PAGE - 1); 869 } 870 data->boundary = nextboundary; 871 } 872 873 874 /*! Start resetting the chip, because of ring overflow */ 875 static int 876 reset(etherpci_private_t *data) 877 { 878 unsigned char cmd; 879 int resend = false; 880 881 cmd = ether_inb(data, EN_CCMD); 882 ether_outb(data, EN_CCMD, ENC_STOP | ENC_NODMA); 883 snooze(10 * 1000); 884 ether_outb(data, EN0_RCNTLO, 0x0); 885 ether_outb(data, EN0_RCNTHI, 0x0); 886 if (cmd & ENC_TRANS) { 887 if(!(getisr(data) & (ISR_TRANSMIT | ISR_TRANSMIT_ERROR))) 888 resend = true; // xmit command issued but ISR shows its not completed 889 } 890 /* get into loopback mode */ 891 ether_outb(data, EN0_TXCR, TXCR_LOOPBACK); 892 ether_outb(data, EN_CCMD, ENC_START | ENC_PAGE0 | ENC_NODMA); 893 return (resend); 894 } 895 896 897 /*! finish the reset */ 898 static void 899 finish_reset(etherpci_private_t *data, int resend) 900 { 901 setisr(data, ISR_OVERWRITE); 902 ether_outb(data, EN0_TXCR, 0x00); 903 904 if (resend) { 905 // dprintf("Xmit CMD resent\n"); 906 ether_outb(data, EN_CCMD, ENC_START | ENC_PAGE0 | ENC_NODMA | ENC_TRANS); 907 } 908 } 909 910 911 /*! Handle ethernet interrupts */ 912 static int32 913 etherpci_interrupt(void *_data) 914 { 915 etherpci_private_t *data = (etherpci_private_t *) _data; 916 unsigned char isr; 917 int wakeup_reader = 0; 918 int wakeup_writer = 0; 919 int32 handled = B_UNHANDLED_INTERRUPT; 920 data->ints++; 921 922 ETHER_DEBUG(INTERRUPT, data->debug, "ENTR isr=%x & %x?\n",getisr(data), INTS_WE_CARE_ABOUT); 923 for (INTR_LOCK(data, isr = getisr(data)); 924 isr & INTS_WE_CARE_ABOUT; 925 INTR_LOCK(data, isr = getisr(data))) { 926 if (isr & ISR_RECEIVE) { 927 data->rints++; 928 wakeup_reader++; 929 INTR_LOCK(data, setisr(data, ISR_RECEIVE)); 930 handled = B_HANDLED_INTERRUPT; 931 continue; 932 } 933 if (isr & ISR_TRANSMIT_ERROR) { 934 data->werrs++; 935 INTR_LOCK(data, setisr(data, ISR_TRANSMIT_ERROR)); 936 wakeup_writer++; 937 handled = B_HANDLED_INTERRUPT; 938 continue; 939 } 940 if (isr & ISR_TRANSMIT) { 941 data->wints++; 942 INTR_LOCK(data, setisr(data, ISR_TRANSMIT)); 943 wakeup_writer++; 944 handled = B_HANDLED_INTERRUPT; 945 continue; 946 } 947 if (isr & ISR_RECEIVE_ERROR) { 948 uint32 err_count; 949 err_count = ether_inb(data, EN0_CNTR0); data->frame_errs += err_count; 950 err_count = ether_inb(data, EN0_CNTR1); data->crc_errs += err_count; 951 err_count = ether_inb(data, EN0_CNTR2); data->frames_lost += err_count; 952 953 isr &= ~ISR_RECEIVE_ERROR; 954 INTR_LOCK(data, setisr(data, ISR_RECEIVE_ERROR)); 955 handled = B_HANDLED_INTERRUPT; 956 } 957 if (isr & ISR_DMADONE) { 958 isr &= ~ISR_DMADONE; /* handled elsewhere */ 959 handled = B_HANDLED_INTERRUPT; 960 } 961 if (isr & ISR_OVERWRITE) { 962 isr &= ~ISR_OVERWRITE; /* handled elsewhere */ 963 handled = B_HANDLED_INTERRUPT; 964 } 965 966 if (isr & ISR_COUNTER) { 967 isr &= ~ISR_COUNTER; /* handled here */ 968 // dprintf("Clearing Stats Cntr\n"); 969 INTR_LOCK(data, setisr(data, ISR_COUNTER)); 970 handled = B_HANDLED_INTERRUPT; 971 } 972 973 if (isr) { 974 /* 975 * If any other interrupts, just clear them (hmmm....) 976 * ??? This doesn't seem right - HB 977 */ 978 // ddprintf("ISR=%x rdr=%x wtr=%x io=%x inrw=%x nonblk=%x\n", 979 // isr,input_count(data), output_count(data),io_count(data), 980 // data->inrw,data->nonblocking); 981 INTR_LOCK(data, setisr(data, isr)); 982 data->interrs++; 983 } 984 } 985 if (wakeup_reader) { 986 input_unwait(data, 1); 987 } 988 if (wakeup_writer) { 989 output_unwait(data, 1); 990 } 991 992 return handled; 993 } 994 995 996 /*! Check to see if there are any new errors */ 997 static void 998 check_errors(etherpci_private_t *data) 999 { 1000 #define DOIT(stat, message) \ 1001 if (stat > stat##_last) { \ 1002 stat##_last = stat; \ 1003 dprintf(message, stat##_last); \ 1004 } 1005 1006 DOIT(data->rerrs, "Receive errors now %d\n"); 1007 DOIT(data->werrs, "Transmit errors now %d\n"); 1008 DOIT(data->interrs, "Interrupt errors now %d\n"); 1009 DOIT(data->frames_lost, "Frames lost now %d\n"); 1010 #undef DOIT 1011 #if 0 1012 /* 1013 * these are normal errors because collisions are normal 1014 * so don't make a big deal about them. 1015 */ 1016 DOIT(data->frame_errs, "Frame alignment errors now %d\n"); 1017 DOIT(data->crc_errs, "CRC errors now %d\n"); 1018 #endif 1019 } 1020 1021 1022 /*! Find out if there are any more packets on the card */ 1023 static int 1024 more_packets(etherpci_private_t *data, int didreset) 1025 { 1026 #if STAY_ON_PAGE_0 1027 unsigned offset; 1028 ring_header ring; 1029 1030 offset = data->boundary << EC_PAGE_SHIFT; 1031 etherpci_min(data, (unsigned char *)&ring, offset, sizeof(ring)); 1032 return ring.status && ring.next_packet && ring.count; 1033 1034 #else /* STAY_ON_PAGE_0 */ 1035 1036 cpu_status ps; 1037 unsigned char cur; 1038 1039 /* 1040 * First, get the current registe 1041 */ 1042 ps = disable_interrupts(); 1043 intr_lock(data); 1044 ether_outb(data, EN_CCMD, ENC_PAGE1); 1045 cur = ether_inb(data, EN1_CURPAG); 1046 ether_outb(data, EN_CCMD, ENC_PAGE0); 1047 intr_unlock(data); 1048 restore_interrupts(ps); 1049 1050 /* 1051 * Then return the result 1052 * Must use didreset since cur == boundary in 1053 * an overflow situation. 1054 */ 1055 return didreset || cur != data->boundary; 1056 #endif /* STAY_ON_PAGE_0 */ 1057 } 1058 1059 1060 /*! Copy a packet from the ethernet card */ 1061 static int 1062 copy_packet(etherpci_private_t *data, unsigned char *ether_buf, 1063 int buflen) 1064 { 1065 ring_header ring; 1066 unsigned offset; 1067 int len; 1068 int rlen; 1069 int ether_len = 0; 1070 int didreset = 0; 1071 int resend = 0; 1072 1073 io_lock(data); 1074 check_errors(data); 1075 1076 /* 1077 * Check for overwrite error first 1078 */ 1079 if (getisr(data) & ISR_OVERWRITE) { 1080 // dprintf("starting ether reset!\n"); 1081 data->resets++; 1082 resend = reset(data); 1083 didreset++; 1084 } 1085 1086 if (more_packets(data, didreset)) do { 1087 /* 1088 * Read packet ring header 1089 */ 1090 offset = data->boundary << EC_PAGE_SHIFT; 1091 etherpci_min(data, (unsigned char *)&ring, offset, sizeof(ring)); 1092 1093 len = swapshort(ring.count); 1094 1095 if (!(ring.status & RSR_INTACT)) { 1096 dprintf("packet not intact! (%02x,%u,%02x) (%d)\n", 1097 ring.status, ring.next_packet, ring.count, data->boundary); 1098 1099 /* discard bad packet */ 1100 ether_len = 0; setboundary(data, ring.next_packet); 1101 break; 1102 } 1103 1104 if (ring.next_packet < data->EC_RXBUF_START_PAGE 1105 || ring.next_packet >= data->EC_RXBUF_END_PAGE) { 1106 dprintf("etherpci_read: bad next packet! (%02x,%u,%02x) (%d)\n", 1107 ring.status, ring.next_packet, ring.count, data->boundary); 1108 1109 data->rerrs++; 1110 /* discard bad packet */ 1111 ether_len = 0; setboundary(data, ring.next_packet); 1112 break; 1113 } 1114 1115 len = swapshort(ring.count); 1116 rlen = len - 4; 1117 if (rlen < ETHER_MIN_SIZE || rlen > ETHER_MAX_SIZE) { 1118 dprintf("etherpci_read: bad length! (%02x,%u,%02x) (%d)\n", 1119 ring.status, ring.next_packet, ring.count, data->boundary); 1120 1121 data->rerrs++; 1122 /* discard bad packet */ 1123 ether_len = 0; setboundary(data, ring.next_packet); 1124 break; 1125 } 1126 1127 if (rlen > buflen) 1128 rlen = buflen; 1129 1130 ringcopy(data, ether_buf, offset + 4, rlen); 1131 1132 #if STAY_ON_PAGE_0 1133 ringzero(data, data->boundary, ring.next_packet); 1134 #endif /* STAY_ON_PAGE_0 */ 1135 1136 ether_len = rlen; 1137 setboundary(data, ring.next_packet); 1138 data->reads++; 1139 } while (0); 1140 1141 if (didreset) { 1142 dprintf("finishing reset!\n"); 1143 finish_reset(data, resend); 1144 } 1145 1146 if (input_count(data) <= 0 && more_packets(data, didreset)) { 1147 /* 1148 * Looks like there is another packet 1149 * So, make sure they get woken up 1150 */ 1151 input_unwait(data, 1); 1152 } 1153 1154 io_unlock(data); 1155 return ether_len; 1156 } 1157 1158 1159 /*! Checks if the received packet is really for us */ 1160 static int 1161 my_packet(etherpci_private_t *data, char *addr) 1162 { 1163 unsigned int i; 1164 const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 1165 1166 if (memcmp(addr, &data->myaddr, sizeof(data->myaddr)) == 0 1167 || memcmp(addr, broadcast, sizeof(broadcast)) == 0) 1168 return 1; 1169 1170 for (i = 0; i < data->nmulti; i++) { 1171 if (memcmp(addr, &data->multi[i], sizeof(data->multi[i])) == 0) 1172 return 1; 1173 } 1174 1175 return 0; 1176 } 1177 1178 1179 static status_t 1180 enable_addressing(etherpci_private_t *data) 1181 { 1182 unsigned char cmd; 1183 1184 #if __i386__ 1185 data->reg_base = data->pciInfo->u.h0.base_registers[0]; 1186 #else 1187 uint32 base, size, offset; 1188 base = data->pciInfo->u.h0.base_registers[0]; 1189 size = data->pciInfo->u.h0.base_register_sizes[0]; 1190 1191 /* Round down to nearest page boundary */ 1192 base = base & ~(B_PAGE_SIZE-1); 1193 1194 /* Adjust the size */ 1195 offset = data->pciInfo->u.h0.base_registers[0] - base; 1196 size += offset; 1197 size = (size +(B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1); 1198 1199 dprintf(kDevName ": PCI base=%x size=%x offset=%x\n", base, size, offset); 1200 1201 if ((data->ioarea = map_physical_memory(kDevName "_regs", base, size, 1202 B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, 1203 (void **)&data->reg_base)) < 0) { 1204 return B_ERROR; 1205 } 1206 1207 data->reg_base = data->reg_base + offset; 1208 1209 #endif 1210 dprintf(kDevName ": reg_base=%" B_PRIx32 "\n", data->reg_base); 1211 1212 /* enable pci address access */ 1213 cmd = (gPCIModInfo->read_pci_config)(data->pciInfo->bus, data->pciInfo->device, data->pciInfo->function, PCI_command, 2); 1214 (gPCIModInfo->write_pci_config)(data->pciInfo->bus, data->pciInfo->device, data->pciInfo->function, PCI_command, 2, cmd | PCI_command_io); 1215 1216 return B_OK; 1217 } 1218 1219 1220 static int 1221 domulti(etherpci_private_t *data, char *addr) 1222 { 1223 int i; 1224 int nmulti = data->nmulti; 1225 1226 if (nmulti == MAX_MULTI) 1227 return B_ERROR; 1228 1229 for (i = 0; i < nmulti; i++) { 1230 if (memcmp(&data->multi[i], addr, sizeof(data->multi[i])) == 0) { 1231 break; 1232 } 1233 } 1234 1235 if (i == nmulti) { 1236 /* 1237 * Only copy if it isn't there already 1238 */ 1239 memcpy(&data->multi[i], addr, sizeof(data->multi[i])); 1240 data->nmulti++; 1241 } 1242 if (data->nmulti == 1) { 1243 dprintf("Enabling multicast\n"); 1244 ether_outb(data, EN0_RXCR, ENRXCR_BCST | ENRXCR_MCST); 1245 } 1246 1247 return B_NO_ERROR; 1248 } 1249 1250 1251 /*! 1252 Serial Debugger command 1253 Connect a terminal emulator to the serial port at 19.2 8-1-None 1254 Press the keys ( alt-sysreq on Intel) or (Clover-leaf Power on Mac ) to enter the debugger 1255 At the kdebug> prompt enter "etherpci arg...", 1256 for example "etherpci R" to enable a received packet trace. 1257 */ 1258 #if DEBUGGER_COMMAND 1259 static int 1260 etherpci(int argc, char **argv) { 1261 uint16 i,j; 1262 const char * usage = "usage: etherpci { Function_calls | PCI_IO | Stats | Rx_trace | Tx_trace }\n"; 1263 1264 1265 if (argc < 2) { 1266 kprintf("%s",usage); return 0; 1267 } 1268 1269 for (i= argc, j= 1; i > 1; i--, j++) { 1270 switch (*argv[j]) { 1271 case 'F': 1272 case 'f': 1273 gdev->debug ^= FUNCTION; 1274 if (gdev->debug & FUNCTION) 1275 kprintf("Function() call trace Enabled\n"); 1276 else 1277 kprintf("Function() call trace Disabled\n"); 1278 break; 1279 case 'N': 1280 case 'n': 1281 gdev->debug ^= SEQ; 1282 if (gdev->debug & SEQ) 1283 kprintf("Sequence numbers packet trace Enabled\n"); 1284 else 1285 kprintf("Sequence numbers packet trace Disabled\n"); 1286 break; 1287 case 'R': 1288 case 'r': 1289 gdev->debug ^= RX; 1290 if (gdev->debug & RX) 1291 kprintf("Receive packet trace Enabled\n"); 1292 else 1293 kprintf("Receive packet trace Disabled\n"); 1294 break; 1295 case 'T': 1296 case 't': 1297 gdev->debug ^= TX; 1298 if (gdev->debug & TX) 1299 kprintf("Transmit packet trace Enabled\n"); 1300 else 1301 kprintf("Transmit packet trace Disabled\n"); 1302 break; 1303 case 'S': 1304 case 's': 1305 kprintf(kDevName " statistics\n"); 1306 kprintf("rx_ints %d, tx_ints %d\n", gdev->rints, gdev->wints); 1307 kprintf("resets %d \n", gdev->resets); 1308 kprintf("crc_errs %d, frame_errs %d, frames_lost %d\n", gdev->crc_errs, gdev->frame_errs, gdev->frames_lost); 1309 break; 1310 case 'P': 1311 case 'p': 1312 gdev->debug ^= PCI_IO; 1313 if (gdev->debug & PCI_IO) 1314 kprintf("PCI IO trace Enabled\n"); 1315 else 1316 kprintf("PCI IO trace Disabled\n"); 1317 break; 1318 default: 1319 kprintf("%s",usage); 1320 return 0; 1321 } 1322 } 1323 1324 return 0; 1325 } 1326 #endif /* DEBUGGER_COMMAND */ 1327 1328 1329 static void 1330 dump_packet(const char * msg, unsigned char * buf, uint16 size) 1331 { 1332 uint16 j; 1333 1334 dprintf("%s dumping %p size %u \n", msg, buf, size); 1335 for (j = 0; j < size; j++) { 1336 if ((j & 0xF) == 0) 1337 dprintf("\n"); 1338 dprintf("%2.2x ", buf[j]); 1339 } 1340 } 1341 1342 1343 // #pragma mark - Driver Entry Points 1344 1345 1346 status_t 1347 init_hardware(void) 1348 { 1349 return B_NO_ERROR; 1350 } 1351 1352 1353 status_t 1354 init_driver(void) 1355 { 1356 status_t status; 1357 int32 entries; 1358 char devName[64]; 1359 int32 i; 1360 1361 dprintf(kDevName ": init_driver "); 1362 1363 if ((status = get_module( B_PCI_MODULE_NAME, (module_info **)&gPCIModInfo )) != B_OK) { 1364 dprintf(kDevName " Get module failed! %s\n", strerror(status )); 1365 return status; 1366 } 1367 1368 /* Find Lan cards*/ 1369 if ((entries = get_pci_list(gDevList, MAX_CARDS )) == 0) { 1370 dprintf("init_driver: " kDevName " not found\n"); 1371 free_pci_list(gDevList); 1372 put_module(B_PCI_MODULE_NAME ); 1373 return B_ERROR; 1374 } 1375 dprintf("\n"); 1376 1377 /* Create device name list*/ 1378 for (i=0; i<entries; i++ ) 1379 { 1380 sprintf(devName, "%s%" B_PRId32, kDevDir, i ); 1381 gDevNameList[i] = (char *)malloc(strlen(devName)+1); 1382 strcpy(gDevNameList[i], devName); 1383 } 1384 gDevNameList[i] = NULL; 1385 1386 return B_OK; 1387 } 1388 1389 1390 void 1391 uninit_driver(void) 1392 { 1393 void *item; 1394 int32 i; 1395 1396 /*Free device name list*/ 1397 for (i = 0; (item = gDevNameList[i]) != NULL; i++) { 1398 free(item); 1399 } 1400 1401 /*Free device list*/ 1402 free_pci_list(gDevList); 1403 put_module(B_PCI_MODULE_NAME); 1404 } 1405 1406 1407 device_hooks * 1408 find_device(const char *name) 1409 { 1410 int32 i; 1411 char *item; 1412 1413 /* Find device name */ 1414 for (i = 0; (item = gDevNameList[i]) != NULL; i++) { 1415 if (!strcmp(name, item)) 1416 return &gDeviceHooks; 1417 } 1418 1419 return NULL; 1420 } 1421 1422 1423 const char** 1424 publish_devices(void) 1425 { 1426 dprintf(kDevName ": publish_devices()\n"); 1427 return (const char **)gDevNameList; 1428 } 1429 1430 1431 // #pragma mark Device Hooks 1432 1433 1434 /*! Implements the read() system call to the ethernet driver */ 1435 static status_t 1436 read_hook(void *_data, off_t pos, void *buf, size_t *len) 1437 { 1438 etherpci_private_t *data = (etherpci_private_t *) _data; 1439 ulong buflen; 1440 int packet_len; 1441 1442 buflen = *len; 1443 atomic_add(&data->inrw, 1); 1444 if (data->interrupted) { 1445 atomic_add(&data->inrw, -1); 1446 return B_INTERRUPTED; 1447 } 1448 1449 do { 1450 if (!data->nonblocking) { 1451 input_wait(data); 1452 } 1453 if (data->interrupted) { 1454 atomic_add(&data->inrw, -1); 1455 return B_INTERRUPTED; 1456 } 1457 packet_len = copy_packet(data, (unsigned char *)buf, buflen); 1458 if ((packet_len) && (data->debug & RX)) { 1459 dump_packet("RX:" ,buf, packet_len); 1460 } 1461 } while (!data->nonblocking && packet_len == 0 && !my_packet(data, buf)); 1462 1463 atomic_add(&data->inrw, -1); 1464 *len = packet_len; 1465 return 0; 1466 } 1467 1468 1469 static status_t 1470 open_hook(const char *name, uint32 flags, void **cookie) 1471 { 1472 int32 devID; 1473 int32 mask; 1474 status_t status; 1475 char *devName; 1476 etherpci_private_t *data; 1477 1478 /* Find device name*/ 1479 for (devID = 0; (devName = gDevNameList[devID]); devID++) { 1480 if (strcmp(name, devName) == 0) 1481 break; 1482 } 1483 if (!devName) 1484 return EINVAL; 1485 1486 /* Check if the device is busy and set in-use flag if not */ 1487 mask = 1 << devID; 1488 if (atomic_or(&gOpenMask, mask) &mask) 1489 return B_BUSY; 1490 1491 /* Allocate storage for the cookie*/ 1492 if (!(*cookie = data = (etherpci_private_t *)malloc(sizeof(etherpci_private_t)))) { 1493 status = B_NO_MEMORY; 1494 goto err0; 1495 } 1496 memset(data, 0, sizeof(etherpci_private_t)); 1497 1498 /* Setup the cookie */ 1499 data->pciInfo = gDevList[devID]; 1500 data->devID = devID; 1501 data->interrupted = 0; 1502 data->inrw = 0; 1503 data->nonblocking = 0; 1504 1505 data->debug = DEFAULT_DEBUG_FLAGS; 1506 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": open %s dev=%p\n", name, data); 1507 1508 #if DEBUGGER_COMMAND 1509 gdev = data; 1510 add_debugger_command (kDevName, etherpci, "Ethernet driver Info"); 1511 #endif 1512 1513 /* enable access to the cards address space */ 1514 if ((status = enable_addressing(data)) != B_OK) 1515 goto err1; 1516 1517 if (!probe(data)) { 1518 dprintf(kDevName ": probe failed\n"); 1519 goto err1; 1520 } 1521 1522 if (create_sems(data) != B_OK) 1523 goto err2; 1524 1525 /* Setup interrupts */ 1526 install_io_interrupt_handler( data->pciInfo->u.h0.interrupt_line, etherpci_interrupt, *cookie, 0 ); 1527 1528 dprintf("Interrupts installed at %x\n", data->pciInfo->u.h0.interrupt_line); 1529 /* Init Device */ 1530 init(data); 1531 1532 return B_NO_ERROR; 1533 1534 err2: 1535 #if !__i386__ 1536 delete_area(data->ioarea); 1537 #endif 1538 err1: 1539 #if DEBUGGER_COMMAND 1540 remove_debugger_command (kDevName, etherpci); 1541 #endif 1542 free(data); 1543 1544 err0: 1545 atomic_and(&gOpenMask, ~mask); 1546 dprintf(kDevName ": open failed!\n"); 1547 return B_ERROR; 1548 } 1549 1550 1551 static status_t 1552 close_hook(void *_data) 1553 { 1554 etherpci_private_t *data = (etherpci_private_t *)_data; 1555 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": close dev=%p\n", data); 1556 1557 /* 1558 * Force pending reads and writes to terminate 1559 */ 1560 io_lock(data); 1561 data->interrupted = 1; 1562 input_unwait(data, 1); 1563 output_unwait(data, 1); 1564 io_unlock(data); 1565 while (inrw(data)) { 1566 snooze(1000000); 1567 dprintf("ether: still waiting for read/write to finish\n"); 1568 } 1569 1570 /* 1571 * Stop the chip 1572 */ 1573 ether_outb(data, EN_CCMD, ENC_STOP); 1574 snooze(2000); 1575 1576 /* 1577 * And clean up 1578 */ 1579 remove_io_interrupt_handler(data->pciInfo->u.h0.interrupt_line, etherpci_interrupt, data); 1580 delete_sem(data->iolock); 1581 delete_sem(data->ilock); 1582 delete_sem(data->olock); 1583 1584 /* 1585 * Reset all the statistics 1586 */ 1587 data->ints = 0; 1588 data->rints = 0; 1589 data->rerrs = 0; 1590 data->wints = 0; 1591 data->werrs = 0; 1592 data->reads = 0; 1593 data->writes = 0; 1594 data->interrs = 0; 1595 data->resets = 0; 1596 data->frame_errs = 0; 1597 data->crc_errs = 0; 1598 data->frames_lost = 0; 1599 1600 data->rerrs_last = 0; 1601 data->werrs_last = 0; 1602 data->interrs_last = 0; 1603 data->frame_errs_last = 0; 1604 data->crc_errs_last = 0; 1605 data->frames_lost_last = 0; 1606 1607 data->chip_rx_frame_errors = 0; 1608 data->chip_rx_crc_errors = 0; 1609 data->chip_rx_missed_errors = 0; 1610 1611 #if DEBUGGER_COMMAND 1612 remove_debugger_command (kDevName, etherpci); 1613 #endif 1614 1615 return B_OK; 1616 } 1617 1618 1619 static status_t 1620 free_hook(void *_data) 1621 { 1622 etherpci_private_t *data = (etherpci_private_t *)_data; 1623 int32 mask; 1624 1625 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": free dev=%p\n", data); 1626 1627 #if !__i386__ 1628 delete_area(data->ioarea); 1629 #endif 1630 1631 // make sure the device can be reopened again 1632 mask = 1L << data->devID; 1633 atomic_and(&gOpenMask, ~mask); 1634 1635 free(data); 1636 return B_OK; 1637 } 1638 1639 1640 static status_t 1641 write_hook(void *_data, off_t pos, const void *buf, size_t *len) 1642 { 1643 etherpci_private_t *data = (etherpci_private_t *) _data; 1644 ulong buflen; 1645 int status; 1646 1647 buflen = *len; 1648 atomic_add(&data->inrw, 1); 1649 if (data->interrupted) { 1650 atomic_add(&data->inrw, -1); 1651 return B_INTERRUPTED; 1652 } 1653 /* 1654 * Wait for somebody else (if any) to finish transmitting 1655 */ 1656 status = output_wait(data, ETHER_TRANSMIT_TIMEOUT); 1657 if (status < B_NO_ERROR || data->interrupted) { 1658 atomic_add(&data->inrw, -1); 1659 return status; 1660 } 1661 1662 io_lock(data); 1663 check_errors(data); 1664 1665 if (data->writes > 0) 1666 check_transmit_status(data); 1667 1668 etherpci_mout(data, data->ETHER_BUF_START, (const unsigned char *)buf, buflen); 1669 if (buflen < ETHER_MIN_SIZE) { 1670 /* 1671 * Round up to ETHER_MIN_SIZE 1672 */ 1673 buflen = ETHER_MIN_SIZE; 1674 } 1675 ether_outb(data, EN0_TCNTLO, (char)(buflen & 0xff)); 1676 ether_outb(data, EN0_TCNTHI, (char)(buflen >> 8)); 1677 ether_outb(data, EN_CCMD, ENC_NODMA | ENC_TRANS); 1678 data->writes++; 1679 io_unlock(data); 1680 atomic_add(&data->inrw, -1); 1681 *len = buflen; 1682 1683 if (data->debug & TX) 1684 dump_packet("TX:",(unsigned char *) buf, buflen); 1685 1686 return 0; 1687 } 1688 1689 1690 /*! Standard driver control function */ 1691 static status_t 1692 control_hook(void *_data, uint32 msg, void *buf, size_t len) 1693 { 1694 etherpci_private_t *data = (etherpci_private_t *) _data; 1695 1696 switch (msg) { 1697 case ETHER_INIT: 1698 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": control: ETHER_INIT \n"); 1699 return B_OK; 1700 1701 case ETHER_GETADDR: 1702 if (data == NULL) 1703 return B_ERROR; 1704 1705 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": control: GET_ADDR \n"); 1706 memcpy(buf, &data->myaddr, sizeof(data->myaddr)); 1707 return B_OK; 1708 1709 case ETHER_NONBLOCK: 1710 if (data == NULL) 1711 return B_ERROR; 1712 1713 memcpy(&data->nonblocking, buf, sizeof(data->nonblocking)); 1714 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": control: NON_BLOCK %x\n", data->nonblocking); 1715 return B_OK; 1716 1717 case ETHER_ADDMULTI: 1718 ETHER_DEBUG(FUNCTION, data->debug, kDevName ": control: DO_MULTI\n"); 1719 return domulti(data, (char *)buf); 1720 } 1721 1722 return B_ERROR; 1723 } 1724 1725