xref: /plan9-contrib/sys/src/boot/vt4/ether.c (revision da917039c7f233c1a27d212bf012c6afa758af39)
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 = &ether[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 = &ethercards[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 = &ether[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 = &ether[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