1*da917039SDavid du Colombier #include "include.h"
2*da917039SDavid du Colombier #include "ip.h"
3*da917039SDavid du Colombier
4*da917039SDavid du Colombier static Ether *ether;
5*da917039SDavid du Colombier
6*da917039SDavid du Colombier int debug;
7*da917039SDavid du Colombier
8*da917039SDavid du Colombier int temacreset(Ether*);
9*da917039SDavid du Colombier int plbtemacreset(Ether*);
10*da917039SDavid du Colombier int isaconfig(char*, int, ISAConf*);
11*da917039SDavid du Colombier
12*da917039SDavid du Colombier typedef struct Ethercard Ethercard;
13*da917039SDavid du Colombier struct Ethercard {
14*da917039SDavid du Colombier char *type;
15*da917039SDavid du Colombier int (*reset)(Ether*);
16*da917039SDavid du Colombier int noprobe;
17*da917039SDavid du Colombier } ethercards[] = {
18*da917039SDavid du Colombier { "temac", temacreset, 0, },
19*da917039SDavid du Colombier { 0, }
20*da917039SDavid du Colombier };
21*da917039SDavid du Colombier
22*da917039SDavid du Colombier static void xetherdetach(void);
23*da917039SDavid du Colombier
24*da917039SDavid du Colombier int
etherinit(void)25*da917039SDavid du Colombier etherinit(void) /* called from probe() */
26*da917039SDavid du Colombier {
27*da917039SDavid du Colombier Ether *ctlr;
28*da917039SDavid du Colombier int ctlrno, i, mask, n, x;
29*da917039SDavid du Colombier
30*da917039SDavid du Colombier fmtinstall('E', eipfmt);
31*da917039SDavid du Colombier fmtinstall('V', eipfmt);
32*da917039SDavid du Colombier
33*da917039SDavid du Colombier etherdetach = xetherdetach;
34*da917039SDavid du Colombier mask = 0;
35*da917039SDavid du Colombier ether = malloc(MaxEther * sizeof *ether);
36*da917039SDavid du Colombier for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
37*da917039SDavid du Colombier ctlr = ðer[ctlrno];
38*da917039SDavid du Colombier memset(ctlr, 0, sizeof(Ether));
39*da917039SDavid du Colombier // if(isaconfig("ether", ctlrno, ctlr) == 0)
40*da917039SDavid du Colombier // continue;
41*da917039SDavid du Colombier
42*da917039SDavid du Colombier for(n = 0; ethercards[n].type; n++){
43*da917039SDavid du Colombier Ethercard *ecp;
44*da917039SDavid du Colombier
45*da917039SDavid du Colombier ecp = ðercards[n];
46*da917039SDavid du Colombier if (1) {
47*da917039SDavid du Colombier if(ecp->noprobe)
48*da917039SDavid du Colombier continue;
49*da917039SDavid du Colombier memset(ctlr, 0, sizeof(Ether));
50*da917039SDavid du Colombier // strecpy(ctlr->type, &ctlr->type[NAMELEN],
51*da917039SDavid du Colombier // ecp->type);
52*da917039SDavid du Colombier }
53*da917039SDavid du Colombier // else if(cistrcmp(ecp->type, ctlr->type) != 0)
54*da917039SDavid du Colombier // continue;
55*da917039SDavid du Colombier ctlr->ctlrno = ctlrno;
56*da917039SDavid du Colombier
57*da917039SDavid du Colombier x = splhi();
58*da917039SDavid du Colombier if((*ecp->reset)(ctlr)){
59*da917039SDavid du Colombier splx(x);
60*da917039SDavid du Colombier continue;
61*da917039SDavid du Colombier }
62*da917039SDavid du Colombier
63*da917039SDavid du Colombier ctlr->state = 1; /* card found */
64*da917039SDavid du Colombier mask |= 1<<ctlrno;
65*da917039SDavid du Colombier // setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr);
66*da917039SDavid du Colombier intrenable(Inttemac, ctlr->interrupt);
67*da917039SDavid du Colombier
68*da917039SDavid du Colombier print("ether#%d: port 0x%lux", ctlr->ctlrno, ctlr->port);
69*da917039SDavid du Colombier if(ctlr->mem)
70*da917039SDavid du Colombier print(" addr 0x%luX", ctlr->mem & ~KZERO);
71*da917039SDavid du Colombier if(ctlr->size)
72*da917039SDavid du Colombier print(" size 0x%luX", ctlr->size);
73*da917039SDavid du Colombier print(": %E\n", ctlr->ea);
74*da917039SDavid du Colombier
75*da917039SDavid du Colombier if(ctlr->nrb == 0)
76*da917039SDavid du Colombier ctlr->nrb = Nrb;
77*da917039SDavid du Colombier ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);
78*da917039SDavid du Colombier if(ctlr->ntb == 0)
79*da917039SDavid du Colombier ctlr->ntb = Ntb;
80*da917039SDavid du Colombier ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);
81*da917039SDavid du Colombier
82*da917039SDavid du Colombier ctlr->rh = 0;
83*da917039SDavid du Colombier ctlr->ri = 0;
84*da917039SDavid du Colombier for(i = 0; i < ctlr->nrb; i++)
85*da917039SDavid du Colombier ctlr->rb[i].owner = Interface;
86*da917039SDavid du Colombier
87*da917039SDavid du Colombier ctlr->th = 0;
88*da917039SDavid du Colombier ctlr->ti = 0;
89*da917039SDavid du Colombier for(i = 0; i < ctlr->ntb; i++)
90*da917039SDavid du Colombier ctlr->tb[i].owner = Host;
91*da917039SDavid du Colombier
92*da917039SDavid du Colombier splx(x);
93*da917039SDavid du Colombier break;
94*da917039SDavid du Colombier }
95*da917039SDavid du Colombier }
96*da917039SDavid du Colombier
97*da917039SDavid du Colombier return mask;
98*da917039SDavid du Colombier }
99*da917039SDavid du Colombier
100*da917039SDavid du Colombier void
etherinitdev(int i,char * s)101*da917039SDavid du Colombier etherinitdev(int i, char *s)
102*da917039SDavid du Colombier {
103*da917039SDavid du Colombier seprint(s, s + NAMELEN, "ether%d", i);
104*da917039SDavid du Colombier }
105*da917039SDavid du Colombier
106*da917039SDavid du Colombier void
etherprintdevs(int i)107*da917039SDavid du Colombier etherprintdevs(int i)
108*da917039SDavid du Colombier {
109*da917039SDavid du Colombier print(" ether%d", i);
110*da917039SDavid du Colombier }
111*da917039SDavid du Colombier
112*da917039SDavid du Colombier static Ether*
attach(int ctlrno)113*da917039SDavid du Colombier attach(int ctlrno)
114*da917039SDavid du Colombier {
115*da917039SDavid du Colombier Ether *ctlr;
116*da917039SDavid du Colombier
117*da917039SDavid du Colombier if(ctlrno >= MaxEther || ether[ctlrno].state == 0)
118*da917039SDavid du Colombier return 0;
119*da917039SDavid du Colombier
120*da917039SDavid du Colombier ctlr = ðer[ctlrno];
121*da917039SDavid du Colombier if(ctlr->state == 1){ /* card found? */
122*da917039SDavid du Colombier ctlr->state = 2; /* attaching */
123*da917039SDavid du Colombier (*ctlr->attach)(ctlr);
124*da917039SDavid du Colombier }
125*da917039SDavid du Colombier
126*da917039SDavid du Colombier return ctlr;
127*da917039SDavid du Colombier }
128*da917039SDavid du Colombier
129*da917039SDavid du Colombier static void
xetherdetach(void)130*da917039SDavid du Colombier xetherdetach(void)
131*da917039SDavid du Colombier {
132*da917039SDavid du Colombier Ether *ctlr;
133*da917039SDavid du Colombier int ctlrno, x;
134*da917039SDavid du Colombier
135*da917039SDavid du Colombier x = splhi();
136*da917039SDavid du Colombier for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
137*da917039SDavid du Colombier ctlr = ðer[ctlrno];
138*da917039SDavid du Colombier if(ctlr->detach && ctlr->state != 0) /* found | attaching? */
139*da917039SDavid du Colombier ctlr->detach(ctlr);
140*da917039SDavid du Colombier }
141*da917039SDavid du Colombier splx(x);
142*da917039SDavid du Colombier }
143*da917039SDavid du Colombier
144*da917039SDavid du Colombier uchar*
etheraddr(int ctlrno)145*da917039SDavid du Colombier etheraddr(int ctlrno)
146*da917039SDavid du Colombier {
147*da917039SDavid du Colombier Ether *ctlr;
148*da917039SDavid du Colombier
149*da917039SDavid du Colombier if((ctlr = attach(ctlrno)) == 0)
150*da917039SDavid du Colombier return 0;
151*da917039SDavid du Colombier
152*da917039SDavid du Colombier return ctlr->ea;
153*da917039SDavid du Colombier }
154*da917039SDavid du Colombier
155*da917039SDavid du Colombier /* wait for owner of RingBuf to change from `owner' */
156*da917039SDavid du Colombier static int
wait(RingBuf * ring,uchar owner,int timo)157*da917039SDavid du Colombier wait(RingBuf* ring, uchar owner, int timo)
158*da917039SDavid du Colombier {
159*da917039SDavid du Colombier ulong start;
160*da917039SDavid du Colombier
161*da917039SDavid du Colombier start = m->ticks;
162*da917039SDavid du Colombier while(TK2MS(m->ticks - start) < timo)
163*da917039SDavid du Colombier if(ring->owner != owner)
164*da917039SDavid du Colombier return 1;
165*da917039SDavid du Colombier return 0;
166*da917039SDavid du Colombier }
167*da917039SDavid du Colombier
168*da917039SDavid du Colombier int
etherrxpkt(int ctlrno,Etherpkt * pkt,int timo)169*da917039SDavid du Colombier etherrxpkt(int ctlrno, Etherpkt* pkt, int timo)
170*da917039SDavid du Colombier {
171*da917039SDavid du Colombier int n;
172*da917039SDavid du Colombier Ether *ctlr;
173*da917039SDavid du Colombier RingBuf *ring;
174*da917039SDavid du Colombier
175*da917039SDavid du Colombier if((ctlr = attach(ctlrno)) == 0)
176*da917039SDavid du Colombier return 0;
177*da917039SDavid du Colombier
178*da917039SDavid du Colombier ring = &ctlr->rb[ctlr->rh];
179*da917039SDavid du Colombier if(wait(ring, Interface, timo) == 0){
180*da917039SDavid du Colombier if(debug)
181*da917039SDavid du Colombier print("ether%d: rx timeout\n", ctlrno);
182*da917039SDavid du Colombier return 0;
183*da917039SDavid du Colombier }
184*da917039SDavid du Colombier
185*da917039SDavid du Colombier n = ring->len;
186*da917039SDavid du Colombier memmove(pkt, ring->pkt, n);
187*da917039SDavid du Colombier coherence();
188*da917039SDavid du Colombier ring->owner = Interface;
189*da917039SDavid du Colombier ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
190*da917039SDavid du Colombier
191*da917039SDavid du Colombier return n;
192*da917039SDavid du Colombier }
193*da917039SDavid du Colombier
194*da917039SDavid du Colombier int
etherrxflush(int ctlrno)195*da917039SDavid du Colombier etherrxflush(int ctlrno)
196*da917039SDavid du Colombier {
197*da917039SDavid du Colombier int n;
198*da917039SDavid du Colombier Ether *ctlr;
199*da917039SDavid du Colombier RingBuf *ring;
200*da917039SDavid du Colombier
201*da917039SDavid du Colombier if((ctlr = attach(ctlrno)) == 0)
202*da917039SDavid du Colombier return 0;
203*da917039SDavid du Colombier
204*da917039SDavid du Colombier n = 0;
205*da917039SDavid du Colombier for(;;){
206*da917039SDavid du Colombier ring = &ctlr->rb[ctlr->rh];
207*da917039SDavid du Colombier if(wait(ring, Interface, 100) == 0)
208*da917039SDavid du Colombier break;
209*da917039SDavid du Colombier
210*da917039SDavid du Colombier ring->owner = Interface;
211*da917039SDavid du Colombier ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);
212*da917039SDavid du Colombier n++;
213*da917039SDavid du Colombier }
214*da917039SDavid du Colombier
215*da917039SDavid du Colombier return n;
216*da917039SDavid du Colombier }
217*da917039SDavid du Colombier
218*da917039SDavid du Colombier int
ethertxpkt(int ctlrno,Etherpkt * pkt,int len,int)219*da917039SDavid du Colombier ethertxpkt(int ctlrno, Etherpkt* pkt, int len, int)
220*da917039SDavid du Colombier {
221*da917039SDavid du Colombier Ether *ctlr;
222*da917039SDavid du Colombier RingBuf *ring;
223*da917039SDavid du Colombier int s;
224*da917039SDavid du Colombier
225*da917039SDavid du Colombier if((ctlr = attach(ctlrno)) == 0)
226*da917039SDavid du Colombier return 0;
227*da917039SDavid du Colombier
228*da917039SDavid du Colombier ring = &ctlr->tb[ctlr->th];
229*da917039SDavid du Colombier if(wait(ring, Interface, 1000) == 0){
230*da917039SDavid du Colombier print("ether%d: tx buffer timeout\n", ctlrno);
231*da917039SDavid du Colombier return 0;
232*da917039SDavid du Colombier }
233*da917039SDavid du Colombier
234*da917039SDavid du Colombier memmove(pkt->s, ctlr->ea, Eaddrlen);
235*da917039SDavid du Colombier if(debug)
236*da917039SDavid du Colombier print("%E to %E...\n", pkt->s, pkt->d);
237*da917039SDavid du Colombier memmove(ring->pkt, pkt, len);
238*da917039SDavid du Colombier if(len < ETHERMINTU){
239*da917039SDavid du Colombier memset(ring->pkt+len, 0, ETHERMINTU-len);
240*da917039SDavid du Colombier len = ETHERMINTU;
241*da917039SDavid du Colombier }
242*da917039SDavid du Colombier ring->len = len;
243*da917039SDavid du Colombier ring->owner = Interface;
244*da917039SDavid du Colombier ctlr->th = NEXT(ctlr->th, ctlr->ntb);
245*da917039SDavid du Colombier coherence();
246*da917039SDavid du Colombier s = splhi();
247*da917039SDavid du Colombier (*ctlr->transmit)(ctlr);
248*da917039SDavid du Colombier splx(s);
249*da917039SDavid du Colombier
250*da917039SDavid du Colombier return 1;
251*da917039SDavid du Colombier }
252