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