2 #include "../port/lib.h"
7 #include "../port/netif.h"
8 #include "../port/etherif.h"
10 typedef struct Hio Hio;
11 typedef struct Desc Desc;
12 typedef struct Ring Ring;
13 typedef struct Ctlr Ctlr;
16 * SEEQ 8003 interfaced to HPC3 (very different from IP20)
21 ulong crbp; /* current receive buf desc ptr */
22 ulong nrbdp; /* next receive buf desc ptr */
24 ulong rbc; /* receive byte count */
25 ulong rstat; /* receiver status */
26 ulong rgio; /* receive gio fifo ptr */
27 ulong rdev; /* receive device fifo ptr */
29 ulong ctl; /* interrupt, channel reset, buf oflow */
30 ulong dmacfg; /* dma configuration */
31 ulong piocfg; /* pio configuration */
33 ulong cxbdp; /* current xmit buf desc ptr */
34 ulong nxbdp; /* next xmit buffer desc. pointer */
36 ulong xbc; /* xmit byte count */
38 ulong xgio; /* xmit gio fifo ptr */
39 ulong xdev; /* xmit device fifo ptr */
41 ulong crbdp; /* current receive descriptor ptr */
43 ulong cpfxbdp; /* current/previous packet 1st xmit */
44 ulong ppfxbdp; /* desc ptr */
46 ulong eaddr[6]; /* seeq station address wo */
47 ulong csr; /* seeq receiver cmd/status reg */
48 ulong csx; /* seeq transmitter cmd/status reg */
53 Cover= 0x08, /* receive buffer overflow */
54 Cnormal=0x00, /* 1=normal, 0=loopback */
55 Cint= 0x02, /* interrupt (write 1 to clear) */
56 Creset= 0x01, /* ethernet channel reset */
59 Xdma= 0x200, /* dma active */
60 Xold= 0x080, /* register has been read */
61 Xok= 0x008, /* transmission was successful */
62 Xmaxtry=0x004, /* transmission failed after 16 attempts */
63 Xcoll= 0x002, /* transmission collided */
64 Xunder= 0x001, /* transmitter underflowed */
67 Xreg0= 0x00, /* access reg bank 0 incl station addr */
74 Rlshort=0x800, /* [small len in received frame] */
75 Rdma= 0x200, /* dma active */
76 Rold= 0x80, /* register has been read */
77 Rok= 0x20, /* received good frame */
78 Rend= 0x10, /* received end of frame */
79 Rshort= 0x08, /* received short frame */
80 Rdrbl= 0x04, /* dribble error */
81 Rcrc= 0x02, /* CRC error */
82 Rover= 0x01, /* overflow error */
85 Rsmb= 0xc0, /* receive station/broadcast/multicast frames */
86 Rsb= 0x80, /* receive station/broadcast frames */
87 Rprom= 0x40, /* receive all frames */
88 RIok= 0x20, /* interrupt on good frame */
89 RIend= 0x10, /* interrupt on end of frame */
90 RIshort=0x08, /* interrupt on short frame */
91 RIdrbl= 0x04, /* interrupt on dribble error */
92 RIcrc= 0x02, /* interrupt on CRC error */
93 RIover= 0x01, /* interrupt on overflow error */
95 HPC_MODNORM= 0x0, /* mode: 0=normal, 1=loopback */
96 HPC_FIX_INTR= 0x8000, /* start timeout counter after */
97 HPC_FIX_EOP= 0x4000, /* rcv_eop_intr/eop_in_chip is set */
98 HPC_FIX_RXDC= 0x2000, /* clear eop status upon rxdc */
103 ulong addr; /* addr */
104 ulong count; /* eox / eop / busy / xie / count:13 */
121 Eor= 1<<31, /* end of ring */
123 Ioc= 1<<29, /* interrupt on completion */
125 Empty= 1<<14, /* no data here */
126 Done= 1<<15, /* transmit done */
130 Rbsize = ETHERMAXTU+3,
145 static int reset(Ether*);
158 if((s & Xmaxtry) != 0)
159 ctlr->txerr = "transmission failed";
160 if((s & Xunder) != 0)
161 ctlr->txerr = "transmitter underflowed";
162 for(p = IO(Desc, ctlr->tx.head->next); (p->count & Busy) != 0; p = IO(Desc, p->next)){
163 if((p->count & Done) == 0){
164 io->nxbdp = PADDR(p);
166 ctlr->txwdog = MACHP(0)->ticks;
178 interrupt(Ureg *, void *arg)
190 io->ctl = Cnormal | Cover;
194 io->ctl = Cnormal | Cint;
205 return (IO(Desc, ctlr->rx.head->next)->count & Empty) == 0;
213 if(ctlr->txerr != nil)
216 if(t != 0 && TK2MS(MACHP(0)->ticks - t) > 1000)
217 return "transmitter dma timeout";
218 if((ctlr->io->rstat & Rdma) == 0)
219 return "recevier dma stopped";
237 for(p = IO(Desc, ctlr->rx.head->next);; p = IO(Desc, p->next)){
238 while((p->count & Empty) != 0){
239 err = checkerr(ctlr);
241 print("%s: %s; reseting\n", up->text, err);
246 tsleep(&ctlr->rx, notempty, ctlr, 500);
248 n = Rbsize - (p->count & 0x3fff)-3;
249 if(n >= ETHERMINTU && (p->base[n+2] & Rok) != 0){
252 memmove(b->rp, p->base+2, n);
255 p->addr = PADDR(p->base);
256 p->count = Ioc|Empty|Rbsize;
265 return ctlr->tx.free > 0;
281 for(p = IO(Desc, ctlr->tx.tail->next); (b = qbread(edev->oq, 1000000)) != nil; p = IO(Desc, p->next)){
282 while(ctlr->tx.free == 0)
283 sleep(&ctlr->tx, notbusy, ctlr);
288 memmove(p->base, b->rp, n);
290 p->addr = PADDR(p->base);
291 p->count = Ioc|Eor|Eop|Busy|n;
293 ctlr->tx.tail->count &= ~(Ioc|Eor);
306 allocring(Ring *r, int n)
316 b = xspanalloc(m, BY2PG, 0);
323 p = xspanalloc(m, BY2PG, 0);
327 r->head = r->tail = p;
329 for(m=0; m<n; m++, p++, b += (BY2PG/2)){
331 p->next = PADDR(p+1);
333 p[-1].next = PADDR(r->head);
353 io->ctl = Cnormal | Creset | Cint;
359 io->dmacfg |= HPC_FIX_INTR | HPC_FIX_EOP | HPC_FIX_RXDC;
363 p->addr = PADDR(p->base);
364 p->count = Ioc|Empty|Rbsize;
365 p = IO(Desc, p->next);
366 } while(p != ctlr->rx.head);
367 io->crbdp = PADDR(p);
370 ctlr->rx.free = ctlr->rx.size;
374 p->addr = PADDR(p->base);
376 p = IO(Desc, p->next);
377 } while(p != ctlr->tx.tail);
378 io->cxbdp = PADDR(p);
381 ctlr->tx.free = ctlr->tx.size;
384 io->eaddr[i] = edev->ea[i];
386 io->csx = XIok | XImaxtry | XIcoll | XIunder;
387 io->csr = Rprom | RIok|RIend|RIshort|RIdrbl|RIcrc;
404 ctlr->io = IO(Hio, edev->port);
405 allocring(&ctlr->rx, 256);
406 allocring(&ctlr->tx, 64);
412 * do nothing for promiscuous() and multicast() as we
413 * are always in promisc mode.
416 promiscuous(void*, int)
420 multicast(void*, uchar*, int)
433 kproc("#l0rx", rxproc, edev);
434 kproc("#l0tx", txproc, edev);
443 /* only one controller */
444 if(edev->ctlrno != 0)
447 /* get mac address from nvram */
448 if((s = getconf("eaddr")) != nil)
449 parseether(edev->ea, s);
452 edev->port = HPC3_ETHER;
455 edev->promiscuous = promiscuous;
456 edev->multicast = multicast;
457 edev->attach = attach;
467 intrenable(hpc3irqlevel(edev->irq), interrupt, edev);
475 addethercard("seeq", pnp);