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