1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "io.h"
7*74a4d8c2SCharles.Forsyth
8*74a4d8c2SCharles.Forsyth #include "ether.h"
9*74a4d8c2SCharles.Forsyth
10*74a4d8c2SCharles.Forsyth static Ctlr ether[MaxEther];
11*74a4d8c2SCharles.Forsyth
12*74a4d8c2SCharles.Forsyth static struct {
13*74a4d8c2SCharles.Forsyth char *type;
14*74a4d8c2SCharles.Forsyth int (*reset)(Ctlr*);
15*74a4d8c2SCharles.Forsyth } cards[] = {
16*74a4d8c2SCharles.Forsyth { "CS8900", cs8900reset, },
17*74a4d8c2SCharles.Forsyth { 0, }
18*74a4d8c2SCharles.Forsyth };
19*74a4d8c2SCharles.Forsyth
20*74a4d8c2SCharles.Forsyth int
etherinit(void)21*74a4d8c2SCharles.Forsyth etherinit(void)
22*74a4d8c2SCharles.Forsyth {
23*74a4d8c2SCharles.Forsyth Ctlr *ctlr;
24*74a4d8c2SCharles.Forsyth int ctlrno, i, mask, n;
25*74a4d8c2SCharles.Forsyth
26*74a4d8c2SCharles.Forsyth mask = 0;
27*74a4d8c2SCharles.Forsyth for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
28*74a4d8c2SCharles.Forsyth ctlr = ðer[ctlrno];
29*74a4d8c2SCharles.Forsyth memset(ctlr, 0, sizeof(Ctlr));
30*74a4d8c2SCharles.Forsyth if(isaconfig("ether", ctlrno, &ctlr->card) == 0)
31*74a4d8c2SCharles.Forsyth continue;
32*74a4d8c2SCharles.Forsyth for(n = 0; cards[n].type; n++){
33*74a4d8c2SCharles.Forsyth if(strcmp(cards[n].type, ctlr->card.type))
34*74a4d8c2SCharles.Forsyth continue;
35*74a4d8c2SCharles.Forsyth ctlr->ctlrno = ctlrno;
36*74a4d8c2SCharles.Forsyth if((*cards[n].reset)(ctlr))
37*74a4d8c2SCharles.Forsyth break;
38*74a4d8c2SCharles.Forsyth
39*74a4d8c2SCharles.Forsyth ctlr->iq = qopen(16*1024, 1, 0, 0);
40*74a4d8c2SCharles.Forsyth ctlr->oq = qopen(16*1024, 1, 0, 0);
41*74a4d8c2SCharles.Forsyth
42*74a4d8c2SCharles.Forsyth ctlr->present = 1;
43*74a4d8c2SCharles.Forsyth mask |= 1<<ctlrno;
44*74a4d8c2SCharles.Forsyth
45*74a4d8c2SCharles.Forsyth print("ether%d: %s: port 0x%luX irq %d",
46*74a4d8c2SCharles.Forsyth ctlr->ctlrno, ctlr->card.type, ctlr->card.port, ctlr->card.irq);
47*74a4d8c2SCharles.Forsyth if(ctlr->card.mem)
48*74a4d8c2SCharles.Forsyth print(" addr 0x%luX", ctlr->card.mem & ~KZERO);
49*74a4d8c2SCharles.Forsyth if(ctlr->card.size)
50*74a4d8c2SCharles.Forsyth print(" size 0x%luX", ctlr->card.size);
51*74a4d8c2SCharles.Forsyth print(":");
52*74a4d8c2SCharles.Forsyth for(i = 0; i < sizeof(ctlr->card.ea); i++)
53*74a4d8c2SCharles.Forsyth print(" %2.2uX", ctlr->card.ea[i]);
54*74a4d8c2SCharles.Forsyth print("\n"); uartwait();
55*74a4d8c2SCharles.Forsyth setvec(ctlr->card.irq, ctlr->card.intr, ctlr);
56*74a4d8c2SCharles.Forsyth break;
57*74a4d8c2SCharles.Forsyth }
58*74a4d8c2SCharles.Forsyth }
59*74a4d8c2SCharles.Forsyth
60*74a4d8c2SCharles.Forsyth return mask;
61*74a4d8c2SCharles.Forsyth }
62*74a4d8c2SCharles.Forsyth
63*74a4d8c2SCharles.Forsyth static Ctlr*
attach(int ctlrno)64*74a4d8c2SCharles.Forsyth attach(int ctlrno)
65*74a4d8c2SCharles.Forsyth {
66*74a4d8c2SCharles.Forsyth Ctlr *ctlr;
67*74a4d8c2SCharles.Forsyth
68*74a4d8c2SCharles.Forsyth if(ctlrno >= MaxEther || ether[ctlrno].present == 0)
69*74a4d8c2SCharles.Forsyth return 0;
70*74a4d8c2SCharles.Forsyth
71*74a4d8c2SCharles.Forsyth ctlr = ðer[ctlrno];
72*74a4d8c2SCharles.Forsyth if(ctlr->present == 1){
73*74a4d8c2SCharles.Forsyth ctlr->present = 2;
74*74a4d8c2SCharles.Forsyth (*ctlr->card.attach)(ctlr);
75*74a4d8c2SCharles.Forsyth }
76*74a4d8c2SCharles.Forsyth
77*74a4d8c2SCharles.Forsyth return ctlr;
78*74a4d8c2SCharles.Forsyth }
79*74a4d8c2SCharles.Forsyth
80*74a4d8c2SCharles.Forsyth uchar*
etheraddr(int ctlrno)81*74a4d8c2SCharles.Forsyth etheraddr(int ctlrno)
82*74a4d8c2SCharles.Forsyth {
83*74a4d8c2SCharles.Forsyth Ctlr *ctlr;
84*74a4d8c2SCharles.Forsyth
85*74a4d8c2SCharles.Forsyth if((ctlr = attach(ctlrno)) == 0)
86*74a4d8c2SCharles.Forsyth return 0;
87*74a4d8c2SCharles.Forsyth
88*74a4d8c2SCharles.Forsyth return ctlr->card.ea;
89*74a4d8c2SCharles.Forsyth }
90*74a4d8c2SCharles.Forsyth
91*74a4d8c2SCharles.Forsyth int
etherrxpkt(int ctlrno,Etherpkt * pkt,int timo)92*74a4d8c2SCharles.Forsyth etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
93*74a4d8c2SCharles.Forsyth {
94*74a4d8c2SCharles.Forsyth int n;
95*74a4d8c2SCharles.Forsyth Ctlr *ctlr;
96*74a4d8c2SCharles.Forsyth Block *b;
97*74a4d8c2SCharles.Forsyth ulong start;
98*74a4d8c2SCharles.Forsyth
99*74a4d8c2SCharles.Forsyth if((ctlr = attach(ctlrno)) == 0)
100*74a4d8c2SCharles.Forsyth return 0;
101*74a4d8c2SCharles.Forsyth
102*74a4d8c2SCharles.Forsyth start = m->ticks;
103*74a4d8c2SCharles.Forsyth while((b = qget(ctlr->iq)) == 0){
104*74a4d8c2SCharles.Forsyth if(TK2MS(m->ticks - start) >= timo){
105*74a4d8c2SCharles.Forsyth /*
106*74a4d8c2SCharles.Forsyth print("ether%d: rx timeout\n", ctlrno);
107*74a4d8c2SCharles.Forsyth */
108*74a4d8c2SCharles.Forsyth return 0;
109*74a4d8c2SCharles.Forsyth }
110*74a4d8c2SCharles.Forsyth //delay(1);
111*74a4d8c2SCharles.Forsyth }
112*74a4d8c2SCharles.Forsyth
113*74a4d8c2SCharles.Forsyth n = BLEN(b);
114*74a4d8c2SCharles.Forsyth memmove(pkt, b->rp, n);
115*74a4d8c2SCharles.Forsyth freeb(b);
116*74a4d8c2SCharles.Forsyth
117*74a4d8c2SCharles.Forsyth return n;
118*74a4d8c2SCharles.Forsyth }
119*74a4d8c2SCharles.Forsyth
120*74a4d8c2SCharles.Forsyth int
etheriq(Ctlr * ctlr,Block * b,int freebp)121*74a4d8c2SCharles.Forsyth etheriq(Ctlr *ctlr, Block *b, int freebp)
122*74a4d8c2SCharles.Forsyth {
123*74a4d8c2SCharles.Forsyth if(memcmp(((Etherpkt*)b->rp)->d, ctlr->card.ea, Eaddrlen) != 0){
124*74a4d8c2SCharles.Forsyth if(freebp)
125*74a4d8c2SCharles.Forsyth freeb(b);
126*74a4d8c2SCharles.Forsyth return 0;
127*74a4d8c2SCharles.Forsyth }
128*74a4d8c2SCharles.Forsyth qbwrite(ctlr->iq, b);
129*74a4d8c2SCharles.Forsyth return 1;
130*74a4d8c2SCharles.Forsyth }
131*74a4d8c2SCharles.Forsyth
132*74a4d8c2SCharles.Forsyth int
ethertxpkt(int ctlrno,Etherpkt * pkt,int len,int)133*74a4d8c2SCharles.Forsyth ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int)
134*74a4d8c2SCharles.Forsyth {
135*74a4d8c2SCharles.Forsyth Ctlr *ctlr;
136*74a4d8c2SCharles.Forsyth Block *b;
137*74a4d8c2SCharles.Forsyth int s;
138*74a4d8c2SCharles.Forsyth
139*74a4d8c2SCharles.Forsyth if((ctlr = attach(ctlrno)) == 0)
140*74a4d8c2SCharles.Forsyth return 0;
141*74a4d8c2SCharles.Forsyth
142*74a4d8c2SCharles.Forsyth if(qlen(ctlr->oq) > 16*1024){
143*74a4d8c2SCharles.Forsyth print("ether%d: tx queue full\n", ctlrno);
144*74a4d8c2SCharles.Forsyth return 0;
145*74a4d8c2SCharles.Forsyth }
146*74a4d8c2SCharles.Forsyth b = iallocb(sizeof(Etherpkt));
147*74a4d8c2SCharles.Forsyth memmove(b->wp, pkt, len);
148*74a4d8c2SCharles.Forsyth memmove(((Etherpkt*)b->wp)->s, ctlr->card.ea, Eaddrlen);
149*74a4d8c2SCharles.Forsyth b->wp += len;
150*74a4d8c2SCharles.Forsyth qbwrite(ctlr->oq, b);
151*74a4d8c2SCharles.Forsyth s = splhi();
152*74a4d8c2SCharles.Forsyth (*ctlr->card.transmit)(ctlr);
153*74a4d8c2SCharles.Forsyth splx(s);
154*74a4d8c2SCharles.Forsyth
155*74a4d8c2SCharles.Forsyth return 1;
156*74a4d8c2SCharles.Forsyth }
157