xref: /minix/minix/drivers/net/fxp/fxp.c (revision ef8d499e)
1 /*
2  * fxp.c
3  *
4  * This file contains an ethernet device driver for Intel 82557, 82558,
5  * 82559, 82550, and 82562 fast ethernet controllers.
6  *
7  * Created:	Nov 2004 by Philip Homburg <philip@f-mnx.phicoh.com>
8  */
9 
10 #include <minix/drivers.h>
11 #include <minix/netdriver.h>
12 
13 #include <machine/pci.h>
14 #include <minix/ds.h>
15 #include <assert.h>
16 
17 #include "fxp.h"
18 #include "mii.h"
19 
20 /* Number of receive buffers */
21 #define N_RX_BUF	40
22 
23 /* Number of transmit buffers */
24 #define N_TX_BUF	4
25 
26 /* Configuration */
27 #define FXP_ENVVAR	"FXPETH"
28 
29 typedef int irq_hook_t;
30 
31 static union tmpbuf
32 {
33 	char pad[4096];
34 	struct cbl_conf cc;
35 	struct ias ias;
36 } *tmpbufp;
37 
38 typedef struct fxp
39 {
40 	port_t fxp_base_port;
41 	int fxp_got_int;
42 	int fxp_send_int;
43 	int fxp_irq;
44 	int fxp_type;			/* What kind of hardware */
45 	int fxp_ms_regs;		/* Master/slave registers */
46 	int fxp_ee_addrlen;		/* #EEPROM address bits */
47 	int fxp_tx_alive;
48 	int fxp_need_reset;
49 
50 	/* Rx */
51 	int fxp_rx_nbuf;
52 	int fxp_rx_bufsize;
53 	struct rfd *fxp_rx_buf;
54 	phys_bytes fxp_rx_busaddr;
55 	int fxp_rx_head;
56 	int fxp_rx_need_restart;
57 	int fxp_need_conf;		/* Re-configure after draining send
58 					 * queue
59 					 */
60 
61 	/* Tx */
62 	int fxp_tx_nbuf;
63 	int fxp_tx_bufsize;
64 	struct tx *fxp_tx_buf;
65 	phys_bytes fxp_tx_busaddr;
66 	int fxp_tx_idle;
67 	int fxp_tx_head;
68 	int fxp_tx_tail;
69 	int fxp_tx_threshold;
70 
71 	/* Link status */
72 	int fxp_report_link;
73 	int fxp_link_up;
74 	u16_t fxp_mii_scr;
75 
76 	irq_hook_t fxp_hook;
77 	struct sc fxp_stat;
78 	u8_t fxp_conf_bytes[CC_BYTES_NR];
79 } fxp_t;
80 
81 /* fxp_type */
82 #define FT_UNKNOWN	0x0
83 #define FT_82557	0x1
84 #define FT_82558A	0x2
85 #define FT_82559	0x4
86 #define FT_82801	0x8
87 
88 static fxp_t *fxp_state;
89 
90 #define fxp_inb(port, offset)	(do_inb((port) + (offset)))
91 #define fxp_inl(port, offset)	(do_inl((port) + (offset)))
92 #define fxp_outb(port, offset, value)	(do_outb((port) + (offset), (value)))
93 #define fxp_outl(port, offset, value)	(do_outl((port) + (offset), (value)))
94 
95 static int fxp_init(unsigned int instance, netdriver_addr_t *addr,
96 	uint32_t *caps, unsigned int *ticks);
97 static void fxp_intr(unsigned int __unused mask);
98 static void fxp_stop(void);
99 static int fxp_probe(fxp_t *fp, int skip);
100 static void fxp_conf_hw(fxp_t *fp);
101 static void fxp_init_hw(fxp_t *fp, netdriver_addr_t *addr,
102 	unsigned int instance);
103 static void fxp_init_buf(fxp_t *fp);
104 static void fxp_reset_hw(fxp_t *fp);
105 static void fxp_confaddr(fxp_t *fp, netdriver_addr_t *addr,
106 	unsigned int instance);
107 static void fxp_set_mode(unsigned int mode, const netdriver_addr_t *mcast_list,
108 	unsigned int mcast_count);
109 static int fxp_send(struct netdriver_data *data, size_t size);
110 static ssize_t fxp_recv(struct netdriver_data *data, size_t max);
111 static void fxp_do_conf(fxp_t *fp);
112 static void fxp_cu_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int
113 	check_idle);
114 static void fxp_ru_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int
115 	check_idle);
116 static void fxp_restart_ru(fxp_t *fp);
117 static void fxp_handler(fxp_t *fp);
118 static void fxp_check_ints(fxp_t *fp);
119 static void fxp_tick(void);
120 static int fxp_link_changed(fxp_t *fp);
121 static unsigned int fxp_get_link(uint32_t *media);
122 static void fxp_report_link(fxp_t *fp);
123 static u16_t eeprom_read(fxp_t *fp, int reg);
124 static void eeprom_addrsize(fxp_t *fp);
125 static u16_t mii_read(fxp_t *fp, int reg);
126 static u8_t do_inb(port_t port);
127 static u32_t do_inl(port_t port);
128 static void do_outb(port_t port, u8_t v);
129 static void do_outl(port_t port, u32_t v);
130 static void tell_iommu(vir_bytes start, size_t size, int pci_bus, int
131 	pci_dev, int pci_func);
132 
133 static const struct netdriver fxp_table = {
134 	.ndr_name	= "fxp",
135 	.ndr_init	= fxp_init,
136 	.ndr_stop	= fxp_stop,
137 	.ndr_set_mode	= fxp_set_mode,
138 	.ndr_recv	= fxp_recv,
139 	.ndr_send	= fxp_send,
140 	.ndr_get_link	= fxp_get_link,
141 	.ndr_intr	= fxp_intr,
142 	.ndr_tick	= fxp_tick,
143 };
144 
145 /*===========================================================================*
146  *				main					     *
147  *===========================================================================*/
148 int main(int argc, char *argv[])
149 {
150 	env_setargs(argc, argv);
151 
152 	netdriver_task(&fxp_table);
153 
154 	return 0;
155 }
156 
157 /*===========================================================================*
158  *				fxp_intr				     *
159  *===========================================================================*/
160 static void fxp_intr(unsigned int __unused mask)
161 {
162 	int r;
163 	fxp_t *fp;
164 
165 	fp= fxp_state;
166 
167 	fxp_handler(fp);
168 
169 	if ((r = sys_irqenable(&fp->fxp_hook)) != OK)
170 		panic("unable to enable interrupts: %d", r);
171 
172 	if (!fp->fxp_got_int)
173 		return;
174 	fp->fxp_got_int= 0;
175 	fxp_check_ints(fp);
176 }
177 
178 /*===========================================================================*
179  *				fxp_stop				     *
180  *===========================================================================*/
181 static void fxp_stop(void)
182 {
183 	port_t port;
184 	fxp_t *fp;
185 
186 	fp= fxp_state;
187 
188 	port= fp->fxp_base_port;
189 
190 	/* Stop device */
191 #if VERBOSE
192 	printf("%s: stopping device\n", netdriver_name());
193 #endif
194 
195 	fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
196 }
197 
198 /*===========================================================================*
199  *				fxp_init				     *
200  *===========================================================================*/
201 static int fxp_init(unsigned int instance, netdriver_addr_t *addr,
202 	uint32_t *caps, unsigned int *ticks)
203 {
204 	fxp_t *fp;
205 	int r;
206 
207 	if (!(fxp_state = alloc_contig(sizeof(*fxp_state), 0, NULL)))
208 		panic("couldn't allocate table");
209 
210 	fp= fxp_state;
211 
212 	memset(fp, 0, sizeof(*fp));
213 
214 	if ((r = tsc_calibrate()) != OK)
215 		panic("tsc_calibrate failed: %d", r);
216 
217 	/* Configure PCI device. */
218 	if (!fxp_probe(fp, instance))
219 		return ENXIO;
220 
221 	fxp_conf_hw(fp);
222 
223 	fxp_init_hw(fp, addr, instance);
224 	fxp_report_link(fp);
225 
226 	*caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST;
227 	*ticks = sys_hz();
228 	return OK;
229 }
230 
231 /*===========================================================================*
232  *				fxp_probe				     *
233  *===========================================================================*/
234 static int fxp_probe(fxp_t *fp, int skip)
235 {
236 	int r, devind;
237 	u16_t vid, did, cr;
238 	u32_t bar;
239 	u8_t ilr, rev;
240 	const char *str;
241 #if VERBOSE
242 	const char *dname;
243 #endif
244 
245 	pci_init();
246 
247 	r= pci_first_dev(&devind, &vid, &did);
248 	if (r == 0)
249 		return FALSE;
250 
251 	while (skip--)
252 	{
253 		r= pci_next_dev(&devind, &vid, &did);
254 		if (!r)
255 			return FALSE;
256 	}
257 
258 #if VERBOSE
259 	dname= pci_dev_name(vid, did);
260 	if (!dname)
261 		dname= "unknown device";
262 	printf("%s: %s (%04x/%04x) at %s\n",
263 		netdriver_name(), dname, vid, did, pci_slot_name(devind));
264 #endif
265 	pci_reserve(devind);
266 
267 	/* Enable bus mastering if necessary. */
268 	cr = pci_attr_r16(devind, PCI_CR);
269 	if (!(cr & PCI_CR_MAST_EN))
270 		pci_attr_w16(devind, PCI_CR, cr | PCI_CR_MAST_EN);
271 
272 	bar= pci_attr_r32(devind, PCI_BAR_2) & 0xffffffe0;
273 	if (bar < 0x400) {
274 		panic("fxp_probe: base address is not properly configured");
275 	}
276 	fp->fxp_base_port= bar;
277 
278 	ilr= pci_attr_r8(devind, PCI_ILR);
279 	fp->fxp_irq= ilr;
280 #if VERBOSE
281 	printf("%s: using I/O address 0x%lx, IRQ %d\n",
282 		netdriver_name(), (unsigned long)bar, ilr);
283 #endif
284 
285 	rev= pci_attr_r8(devind, PCI_REV);
286 	str= NULL;
287 	fp->fxp_type= FT_UNKNOWN;
288 	switch(rev)
289 	{
290 	case FXP_REV_82557A:	str= "82557A";			/* 0x01 */
291 				fp->fxp_type= FT_82557;
292 				break;
293 	case FXP_REV_82557B:	str= "82557B"; break;		/* 0x02 */
294 	case FXP_REV_82557C:	str= "82557C"; break;		/* 0x03 */
295 	case FXP_REV_82558A:	str= "82558A"; 			/* 0x04 */
296 				fp->fxp_type= FT_82558A;
297 				break;
298 	case FXP_REV_82558B:	str= "82558B"; 			/* 0x05 */
299 				fp->fxp_type= FT_82559;
300 				break;
301 	case FXP_REV_82559A:	str= "82559A"; break;		/* 0x06 */
302 	case FXP_REV_82559B:	str= "82559B"; break;		/* 0x07 */
303 	case FXP_REV_82559C:	str= "82559C";			/* 0x08 */
304 				fp->fxp_type= FT_82559;
305 				break;
306 	case FXP_REV_82559ERA:	str= "82559ER-A"; 		/* 0x09 */
307 				fp->fxp_type= FT_82559;
308 				break;
309 	case FXP_REV_82550_1:	str= "82550(1)"; 		/* 0x0C */
310 				fp->fxp_type= FT_82559;
311 				break;
312 	case FXP_REV_82550_2:	str= "82550(2)"; 		/* 0x0D */
313 				fp->fxp_type= FT_82559;
314 				break;
315 	case FXP_REV_82550_3:	str= "82550(3)"; 		/* 0x0E */
316 				fp->fxp_type= FT_82559;
317 				break;
318 	case FXP_REV_82551_1:	str= "82551(1)"; 		/* 0x0F */
319 				fp->fxp_type= FT_82559;
320 				break;
321 	case FXP_REV_82551_2:	str= "82551(2)"; 		/* 0x10 */
322 				fp->fxp_type= FT_82559;
323 				break;
324 	case FXP_REV_82801CAM:	str= "82801CAM"; 		/* 0x42 */
325 				fp->fxp_type= FT_82801;
326 				break;
327 	case FXP_REV_82801DB:	str= "82801DB"; 		/* 0x81 */
328 				fp->fxp_type= FT_82801;
329 				break;
330 	case FXP_REV_82550_4:	str= "82550(4)"; 		/* 0x83 */
331 				fp->fxp_type= FT_82559;
332 				break;
333 	}
334 
335 #if VERBOSE
336 	if (str)
337 		printf("%s: device revision: %s\n", netdriver_name(), str);
338 	else
339 		printf("%s: unknown revision: 0x%x\n", netdriver_name(),
340 		    rev);
341 #endif
342 
343 	if (fp->fxp_type == FT_UNKNOWN)
344 	{
345 		printf("fxp_probe: device is not supported by this driver\n");
346 		return FALSE;
347 	}
348 
349 	return TRUE;
350 }
351 
352 /*===========================================================================*
353  *				fxp_conf_hw				     *
354  *===========================================================================*/
355 static void fxp_conf_hw(fxp_t *fp)
356 {
357 #if VERBOSE
358 	int i;
359 #endif
360 
361 	fp->fxp_got_int= 0;
362 	fp->fxp_send_int= 0;
363 	fp->fxp_ee_addrlen= 0;	/* Unknown */
364 	fp->fxp_need_reset= 0;
365 	fp->fxp_report_link= 0;
366 	fp->fxp_link_up= -1;	/* Unknown */
367 	fp->fxp_rx_need_restart= 0;
368 	fp->fxp_need_conf= 0;
369 	fp->fxp_tx_head= 0;
370 	fp->fxp_tx_tail= 0;
371 	fp->fxp_tx_alive= 0;
372 	fp->fxp_tx_threshold= TXTT_MIN;
373 
374 	/* Try to come up with a sensible configuration for the current
375 	 * device. Unfortunately every device is different, defaults are
376 	 * not always zero, and some fields are re-used with a completely
377 	 * different interpretation. We start out with a sensible default
378 	 * for all devices and then add device specific changes.
379 	 */
380 	fp->fxp_conf_bytes[0]= CC_BYTES_NR;
381 	fp->fxp_conf_bytes[1]= CTL_DEFAULT | CRL_DEFAULT;
382 	fp->fxp_conf_bytes[2]= CAI_DEFAULT;
383 	fp->fxp_conf_bytes[3]= 0;
384 	fp->fxp_conf_bytes[4]= 0;
385 	fp->fxp_conf_bytes[5]= 0;
386 	fp->fxp_conf_bytes[6]= CCB6_ESC | CCB6_ETCB | CCB6_RES;
387 	fp->fxp_conf_bytes[7]= CUR_1;
388 	fp->fxp_conf_bytes[8]= CCB8_503_MII;
389 	fp->fxp_conf_bytes[9]= 0;
390 	fp->fxp_conf_bytes[10]= CLB_NORMAL | CPAL_DEFAULT | CCB10_NSAI |
391 				CCB10_RES1;
392 	fp->fxp_conf_bytes[11]= 0;
393 	fp->fxp_conf_bytes[12]= CIS_DEFAULT;
394 	fp->fxp_conf_bytes[13]= CCB13_DEFAULT;
395 	fp->fxp_conf_bytes[14]= CCB14_DEFAULT;
396 	fp->fxp_conf_bytes[15]= CCB15_RES1 | CCB15_RES2;
397 	fp->fxp_conf_bytes[16]= CCB16_DEFAULT;
398 	fp->fxp_conf_bytes[17]= CCB17_DEFAULT;
399 	fp->fxp_conf_bytes[18]= CCB18_RES1 | CCB18_PFCT | CCB18_PE;
400 	fp->fxp_conf_bytes[19]= CCB19_FDPE;
401 	fp->fxp_conf_bytes[20]= CCB20_PFCL | CCB20_RES1;
402 	fp->fxp_conf_bytes[21]= CCB21_RES21;
403 
404 #if VERBOSE
405 	for (i= 0; i<CC_BYTES_NR; i++)
406 		printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]);
407 	printf("\n");
408 #endif
409 
410 	switch(fp->fxp_type)
411 	{
412 	case FT_82557:
413 		break;
414 	case FT_82558A:
415 	case FT_82559:
416 	case FT_82801:
417 		fp->fxp_conf_bytes[18] |= CCB18_LROK;
418 
419 		if (fp->fxp_type == FT_82801)
420 		{
421 			fp->fxp_conf_bytes[6] = 0xba; /* ctrl 1 */
422 			fp->fxp_conf_bytes[15] = 0x48; /* promiscuous */
423 			fp->fxp_conf_bytes[21] = 0x05; /* mc_all */
424 		}
425 		break;
426 	default:
427 		panic("fxp_conf_hw: bad device type: %d", fp->fxp_type);
428 	}
429 
430 	/* Assume an 82555 (compatible) PHY. The should be changed for
431 	 * 82557 NICs with different PHYs
432 	 */
433 	fp->fxp_ms_regs = 0;	/* No master/slave registers. */
434 
435 #if VERBOSE
436 	for (i= 0; i<CC_BYTES_NR; i++)
437 		printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]);
438 	printf("\n");
439 #endif
440 }
441 
442 /*===========================================================================*
443  *				fxp_init_hw				     *
444  *===========================================================================*/
445 static void fxp_init_hw(fxp_t *fp, netdriver_addr_t *addr,
446 	unsigned int instance)
447 {
448 	int r, isr;
449 	port_t port;
450 	phys_bytes bus_addr;
451 
452 	port= fp->fxp_base_port;
453 
454 	fxp_init_buf(fp);
455 
456 	/* Set the interrupt handler and policy. Do not automatically
457 	 * reenable interrupts. Return the IRQ line number on interrupts.
458  	 */
459  	fp->fxp_hook = fp->fxp_irq;
460 	r= sys_irqsetpolicy(fp->fxp_irq, 0, &fp->fxp_hook);
461 	if (r != OK)
462 		panic("sys_irqsetpolicy failed: %d", r);
463 
464 	fxp_reset_hw(fp);
465 
466 	r= sys_irqenable(&fp->fxp_hook);
467 	if (r != OK)
468 		panic("sys_irqenable failed: %d", r);
469 
470 	/* Reset PHY? */
471 
472 	fxp_do_conf(fp);
473 
474 	/* Set pointer to statistical counters */
475 	r= sys_umap(SELF, VM_D, (vir_bytes)&fp->fxp_stat, sizeof(fp->fxp_stat),
476 		&bus_addr);
477 	if (r != OK)
478 		panic("sys_umap failed: %d", r);
479 	fxp_cu_ptr_cmd(fp, SC_CU_LOAD_DCA, bus_addr, TRUE /* check idle */);
480 
481 	/* Ack previous interrupts */
482 	isr= fxp_inb(port, SCB_INT_STAT);
483 	fxp_outb(port, SCB_INT_STAT, isr);
484 
485 	/* Enable interrupts */
486 	fxp_outb(port, SCB_INT_MASK, 0);
487 
488 	fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr,
489 		TRUE /* check idle */);
490 
491 	fxp_confaddr(fp, addr, instance);
492 }
493 
494 /*===========================================================================*
495  *				fxp_init_buf				     *
496  *===========================================================================*/
497 static void fxp_init_buf(fp)
498 fxp_t *fp;
499 {
500 	size_t rx_totbufsize, tx_totbufsize, tot_bufsize, alloc_bufsize;
501 	char *alloc_buf;
502 	phys_bytes buf, bus_addr;
503 	int i, r;
504 	struct rfd *rfdp;
505 	struct tx *txp;
506 	phys_bytes ph;
507 
508 	fp->fxp_rx_nbuf= N_RX_BUF;
509 	rx_totbufsize= fp->fxp_rx_nbuf * sizeof(struct rfd);
510 	fp->fxp_rx_bufsize= rx_totbufsize;
511 
512 	fp->fxp_tx_nbuf= N_TX_BUF;
513 	tx_totbufsize= fp->fxp_tx_nbuf * sizeof(struct tx);
514 	fp->fxp_tx_bufsize= tx_totbufsize;
515 
516 	tot_bufsize= sizeof(*tmpbufp) + tx_totbufsize + rx_totbufsize;
517 	if (tot_bufsize % 4096)
518 		tot_bufsize += 4096 - (tot_bufsize % 4096);
519 	alloc_bufsize= tot_bufsize;
520 	alloc_buf= alloc_contig(alloc_bufsize, AC_ALIGN4K, &ph);
521 	if (alloc_buf == NULL)
522 		panic("fxp_init_buf: unable to alloc_contig size: %d",
523 			alloc_bufsize);
524 
525 	buf= (phys_bytes)alloc_buf;
526 
527 	tell_iommu((vir_bytes)buf, tot_bufsize, 0, 0, 0);
528 
529 	tmpbufp= (union tmpbuf *)buf;
530 
531 	fp->fxp_rx_buf= (struct rfd *)&tmpbufp[1];
532 	r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_rx_buf, rx_totbufsize,
533 		&bus_addr);
534 	if (r != OK)
535 		panic("sys_umap failed: %d", r);
536 	fp->fxp_rx_busaddr= bus_addr;
537 
538 #if 0
539 	printf("fxp_init_buf: got phys 0x%x for vir 0x%x\n",
540 		fp->fxp_rx_busaddr, fp->fxp_rx_buf);
541 #endif
542 
543 	for (i= 0, rfdp= fp->fxp_rx_buf; i<fp->fxp_rx_nbuf; i++, rfdp++)
544 	{
545 		rfdp->rfd_status= 0;
546 		rfdp->rfd_command= 0;
547 		if (i != fp->fxp_rx_nbuf-1)
548 		{
549 			r= sys_umap(SELF, VM_D, (vir_bytes)&rfdp[1],
550 				sizeof(rfdp[1]), &bus_addr);
551 			if (r != OK)
552 				panic("sys_umap failed: %d", r);
553 			rfdp->rfd_linkaddr= bus_addr;
554 		}
555 		else
556 		{
557 			rfdp->rfd_linkaddr= fp->fxp_rx_busaddr;
558 			rfdp->rfd_command |= RFDC_EL;
559 		}
560 		rfdp->rfd_reserved= 0;
561 		rfdp->rfd_res= 0;
562 		rfdp->rfd_size= sizeof(rfdp->rfd_buf);
563 
564 	}
565 	fp->fxp_rx_head= 0;
566 
567 	fp->fxp_tx_buf= (struct tx *)((char *)fp->fxp_rx_buf+rx_totbufsize);
568 	r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_tx_buf,
569 		(phys_bytes)tx_totbufsize, &fp->fxp_tx_busaddr);
570 	if (r != OK)
571 		panic("sys_umap failed: %d", r);
572 
573 	for (i= 0, txp= fp->fxp_tx_buf; i<fp->fxp_tx_nbuf; i++, txp++)
574 	{
575 		txp->tx_status= 0;
576 		txp->tx_command= TXC_EL | CBL_NOP;	/* Just in case */
577 		if (i != fp->fxp_tx_nbuf-1)
578 		{
579 			r= sys_umap(SELF, VM_D, (vir_bytes)&txp[1],
580 				(phys_bytes)sizeof(txp[1]), &bus_addr);
581 			if (r != OK)
582 				panic("sys_umap failed: %d", r);
583 			txp->tx_linkaddr= bus_addr;
584 		}
585 		else
586 		{
587 			txp->tx_linkaddr= fp->fxp_tx_busaddr;
588 		}
589 		txp->tx_tbda= TX_TBDA_NIL;
590 		txp->tx_size= 0;
591 		txp->tx_tthresh= fp->fxp_tx_threshold;
592 		txp->tx_ntbd= 0;
593 	}
594 	fp->fxp_tx_idle= TRUE;
595 }
596 
597 /*===========================================================================*
598  *				fxp_reset_hw				     *
599  *===========================================================================*/
600 static void fxp_reset_hw(fp)
601 fxp_t *fp;
602 {
603 /* Inline the function in init? */
604 	port_t port;
605 
606 	port= fp->fxp_base_port;
607 
608 	/* Reset device */
609 	fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
610 	tickdelay(micros_to_ticks(CSR_PORT_RESET_DELAY));
611 
612 	/* Disable interrupts */
613 	fxp_outb(port, SCB_INT_MASK, SIM_M);
614 
615 	/* Set CU base to zero */
616 	fxp_cu_ptr_cmd(fp, SC_CU_LOAD_BASE, 0, TRUE /* check idle */);
617 
618 	/* Set RU base to zero */
619 	fxp_ru_ptr_cmd(fp, SC_RU_LOAD_BASE, 0, TRUE /* check idle */);
620 }
621 
622 /*===========================================================================*
623  *				fxp_confaddr				     *
624  *===========================================================================*/
625 static void fxp_confaddr(fxp_t *fp, netdriver_addr_t *addr,
626 	unsigned int instance)
627 {
628 	static char eakey[]= FXP_ENVVAR "#_EA";
629 	static char eafmt[]= "x:x:x:x:x:x";
630 	int i, r;
631 	phys_bytes bus_addr;
632 	long v;
633 
634 	/* User defined ethernet address? */
635 	eakey[sizeof(FXP_ENVVAR)-1]= '0' + instance;
636 
637 	for (i= 0; i < 6; i++)
638 	{
639 		if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
640 			break;
641 		addr->na_addr[i]= v;
642 	}
643 
644 	if (i != 0 && i != 6) env_panic(eakey);	/* It's all or nothing */
645 
646 	if (i == 0)
647 	{
648 		/* Get ethernet address from EEPROM */
649 		for (i= 0; i<3; i++)
650 		{
651 			v= eeprom_read(fp, i);
652 			addr->na_addr[i*2]= (v & 0xff);
653 			addr->na_addr[i*2+1]= ((v >> 8) & 0xff);
654 		}
655 	}
656 
657 	/* Tell NIC about ethernet address */
658 	tmpbufp->ias.ias_status= 0;
659 	tmpbufp->ias.ias_command= CBL_C_EL | CBL_AIS;
660 	tmpbufp->ias.ias_linkaddr= 0;
661 	memcpy(tmpbufp->ias.ias_ethaddr, addr->na_addr,
662 		sizeof(tmpbufp->ias.ias_ethaddr));
663 	r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->ias,
664 		(phys_bytes)sizeof(tmpbufp->ias), &bus_addr);
665 	if (r != OK)
666 		panic("sys_umap failed: %d", r);
667 
668 	fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */);
669 
670 	/* Wait for CU command to complete */
671 	SPIN_UNTIL(tmpbufp->ias.ias_status & CBL_F_C, 1000);
672 
673 	if (!(tmpbufp->ias.ias_status & CBL_F_C))
674 		panic("fxp_confaddr: CU command failed to complete");
675 	if (!(tmpbufp->ias.ias_status & CBL_F_OK))
676 		panic("fxp_confaddr: CU command failed");
677 
678 #if VERBOSE
679 	printf("%s: hardware ethernet address: ", netdriver_name());
680 	for (i= 0; i<6; i++)
681 		printf("%02x%s", addr->na_addr[i], i < 5 ? ":" : "");
682 	printf("\n");
683 #endif
684 }
685 
686 /*===========================================================================*
687  *				fxp_set_mode				     *
688  *===========================================================================*/
689 static void fxp_set_mode(unsigned int mode,
690 	const netdriver_addr_t * mcast_list __unused,
691 	unsigned int mcast_count __unused)
692 {
693 	fxp_t *fp;
694 
695 	fp = fxp_state;
696 
697 	fp->fxp_conf_bytes[0]= CC_BYTES_NR;	/* Just to be sure */
698 	fp->fxp_conf_bytes[15] &= ~(CCB15_BD|CCB15_PM);
699 	fp->fxp_conf_bytes[21] &= ~CCB21_MA;
700 
701 	if (mode & NDEV_MODE_PROMISC)
702 		fp->fxp_conf_bytes[15] |= CCB15_PM;
703 	if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
704 		fp->fxp_conf_bytes[21] |= CCB21_MA;
705 
706 	if (!(mode & (NDEV_MODE_BCAST | NDEV_MODE_MCAST_LIST |
707 	    NDEV_MODE_MCAST_ALL | NDEV_MODE_PROMISC)))
708 		fp->fxp_conf_bytes[15] |= CCB15_BD;
709 
710 	/* Queue request if not idle */
711 	if (fp->fxp_tx_idle)
712 	{
713 		fxp_do_conf(fp);
714 	}
715 	else
716 	{
717 		printf("fxp_rec_mode: setting fxp_need_conf\n");
718 		fp->fxp_need_conf= TRUE;
719 	}
720 }
721 
722 /*===========================================================================*
723  *				fxp_send				     *
724  *===========================================================================*/
725 static int fxp_send(struct netdriver_data *data, size_t size)
726 {
727 	int prev_head;
728 	int fxp_tx_nbuf, fxp_tx_head;
729 	u16_t tx_command;
730 	fxp_t *fp;
731 	struct tx *txp, *prev_txp;
732 
733 	fp= fxp_state;
734 
735 	if (fp->fxp_tx_idle)
736 	{
737 		txp= fp->fxp_tx_buf;
738 		fxp_tx_head= 0;	/* lint */
739 		prev_txp= NULL;	/* lint */
740 	}
741 	else
742 	{
743 		fxp_tx_nbuf= fp->fxp_tx_nbuf;
744 		prev_head= fp->fxp_tx_head;
745 		fxp_tx_head= prev_head+1;
746 		if (fxp_tx_head == fxp_tx_nbuf)
747 			fxp_tx_head= 0;
748 		assert(fxp_tx_head < fxp_tx_nbuf);
749 
750 		if (fxp_tx_head == fp->fxp_tx_tail)
751 		{
752 			/* Send queue is full */
753 			return SUSPEND;
754 		}
755 
756 		prev_txp= &fp->fxp_tx_buf[prev_head];
757 		txp= &fp->fxp_tx_buf[fxp_tx_head];
758 	}
759 
760 	/* Copy in the packet data */
761 	netdriver_copyin(data, 0, txp->tx_buf, size);
762 
763 	txp->tx_status= 0;
764 	txp->tx_command= TXC_EL | CBL_XMIT;
765 	txp->tx_tbda= TX_TBDA_NIL;
766 	txp->tx_size= TXSZ_EOF | size;
767 	txp->tx_tthresh= fp->fxp_tx_threshold;
768 	txp->tx_ntbd= 0;
769 	if (fp->fxp_tx_idle)
770 	{
771 		fp->fxp_tx_idle= FALSE;
772 		fp->fxp_tx_head= fp->fxp_tx_tail= 0;
773 
774 		fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr,
775 			TRUE /* check idle */);
776 	}
777 	else
778 	{
779 		/* Link new request in transmit list */
780 		tx_command= prev_txp->tx_command;
781 		assert(tx_command == (TXC_EL | CBL_XMIT));
782 		prev_txp->tx_command= CBL_XMIT;
783 		fp->fxp_tx_head= fxp_tx_head;
784 	}
785 
786 	return OK;
787 }
788 
789 /*===========================================================================*
790  *				fxp_check_restart			     *
791  *===========================================================================*/
792 static void fxp_check_restart(fxp_t *fp)
793 {
794 	port_t port;
795 	u8_t scb_status;
796 
797 	if (!fp->fxp_rx_need_restart)
798 		return;
799 
800 	fp->fxp_rx_need_restart= 0;
801 
802 	/* Check the status of the RU */
803 	port= fp->fxp_base_port;
804 	scb_status= fxp_inb(port, SCB_STATUS);
805 	if ((scb_status & SS_RUS_MASK) != SS_RU_NORES)
806 	{
807 		/* Race condition? */
808 		printf("fxp_check_restart: restart race: 0x%x\n", scb_status);
809 		assert((scb_status & SS_RUS_MASK) == SS_RU_READY);
810 	}
811 	else
812 	{
813 		fxp_restart_ru(fp);
814 	}
815 }
816 
817 /*===========================================================================*
818  *				fxp_recv				     *
819  *===========================================================================*/
820 static ssize_t fxp_recv(struct netdriver_data *data, size_t max)
821 {
822 	int fxp_rx_head, fxp_rx_nbuf;
823 	port_t port;
824 	unsigned packlen;
825 	u16_t rfd_status;
826 	u16_t rfd_res;
827 	fxp_t *fp;
828 	struct rfd *rfdp, *prev_rfdp;
829 
830 	fp= fxp_state;
831 
832 	port= fp->fxp_base_port;
833 
834 	fxp_rx_head= fp->fxp_rx_head;
835 	rfdp= &fp->fxp_rx_buf[fxp_rx_head];
836 
837 	rfd_status= rfdp->rfd_status;
838 	if (!(rfd_status & RFDS_C)) {
839 		/* Receive buffer is empty, suspend */
840 		fxp_check_restart(fp);
841 
842 		return SUSPEND;
843 	}
844 
845 	if (!(rfd_status & RFDS_OK))
846 	{
847 		/* Not OK? What happened? */
848 		assert(0);
849 	}
850 	else
851 	{
852 		assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR |
853 			RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT |
854 			RFDS_RXERR)));
855 	}
856 	rfd_res= rfdp->rfd_res;
857 	assert(rfd_res & RFDR_EOF);
858 	assert(rfd_res & RFDR_F);
859 
860 	packlen= rfd_res & RFDSZ_SIZE;
861 
862 	/* Copy out the packet data */
863 	if (packlen > max)
864 		packlen = max;
865 
866 	netdriver_copyout(data, 0, rfdp->rfd_buf, packlen);
867 
868 	/* Re-init the current buffer */
869 	rfdp->rfd_status= 0;
870 	rfdp->rfd_command= RFDC_EL;
871 	rfdp->rfd_reserved= 0;
872 	rfdp->rfd_res= 0;
873 	rfdp->rfd_size= sizeof(rfdp->rfd_buf);
874 
875 	fxp_rx_nbuf= fp->fxp_rx_nbuf;
876 	if (fxp_rx_head == 0)
877 	{
878 		prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1];
879 	}
880 	else
881 		prev_rfdp= &rfdp[-1];
882 
883 	assert(prev_rfdp->rfd_command & RFDC_EL);
884 	prev_rfdp->rfd_command &= ~RFDC_EL;
885 
886 	fxp_rx_head++;
887 	if (fxp_rx_head == fxp_rx_nbuf)
888 		fxp_rx_head= 0;
889 	assert(fxp_rx_head < fxp_rx_nbuf);
890 	fp->fxp_rx_head= fxp_rx_head;
891 
892 	return packlen;
893 }
894 
895 /*===========================================================================*
896  *				fxp_do_conf				     *
897  *===========================================================================*/
898 static void fxp_do_conf(fp)
899 fxp_t *fp;
900 {
901 	int r;
902 	phys_bytes bus_addr;
903 
904 	/* Configure device */
905 	tmpbufp->cc.cc_status= 0;
906 	tmpbufp->cc.cc_command= CBL_C_EL | CBL_CONF;
907 	tmpbufp->cc.cc_linkaddr= 0;
908 	memcpy(tmpbufp->cc.cc_bytes, fp->fxp_conf_bytes,
909 		sizeof(tmpbufp->cc.cc_bytes));
910 
911 	r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->cc,
912 		(phys_bytes)sizeof(tmpbufp->cc), &bus_addr);
913 	if (r != OK)
914 		panic("sys_umap failed: %d", r);
915 
916 	fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */);
917 
918 	/* Wait for CU command to complete */
919 	SPIN_UNTIL(tmpbufp->cc.cc_status & CBL_F_C, 100000);
920 
921 	if (!(tmpbufp->cc.cc_status & CBL_F_C))
922 		panic("fxp_do_conf: CU command failed to complete");
923 	if (!(tmpbufp->cc.cc_status & CBL_F_OK))
924 		panic("fxp_do_conf: CU command failed");
925 
926 }
927 
928 /*===========================================================================*
929  *				fxp_cu_ptr_cmd				     *
930  *===========================================================================*/
931 static void fxp_cu_ptr_cmd(fp, cmd, bus_addr, check_idle)
932 fxp_t *fp;
933 int cmd;
934 phys_bytes bus_addr;
935 int check_idle;
936 {
937 	spin_t spin;
938 	port_t port;
939 	u8_t scb_cmd;
940 
941 	port= fp->fxp_base_port;
942 
943 	if (check_idle)
944 	{
945 		/* Consistency check. Make sure that CU is idle */
946 		if ((fxp_inb(port, SCB_STATUS) & SS_CUS_MASK) != SS_CU_IDLE)
947 			panic("fxp_cu_ptr_cmd: CU is not idle");
948 	}
949 
950 	fxp_outl(port, SCB_POINTER, bus_addr);
951 	fxp_outb(port, SCB_CMD, cmd);
952 
953 	/* What is a reasonable time-out? There is nothing in the
954 	 * documentation. 1 ms should be enough. We use 100 ms.
955 	 */
956 	spin_init(&spin, 100000);
957 	do {
958 		/* Wait for CU command to be accepted */
959 		scb_cmd= fxp_inb(port, SCB_CMD);
960 		if ((scb_cmd & SC_CUC_MASK) == SC_CU_NOP)
961 			break;
962 	} while (spin_check(&spin));
963 
964 	if ((scb_cmd & SC_CUC_MASK) != SC_CU_NOP)
965 		panic("fxp_cu_ptr_cmd: CU does not accept command");
966 }
967 
968 /*===========================================================================*
969  *				fxp_ru_ptr_cmd				     *
970  *===========================================================================*/
971 static void fxp_ru_ptr_cmd(fp, cmd, bus_addr, check_idle)
972 fxp_t *fp;
973 int cmd;
974 phys_bytes bus_addr;
975 int check_idle;
976 {
977 	spin_t spin;
978 	port_t port;
979 	u8_t scb_cmd;
980 
981 	port= fp->fxp_base_port;
982 
983 	if (check_idle)
984 	{
985 		/* Consistency check, make sure that RU is idle */
986 		if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_IDLE)
987 			panic("fxp_ru_ptr_cmd: RU is not idle");
988 	}
989 
990 	fxp_outl(port, SCB_POINTER, bus_addr);
991 	fxp_outb(port, SCB_CMD, cmd);
992 
993 	spin_init(&spin, 1000);
994 	do {
995 		/* Wait for RU command to be accepted */
996 		scb_cmd= fxp_inb(port, SCB_CMD);
997 		if ((scb_cmd & SC_RUC_MASK) == SC_RU_NOP)
998 			break;
999 	} while (spin_check(&spin));
1000 
1001 	if ((scb_cmd & SC_RUC_MASK) != SC_RU_NOP)
1002 		panic("fxp_ru_ptr_cmd: RU does not accept command");
1003 }
1004 
1005 /*===========================================================================*
1006  *				fxp_restart_ru				     *
1007  *===========================================================================*/
1008 static void fxp_restart_ru(fp)
1009 fxp_t *fp;
1010 {
1011 	int i, fxp_rx_nbuf;
1012 	port_t port;
1013 	struct rfd *rfdp;
1014 
1015 	port= fp->fxp_base_port;
1016 
1017 	fxp_rx_nbuf= fp->fxp_rx_nbuf;
1018 	for (i= 0, rfdp= fp->fxp_rx_buf; i<fxp_rx_nbuf; i++, rfdp++)
1019 	{
1020 		rfdp->rfd_status= 0;
1021 		rfdp->rfd_command= 0;
1022 		if (i == fp->fxp_rx_nbuf-1)
1023 			rfdp->rfd_command= RFDC_EL;
1024 		rfdp->rfd_reserved= 0;
1025 		rfdp->rfd_res= 0;
1026 		rfdp->rfd_size= sizeof(rfdp->rfd_buf);
1027 	}
1028 	fp->fxp_rx_head= 0;
1029 
1030 	/* Make sure that RU is in the 'No resources' state */
1031 	if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_NORES)
1032 		panic("fxp_restart_ru: RU is in an unexpected state");
1033 
1034 	fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr,
1035 		FALSE /* do not check idle */);
1036 }
1037 
1038 /*===========================================================================*
1039  *				fxp_update_stats			     *
1040  *===========================================================================*/
1041 static void fxp_update_stats(void)
1042 {
1043 	fxp_t *fp;
1044 	u32_t *p;
1045 
1046 	fp= fxp_state;
1047 
1048 	p= &fp->fxp_stat.sc_tx_fcp;
1049 	*p= 0;
1050 
1051 	/* The dump commmand doesn't take a pointer. Setting a pointer
1052 	 * doesn't hurt though.
1053 	 */
1054 	fxp_cu_ptr_cmd(fp, SC_CU_DUMP_RSET_SC, 0,
1055 	    FALSE /* do not check idle */);
1056 
1057 	/* Wait for CU command to complete */
1058 	SPIN_UNTIL(*p != 0, 2500);
1059 
1060 	if (*p == 0)
1061 		panic("fxp_stat: CU command failed to complete");
1062 	if (*p != SCM_DRSC)
1063 		panic("fxp_stat: bad magic");
1064 
1065 	netdriver_stat_ierror(fp->fxp_stat.sc_rx_crc +
1066 		fp->fxp_stat.sc_rx_align +
1067 		fp->fxp_stat.sc_rx_resource +
1068 		fp->fxp_stat.sc_rx_overrun +
1069 		fp->fxp_stat.sc_rx_cd +
1070 		fp->fxp_stat.sc_rx_short);
1071 	netdriver_stat_coll(fp->fxp_stat.sc_tx_maxcol +
1072 		fp->fxp_stat.sc_tx_latecol);
1073 	netdriver_stat_oerror(fp->fxp_stat.sc_tx_crs);
1074 }
1075 
1076 /*===========================================================================*
1077  *				fxp_handler				     *
1078  *===========================================================================*/
1079 static void fxp_handler(fxp_t *fp)
1080 {
1081 	int port;
1082 	u16_t isr;
1083 
1084 	port= fp->fxp_base_port;
1085 
1086 	/* Ack interrupt */
1087 	isr= fxp_inb(port, SCB_INT_STAT);
1088 	fxp_outb(port, SCB_INT_STAT, isr);
1089 
1090 	if (isr & SIS_FR)
1091 	{
1092 		isr &= ~SIS_FR;
1093 
1094 		fp->fxp_got_int= TRUE;
1095 	}
1096 	if (isr & SIS_CNA)
1097 	{
1098 		isr &= ~SIS_CNA;
1099 		if (!fp->fxp_tx_idle)
1100 		{
1101 			fp->fxp_send_int= TRUE;
1102 			fp->fxp_got_int= TRUE;
1103 		}
1104 	}
1105 	if (isr & SIS_RNR)
1106 	{
1107 		isr &= ~SIS_RNR;
1108 
1109 		/* Assume that receive buffer is full of packets. fxp_recv
1110 		 * will restart the RU.
1111 		 */
1112 		fp->fxp_rx_need_restart= 1;
1113 	}
1114 	if (isr)
1115 	{
1116 		printf("fxp_handler: unhandled interrupt: isr = 0x%02x\n",
1117 			isr);
1118 	}
1119 }
1120 
1121 /*===========================================================================*
1122  *				fxp_check_ints				     *
1123  *===========================================================================*/
1124 static void fxp_check_ints(fxp_t *fp)
1125 {
1126 	int n, prev_tail;
1127 	int fxp_tx_tail, fxp_tx_nbuf, fxp_tx_threshold;
1128 	port_t port;
1129 	u32_t busaddr;
1130 	u16_t tx_status;
1131 	u8_t scb_status;
1132 	struct tx *txp;
1133 
1134 	netdriver_recv();
1135 
1136 	if (fp->fxp_tx_idle)
1137 		;	/* Nothing to do */
1138 	else if (fp->fxp_send_int)
1139 	{
1140 		fp->fxp_send_int= FALSE;
1141 		fxp_tx_tail= fp->fxp_tx_tail;
1142 		fxp_tx_nbuf= fp->fxp_tx_nbuf;
1143 		n= 0;
1144 		for (;;)
1145 		{
1146 			txp= &fp->fxp_tx_buf[fxp_tx_tail];
1147 			tx_status= txp->tx_status;
1148 			if (!(tx_status & TXS_C))
1149 				break;
1150 
1151 			n++;
1152 
1153 			assert(tx_status & TXS_OK);
1154 			if (tx_status & TXS_U)
1155 			{
1156 				fxp_tx_threshold= fp->fxp_tx_threshold;
1157 				if (fxp_tx_threshold < TXTT_MAX)
1158 				{
1159 					fxp_tx_threshold++;
1160 					fp->fxp_tx_threshold= fxp_tx_threshold;
1161 				}
1162 				printf(
1163 			"fxp_check_ints: fxp_tx_threshold = 0x%x\n",
1164 					fxp_tx_threshold);
1165 			}
1166 
1167 			if (txp->tx_command & TXC_EL)
1168 			{
1169 				fp->fxp_tx_idle= TRUE;
1170 				break;
1171 			}
1172 
1173 			fxp_tx_tail++;
1174 			if (fxp_tx_tail == fxp_tx_nbuf)
1175 				fxp_tx_tail= 0;
1176 			assert(fxp_tx_tail < fxp_tx_nbuf);
1177 		}
1178 
1179 		if (fp->fxp_need_conf)
1180 		{
1181 			/* Check the status of the CU */
1182 			port= fp->fxp_base_port;
1183 			scb_status= fxp_inb(port, SCB_STATUS);
1184 			if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE)
1185 			{
1186 				/* Nothing to do */
1187 				printf("scb_status = 0x%x\n", scb_status);
1188 			}
1189 			else
1190 			{
1191 				printf("fxp_check_ints: fxp_need_conf\n");
1192 				fp->fxp_need_conf= FALSE;
1193 				fxp_do_conf(fp);
1194 			}
1195 		}
1196 
1197 		if (n)
1198 		{
1199 			if (!fp->fxp_tx_idle)
1200 			{
1201 				fp->fxp_tx_tail= fxp_tx_tail;
1202 
1203 				/* Check the status of the CU */
1204 				port= fp->fxp_base_port;
1205 				scb_status= fxp_inb(port, SCB_STATUS);
1206 				if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE)
1207 				{
1208 					/* Nothing to do */
1209 					printf("scb_status = 0x%x\n",
1210 						scb_status);
1211 
1212 				}
1213 				else
1214 				{
1215 					if (fxp_tx_tail == 0)
1216 						prev_tail= fxp_tx_nbuf-1;
1217 					else
1218 						prev_tail= fxp_tx_tail-1;
1219 					busaddr= fp->fxp_tx_buf[prev_tail].
1220 						tx_linkaddr;
1221 
1222 					fxp_cu_ptr_cmd(fp, SC_CU_START,
1223 						busaddr, 1 /* check idle */);
1224 				}
1225 			}
1226 
1227 			fp->fxp_tx_alive = TRUE;
1228 
1229 			netdriver_send();
1230 		}
1231 
1232 	}
1233 	if (fp->fxp_report_link) {
1234 		netdriver_link();
1235 
1236 		fxp_report_link(fp);
1237 	}
1238 }
1239 
1240 /*===========================================================================*
1241  *				fxp_tick				     *
1242  *===========================================================================*/
1243 static void fxp_tick(void)
1244 {
1245 	fxp_t *fp;
1246 
1247 	fxp_update_stats();
1248 
1249 	fp= fxp_state;
1250 
1251 	/* Check the link status. */
1252 	if (fxp_link_changed(fp)) {
1253 #if VERBOSE
1254 		printf("fxp_tick: link changed\n");
1255 #endif
1256 		fp->fxp_report_link= TRUE;
1257 		fxp_check_ints(fp);
1258 	}
1259 
1260 	if (fp->fxp_tx_idle)
1261 	{
1262 		/* Assume that an idle system is alive */
1263 		fp->fxp_tx_alive= TRUE;
1264 		return;
1265 	}
1266 	if (fp->fxp_tx_alive)
1267 	{
1268 		fp->fxp_tx_alive= FALSE;
1269 		return;
1270 	}
1271 
1272 	/* XXX this flag is never actually checked! */
1273 	fp->fxp_need_reset= TRUE;
1274 	fxp_check_ints(fp);
1275 }
1276 
1277 /*===========================================================================*
1278  *				fxp_link_changed			     *
1279  *===========================================================================*/
1280 static int fxp_link_changed(fxp_t *fp)
1281 {
1282 	u16_t scr;
1283 
1284 	scr= mii_read(fp, MII_SCR);
1285 	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);
1286 
1287 	return (fp->fxp_mii_scr != scr);
1288 }
1289 
1290 /*===========================================================================*
1291  *				fxp_get_link				     *
1292  *===========================================================================*/
1293 static unsigned int fxp_get_link(uint32_t *media)
1294 {
1295 	fxp_t *fp;
1296 	u16_t mii_status, scr;
1297 
1298 	fp = fxp_state;
1299 
1300 	scr= mii_read(fp, MII_SCR);
1301 
1302 	mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */
1303 	mii_status= mii_read(fp, MII_STATUS);
1304 
1305 	if (!(mii_status & MII_STATUS_LS))
1306 		return NDEV_LINK_DOWN;
1307 
1308 	if (scr & MII_SCR_100)
1309 		*media = IFM_ETHER | IFM_100_TX;
1310 	else
1311 		*media = IFM_ETHER | IFM_10_T;
1312 
1313 	if (scr & MII_SCR_FD)
1314 		*media |= IFM_FDX;
1315 	else
1316 		*media |= IFM_HDX;
1317 
1318 	return NDEV_LINK_UP;
1319 }
1320 
1321 /*===========================================================================*
1322  *				fxp_report_link				     *
1323  *===========================================================================*/
1324 static void fxp_report_link(fxp_t *fp)
1325 {
1326 	u16_t mii_ctrl, mii_status, mii_id1, mii_id2,
1327 		mii_ana, mii_anlpa, mii_ane, mii_extstat,
1328 		mii_ms_ctrl, mii_ms_status, scr;
1329 	u32_t oui;
1330 	int model, rev;
1331 	int f, link_up;
1332 
1333 	fp->fxp_report_link= FALSE;
1334 
1335 	scr= mii_read(fp, MII_SCR);
1336 	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);
1337 	fp->fxp_mii_scr= scr;
1338 
1339 	mii_ctrl= mii_read(fp, MII_CTRL);
1340 	mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */
1341 	mii_status= mii_read(fp, MII_STATUS);
1342 	mii_id1= mii_read(fp, MII_PHYID_H);
1343 	mii_id2= mii_read(fp, MII_PHYID_L);
1344 	mii_ana= mii_read(fp, MII_ANA);
1345 	mii_anlpa= mii_read(fp, MII_ANLPA);
1346 	mii_ane= mii_read(fp, MII_ANE);
1347 	if (mii_status & MII_STATUS_EXT_STAT)
1348 		mii_extstat= mii_read(fp, MII_EXT_STATUS);
1349 	else
1350 		mii_extstat= 0;
1351 	if (fp->fxp_ms_regs)
1352 	{
1353 		mii_ms_ctrl= mii_read(fp, MII_MS_CTRL);
1354 		mii_ms_status= mii_read(fp, MII_MS_STATUS);
1355 	}
1356 	else
1357 	{
1358 		mii_ms_ctrl= 0;
1359 		mii_ms_status= 0;
1360 	}
1361 
1362 	/* How do we know about the link status? */
1363 	link_up= !!(mii_status & MII_STATUS_LS);
1364 
1365 	fp->fxp_link_up= link_up;
1366 	if (!link_up)
1367 	{
1368 #if VERBOSE
1369 		printf("%s: link down\n", netdriver_name());
1370 #endif
1371 		return;
1372 	}
1373 
1374 	oui= (mii_id1 << MII_PH_OUI_H_C_SHIFT) |
1375 		((mii_id2 & MII_PL_OUI_L_MASK) >> MII_PL_OUI_L_SHIFT);
1376 	model= ((mii_id2 & MII_PL_MODEL_MASK) >> MII_PL_MODEL_SHIFT);
1377 	rev= (mii_id2 & MII_PL_REV_MASK);
1378 
1379 #if VERBOSE
1380 	printf("OUI 0x%06x, Model 0x%02x, Revision 0x%x\n", oui, model, rev);
1381 #endif
1382 
1383 	if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO))
1384 	{
1385 		f= 1;
1386 #if VERBOSE
1387 		printf("%s: PHY: ", netdriver_name());
1388 		if (mii_ctrl & MII_CTRL_LB)
1389 		{
1390 			printf("loopback mode");
1391 			f= 0;
1392 		}
1393 		if (mii_ctrl & MII_CTRL_PD)
1394 		{
1395 			if (!f) printf(", ");
1396 			f= 0;
1397 			printf("powered down");
1398 		}
1399 		if (mii_ctrl & MII_CTRL_ISO)
1400 		{
1401 			if (!f) printf(", ");
1402 			f= 0;
1403 			printf("isolated");
1404 		}
1405 		printf("\n");
1406 #endif
1407 		return;
1408 	}
1409 	if (!(mii_ctrl & MII_CTRL_ANE))
1410 	{
1411 #if VERBOSE
1412 		printf("%s: manual config: ", netdriver_name());
1413 		switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB))
1414 		{
1415 		case MII_CTRL_SP_10:	printf("10 Mbps"); break;
1416 		case MII_CTRL_SP_100:	printf("100 Mbps"); break;
1417 		case MII_CTRL_SP_1000:	printf("1000 Mbps"); break;
1418 		case MII_CTRL_SP_RES:	printf("reserved speed"); break;
1419 		}
1420 		if (mii_ctrl & MII_CTRL_DM)
1421 			printf(", full duplex");
1422 		else
1423 			printf(", half duplex");
1424 		printf("\n");
1425 #endif
1426 		return;
1427 	}
1428 
1429 #if VERBOSE
1430 	printf("%s: ", netdriver_name());
1431 	mii_print_stat_speed(mii_status, mii_extstat);
1432 	printf("\n");
1433 
1434 	if (!(mii_status & MII_STATUS_ANC))
1435 		printf("%s: auto-negotiation not complete\n",
1436 		    netdriver_name());
1437 	if (mii_status & MII_STATUS_RF)
1438 		printf("%s: remote fault detected\n", netdriver_name());
1439 	if (!(mii_status & MII_STATUS_ANA))
1440 	{
1441 		printf("%s: local PHY has no auto-negotiation ability\n",
1442 			netdriver_name());
1443 	}
1444 	if (!(mii_status & MII_STATUS_LS))
1445 		printf("%s: link down\n", netdriver_name());
1446 	if (mii_status & MII_STATUS_JD)
1447 		printf("%s: jabber condition detected\n", netdriver_name());
1448 	if (!(mii_status & MII_STATUS_EC))
1449 	{
1450 		printf("%s: no extended register set\n", netdriver_name());
1451 		goto resspeed;
1452 	}
1453 	if (!(mii_status & MII_STATUS_ANC))
1454 		goto resspeed;
1455 
1456 	printf("%s: local cap.: ", netdriver_name());
1457 	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1458 	{
1459 		printf("1000 Mbps: T-");
1460 		switch(mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1461 		{
1462 		case MII_MSC_1000T_FD:	printf("FD"); break;
1463 		case MII_MSC_1000T_HD:	printf("HD"); break;
1464 		default:		printf("FD/HD"); break;
1465 		}
1466 		if (mii_ana)
1467 			printf(", ");
1468 	}
1469 	mii_print_techab(mii_ana);
1470 	printf("\n");
1471 
1472 	if (mii_ane & MII_ANE_PDF)
1473 		printf("%s: parallel detection fault\n", netdriver_name());
1474 	if (!(mii_ane & MII_ANE_LPANA))
1475 	{
1476 		printf("%s: link-partner does not support auto-negotiation\n",
1477 			netdriver_name());
1478 		goto resspeed;
1479 	}
1480 
1481 	printf("%s: remote cap.: ", netdriver_name());
1482 	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1483 	if (mii_ms_status & (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))
1484 	{
1485 		printf("1000 Mbps: T-");
1486 		switch(mii_ms_status &
1487 			(MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))
1488 		{
1489 		case MII_MSS_LP1000T_FD:	printf("FD"); break;
1490 		case MII_MSS_LP1000T_HD:	printf("HD"); break;
1491 		default:			printf("FD/HD"); break;
1492 		}
1493 		if (mii_anlpa)
1494 			printf(", ");
1495 	}
1496 	mii_print_techab(mii_anlpa);
1497 	printf("\n");
1498 
1499 	if (fp->fxp_ms_regs)
1500 	{
1501 		printf("%s: ", netdriver_name());
1502 		if (mii_ms_ctrl & MII_MSC_MS_MANUAL)
1503 		{
1504 			printf("manual %s",
1505 				(mii_ms_ctrl & MII_MSC_MS_VAL) ?
1506 				"MASTER" : "SLAVE");
1507 		}
1508 		else
1509 		{
1510 			printf("%s device",
1511 				(mii_ms_ctrl & MII_MSC_MULTIPORT) ?
1512 				"multiport" : "single-port");
1513 		}
1514 		if (mii_ms_ctrl & MII_MSC_RES)
1515 			printf(" reserved<0x%x>", mii_ms_ctrl & MII_MSC_RES);
1516 		printf(": ");
1517 		if (mii_ms_status & MII_MSS_FAULT)
1518 			printf("M/S config fault");
1519 		else if (mii_ms_status & MII_MSS_MASTER)
1520 			printf("MASTER");
1521 		else
1522 			printf("SLAVE");
1523 		printf("\n");
1524 	}
1525 
1526 	if (mii_ms_status & (MII_MSS_LP1000T_FD|MII_MSS_LP1000T_HD))
1527 	{
1528 		if (!(mii_ms_status & MII_MSS_LOCREC))
1529 		{
1530 			printf("%s: local receiver not OK\n",
1531 				netdriver_name());
1532 		}
1533 		if (!(mii_ms_status & MII_MSS_REMREC))
1534 		{
1535 			printf("%s: remote receiver not OK\n",
1536 				netdriver_name());
1537 		}
1538 	}
1539 	if (mii_ms_status & (MII_MSS_RES|MII_MSS_IDLE_ERR))
1540 	{
1541 		printf("%s", netdriver_name());
1542 		if (mii_ms_status & MII_MSS_RES)
1543 			printf(" reserved<0x%x>", mii_ms_status & MII_MSS_RES);
1544 		if (mii_ms_status & MII_MSS_IDLE_ERR)
1545 		{
1546 			printf(" idle error %d",
1547 				mii_ms_status & MII_MSS_IDLE_ERR);
1548 		}
1549 		printf("\n");
1550 	}
1551 resspeed:
1552 #endif
1553 
1554 #if VERBOSE
1555 	printf("%s: link up, %d Mbps, %s duplex\n",
1556 		netdriver_name(), (scr & MII_SCR_100) ? 100 : 10,
1557 		(scr & MII_SCR_FD) ? "full" : "half");
1558 #endif
1559 }
1560 
1561 /*===========================================================================*
1562  *				eeprom_read				     *
1563  *===========================================================================*/
1564 static u16_t eeprom_read(fxp_t *fp, int reg)
1565 {
1566 	port_t port;
1567 	u16_t v;
1568 	int b, i, alen;
1569 
1570 	alen= fp->fxp_ee_addrlen;
1571 	if (!alen)
1572 	{
1573 		eeprom_addrsize(fp);
1574 		alen= fp->fxp_ee_addrlen;
1575 		assert(alen == 6 || alen == 8);
1576 	}
1577 
1578 	port= fp->fxp_base_port;
1579 
1580 	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */
1581 	v= EEPROM_READ_PREFIX;
1582 	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)
1583 	{
1584 		b= ((v & (1 << i)) ? CE_EEDI : 0);
1585 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
1586 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
1587 		micro_delay(EESK_PERIOD/2+1);
1588 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
1589 		micro_delay(EESK_PERIOD/2+1);
1590 	}
1591 
1592 	v= reg;
1593 	for (i= alen-1; i >= 0; i--)
1594 	{
1595 		b= ((v & (1 << i)) ? CE_EEDI : 0);
1596 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
1597 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
1598 		micro_delay(EESK_PERIOD/2+1);
1599 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
1600 		micro_delay(EESK_PERIOD/2+1);
1601 	}
1602 
1603 	v= 0;
1604 	for (i= 0; i<16; i++)
1605 	{
1606 		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */
1607 		micro_delay(EESK_PERIOD/2+1);
1608 		b= !!(fxp_inb(port, CSR_EEPROM) & CE_EEDO);
1609 		v= (v << 1) | b;
1610 		fxp_outb(port, CSR_EEPROM, CE_EECS );
1611 		micro_delay(EESK_PERIOD/2+1);
1612 	}
1613 	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */
1614 	micro_delay(EECS_DELAY);
1615 
1616 	return v;
1617 }
1618 
1619 /*===========================================================================*
1620  *				eeprom_addrsize				     *
1621  *===========================================================================*/
1622 static void eeprom_addrsize(fxp_t *fp)
1623 {
1624 	port_t port;
1625 	u16_t v;
1626 	int b, i;
1627 
1628 	port= fp->fxp_base_port;
1629 
1630 	/* Try to find out the size of the EEPROM */
1631 	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */
1632 	v= EEPROM_READ_PREFIX;
1633 	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)
1634 	{
1635 		b= ((v & (1 << i)) ? CE_EEDI : 0);
1636 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
1637 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
1638 		micro_delay(EESK_PERIOD/2+1);
1639 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
1640 		micro_delay(EESK_PERIOD/2+1);
1641 	}
1642 
1643 	for (i= 0; i<32; i++)
1644 	{
1645 		b= 0;
1646 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
1647 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
1648 		micro_delay(EESK_PERIOD/2+1);
1649 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
1650 		micro_delay(EESK_PERIOD/2+1);
1651 		v= fxp_inb(port, CSR_EEPROM);
1652 		if (!(v & CE_EEDO))
1653 			break;
1654 	}
1655 	if (i >= 32)
1656 		panic("eeprom_addrsize: failed");
1657 	fp->fxp_ee_addrlen= i+1;
1658 
1659 	/* Discard 16 data bits */
1660 	for (i= 0; i<16; i++)
1661 	{
1662 		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */
1663 		micro_delay(EESK_PERIOD/2+1);
1664 		fxp_outb(port, CSR_EEPROM, CE_EECS );
1665 		micro_delay(EESK_PERIOD/2+1);
1666 	}
1667 	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */
1668 	micro_delay(EECS_DELAY);
1669 
1670 #if VERBOSE
1671 	printf("%s EEPROM address length: %d\n",
1672 		netdriver_name(), fp->fxp_ee_addrlen);
1673 #endif
1674 }
1675 
1676 /*===========================================================================*
1677  *				mii_read				     *
1678  *===========================================================================*/
1679 static u16_t mii_read(fxp_t *fp, int reg)
1680 {
1681 	spin_t spin;
1682 	port_t port;
1683 	u32_t v;
1684 
1685 	port= fp->fxp_base_port;
1686 
1687 	if (!(fxp_inl(port, CSR_MDI_CTL) & CM_READY))
1688 		panic("mii_read: MDI not ready");
1689 	fxp_outl(port, CSR_MDI_CTL, CM_READ | (1 << CM_PHYADDR_SHIFT) |
1690 		(reg << CM_REG_SHIFT));
1691 
1692 	spin_init(&spin, 100000);
1693 	do {
1694 		v= fxp_inl(port, CSR_MDI_CTL);
1695 		if (v & CM_READY)
1696 			break;
1697 	} while (spin_check(&spin));
1698 
1699 	if (!(v & CM_READY))
1700 		panic("mii_read: MDI not ready after command");
1701 
1702 	return v & CM_DATA_MASK;
1703 }
1704 
1705 static u8_t do_inb(port_t port)
1706 {
1707 	int r;
1708 	u32_t value;
1709 
1710 	r= sys_inb(port, &value);
1711 	if (r != OK)
1712 		panic("sys_inb failed: %d", r);
1713 	return value;
1714 }
1715 
1716 static u32_t do_inl(port_t port)
1717 {
1718 	int r;
1719 	u32_t value;
1720 
1721 	r= sys_inl(port, &value);
1722 	if (r != OK)
1723 		panic("sys_inl failed: %d", r);
1724 	return value;
1725 }
1726 
1727 static void do_outb(port_t port, u8_t value)
1728 {
1729 	int r;
1730 
1731 	r= sys_outb(port, value);
1732 	if (r != OK)
1733 		panic("sys_outb failed: %d", r);
1734 }
1735 
1736 static void do_outl(port_t port, u32_t value)
1737 {
1738 	int r;
1739 
1740 	r= sys_outl(port, value);
1741 	if (r != OK)
1742 		panic("sys_outl failed: %d", r);
1743 }
1744 
1745 /* TODO: obviously this needs a lot of work. */
1746 static void tell_iommu(vir_bytes buf, size_t size, int pci_bus, int pci_dev,
1747 	int pci_func)
1748 {
1749 	int r;
1750 	endpoint_t dev_e;
1751 	message m;
1752 
1753 	r= ds_retrieve_label_endpt("amddev", &dev_e);
1754 	if (r != OK)
1755 	{
1756 #if 0
1757 		printf("fxp`tell_iommu: ds_retrieve_label_endpt failed "
1758 		    "for 'amddev': %d\n", r);
1759 #endif
1760 		return;
1761 	}
1762 
1763 	m.m_type= IOMMU_MAP;
1764 	m.m2_i1= pci_bus;
1765 	m.m2_i2= pci_dev;
1766 	m.m2_i3= pci_func;
1767 	m.m2_l1= buf;
1768 	m.m2_l2= size;
1769 
1770 	r= ipc_sendrec(dev_e, &m);
1771 	if (r != OK)
1772 	{
1773 		printf("fxp`tell_iommu: ipc_sendrec to %d failed: %d\n",
1774 			dev_e, r);
1775 		return;
1776 	}
1777 	if (m.m_type != OK)
1778 	{
1779 		printf("fxp`tell_iommu: dma map request failed: %d\n",
1780 			m.m_type);
1781 		return;
1782 	}
1783 }
1784 
1785 /*
1786  * $PchId: fxp.c,v 1.4 2005/01/31 22:10:37 philip Exp $
1787  */
1788