xref: /minix/minix/drivers/net/fxp/fxp.c (revision 433d6423)
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 <stdlib.h>
14 #include <net/hton.h>
15 #include <net/gen/ether.h>
16 #include <net/gen/eth_io.h>
17 #include <machine/pci.h>
18 #include <minix/ds.h>
19 #include <minix/endpoint.h>
20 
21 #include <minix/timers.h>
22 
23 #define debug			0
24 #define RAND_UPDATE		/**/
25 #define printW()		((void)0)
26 
27 #include "assert.h"
28 #include "fxp.h"
29 #include "mii.h"
30 
31 /* Number of receive buffers */
32 #define N_RX_BUF	40
33 
34 /* Number of transmit buffers */
35 #define N_TX_BUF	4
36 
37 /* I/O vectors are handled IOVEC_NR entries at a time. */
38 #define IOVEC_NR	16
39 
40 /* Configuration */
41 #define FXP_ENVVAR	"FXPETH"
42 
43 typedef int irq_hook_t;
44 
45 /* ignore interrupt for the moment */
46 #define interrupt(x)	do { } while(0)
47 
48 static union tmpbuf
49 {
50 	char pad[4096];
51 	struct cbl_conf cc;
52 	struct ias ias;
53 } *tmpbufp;
54 
55 typedef struct fxp
56 {
57 	port_t fxp_base_port;
58 	int fxp_mode;
59 	int fxp_got_int;
60 	int fxp_send_int;
61 	int fxp_flags;
62 	int fxp_client;
63 	int fxp_features;		/* Needed? */
64 	int fxp_irq;
65 	int fxp_type;			/* What kind of hardware */
66 	int fxp_ms_regs;		/* Master/slave registers */
67 	int fxp_ee_addrlen;		/* #EEPROM address bits */
68 	int fxp_tx_alive;
69 	int fxp_need_reset;
70 
71 	/* Rx */
72 	vir_bytes fxp_read_s;
73 	int fxp_rx_nbuf;
74 	int fxp_rx_bufsize;
75 	struct rfd *fxp_rx_buf;
76 	phys_bytes fxp_rx_busaddr;
77 	int fxp_rx_head;
78 	int fxp_rx_need_restart;
79 	int fxp_need_conf;		/* Re-configure after draining send
80 					 * queue
81 					 */
82 
83 	/* Tx */
84 	int fxp_tx_nbuf;
85 	int fxp_tx_bufsize;
86 	struct tx *fxp_tx_buf;
87 	phys_bytes fxp_tx_busaddr;
88 	int fxp_tx_idle;
89 	int fxp_tx_head;
90 	int fxp_tx_tail;
91 	int fxp_tx_threshold;
92 
93 	/* Link status */
94 	int fxp_report_link;
95 	int fxp_link_up;
96 	int fxp_mii_busy;
97 	u16_t fxp_mii_scr;
98 
99 	/* PCI related */
100 	int fxp_seen;			/* TRUE iff device available */
101 
102 	/* 'large' items */
103 	irq_hook_t fxp_hook;
104 	ether_addr_t fxp_address;
105 	message fxp_rx_mess;
106 	message fxp_tx_mess;
107 	struct sc fxp_stat;
108 	u8_t fxp_conf_bytes[CC_BYTES_NR];
109 	char fxp_name[sizeof("fxp#n")];
110 	iovec_t fxp_iovec[IOVEC_NR];
111 	iovec_s_t fxp_iovec_s[IOVEC_NR];
112 }
113 fxp_t;
114 
115 /* fxp_mode */
116 #define FM_DISABLED	0x0
117 #define FM_ENABLED	0x1
118 
119 /* fxp_flags */
120 #define FF_EMPTY	0x000
121 #define FF_PACK_SENT	0x001
122 #define FF_PACK_RECV	0x002
123 #define FF_SEND_AVAIL	0x004
124 #define FF_READING	0x010
125 #define FF_PROMISC	0x040
126 #define FF_MULTI	0x080
127 #define FF_BROAD	0x100
128 #define FF_ENABLED	0x200
129 
130 /* fxp_features */
131 #define FFE_NONE	0x0
132 
133 /* fxp_type */
134 #define FT_UNKNOWN	0x0
135 #define FT_82557	0x1
136 #define FT_82558A	0x2
137 #define FT_82559	0x4
138 #define FT_82801	0x8
139 
140 static int fxp_instance;
141 
142 static fxp_t *fxp_state;
143 
144 static minix_timer_t fxp_watchdog;
145 
146 static u32_t system_hz;
147 
148 #define fxp_inb(port, offset)	(do_inb((port) + (offset)))
149 #define fxp_inl(port, offset)	(do_inl((port) + (offset)))
150 #define fxp_outb(port, offset, value)	(do_outb((port) + (offset), (value)))
151 #define fxp_outl(port, offset, value)	(do_outl((port) + (offset), (value)))
152 
153 static void fxp_init(message *mp);
154 static void fxp_pci_conf(void);
155 static int fxp_probe(fxp_t *fp, int skip);
156 static void fxp_conf_hw(fxp_t *fp);
157 static void fxp_init_hw(fxp_t *fp);
158 static void fxp_init_buf(fxp_t *fp);
159 static void fxp_reset_hw(fxp_t *fp);
160 static void fxp_confaddr(fxp_t *fp);
161 static void fxp_rec_mode(fxp_t *fp);
162 static void fxp_writev_s(const message *mp, int from_int);
163 static void fxp_readv_s(message *mp, int from_int);
164 static void fxp_do_conf(fxp_t *fp);
165 static void fxp_cu_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int
166 	check_idle);
167 static void fxp_ru_ptr_cmd(fxp_t *fp, int cmd, phys_bytes bus_addr, int
168 	check_idle);
169 static void fxp_restart_ru(fxp_t *fp);
170 static void fxp_getstat_s(message *mp);
171 static void fxp_handler(fxp_t *fp);
172 static void fxp_check_ints(fxp_t *fp);
173 static void fxp_watchdog_f(minix_timer_t *tp);
174 static int fxp_link_changed(fxp_t *fp);
175 static void fxp_report_link(fxp_t *fp);
176 static void reply(fxp_t *fp);
177 static void mess_reply(message *req, message *reply);
178 static u16_t eeprom_read(fxp_t *fp, int reg);
179 static void eeprom_addrsize(fxp_t *fp);
180 static u16_t mii_read(fxp_t *fp, int reg);
181 static u8_t do_inb(port_t port);
182 static u32_t do_inl(port_t port);
183 static void do_outb(port_t port, u8_t v);
184 static void do_outl(port_t port, u32_t v);
185 static void tell_dev(vir_bytes start, size_t size, int pci_bus, int
186 	pci_dev, int pci_func);
187 
188 static void handle_hw_intr(void)
189 {
190 	int r;
191 	fxp_t *fp;
192 
193 	fp= fxp_state;
194 
195 	if (fp->fxp_mode != FM_ENABLED)
196 		return;
197 	fxp_handler(fp);
198 
199 	r= sys_irqenable(&fp->fxp_hook);
200 	if (r != OK) {
201 		panic("unable enable interrupts: %d", r);
202 	}
203 
204 	if (!fp->fxp_got_int)
205 		return;
206 	fp->fxp_got_int= 0;
207 	assert(fp->fxp_flags & FF_ENABLED);
208 	fxp_check_ints(fp);
209 }
210 
211 /* SEF functions and variables. */
212 static void sef_local_startup(void);
213 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
214 static void sef_cb_signal_handler(int signo);
215 
216 /*===========================================================================*
217  *				main					     *
218  *===========================================================================*/
219 int main(int argc, char *argv[])
220 {
221 	message m;
222 	int ipc_status;
223 	int r;
224 
225 	/* SEF local startup. */
226 	env_setargs(argc, argv);
227 	sef_local_startup();
228 
229 	while (TRUE)
230 	{
231 		if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
232 			panic("netdriver_receive failed: %d", r);
233 
234 		if (is_ipc_notify(ipc_status)) {
235 			switch (_ENDPOINT_P(m.m_source)) {
236 				case HARDWARE:
237 					handle_hw_intr();
238 					break;
239 				case CLOCK:
240 					expire_timers(m.m_notify.timestamp);
241 					break;
242 				default:
243 					panic(" illegal notify from: %d", m.m_source);
244 			}
245 
246 			/* get new message */
247 			continue;
248 		}
249 
250 		switch (m.m_type)
251 		{
252 		case DL_WRITEV_S: fxp_writev_s(&m, FALSE);	break;
253 		case DL_READV_S: fxp_readv_s(&m, FALSE);	break;
254 		case DL_CONF:	fxp_init(&m);			break;
255 		case DL_GETSTAT_S: fxp_getstat_s(&m);		break;
256 		default:
257 			panic(" illegal message: %d", m.m_type);
258 		}
259 	}
260 }
261 
262 /*===========================================================================*
263  *			       sef_local_startup			     *
264  *===========================================================================*/
265 static void sef_local_startup()
266 {
267   /* Register init callbacks. */
268   sef_setcb_init_fresh(sef_cb_init_fresh);
269   sef_setcb_init_lu(sef_cb_init_fresh);
270   sef_setcb_init_restart(sef_cb_init_fresh);
271 
272   /* Register live update callbacks. */
273   sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
274   sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
275 
276   /* Register signal callbacks. */
277   sef_setcb_signal_handler(sef_cb_signal_handler);
278 
279   /* Let SEF perform startup. */
280   sef_startup();
281 }
282 
283 /*===========================================================================*
284  *		            sef_cb_init_fresh                                *
285  *===========================================================================*/
286 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
287 {
288 /* Initialize the fxp driver. */
289 	long v;
290 	int r;
291 	vir_bytes ft;
292 
293 	system_hz = sys_hz();
294 
295 	v = 0;
296 	(void) env_parse("instance", "d", 0, &v, 0, 255);
297 	fxp_instance = (int) v;
298 
299 	ft = sizeof(*fxp_state);
300 
301 	if(!(fxp_state = alloc_contig(ft, 0, NULL)))
302 		panic("couldn't allocate table: %d", ENOMEM);
303 
304 	memset(fxp_state, 0, ft);
305 
306 	if((r=tsc_calibrate()) != OK)
307 		panic("tsc_calibrate failed: %d", r);
308 
309 	/* Announce we are up! */
310 	netdriver_announce();
311 
312 	return(OK);
313 }
314 
315 /*===========================================================================*
316  *		           sef_cb_signal_handler                             *
317  *===========================================================================*/
318 static void sef_cb_signal_handler(int signo)
319 {
320 	port_t port;
321 	fxp_t *fp;
322 
323 	/* Only check for termination signal, ignore anything else. */
324 	if (signo != SIGTERM) return;
325 
326 	fp= fxp_state;
327 
328 	if (fp->fxp_mode == FM_ENABLED && (fp->fxp_flags & FF_ENABLED)) {
329 		port= fp->fxp_base_port;
330 
331 		/* Reset device */
332 		if (debug)
333 			printf("%s: resetting device\n", fp->fxp_name);
334 		fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
335 	}
336 
337 	exit(0);
338 }
339 
340 /*===========================================================================*
341  *				fxp_init				     *
342  *===========================================================================*/
343 static void fxp_init(mp)
344 message *mp;
345 {
346 	static int first_time= 1;
347 
348 	fxp_t *fp;
349 	message reply_mess;
350 
351 	if (first_time)
352 	{
353 		first_time= 0;
354 		fxp_pci_conf(); /* Configure PCI devices. */
355 
356 		init_timer(&fxp_watchdog);
357 		set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f, 0);
358 	}
359 
360 	fp= fxp_state;
361 	if (fp->fxp_mode == FM_DISABLED)
362 	{
363 		/* This is the default, try to (re)locate the device. */
364 		fxp_conf_hw(fp);
365 		if (fp->fxp_mode == FM_DISABLED)
366 		{
367 			/* Probe failed, or the device is configured off. */
368 			reply_mess.m_type= DL_CONF_REPLY;
369 			reply_mess.m_netdrv_net_dl_conf.stat= ENXIO;
370 			mess_reply(mp, &reply_mess);
371 			return;
372 		}
373 		if (fp->fxp_mode == FM_ENABLED)
374 			fxp_init_hw(fp);
375 		fxp_report_link(fp);
376 	}
377 
378 	assert(fp->fxp_mode == FM_ENABLED);
379 	assert(fp->fxp_flags & FF_ENABLED);
380 
381 	fp->fxp_flags &= ~(FF_PROMISC | FF_MULTI | FF_BROAD);
382 
383 	if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ)
384 		fp->fxp_flags |= FF_PROMISC;
385 	if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ)
386 		fp->fxp_flags |= FF_MULTI;
387 	if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ)
388 		fp->fxp_flags |= FF_BROAD;
389 
390 	fxp_rec_mode(fp);
391 
392 	reply_mess.m_type = DL_CONF_REPLY;
393 	reply_mess.m_netdrv_net_dl_conf.stat = OK;
394 	memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr,
395 		fp->fxp_address.ea_addr,
396 		sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr));
397 
398 	mess_reply(mp, &reply_mess);
399 }
400 
401 /*===========================================================================*
402  *				fxp_pci_conf				     *
403  *===========================================================================*/
404 static void fxp_pci_conf()
405 {
406 	fxp_t *fp;
407 
408 	fp= fxp_state;
409 
410 	strlcpy(fp->fxp_name, "fxp#0", sizeof(fp->fxp_name));
411 	fp->fxp_name[4] += fxp_instance;
412 	fp->fxp_seen= FALSE;
413 	fp->fxp_features= FFE_NONE;
414 
415 	pci_init();
416 
417 	if (fxp_probe(fp, fxp_instance))
418 		fp->fxp_seen= TRUE;
419 }
420 
421 /*===========================================================================*
422  *				fxp_probe				     *
423  *===========================================================================*/
424 static int fxp_probe(fxp_t *fp, int skip)
425 {
426 	int r, devind;
427 	u16_t vid, did;
428 	u32_t bar;
429 	u8_t ilr, rev;
430 	char *str;
431 #if VERBOSE
432 	char *dname;
433 #endif
434 
435 	r= pci_first_dev(&devind, &vid, &did);
436 	if (r == 0)
437 		return FALSE;
438 
439 	while (skip--)
440 	{
441 		r= pci_next_dev(&devind, &vid, &did);
442 		if (!r)
443 			return FALSE;
444 	}
445 
446 #if VERBOSE
447 	dname= pci_dev_name(vid, did);
448 	if (!dname)
449 		dname= "unknown device";
450 	printf("%s: %s (%04x/%04x) at %s\n",
451 		fp->fxp_name, dname, vid, did, pci_slot_name(devind));
452 #endif
453 	pci_reserve(devind);
454 
455 	bar= pci_attr_r32(devind, PCI_BAR_2) & 0xffffffe0;
456 	if (bar < 0x400) {
457 		panic("fxp_probe: base address is not properly configured");
458 	}
459 	fp->fxp_base_port= bar;
460 
461 	ilr= pci_attr_r8(devind, PCI_ILR);
462 	fp->fxp_irq= ilr;
463 	if (debug)
464 	{
465 		printf("%s: using I/O address 0x%lx, IRQ %d\n",
466 			fp->fxp_name, (unsigned long)bar, ilr);
467 	}
468 
469 	rev= pci_attr_r8(devind, PCI_REV);
470 	str= NULL;
471 	fp->fxp_type= FT_UNKNOWN;
472 	switch(rev)
473 	{
474 	case FXP_REV_82557A:	str= "82557A";			/* 0x01 */
475 				fp->fxp_type= FT_82557;
476 				break;
477 	case FXP_REV_82557B:	str= "82557B"; break;		/* 0x02 */
478 	case FXP_REV_82557C:	str= "82557C"; break;		/* 0x03 */
479 	case FXP_REV_82558A:	str= "82558A"; 			/* 0x04 */
480 				fp->fxp_type= FT_82558A;
481 				break;
482 	case FXP_REV_82558B:	str= "82558B"; 			/* 0x05 */
483 				fp->fxp_type= FT_82559;
484 				break;
485 	case FXP_REV_82559A:	str= "82559A"; break;		/* 0x06 */
486 	case FXP_REV_82559B:	str= "82559B"; break;		/* 0x07 */
487 	case FXP_REV_82559C:	str= "82559C";			/* 0x08 */
488 				fp->fxp_type= FT_82559;
489 				break;
490 	case FXP_REV_82559ERA:	str= "82559ER-A"; 		/* 0x09 */
491 				fp->fxp_type= FT_82559;
492 				break;
493 	case FXP_REV_82550_1:	str= "82550(1)"; 		/* 0x0C */
494 				fp->fxp_type= FT_82559;
495 				break;
496 	case FXP_REV_82550_2:	str= "82550(2)"; 		/* 0x0D */
497 				fp->fxp_type= FT_82559;
498 				break;
499 	case FXP_REV_82550_3:	str= "82550(3)"; 		/* 0x0E */
500 				fp->fxp_type= FT_82559;
501 				break;
502 	case FXP_REV_82551_1:	str= "82551(1)"; 		/* 0x0F */
503 				fp->fxp_type= FT_82559;
504 				break;
505 	case FXP_REV_82551_2:	str= "82551(2)"; 		/* 0x10 */
506 				fp->fxp_type= FT_82559;
507 				break;
508 	case FXP_REV_82801CAM:	str= "82801CAM"; 		/* 0x42 */
509 				fp->fxp_type= FT_82801;
510 				break;
511 	case FXP_REV_82801DB:	str= "82801DB"; 		/* 0x81 */
512 				fp->fxp_type= FT_82801;
513 				break;
514 	case FXP_REV_82550_4:	str= "82550(4)"; 		/* 0x83 */
515 				fp->fxp_type= FT_82559;
516 				break;
517 	}
518 
519 #if VERBOSE
520 	if (str)
521 		printf("%s: device revision: %s\n", fp->fxp_name, str);
522 	else
523 		printf("%s: unknown revision: 0x%x\n", fp->fxp_name, rev);
524 #endif
525 
526 	if (fp->fxp_type == FT_UNKNOWN)
527 	{
528 		printf("fxp_probe: device is not supported by this driver\n");
529 		return FALSE;
530 	}
531 
532 	return TRUE;
533 }
534 
535 /*===========================================================================*
536  *				fxp_conf_hw				     *
537  *===========================================================================*/
538 static void fxp_conf_hw(fxp_t *fp)
539 {
540 #if VERBOSE
541 	int i;
542 #endif
543 
544 	fp->fxp_mode= FM_DISABLED;	/* Superfluous */
545 
546 	if (!fp->fxp_seen)
547 		return;
548 
549 	/* PCI device is present */
550 	fp->fxp_mode= FM_ENABLED;
551 
552 	fp->fxp_flags= FF_EMPTY;
553 	fp->fxp_got_int= 0;
554 	fp->fxp_send_int= 0;
555 	fp->fxp_ee_addrlen= 0;	/* Unknown */
556 	fp->fxp_need_reset= 0;
557 	fp->fxp_report_link= 0;
558 	fp->fxp_link_up= -1;	/* Unknown */
559 	fp->fxp_mii_busy= 0;
560 	fp->fxp_read_s= 0;
561 	fp->fxp_rx_need_restart= 0;
562 	fp->fxp_need_conf= 0;
563 	fp->fxp_tx_head= 0;
564 	fp->fxp_tx_tail= 0;
565 	fp->fxp_tx_alive= 0;
566 	fp->fxp_tx_threshold= TXTT_MIN;
567 
568 	/* Try to come up with a sensible configuration for the current
569 	 * device. Unfortunately every device is different, defaults are
570 	 * not always zero, and some fields are re-used with a completely
571 	 * different interpretation. We start out with a sensible default
572 	 * for all devices and then add device specific changes.
573 	 */
574 	fp->fxp_conf_bytes[0]= CC_BYTES_NR;
575 	fp->fxp_conf_bytes[1]= CTL_DEFAULT | CRL_DEFAULT;
576 	fp->fxp_conf_bytes[2]= CAI_DEFAULT;
577 	fp->fxp_conf_bytes[3]= 0;
578 	fp->fxp_conf_bytes[4]= 0;
579 	fp->fxp_conf_bytes[5]= 0;
580 	fp->fxp_conf_bytes[6]= CCB6_ESC | CCB6_ETCB | CCB6_RES;
581 	fp->fxp_conf_bytes[7]= CUR_1;
582 	fp->fxp_conf_bytes[8]= CCB8_503_MII;
583 	fp->fxp_conf_bytes[9]= 0;
584 	fp->fxp_conf_bytes[10]= CLB_NORMAL | CPAL_DEFAULT | CCB10_NSAI |
585 				CCB10_RES1;
586 	fp->fxp_conf_bytes[11]= 0;
587 	fp->fxp_conf_bytes[12]= CIS_DEFAULT;
588 	fp->fxp_conf_bytes[13]= CCB13_DEFAULT;
589 	fp->fxp_conf_bytes[14]= CCB14_DEFAULT;
590 	fp->fxp_conf_bytes[15]= CCB15_RES1 | CCB15_RES2;
591 	fp->fxp_conf_bytes[16]= CCB16_DEFAULT;
592 	fp->fxp_conf_bytes[17]= CCB17_DEFAULT;
593 	fp->fxp_conf_bytes[18]= CCB18_RES1 | CCB18_PFCT | CCB18_PE;
594 	fp->fxp_conf_bytes[19]= CCB19_FDPE;
595 	fp->fxp_conf_bytes[20]= CCB20_PFCL | CCB20_RES1;
596 	fp->fxp_conf_bytes[21]= CCB21_RES21;
597 
598 #if VERBOSE
599 	for (i= 0; i<CC_BYTES_NR; i++)
600 		printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]);
601 	printf("\n");
602 #endif
603 
604 	switch(fp->fxp_type)
605 	{
606 	case FT_82557:
607 		break;
608 	case FT_82558A:
609 	case FT_82559:
610 	case FT_82801:
611 		fp->fxp_conf_bytes[18] |= CCB18_LROK;
612 
613 		if (fp->fxp_type == FT_82801)
614 		{
615 			fp->fxp_conf_bytes[6] = 0xba; /* ctrl 1 */
616 			fp->fxp_conf_bytes[15] = 0x48; /* promiscuous */
617 			fp->fxp_conf_bytes[21] = 0x05; /* mc_all */
618 		}
619 		break;
620 	default:
621 		panic("fxp_conf_hw: bad device type: %d", fp->fxp_type);
622 	}
623 
624 	/* Assume an 82555 (compatible) PHY. The should be changed for
625 	 * 82557 NICs with different PHYs
626 	 */
627 	fp->fxp_ms_regs = 0;	/* No master/slave registers. */
628 
629 #if VERBOSE
630 	for (i= 0; i<CC_BYTES_NR; i++)
631 		printf("%d: %0x, ", i, fp->fxp_conf_bytes[i]);
632 	printf("\n");
633 #endif
634 }
635 
636 /*===========================================================================*
637  *				fxp_init_hw				     *
638  *===========================================================================*/
639 static void fxp_init_hw(fp)
640 fxp_t *fp;
641 {
642 	int i, r, isr;
643 	port_t port;
644 	phys_bytes bus_addr;
645 
646 	port= fp->fxp_base_port;
647 
648 	fxp_init_buf(fp);
649 
650 	fp->fxp_flags = FF_EMPTY;
651 	fp->fxp_flags |= FF_ENABLED;
652 
653 	/* Set the interrupt handler and policy. Do not automatically
654 	 * reenable interrupts. Return the IRQ line number on interrupts.
655  	 */
656  	fp->fxp_hook = fp->fxp_irq;
657 	r= sys_irqsetpolicy(fp->fxp_irq, 0, &fp->fxp_hook);
658 	if (r != OK)
659 		panic("sys_irqsetpolicy failed: %d", r);
660 
661 	fxp_reset_hw(fp);
662 
663 	r= sys_irqenable(&fp->fxp_hook);
664 	if (r != OK)
665 		panic("sys_irqenable failed: %d", r);
666 
667 	/* Reset PHY? */
668 
669 	fxp_do_conf(fp);
670 
671 	/* Set pointer to statistical counters */
672 	r= sys_umap(SELF, VM_D, (vir_bytes)&fp->fxp_stat, sizeof(fp->fxp_stat),
673 		&bus_addr);
674 	if (r != OK)
675 		panic("sys_umap failed: %d", r);
676 	fxp_cu_ptr_cmd(fp, SC_CU_LOAD_DCA, bus_addr, TRUE /* check idle */);
677 
678 	/* Ack previous interrupts */
679 	isr= fxp_inb(port, SCB_INT_STAT);
680 	fxp_outb(port, SCB_INT_STAT, isr);
681 
682 	/* Enable interrupts */
683 	fxp_outb(port, SCB_INT_MASK, 0);
684 
685 	fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr,
686 		TRUE /* check idle */);
687 
688 	fxp_confaddr(fp);
689 	if (debug)
690 	{
691 		printf("%s: Ethernet address ", fp->fxp_name);
692 		for (i= 0; i < 6; i++)
693 		{
694 			printf("%x%c", fp->fxp_address.ea_addr[i],
695 				i < 5 ? ':' : '\n');
696 		}
697 	}
698 }
699 
700 /*===========================================================================*
701  *				fxp_init_buf				     *
702  *===========================================================================*/
703 static void fxp_init_buf(fp)
704 fxp_t *fp;
705 {
706 	size_t rx_totbufsize, tx_totbufsize, tot_bufsize, alloc_bufsize;
707 	char *alloc_buf;
708 	phys_bytes buf, bus_addr;
709 	int i, r;
710 	struct rfd *rfdp;
711 	struct tx *txp;
712 	phys_bytes ph;
713 
714 	fp->fxp_rx_nbuf= N_RX_BUF;
715 	rx_totbufsize= fp->fxp_rx_nbuf * sizeof(struct rfd);
716 	fp->fxp_rx_bufsize= rx_totbufsize;
717 
718 	fp->fxp_tx_nbuf= N_TX_BUF;
719 	tx_totbufsize= fp->fxp_tx_nbuf * sizeof(struct tx);
720 	fp->fxp_tx_bufsize= tx_totbufsize;
721 
722 	tot_bufsize= sizeof(*tmpbufp) + tx_totbufsize + rx_totbufsize;
723 	if (tot_bufsize % 4096)
724 		tot_bufsize += 4096 - (tot_bufsize % 4096);
725 	alloc_bufsize= tot_bufsize;
726 	alloc_buf= alloc_contig(alloc_bufsize, AC_ALIGN4K, &ph);
727 	if (alloc_buf == NULL) {
728 		panic("fxp_init_buf: unable to alloc_contig size: %d", 			alloc_bufsize);
729 	}
730 
731 	buf= (phys_bytes)alloc_buf;
732 
733 	tell_dev((vir_bytes)buf, tot_bufsize, 0, 0, 0);
734 
735 	tmpbufp= (union tmpbuf *)buf;
736 
737 	fp->fxp_rx_buf= (struct rfd *)&tmpbufp[1];
738 	r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_rx_buf, rx_totbufsize,
739 		&bus_addr);
740 	if (r != OK)
741 		panic("sys_umap failed: %d", r);
742 	fp->fxp_rx_busaddr= bus_addr;
743 
744 #if 0
745 	printf("fxp_init_buf: got phys 0x%x for vir 0x%x\n",
746 		fp->fxp_rx_busaddr, fp->fxp_rx_buf);
747 #endif
748 
749 	for (i= 0, rfdp= fp->fxp_rx_buf; i<fp->fxp_rx_nbuf; i++, rfdp++)
750 	{
751 		rfdp->rfd_status= 0;
752 		rfdp->rfd_command= 0;
753 		if (i != fp->fxp_rx_nbuf-1)
754 		{
755 			r= sys_umap(SELF, VM_D, (vir_bytes)&rfdp[1],
756 				sizeof(rfdp[1]), &bus_addr);
757 			if (r != OK)
758 				panic("sys_umap failed: %d", r);
759 			rfdp->rfd_linkaddr= bus_addr;
760 		}
761 		else
762 		{
763 			rfdp->rfd_linkaddr= fp->fxp_rx_busaddr;
764 			rfdp->rfd_command |= RFDC_EL;
765 		}
766 		rfdp->rfd_reserved= 0;
767 		rfdp->rfd_res= 0;
768 		rfdp->rfd_size= sizeof(rfdp->rfd_buf);
769 
770 	}
771 	fp->fxp_rx_head= 0;
772 
773 	fp->fxp_tx_buf= (struct tx *)((char *)fp->fxp_rx_buf+rx_totbufsize);
774 	r= sys_umap(SELF, VM_D, (vir_bytes)fp->fxp_tx_buf,
775 		(phys_bytes)tx_totbufsize, &fp->fxp_tx_busaddr);
776 	if (r != OK)
777 		panic("sys_umap failed: %d", r);
778 
779 	for (i= 0, txp= fp->fxp_tx_buf; i<fp->fxp_tx_nbuf; i++, txp++)
780 	{
781 		txp->tx_status= 0;
782 		txp->tx_command= TXC_EL | CBL_NOP;	/* Just in case */
783 		if (i != fp->fxp_tx_nbuf-1)
784 		{
785 			r= sys_umap(SELF, VM_D, (vir_bytes)&txp[1],
786 				(phys_bytes)sizeof(txp[1]), &bus_addr);
787 			if (r != OK)
788 				panic("sys_umap failed: %d", r);
789 			txp->tx_linkaddr= bus_addr;
790 		}
791 		else
792 		{
793 			txp->tx_linkaddr= fp->fxp_tx_busaddr;
794 		}
795 		txp->tx_tbda= TX_TBDA_NIL;
796 		txp->tx_size= 0;
797 		txp->tx_tthresh= fp->fxp_tx_threshold;
798 		txp->tx_ntbd= 0;
799 	}
800 	fp->fxp_tx_idle= 1;
801 }
802 
803 /*===========================================================================*
804  *				fxp_reset_hw				     *
805  *===========================================================================*/
806 static void fxp_reset_hw(fp)
807 fxp_t *fp;
808 {
809 /* Inline the function in init? */
810 	port_t port;
811 
812 	port= fp->fxp_base_port;
813 
814 	/* Reset device */
815 	fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
816 	tickdelay(micros_to_ticks(CSR_PORT_RESET_DELAY));
817 
818 	/* Disable interrupts */
819 	fxp_outb(port, SCB_INT_MASK, SIM_M);
820 
821 	/* Set CU base to zero */
822 	fxp_cu_ptr_cmd(fp, SC_CU_LOAD_BASE, 0, TRUE /* check idle */);
823 
824 	/* Set RU base to zero */
825 	fxp_ru_ptr_cmd(fp, SC_RU_LOAD_BASE, 0, TRUE /* check idle */);
826 }
827 
828 /*===========================================================================*
829  *				fxp_confaddr				     *
830  *===========================================================================*/
831 static void fxp_confaddr(fxp_t *fp)
832 {
833 	static char eakey[]= FXP_ENVVAR "#_EA";
834 	static char eafmt[]= "x:x:x:x:x:x";
835 	int i, r;
836 	phys_bytes bus_addr;
837 	long v;
838 
839 	/* User defined ethernet address? */
840 	eakey[sizeof(FXP_ENVVAR)-1]= '0' + fxp_instance;
841 
842 	for (i= 0; i < 6; i++)
843 	{
844 		if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
845 			break;
846 		fp->fxp_address.ea_addr[i]= v;
847 	}
848 
849 	if (i != 0 && i != 6) env_panic(eakey);	/* It's all or nothing */
850 
851 	if (i == 0)
852 	{
853 		/* Get ethernet address from EEPROM */
854 		for (i= 0; i<3; i++)
855 		{
856 			v= eeprom_read(fp, i);
857 			fp->fxp_address.ea_addr[i*2]= (v & 0xff);
858 			fp->fxp_address.ea_addr[i*2+1]= ((v >> 8) & 0xff);
859 		}
860 	}
861 
862 	/* Tell NIC about ethernet address */
863 	tmpbufp->ias.ias_status= 0;
864 	tmpbufp->ias.ias_command= CBL_C_EL | CBL_AIS;
865 	tmpbufp->ias.ias_linkaddr= 0;
866 	memcpy(tmpbufp->ias.ias_ethaddr, fp->fxp_address.ea_addr,
867 		sizeof(tmpbufp->ias.ias_ethaddr));
868 	r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->ias,
869 		(phys_bytes)sizeof(tmpbufp->ias), &bus_addr);
870 	if (r != OK)
871 		panic("sys_umap failed: %d", r);
872 
873 	fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */);
874 
875 	/* Wait for CU command to complete */
876 	SPIN_UNTIL(tmpbufp->ias.ias_status & CBL_F_C, 1000);
877 
878 	if (!(tmpbufp->ias.ias_status & CBL_F_C))
879 		panic("fxp_confaddr: CU command failed to complete");
880 	if (!(tmpbufp->ias.ias_status & CBL_F_OK))
881 		panic("fxp_confaddr: CU command failed");
882 
883 #if VERBOSE
884 	printf("%s: hardware ethernet address: ", fp->fxp_name);
885 	for (i= 0; i<6; i++)
886 	{
887 		printf("%02x%s", fp->fxp_address.ea_addr[i],
888 			i < 5 ? ":" : "");
889 	}
890 	printf("\n");
891 #endif
892 }
893 
894 /*===========================================================================*
895  *				fxp_rec_mode				     *
896  *===========================================================================*/
897 static void fxp_rec_mode(fp)
898 fxp_t *fp;
899 {
900 	fp->fxp_conf_bytes[0]= CC_BYTES_NR;	/* Just to be sure */
901 	fp->fxp_conf_bytes[15] &= ~(CCB15_BD|CCB15_PM);
902 	fp->fxp_conf_bytes[21] &= ~CCB21_MA;
903 
904 	if (fp->fxp_flags & FF_PROMISC)
905 		fp->fxp_conf_bytes[15] |= CCB15_PM;
906 	if (fp->fxp_flags & FF_MULTI)
907 		fp->fxp_conf_bytes[21] |= CCB21_MA;
908 
909 	if (!(fp->fxp_flags & (FF_BROAD|FF_MULTI|FF_PROMISC)))
910 		fp->fxp_conf_bytes[15] |= CCB15_BD;
911 
912 	/* Queue request if not idle */
913 	if (fp->fxp_tx_idle)
914 	{
915 		fxp_do_conf(fp);
916 	}
917 	else
918 	{
919 		printf("fxp_rec_mode: setting fxp_need_conf\n");
920 		fp->fxp_need_conf= TRUE;
921 	}
922 }
923 
924 /*===========================================================================*
925  *				fxp_writev_s				     *
926  *===========================================================================*/
927 static void fxp_writev_s(const message *mp, int from_int)
928 {
929 	endpoint_t iov_endpt;
930 	cp_grant_id_t iov_grant;
931 	vir_bytes iov_offset;
932 	int i, j, n, o, r, s, count, size, prev_head;
933 	int fxp_tx_nbuf, fxp_tx_head;
934 	u16_t tx_command;
935 	fxp_t *fp;
936 	iovec_s_t *iovp;
937 	struct tx *txp, *prev_txp;
938 
939 	fp= fxp_state;
940 
941 	count = mp->m_net_netdrv_dl_writev_s.count;
942 	fp->fxp_client= mp->m_source;
943 
944 	assert(fp->fxp_mode == FM_ENABLED);
945 	assert(fp->fxp_flags & FF_ENABLED);
946 
947 	if (from_int)
948 	{
949 		assert(fp->fxp_flags & FF_SEND_AVAIL);
950 		fp->fxp_flags &= ~FF_SEND_AVAIL;
951 		fp->fxp_tx_alive= TRUE;
952 	}
953 
954 	if (fp->fxp_tx_idle)
955 	{
956 		txp= fp->fxp_tx_buf;
957 		fxp_tx_head= 0;	/* lint */
958 		prev_txp= NULL;	/* lint */
959 	}
960 	else
961 	{
962 		fxp_tx_nbuf= fp->fxp_tx_nbuf;
963 		prev_head= fp->fxp_tx_head;
964 		fxp_tx_head= prev_head+1;
965 		if (fxp_tx_head == fxp_tx_nbuf)
966 			fxp_tx_head= 0;
967 		assert(fxp_tx_head < fxp_tx_nbuf);
968 
969 		if (fxp_tx_head == fp->fxp_tx_tail)
970 		{
971 			/* Send queue is full */
972 			assert(!(fp->fxp_flags & FF_SEND_AVAIL));
973 			fp->fxp_flags |= FF_SEND_AVAIL;
974 			goto suspend;
975 		}
976 
977 		prev_txp= &fp->fxp_tx_buf[prev_head];
978 		txp= &fp->fxp_tx_buf[fxp_tx_head];
979 	}
980 
981 	assert(!(fp->fxp_flags & FF_SEND_AVAIL));
982 	assert(!(fp->fxp_flags & FF_PACK_SENT));
983 
984 	iov_endpt= mp->m_source;
985 	iov_grant= mp->m_net_netdrv_dl_writev_s.grant;
986 
987 	size= 0;
988 	o= 0;
989 	iov_offset= 0;
990 	for (i= 0; i<count; i += IOVEC_NR,
991 		iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0]))
992 	{
993 		n= IOVEC_NR;
994 		if (i+n > count)
995 			n= count-i;
996 		r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset,
997 			(vir_bytes)fp->fxp_iovec_s,
998 			n * sizeof(fp->fxp_iovec_s[0]));
999 		if (r != OK)
1000 			panic("fxp_writev: sys_safecopyfrom failed: %d", r);
1001 
1002 		for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++)
1003 		{
1004 			s= iovp->iov_size;
1005 			if (size + s > ETH_MAX_PACK_SIZE_TAGGED) {
1006 				panic("fxp_writev: invalid packet size: %d", size + s);
1007 			}
1008 
1009 			r= sys_safecopyfrom(iov_endpt, iovp->iov_grant,
1010 				0, (vir_bytes)(txp->tx_buf+o), s);
1011 			if (r != OK) {
1012 				panic("fxp_writev_s: sys_safecopyfrom failed: %d", r);
1013 			}
1014 			size += s;
1015 			o += s;
1016 		}
1017 	}
1018 	if (size < ETH_MIN_PACK_SIZE)
1019 		panic("fxp_writev: invalid packet size: %d", size);
1020 
1021 	txp->tx_status= 0;
1022 	txp->tx_command= TXC_EL | CBL_XMIT;
1023 	txp->tx_tbda= TX_TBDA_NIL;
1024 	txp->tx_size= TXSZ_EOF | size;
1025 	txp->tx_tthresh= fp->fxp_tx_threshold;
1026 	txp->tx_ntbd= 0;
1027 	if (fp->fxp_tx_idle)
1028 	{
1029 		fp->fxp_tx_idle= 0;
1030 		fp->fxp_tx_head= fp->fxp_tx_tail= 0;
1031 
1032 		fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr,
1033 			TRUE /* check idle */);
1034 	}
1035 	else
1036 	{
1037 		/* Link new request in transmit list */
1038 		tx_command= prev_txp->tx_command;
1039 		assert(tx_command == (TXC_EL | CBL_XMIT));
1040 		prev_txp->tx_command= CBL_XMIT;
1041 		fp->fxp_tx_head= fxp_tx_head;
1042 	}
1043 
1044 	fp->fxp_flags |= FF_PACK_SENT;
1045 
1046 	/* If the interrupt handler called, don't send a reply. The reply
1047 	 * will be sent after all interrupts are handled.
1048 	 */
1049 	if (from_int)
1050 		return;
1051 	reply(fp);
1052 	return;
1053 
1054 suspend:
1055 	if (from_int)
1056 		panic("fxp: should not be sending");
1057 
1058 	fp->fxp_tx_mess= *mp;
1059 	reply(fp);
1060 }
1061 
1062 /*===========================================================================*
1063  *				fxp_readv_s				     *
1064  *===========================================================================*/
1065 static void fxp_readv_s(mp, from_int)
1066 message *mp;
1067 int from_int;
1068 {
1069 	int i, j, n, o, r, s, count, size, fxp_rx_head, fxp_rx_nbuf;
1070 	endpoint_t iov_endpt;
1071 	cp_grant_id_t iov_grant;
1072 	port_t port;
1073 	unsigned packlen;
1074 	vir_bytes iov_offset;
1075 	u16_t rfd_status;
1076 	u16_t rfd_res;
1077 	u8_t scb_status;
1078 	fxp_t *fp;
1079 	iovec_s_t *iovp;
1080 	struct rfd *rfdp, *prev_rfdp;
1081 
1082 	fp= fxp_state;
1083 
1084 	count = mp->m_net_netdrv_dl_readv_s.count;
1085 	fp->fxp_client= mp->m_source;
1086 
1087 	assert(fp->fxp_mode == FM_ENABLED);
1088 	assert(fp->fxp_flags & FF_ENABLED);
1089 
1090 	port= fp->fxp_base_port;
1091 
1092 	fxp_rx_head= fp->fxp_rx_head;
1093 	rfdp= &fp->fxp_rx_buf[fxp_rx_head];
1094 
1095 	rfd_status= rfdp->rfd_status;
1096 	if (!(rfd_status & RFDS_C))
1097 	{
1098 		/* Receive buffer is empty, suspend */
1099 		goto suspend;
1100 	}
1101 
1102 	if (!(rfd_status & RFDS_OK))
1103 	{
1104 		/* Not OK? What happened? */
1105 		assert(0);
1106 	}
1107 	else
1108 	{
1109 		assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR |
1110 			RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT |
1111 			RFDS_RXERR)));
1112 	}
1113 	rfd_res= rfdp->rfd_res;
1114 	assert(rfd_res & RFDR_EOF);
1115 	assert(rfd_res & RFDR_F);
1116 
1117 	packlen= rfd_res & RFDSZ_SIZE;
1118 
1119 	iov_endpt = mp->m_source;
1120 	iov_grant = mp->m_net_netdrv_dl_readv_s.grant;
1121 
1122 	size= 0;
1123 	o= 0;
1124 	iov_offset= 0;
1125 	for (i= 0; i<count; i += IOVEC_NR,
1126 		iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0]))
1127 	{
1128 		n= IOVEC_NR;
1129 		if (i+n > count)
1130 			n= count-i;
1131 		r= sys_safecopyfrom(iov_endpt, iov_grant, iov_offset,
1132 			(vir_bytes)fp->fxp_iovec_s,
1133 			n * sizeof(fp->fxp_iovec_s[0]));
1134 		if (r != OK)
1135 			panic("fxp_readv_s: sys_safecopyfrom failed: %d", r);
1136 
1137 		for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++)
1138 		{
1139 			s= iovp->iov_size;
1140 			if (size + s > packlen)
1141 			{
1142 				assert(packlen > size);
1143 				s= packlen-size;
1144 			}
1145 
1146 			r= sys_safecopyto(iov_endpt, iovp->iov_grant,
1147 				0, (vir_bytes)(rfdp->rfd_buf+o), s);
1148 			if (r != OK)
1149 			{
1150 				panic("fxp_readv: sys_safecopyto failed: %d", r);
1151 			}
1152 
1153 			size += s;
1154 			if (size == packlen)
1155 				break;
1156 			o += s;
1157 		}
1158 		if (size == packlen)
1159 			break;
1160 	}
1161 	if (size < packlen)
1162 	{
1163 		assert(0);
1164 	}
1165 
1166 	fp->fxp_read_s= packlen;
1167 	fp->fxp_flags= (fp->fxp_flags & ~FF_READING) | FF_PACK_RECV;
1168 
1169 	/* Re-init the current buffer */
1170 	rfdp->rfd_status= 0;
1171 	rfdp->rfd_command= RFDC_EL;
1172 	rfdp->rfd_reserved= 0;
1173 	rfdp->rfd_res= 0;
1174 	rfdp->rfd_size= sizeof(rfdp->rfd_buf);
1175 
1176 	fxp_rx_nbuf= fp->fxp_rx_nbuf;
1177 	if (fxp_rx_head == 0)
1178 	{
1179 		prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1];
1180 	}
1181 	else
1182 		prev_rfdp= &rfdp[-1];
1183 
1184 	assert(prev_rfdp->rfd_command & RFDC_EL);
1185 	prev_rfdp->rfd_command &= ~RFDC_EL;
1186 
1187 	fxp_rx_head++;
1188 	if (fxp_rx_head == fxp_rx_nbuf)
1189 		fxp_rx_head= 0;
1190 	assert(fxp_rx_head < fxp_rx_nbuf);
1191 	fp->fxp_rx_head= fxp_rx_head;
1192 
1193 	if (!from_int)
1194 		reply(fp);
1195 
1196 	return;
1197 
1198 suspend:
1199 	if (fp->fxp_rx_need_restart)
1200 	{
1201 		fp->fxp_rx_need_restart= 0;
1202 
1203 		/* Check the status of the RU */
1204 		scb_status= fxp_inb(port, SCB_STATUS);
1205 		if ((scb_status & SS_RUS_MASK) != SS_RU_NORES)
1206 		{
1207 			/* Race condition? */
1208 			printf("fxp_readv: restart race: 0x%x\n",
1209 				scb_status);
1210 			assert((scb_status & SS_RUS_MASK) == SS_RU_READY);
1211 		}
1212 		else
1213 		{
1214 			fxp_restart_ru(fp);
1215 		}
1216 	}
1217 	if (from_int)
1218 	{
1219 		assert(fp->fxp_flags & FF_READING);
1220 
1221 		/* No need to store any state */
1222 		return;
1223 	}
1224 
1225 	fp->fxp_rx_mess= *mp;
1226 	assert(!(fp->fxp_flags & FF_READING));
1227 	fp->fxp_flags |= FF_READING;
1228 
1229 	reply(fp);
1230 }
1231 
1232 /*===========================================================================*
1233  *				fxp_do_conf				     *
1234  *===========================================================================*/
1235 static void fxp_do_conf(fp)
1236 fxp_t *fp;
1237 {
1238 	int r;
1239 	phys_bytes bus_addr;
1240 
1241 	/* Configure device */
1242 	tmpbufp->cc.cc_status= 0;
1243 	tmpbufp->cc.cc_command= CBL_C_EL | CBL_CONF;
1244 	tmpbufp->cc.cc_linkaddr= 0;
1245 	memcpy(tmpbufp->cc.cc_bytes, fp->fxp_conf_bytes,
1246 		sizeof(tmpbufp->cc.cc_bytes));
1247 
1248 	r= sys_umap(SELF, VM_D, (vir_bytes)&tmpbufp->cc,
1249 		(phys_bytes)sizeof(tmpbufp->cc), &bus_addr);
1250 	if (r != OK)
1251 		panic("sys_umap failed: %d", r);
1252 
1253 	fxp_cu_ptr_cmd(fp, SC_CU_START, bus_addr, TRUE /* check idle */);
1254 
1255 	/* Wait for CU command to complete */
1256 	SPIN_UNTIL(tmpbufp->cc.cc_status & CBL_F_C, 100000);
1257 
1258 	if (!(tmpbufp->cc.cc_status & CBL_F_C))
1259 		panic("fxp_do_conf: CU command failed to complete");
1260 	if (!(tmpbufp->cc.cc_status & CBL_F_OK))
1261 		panic("fxp_do_conf: CU command failed");
1262 
1263 }
1264 
1265 /*===========================================================================*
1266  *				fxp_cu_ptr_cmd				     *
1267  *===========================================================================*/
1268 static void fxp_cu_ptr_cmd(fp, cmd, bus_addr, check_idle)
1269 fxp_t *fp;
1270 int cmd;
1271 phys_bytes bus_addr;
1272 int check_idle;
1273 {
1274 	spin_t spin;
1275 	port_t port;
1276 	u8_t scb_cmd;
1277 
1278 	port= fp->fxp_base_port;
1279 
1280 	if (check_idle)
1281 	{
1282 		/* Consistency check. Make sure that CU is idle */
1283 		if ((fxp_inb(port, SCB_STATUS) & SS_CUS_MASK) != SS_CU_IDLE)
1284 			panic("fxp_cu_ptr_cmd: CU is not idle");
1285 	}
1286 
1287 	fxp_outl(port, SCB_POINTER, bus_addr);
1288 	fxp_outb(port, SCB_CMD, cmd);
1289 
1290 	/* What is a reasonable time-out? There is nothing in the
1291 	 * documentation. 1 ms should be enough. We use 100 ms.
1292 	 */
1293 	spin_init(&spin, 100000);
1294 	do {
1295 		/* Wait for CU command to be accepted */
1296 		scb_cmd= fxp_inb(port, SCB_CMD);
1297 		if ((scb_cmd & SC_CUC_MASK) == SC_CU_NOP)
1298 			break;
1299 	} while (spin_check(&spin));
1300 
1301 	if ((scb_cmd & SC_CUC_MASK) != SC_CU_NOP)
1302 		panic("fxp_cu_ptr_cmd: CU does not accept command");
1303 }
1304 
1305 /*===========================================================================*
1306  *				fxp_ru_ptr_cmd				     *
1307  *===========================================================================*/
1308 static void fxp_ru_ptr_cmd(fp, cmd, bus_addr, check_idle)
1309 fxp_t *fp;
1310 int cmd;
1311 phys_bytes bus_addr;
1312 int check_idle;
1313 {
1314 	spin_t spin;
1315 	port_t port;
1316 	u8_t scb_cmd;
1317 
1318 	port= fp->fxp_base_port;
1319 
1320 	if (check_idle)
1321 	{
1322 		/* Consistency check, make sure that RU is idle */
1323 		if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_IDLE)
1324 			panic("fxp_ru_ptr_cmd: RU is not idle");
1325 	}
1326 
1327 	fxp_outl(port, SCB_POINTER, bus_addr);
1328 	fxp_outb(port, SCB_CMD, cmd);
1329 
1330 	spin_init(&spin, 1000);
1331 	do {
1332 		/* Wait for RU command to be accepted */
1333 		scb_cmd= fxp_inb(port, SCB_CMD);
1334 		if ((scb_cmd & SC_RUC_MASK) == SC_RU_NOP)
1335 			break;
1336 	} while (spin_check(&spin));
1337 
1338 	if ((scb_cmd & SC_RUC_MASK) != SC_RU_NOP)
1339 		panic("fxp_ru_ptr_cmd: RU does not accept command");
1340 }
1341 
1342 /*===========================================================================*
1343  *				fxp_restart_ru				     *
1344  *===========================================================================*/
1345 static void fxp_restart_ru(fp)
1346 fxp_t *fp;
1347 {
1348 	int i, fxp_rx_nbuf;
1349 	port_t port;
1350 	struct rfd *rfdp;
1351 
1352 	port= fp->fxp_base_port;
1353 
1354 	fxp_rx_nbuf= fp->fxp_rx_nbuf;
1355 	for (i= 0, rfdp= fp->fxp_rx_buf; i<fxp_rx_nbuf; i++, rfdp++)
1356 	{
1357 		rfdp->rfd_status= 0;
1358 		rfdp->rfd_command= 0;
1359 		if (i == fp->fxp_rx_nbuf-1)
1360 			rfdp->rfd_command= RFDC_EL;
1361 		rfdp->rfd_reserved= 0;
1362 		rfdp->rfd_res= 0;
1363 		rfdp->rfd_size= sizeof(rfdp->rfd_buf);
1364 	}
1365 	fp->fxp_rx_head= 0;
1366 
1367 	/* Make sure that RU is in the 'No resources' state */
1368 	if ((fxp_inb(port, SCB_STATUS) & SS_RUS_MASK) != SS_RU_NORES)
1369 		panic("fxp_restart_ru: RU is in an unexpected state");
1370 
1371 	fxp_ru_ptr_cmd(fp, SC_RU_START, fp->fxp_rx_busaddr,
1372 		FALSE /* do not check idle */);
1373 }
1374 
1375 /*===========================================================================*
1376  *				fxp_getstat_s				     *
1377  *===========================================================================*/
1378 static void fxp_getstat_s(message *mp)
1379 {
1380 	int r;
1381 	fxp_t *fp;
1382 	u32_t *p;
1383 	eth_stat_t stats;
1384 
1385 	fp= fxp_state;
1386 
1387 	assert(fp->fxp_mode == FM_ENABLED);
1388 	assert(fp->fxp_flags & FF_ENABLED);
1389 
1390 	p= &fp->fxp_stat.sc_tx_fcp;
1391 	*p= 0;
1392 
1393 	/* The dump commmand doesn't take a pointer. Setting a pointer
1394 	 * doesn't hurt though.
1395 	 */
1396 	fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */);
1397 
1398 	/* Wait for CU command to complete */
1399 	SPIN_UNTIL(*p != 0, 1000);
1400 
1401 	if (*p == 0)
1402 		panic("fxp_getstat: CU command failed to complete");
1403 	if (*p != SCM_DSC)
1404 		panic("fxp_getstat: bad magic");
1405 
1406 	stats.ets_recvErr=
1407 		fp->fxp_stat.sc_rx_crc +
1408 		fp->fxp_stat.sc_rx_align +
1409 		fp->fxp_stat.sc_rx_resource +
1410 		fp->fxp_stat.sc_rx_overrun +
1411 		fp->fxp_stat.sc_rx_cd +
1412 		fp->fxp_stat.sc_rx_short;
1413 	stats.ets_sendErr=
1414 		fp->fxp_stat.sc_tx_maxcol +
1415 		fp->fxp_stat.sc_tx_latecol +
1416 		fp->fxp_stat.sc_tx_crs;
1417 	stats.ets_OVW= fp->fxp_stat.sc_rx_overrun;
1418 	stats.ets_CRCerr= fp->fxp_stat.sc_rx_crc;
1419 	stats.ets_frameAll= fp->fxp_stat.sc_rx_align;
1420 	stats.ets_missedP= fp->fxp_stat.sc_rx_resource;
1421 	stats.ets_packetR= fp->fxp_stat.sc_rx_good;
1422 	stats.ets_packetT= fp->fxp_stat.sc_tx_good;
1423 	stats.ets_transDef= fp->fxp_stat.sc_tx_defered;
1424 	stats.ets_collision= fp->fxp_stat.sc_tx_totcol;
1425 	stats.ets_transAb= fp->fxp_stat.sc_tx_maxcol;
1426 	stats.ets_carrSense= fp->fxp_stat.sc_tx_crs;
1427 	stats.ets_fifoUnder= fp->fxp_stat.sc_tx_underrun;
1428 	stats.ets_fifoOver= fp->fxp_stat.sc_rx_overrun;
1429 	stats.ets_CDheartbeat= 0;
1430 	stats.ets_OWC= fp->fxp_stat.sc_tx_latecol;
1431 
1432 	r= sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0,
1433 		(vir_bytes)&stats, sizeof(stats));
1434 	if (r != OK)
1435 		panic("fxp_getstat_s: sys_safecopyto failed: %d", r);
1436 
1437 	mp->m_type= DL_STAT_REPLY;
1438 	r= ipc_send(mp->m_source, mp);
1439 	if (r != OK)
1440 		panic("fxp_getstat_s: ipc_send failed: %d", r);
1441 }
1442 
1443 /*===========================================================================*
1444  *				fxp_handler				     *
1445  *===========================================================================*/
1446 static void fxp_handler(fxp_t *fp)
1447 {
1448 	int port;
1449 	u16_t isr;
1450 
1451 	RAND_UPDATE
1452 
1453 	port= fp->fxp_base_port;
1454 
1455 	/* Ack interrupt */
1456 	isr= fxp_inb(port, SCB_INT_STAT);
1457 	fxp_outb(port, SCB_INT_STAT, isr);
1458 
1459 	if (isr & SIS_FR)
1460 	{
1461 		isr &= ~SIS_FR;
1462 
1463 		if (!fp->fxp_got_int && (fp->fxp_flags & FF_READING))
1464 		{
1465 			fp->fxp_got_int= TRUE;
1466 			interrupt(fxp_tasknr);
1467 		}
1468 	}
1469 	if (isr & SIS_CNA)
1470 	{
1471 		isr &= ~SIS_CNA;
1472 		if (!fp->fxp_tx_idle)
1473 		{
1474 			fp->fxp_send_int= TRUE;
1475 			if (!fp->fxp_got_int)
1476 			{
1477 				fp->fxp_got_int= TRUE;
1478 				interrupt(fxp_tasknr);
1479 			}
1480 		}
1481 	}
1482 	if (isr & SIS_RNR)
1483 	{
1484 		isr &= ~SIS_RNR;
1485 
1486 		/* Assume that receive buffer is full of packets. fxp_readv
1487 		 * will restart the RU.
1488 		 */
1489 		fp->fxp_rx_need_restart= 1;
1490 	}
1491 	if (isr)
1492 	{
1493 		printf("fxp_handler: unhandled interrupt: isr = 0x%02x\n",
1494 			isr);
1495 	}
1496 }
1497 
1498 /*===========================================================================*
1499  *				fxp_check_ints				     *
1500  *===========================================================================*/
1501 static void fxp_check_ints(fxp_t *fp)
1502 {
1503 	int n, fxp_flags, prev_tail;
1504 	int fxp_tx_tail, fxp_tx_nbuf, fxp_tx_threshold;
1505 	port_t port;
1506 	u32_t busaddr;
1507 	u16_t tx_status;
1508 	u8_t scb_status;
1509 	struct tx *txp;
1510 
1511 	fxp_flags= fp->fxp_flags;
1512 
1513 	if (fxp_flags & FF_READING)
1514 	{
1515 		if (!(fp->fxp_rx_buf[fp->fxp_rx_head].rfd_status & RFDS_C))
1516 			; /* Nothing */
1517 		else
1518 		{
1519 			fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */);
1520 		}
1521 	}
1522 	if (fp->fxp_tx_idle)
1523 		;	/* Nothing to do */
1524 	else if (fp->fxp_send_int)
1525 	{
1526 		fp->fxp_send_int= FALSE;
1527 		fxp_tx_tail= fp->fxp_tx_tail;
1528 		fxp_tx_nbuf= fp->fxp_tx_nbuf;
1529 		n= 0;
1530 		for (;;)
1531 		{
1532 			txp= &fp->fxp_tx_buf[fxp_tx_tail];
1533 			tx_status= txp->tx_status;
1534 			if (!(tx_status & TXS_C))
1535 				break;
1536 
1537 			n++;
1538 
1539 			assert(tx_status & TXS_OK);
1540 			if (tx_status & TXS_U)
1541 			{
1542 				fxp_tx_threshold= fp->fxp_tx_threshold;
1543 				if (fxp_tx_threshold < TXTT_MAX)
1544 				{
1545 					fxp_tx_threshold++;
1546 					fp->fxp_tx_threshold= fxp_tx_threshold;
1547 				}
1548 				printf(
1549 			"fxp_check_ints: fxp_tx_threshold = 0x%x\n",
1550 					fxp_tx_threshold);
1551 			}
1552 
1553 			if (txp->tx_command & TXC_EL)
1554 			{
1555 				fp->fxp_tx_idle= 1;
1556 				break;
1557 			}
1558 
1559 			fxp_tx_tail++;
1560 			if (fxp_tx_tail == fxp_tx_nbuf)
1561 				fxp_tx_tail= 0;
1562 			assert(fxp_tx_tail < fxp_tx_nbuf);
1563 		}
1564 
1565 		if (fp->fxp_need_conf)
1566 		{
1567 			/* Check the status of the CU */
1568 			port= fp->fxp_base_port;
1569 			scb_status= fxp_inb(port, SCB_STATUS);
1570 			if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE)
1571 			{
1572 				/* Nothing to do */
1573 				printf("scb_status = 0x%x\n", scb_status);
1574 			}
1575 			else
1576 			{
1577 				printf("fxp_check_ints: fxp_need_conf\n");
1578 				fp->fxp_need_conf= FALSE;
1579 				fxp_do_conf(fp);
1580 			}
1581 		}
1582 
1583 		if (n)
1584 		{
1585 			if (!fp->fxp_tx_idle)
1586 			{
1587 				fp->fxp_tx_tail= fxp_tx_tail;
1588 
1589 				/* Check the status of the CU */
1590 				port= fp->fxp_base_port;
1591 				scb_status= fxp_inb(port, SCB_STATUS);
1592 				if ((scb_status & SS_CUS_MASK) != SS_CU_IDLE)
1593 				{
1594 					/* Nothing to do */
1595 					printf("scb_status = 0x%x\n",
1596 						scb_status);
1597 
1598 				}
1599 				else
1600 				{
1601 					if (fxp_tx_tail == 0)
1602 						prev_tail= fxp_tx_nbuf-1;
1603 					else
1604 						prev_tail= fxp_tx_tail-1;
1605 					busaddr= fp->fxp_tx_buf[prev_tail].
1606 						tx_linkaddr;
1607 
1608 					fxp_cu_ptr_cmd(fp, SC_CU_START,
1609 						busaddr, 1 /* check idle */);
1610 				}
1611 			}
1612 
1613 			if (fp->fxp_flags & FF_SEND_AVAIL)
1614 			{
1615 				fxp_writev_s(&fp->fxp_tx_mess,
1616 					TRUE /* from int */);
1617 			}
1618 		}
1619 
1620 	}
1621 	if (fp->fxp_report_link)
1622 		fxp_report_link(fp);
1623 
1624 	if (fp->fxp_flags & (FF_PACK_SENT | FF_PACK_RECV))
1625 		reply(fp);
1626 }
1627 
1628 /*===========================================================================*
1629  *				fxp_watchdog_f				     *
1630  *===========================================================================*/
1631 static void fxp_watchdog_f(tp)
1632 minix_timer_t *tp;
1633 {
1634 	fxp_t *fp;
1635 
1636 	set_timer(&fxp_watchdog, system_hz, fxp_watchdog_f, 0);
1637 
1638 	fp= fxp_state;
1639 	if (fp->fxp_mode != FM_ENABLED)
1640 		return;
1641 
1642 	/* Handle race condition, MII interface might be busy */
1643 	if(!fp->fxp_mii_busy)
1644 	{
1645 		/* Check the link status. */
1646 		if (fxp_link_changed(fp))
1647 		{
1648 #if VERBOSE
1649 			printf("fxp_watchdog_f: link changed\n");
1650 #endif
1651 			fp->fxp_report_link= TRUE;
1652 			fp->fxp_got_int= TRUE;
1653 			interrupt(fxp_tasknr);
1654 		}
1655 	}
1656 
1657 	if (!(fp->fxp_flags & FF_SEND_AVAIL))
1658 	{
1659 		/* Assume that an idle system is alive */
1660 		fp->fxp_tx_alive= TRUE;
1661 		return;
1662 	}
1663 	if (fp->fxp_tx_alive)
1664 	{
1665 		fp->fxp_tx_alive= FALSE;
1666 		return;
1667 	}
1668 
1669 	fp->fxp_need_reset= TRUE;
1670 	fp->fxp_got_int= TRUE;
1671 	interrupt(fxp_tasknr);
1672 }
1673 
1674 /*===========================================================================*
1675  *				fxp_link_changed			     *
1676  *===========================================================================*/
1677 static int fxp_link_changed(fp)
1678 fxp_t *fp;
1679 {
1680 	u16_t scr;
1681 
1682 	scr= mii_read(fp, MII_SCR);
1683 	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);
1684 
1685 	return (fp->fxp_mii_scr != scr);
1686 }
1687 
1688 /*===========================================================================*
1689  *				fxp_report_link				     *
1690  *===========================================================================*/
1691 static void fxp_report_link(fxp_t *fp)
1692 {
1693 	u16_t mii_ctrl, mii_status, mii_id1, mii_id2,
1694 		mii_ana, mii_anlpa, mii_ane, mii_extstat,
1695 		mii_ms_ctrl, mii_ms_status, scr;
1696 	u32_t oui;
1697 	int model, rev;
1698 	int f, link_up;
1699 
1700 	fp->fxp_report_link= FALSE;
1701 
1702 	scr= mii_read(fp, MII_SCR);
1703 	scr &= ~(MII_SCR_RES|MII_SCR_RES_1);
1704 	fp->fxp_mii_scr= scr;
1705 
1706 	mii_ctrl= mii_read(fp, MII_CTRL);
1707 	mii_read(fp, MII_STATUS); /* The status reg is latched, read twice */
1708 	mii_status= mii_read(fp, MII_STATUS);
1709 	mii_id1= mii_read(fp, MII_PHYID_H);
1710 	mii_id2= mii_read(fp, MII_PHYID_L);
1711 	mii_ana= mii_read(fp, MII_ANA);
1712 	mii_anlpa= mii_read(fp, MII_ANLPA);
1713 	mii_ane= mii_read(fp, MII_ANE);
1714 	if (mii_status & MII_STATUS_EXT_STAT)
1715 		mii_extstat= mii_read(fp, MII_EXT_STATUS);
1716 	else
1717 		mii_extstat= 0;
1718 	if (fp->fxp_ms_regs)
1719 	{
1720 		mii_ms_ctrl= mii_read(fp, MII_MS_CTRL);
1721 		mii_ms_status= mii_read(fp, MII_MS_STATUS);
1722 	}
1723 	else
1724 	{
1725 		mii_ms_ctrl= 0;
1726 		mii_ms_status= 0;
1727 	}
1728 
1729 	/* How do we know about the link status? */
1730 	link_up= !!(mii_status & MII_STATUS_LS);
1731 
1732 	fp->fxp_link_up= link_up;
1733 	if (!link_up)
1734 	{
1735 #if VERBOSE
1736 		printf("%s: link down\n", fp->fxp_name);
1737 #endif
1738 		return;
1739 	}
1740 
1741 	oui= (mii_id1 << MII_PH_OUI_H_C_SHIFT) |
1742 		((mii_id2 & MII_PL_OUI_L_MASK) >> MII_PL_OUI_L_SHIFT);
1743 	model= ((mii_id2 & MII_PL_MODEL_MASK) >> MII_PL_MODEL_SHIFT);
1744 	rev= (mii_id2 & MII_PL_REV_MASK);
1745 
1746 #if VERBOSE
1747 	printf("OUI 0x%06lx, Model 0x%02x, Revision 0x%x\n", oui, model, rev);
1748 #endif
1749 
1750 	if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO))
1751 	{
1752 		printf("%s: PHY: ", fp->fxp_name);
1753 		f= 1;
1754 		if (mii_ctrl & MII_CTRL_LB)
1755 		{
1756 			printf("loopback mode");
1757 			f= 0;
1758 		}
1759 		if (mii_ctrl & MII_CTRL_PD)
1760 		{
1761 			if (!f) printf(", ");
1762 			f= 0;
1763 			printf("powered down");
1764 		}
1765 		if (mii_ctrl & MII_CTRL_ISO)
1766 		{
1767 			if (!f) printf(", ");
1768 			f= 0;
1769 			printf("isolated");
1770 		}
1771 		printf("\n");
1772 		return;
1773 	}
1774 	if (!(mii_ctrl & MII_CTRL_ANE))
1775 	{
1776 		printf("%s: manual config: ", fp->fxp_name);
1777 		switch(mii_ctrl & (MII_CTRL_SP_LSB|MII_CTRL_SP_MSB))
1778 		{
1779 		case MII_CTRL_SP_10:	printf("10 Mbps"); break;
1780 		case MII_CTRL_SP_100:	printf("100 Mbps"); break;
1781 		case MII_CTRL_SP_1000:	printf("1000 Mbps"); break;
1782 		case MII_CTRL_SP_RES:	printf("reserved speed"); break;
1783 		}
1784 		if (mii_ctrl & MII_CTRL_DM)
1785 			printf(", full duplex");
1786 		else
1787 			printf(", half duplex");
1788 		printf("\n");
1789 		return;
1790 	}
1791 
1792 	if (!debug) goto resspeed;
1793 
1794 	printf("%s: ", fp->fxp_name);
1795 	mii_print_stat_speed(mii_status, mii_extstat);
1796 	printf("\n");
1797 
1798 	if (!(mii_status & MII_STATUS_ANC))
1799 		printf("%s: auto-negotiation not complete\n", fp->fxp_name);
1800 	if (mii_status & MII_STATUS_RF)
1801 		printf("%s: remote fault detected\n", fp->fxp_name);
1802 	if (!(mii_status & MII_STATUS_ANA))
1803 	{
1804 		printf("%s: local PHY has no auto-negotiation ability\n",
1805 			fp->fxp_name);
1806 	}
1807 	if (!(mii_status & MII_STATUS_LS))
1808 		printf("%s: link down\n", fp->fxp_name);
1809 	if (mii_status & MII_STATUS_JD)
1810 		printf("%s: jabber condition detected\n", fp->fxp_name);
1811 	if (!(mii_status & MII_STATUS_EC))
1812 	{
1813 		printf("%s: no extended register set\n", fp->fxp_name);
1814 		goto resspeed;
1815 	}
1816 	if (!(mii_status & MII_STATUS_ANC))
1817 		goto resspeed;
1818 
1819 	printf("%s: local cap.: ", fp->fxp_name);
1820 	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1821 	{
1822 		printf("1000 Mbps: T-");
1823 		switch(mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1824 		{
1825 		case MII_MSC_1000T_FD:	printf("FD"); break;
1826 		case MII_MSC_1000T_HD:	printf("HD"); break;
1827 		default:		printf("FD/HD"); break;
1828 		}
1829 		if (mii_ana)
1830 			printf(", ");
1831 	}
1832 	mii_print_techab(mii_ana);
1833 	printf("\n");
1834 
1835 	if (mii_ane & MII_ANE_PDF)
1836 		printf("%s: parallel detection fault\n", fp->fxp_name);
1837 	if (!(mii_ane & MII_ANE_LPANA))
1838 	{
1839 		printf("%s: link-partner does not support auto-negotiation\n",
1840 			fp->fxp_name);
1841 		goto resspeed;
1842 	}
1843 
1844 	printf("%s: remote cap.: ", fp->fxp_name);
1845 	if (mii_ms_ctrl & (MII_MSC_1000T_FD | MII_MSC_1000T_HD))
1846 	if (mii_ms_status & (MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))
1847 	{
1848 		printf("1000 Mbps: T-");
1849 		switch(mii_ms_status &
1850 			(MII_MSS_LP1000T_FD | MII_MSS_LP1000T_HD))
1851 		{
1852 		case MII_MSS_LP1000T_FD:	printf("FD"); break;
1853 		case MII_MSS_LP1000T_HD:	printf("HD"); break;
1854 		default:			printf("FD/HD"); break;
1855 		}
1856 		if (mii_anlpa)
1857 			printf(", ");
1858 	}
1859 	mii_print_techab(mii_anlpa);
1860 	printf("\n");
1861 
1862 	if (fp->fxp_ms_regs)
1863 	{
1864 		printf("%s: ", fp->fxp_name);
1865 		if (mii_ms_ctrl & MII_MSC_MS_MANUAL)
1866 		{
1867 			printf("manual %s",
1868 				(mii_ms_ctrl & MII_MSC_MS_VAL) ?
1869 				"MASTER" : "SLAVE");
1870 		}
1871 		else
1872 		{
1873 			printf("%s device",
1874 				(mii_ms_ctrl & MII_MSC_MULTIPORT) ?
1875 				"multiport" : "single-port");
1876 		}
1877 		if (mii_ms_ctrl & MII_MSC_RES)
1878 			printf(" reserved<0x%x>", mii_ms_ctrl & MII_MSC_RES);
1879 		printf(": ");
1880 		if (mii_ms_status & MII_MSS_FAULT)
1881 			printf("M/S config fault");
1882 		else if (mii_ms_status & MII_MSS_MASTER)
1883 			printf("MASTER");
1884 		else
1885 			printf("SLAVE");
1886 		printf("\n");
1887 	}
1888 
1889 	if (mii_ms_status & (MII_MSS_LP1000T_FD|MII_MSS_LP1000T_HD))
1890 	{
1891 		if (!(mii_ms_status & MII_MSS_LOCREC))
1892 		{
1893 			printf("%s: local receiver not OK\n",
1894 				fp->fxp_name);
1895 		}
1896 		if (!(mii_ms_status & MII_MSS_REMREC))
1897 		{
1898 			printf("%s: remote receiver not OK\n",
1899 				fp->fxp_name);
1900 		}
1901 	}
1902 	if (mii_ms_status & (MII_MSS_RES|MII_MSS_IDLE_ERR))
1903 	{
1904 		printf("%s", fp->fxp_name);
1905 		if (mii_ms_status & MII_MSS_RES)
1906 			printf(" reserved<0x%x>", mii_ms_status & MII_MSS_RES);
1907 		if (mii_ms_status & MII_MSS_IDLE_ERR)
1908 		{
1909 			printf(" idle error %d",
1910 				mii_ms_status & MII_MSS_IDLE_ERR);
1911 		}
1912 		printf("\n");
1913 	}
1914 
1915 resspeed:
1916 #if VERBOSE
1917 	printf("%s: link up, %d Mbps, %s duplex\n",
1918 		fp->fxp_name, (scr & MII_SCR_100) ? 100 : 10,
1919 		(scr & MII_SCR_FD) ? "full" : "half");
1920 #endif
1921 	;
1922 }
1923 
1924 /*===========================================================================*
1925  *				reply					     *
1926  *===========================================================================*/
1927 static void reply(fp)
1928 fxp_t *fp;
1929 {
1930 	message reply;
1931 	int flags;
1932 	int r;
1933 
1934 	flags = DL_NOFLAGS;
1935 	if (fp->fxp_flags & FF_PACK_SENT)
1936 		flags |= DL_PACK_SEND;
1937 	if (fp->fxp_flags & FF_PACK_RECV)
1938 		flags |= DL_PACK_RECV;
1939 
1940 	reply.m_type = DL_TASK_REPLY;
1941 	reply.m_netdrv_net_dl_task.flags = flags;
1942 	reply.m_netdrv_net_dl_task.count = fp->fxp_read_s;
1943 
1944 	r= ipc_send(fp->fxp_client, &reply);
1945 
1946 	if (r < 0)
1947 		panic("fxp: ipc_send failed: %d", r);
1948 
1949 	fp->fxp_read_s = 0;
1950 	fp->fxp_flags &= ~(FF_PACK_SENT | FF_PACK_RECV);
1951 }
1952 
1953 /*===========================================================================*
1954  *				mess_reply				     *
1955  *===========================================================================*/
1956 static void mess_reply(req, reply_mess)
1957 message *req;
1958 message *reply_mess;
1959 {
1960 	if (ipc_send(req->m_source, reply_mess) != OK)
1961 		panic("fxp: unable to mess_reply");
1962 }
1963 
1964 /*===========================================================================*
1965  *				eeprom_read				     *
1966  *===========================================================================*/
1967 static u16_t eeprom_read(fp, reg)
1968 fxp_t *fp;
1969 int reg;
1970 {
1971 	port_t port;
1972 	u16_t v;
1973 	int b, i, alen;
1974 
1975 	alen= fp->fxp_ee_addrlen;
1976 	if (!alen)
1977 	{
1978 		eeprom_addrsize(fp);
1979 		alen= fp->fxp_ee_addrlen;
1980 		assert(alen == 6 || alen == 8);
1981 	}
1982 
1983 	port= fp->fxp_base_port;
1984 
1985 	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */
1986 	v= EEPROM_READ_PREFIX;
1987 	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)
1988 	{
1989 		b= ((v & (1 << i)) ? CE_EEDI : 0);
1990 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
1991 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
1992 		micro_delay(EESK_PERIOD/2+1);
1993 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
1994 		micro_delay(EESK_PERIOD/2+1);
1995 	}
1996 
1997 	v= reg;
1998 	for (i= alen-1; i >= 0; i--)
1999 	{
2000 		b= ((v & (1 << i)) ? CE_EEDI : 0);
2001 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
2002 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
2003 		micro_delay(EESK_PERIOD/2+1);
2004 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
2005 		micro_delay(EESK_PERIOD/2+1);
2006 	}
2007 
2008 	v= 0;
2009 	for (i= 0; i<16; i++)
2010 	{
2011 		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */
2012 		micro_delay(EESK_PERIOD/2+1);
2013 		b= !!(fxp_inb(port, CSR_EEPROM) & CE_EEDO);
2014 		v= (v << 1) | b;
2015 		fxp_outb(port, CSR_EEPROM, CE_EECS );
2016 		micro_delay(EESK_PERIOD/2+1);
2017 	}
2018 	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */
2019 	micro_delay(EECS_DELAY);
2020 
2021 	return v;
2022 }
2023 
2024 /*===========================================================================*
2025  *				eeprom_addrsize				     *
2026  *===========================================================================*/
2027 static void eeprom_addrsize(fp)
2028 fxp_t *fp;
2029 {
2030 	port_t port;
2031 	u16_t v;
2032 	int b, i;
2033 
2034 	port= fp->fxp_base_port;
2035 
2036 	/* Try to find out the size of the EEPROM */
2037 	fxp_outb(port, CSR_EEPROM, CE_EECS);	/* Enable EEPROM */
2038 	v= EEPROM_READ_PREFIX;
2039 	for (i= EEPROM_PREFIX_LEN-1; i >= 0; i--)
2040 	{
2041 		b= ((v & (1 << i)) ? CE_EEDI : 0);
2042 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
2043 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
2044 		micro_delay(EESK_PERIOD/2+1);
2045 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
2046 		micro_delay(EESK_PERIOD/2+1);
2047 	}
2048 
2049 	for (i= 0; i<32; i++)
2050 	{
2051 		b= 0;
2052 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);	/* bit */
2053 		fxp_outb(port, CSR_EEPROM, CE_EECS | b | CE_EESK); /* Clock */
2054 		micro_delay(EESK_PERIOD/2+1);
2055 		fxp_outb(port, CSR_EEPROM, CE_EECS | b);
2056 		micro_delay(EESK_PERIOD/2+1);
2057 		v= fxp_inb(port, CSR_EEPROM);
2058 		if (!(v & CE_EEDO))
2059 			break;
2060 	}
2061 	if (i >= 32)
2062 		panic("eeprom_addrsize: failed");
2063 	fp->fxp_ee_addrlen= i+1;
2064 
2065 	/* Discard 16 data bits */
2066 	for (i= 0; i<16; i++)
2067 	{
2068 		fxp_outb(port, CSR_EEPROM, CE_EECS | CE_EESK); /* Clock */
2069 		micro_delay(EESK_PERIOD/2+1);
2070 		fxp_outb(port, CSR_EEPROM, CE_EECS );
2071 		micro_delay(EESK_PERIOD/2+1);
2072 	}
2073 	fxp_outb(port, CSR_EEPROM, 0);	/* Disable EEPROM */
2074 	micro_delay(EECS_DELAY);
2075 
2076 #if VERBOSE
2077 	printf("%s EEPROM address length: %d\n",
2078 		fp->fxp_name, fp->fxp_ee_addrlen);
2079 #endif
2080 }
2081 
2082 /*===========================================================================*
2083  *				mii_read				     *
2084  *===========================================================================*/
2085 static u16_t mii_read(fp, reg)
2086 fxp_t *fp;
2087 int reg;
2088 {
2089 	spin_t spin;
2090 	port_t port;
2091 	u32_t v;
2092 
2093 	port= fp->fxp_base_port;
2094 
2095 	assert(!fp->fxp_mii_busy);
2096 	fp->fxp_mii_busy++;
2097 
2098 	if (!(fxp_inl(port, CSR_MDI_CTL) & CM_READY))
2099 		panic("mii_read: MDI not ready");
2100 	fxp_outl(port, CSR_MDI_CTL, CM_READ | (1 << CM_PHYADDR_SHIFT) |
2101 		(reg << CM_REG_SHIFT));
2102 
2103 	spin_init(&spin, 100000);
2104 	do {
2105 		v= fxp_inl(port, CSR_MDI_CTL);
2106 		if (v & CM_READY)
2107 			break;
2108 	} while (spin_check(&spin));
2109 
2110 	if (!(v & CM_READY))
2111 		panic("mii_read: MDI not ready after command");
2112 
2113 	fp->fxp_mii_busy--;
2114 	assert(!fp->fxp_mii_busy);
2115 
2116 	return v & CM_DATA_MASK;
2117 }
2118 
2119 static u8_t do_inb(port_t port)
2120 {
2121 	int r;
2122 	u32_t value;
2123 
2124 	r= sys_inb(port, &value);
2125 	if (r != OK)
2126 		panic("sys_inb failed: %d", r);
2127 	return value;
2128 }
2129 
2130 static u32_t do_inl(port_t port)
2131 {
2132 	int r;
2133 	u32_t value;
2134 
2135 	r= sys_inl(port, &value);
2136 	if (r != OK)
2137 		panic("sys_inl failed: %d", r);
2138 	return value;
2139 }
2140 
2141 static void do_outb(port_t port, u8_t value)
2142 {
2143 	int r;
2144 
2145 	r= sys_outb(port, value);
2146 	if (r != OK)
2147 		panic("sys_outb failed: %d", r);
2148 }
2149 
2150 static void do_outl(port_t port, u32_t value)
2151 {
2152 	int r;
2153 
2154 	r= sys_outl(port, value);
2155 	if (r != OK)
2156 		panic("sys_outl failed: %d", r);
2157 }
2158 
2159 static void tell_dev(buf, size, pci_bus, pci_dev, pci_func)
2160 vir_bytes buf;
2161 size_t size;
2162 int pci_bus;
2163 int pci_dev;
2164 int pci_func;
2165 {
2166 	int r;
2167 	endpoint_t dev_e;
2168 	message m;
2169 
2170 	r= ds_retrieve_label_endpt("amddev", &dev_e);
2171 	if (r != OK)
2172 	{
2173 #if 0
2174 		printf(
2175 		"fxp`tell_dev: ds_retrieve_label_endpt failed for 'amddev': %d\n",
2176 			r);
2177 #endif
2178 		return;
2179 	}
2180 
2181 	m.m_type= IOMMU_MAP;
2182 	m.m2_i1= pci_bus;
2183 	m.m2_i2= pci_dev;
2184 	m.m2_i3= pci_func;
2185 	m.m2_l1= buf;
2186 	m.m2_l2= size;
2187 
2188 	r= ipc_sendrec(dev_e, &m);
2189 	if (r != OK)
2190 	{
2191 		printf("fxp`tell_dev: ipc_sendrec to %d failed: %d\n",
2192 			dev_e, r);
2193 		return;
2194 	}
2195 	if (m.m_type != OK)
2196 	{
2197 		printf("fxp`tell_dev: dma map request failed: %d\n",
2198 			m.m_type);
2199 		return;
2200 	}
2201 }
2202 
2203 /*
2204  * $PchId: fxp.c,v 1.4 2005/01/31 22:10:37 philip Exp $
2205  */
2206 
2207