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
get_pci_list(pci_info * info[],int32 maxEntries)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
free_pci_list(pci_info * info[])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
input_count(etherpci_private_t * data)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
calc_constants(etherpci_private_t * data)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
print_address(ether_address_t * addr)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
getisr(etherpci_private_t * data)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
setisr(etherpci_private_t * data,unsigned char isr)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
wait_for_dma_complete(etherpci_private_t * data,unsigned short addr,unsigned short size)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
check_transmit_status(etherpci_private_t * data)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
inrw(etherpci_private_t * data)520 inrw(etherpci_private_t *data)
521 {
522 return data->inrw;
523 }
524
525
526 static status_t
create_sems(etherpci_private_t * data)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
etherpci_min(etherpci_private_t * data,unsigned char * dst,unsigned src,unsigned len)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
etherpci_mout(etherpci_private_t * data,unsigned dst,const unsigned char * src,unsigned len)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
ringzero(etherpci_private_t * data,unsigned boundary,unsigned next_boundary)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
probe(etherpci_private_t * data)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
init(etherpci_private_t * data)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
ringcopy(etherpci_private_t * data,unsigned char * ether_buf,int offset,int len)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
setboundary(etherpci_private_t * data,unsigned char nextboundary)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
reset(etherpci_private_t * data)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
finish_reset(etherpci_private_t * data,int resend)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
etherpci_interrupt(void * _data)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
check_errors(etherpci_private_t * data)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
more_packets(etherpci_private_t * data,int didreset)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
copy_packet(etherpci_private_t * data,unsigned char * ether_buf,int buflen)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
my_packet(etherpci_private_t * data,char * addr)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
enable_addressing(etherpci_private_t * data)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
domulti(etherpci_private_t * data,char * addr)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
etherpci(int argc,char ** argv)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
dump_packet(const char * msg,unsigned char * buf,uint16 size)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
init_hardware(void)1347 init_hardware(void)
1348 {
1349 return B_NO_ERROR;
1350 }
1351
1352
1353 status_t
init_driver(void)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
uninit_driver(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 *
find_device(const char * name)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**
publish_devices(void)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
read_hook(void * _data,off_t pos,void * buf,size_t * len)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
open_hook(const char * name,uint32 flags,void ** cookie)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
close_hook(void * _data)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
free_hook(void * _data)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
write_hook(void * _data,off_t pos,const void * buf,size_t * len)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
control_hook(void * _data,uint32 msg,void * buf,size_t len)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