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