xref: /inferno-os/os/boot/puma/ether.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
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 = &ether[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 = &ether[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