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