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