xref: /haiku/src/add-ons/kernel/drivers/network/ether/etherpci/etherpci.c (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
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, &ether_buf[0], offset, rem);
849 		etherpci_min(data, &ether_buf[rem], data->EC_RINGSTART, len - rem);
850 	} else {
851 		etherpci_min(data, &ether_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