Use readstr() for #device text buffers
[akaros.git] / kern / drivers / dev / ether.c
1 /* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
2  * Portions Copyright © 1997-1999 Vita Nuova Limited
3  * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
4  *                                (www.vitanuova.com)
5  * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
6  *
7  * Modified for the Akaros operating system:
8  * Copyright (c) 2013-2014 The Regents of the University of California
9  * Copyright (c) 2013-2015 Google Inc.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE. */
28
29 #include <slab.h>
30 #include <kmalloc.h>
31 #include <kref.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include <error.h>
36 #include <cpio.h>
37 #include <pmap.h>
38 #include <smp.h>
39 #include <net/ip.h>
40
41 struct dev etherdevtab;
42
43 static char *devname(void)
44 {
45         return etherdevtab.name;
46 }
47
48 enum {
49         Type8021Q = 0x8100,                     /* value of type field for 802.1[pQ] tags */
50 };
51
52 static struct ether *etherxx[MaxEther]; /* real controllers */
53 static struct ether *vlanalloc(struct ether *, int);
54 static void vlanoq(struct ether *, struct block *);
55
56 struct chan *etherattach(char *spec)
57 {
58         ERRSTACK(1);
59         uint32_t ctlrno;
60         char *p;
61         struct chan *chan;
62         struct ether *ether, *vlan;
63         int vlanid;
64
65         ctlrno = 0;
66         vlanid = 0;
67         if (spec && *spec) {
68                 ctlrno = strtoul(spec, &p, 0);
69                 /* somebody interpret this for me. */
70                 if (((ctlrno == 0) && (p == spec)) ||
71                         (ctlrno >= MaxEther) || ((*p) && (*p != '.')))
72                         error(EINVAL, ERROR_FIXME);
73                 if (*p == '.') {        /* vlan */
74                         vlanid = strtoul(p + 1, &p, 0);
75                         if (vlanid <= 0 || vlanid > 0xFFF || *p)
76                                 error(EINVAL, ERROR_FIXME);
77                 }
78         }
79         if ((ether = etherxx[ctlrno]) == 0)
80                 error(ENODEV, ERROR_FIXME);
81         rlock(&ether->rwlock);
82         if (waserror()) {
83                 runlock(&ether->rwlock);
84                 nexterror();
85         }
86         if (vlanid) {
87                 if (ether->max_mtu < ETHERMAXTU + ETHERHDRSIZE + 4)
88                         error(EFAIL, "interface cannot support 802.1 tags");
89                 vlan = vlanalloc(ether, vlanid);
90                 chan = devattach(devname(), spec);
91                 chan->dev = ctlrno + (vlanid << 8);
92                 chan->aux = vlan;
93                 poperror();
94                 runlock(&ether->rwlock);
95                 return chan;
96         }
97         chan = devattach(devname(), spec);
98         chan->dev = ctlrno;
99         chan->aux = ether;
100         if (ether->attach)
101                 ether->attach(ether);
102         poperror();
103         runlock(&ether->rwlock);
104         return chan;
105 }
106
107 static void ethershutdown(void)
108 {
109         struct ether *ether;
110         int i;
111
112         for (i = 0; i < MaxEther; i++) {
113                 ether = etherxx[i];
114                 if (ether != NULL && ether->detach != NULL)
115                         ether->detach(ether);
116         }
117 }
118
119 static struct walkqid *etherwalk(struct chan *chan, struct chan *nchan,
120                                                                  char **name, unsigned int nname)
121 {
122         ERRSTACK(1);
123         struct walkqid *wq;
124         struct ether *ether;
125
126         ether = chan->aux;
127         rlock(&ether->rwlock);
128         if (waserror()) {
129                 runlock(&ether->rwlock);
130                 nexterror();
131         }
132         wq = netifwalk(ether, chan, nchan, name, nname);
133         if (wq && wq->clone != NULL && wq->clone != chan)
134                 wq->clone->aux = ether;
135         poperror();
136         runlock(&ether->rwlock);
137         return wq;
138 }
139
140 static size_t etherstat(struct chan *chan, uint8_t *dp, size_t n)
141 {
142         ERRSTACK(1);
143         size_t s;
144         struct ether *ether;
145
146         ether = chan->aux;
147         rlock(&ether->rwlock);
148         if (waserror()) {
149                 runlock(&ether->rwlock);
150                 nexterror();
151         }
152         s = netifstat(ether, chan, dp, n);
153         poperror();
154         runlock(&ether->rwlock);
155         return s;
156 }
157
158 static struct chan *etheropen(struct chan *chan, int omode)
159 {
160         ERRSTACK(1);
161         struct chan *c;
162         struct ether *ether;
163
164         ether = chan->aux;
165         rlock(&ether->rwlock);
166         if (waserror()) {
167                 runlock(&ether->rwlock);
168                 nexterror();
169         }
170         c = netifopen(ether, chan, omode);
171         poperror();
172         runlock(&ether->rwlock);
173         return c;
174 }
175
176 static void etherclose(struct chan *chan)
177 {
178         ERRSTACK(1);
179         struct ether *ether;
180
181         ether = chan->aux;
182         rlock(&ether->rwlock);
183         if (waserror()) {
184                 runlock(&ether->rwlock);
185                 nexterror();
186         }
187         netifclose(ether, chan);
188         poperror();
189         runlock(&ether->rwlock);
190 }
191
192 static size_t etherread(struct chan *chan, void *buf, size_t n, off64_t off)
193 {
194         ERRSTACK(1);
195         struct ether *ether;
196         uint32_t offset = off;
197         long r;
198
199         ether = chan->aux;
200         rlock(&ether->rwlock);
201         if (waserror()) {
202                 runlock(&ether->rwlock);
203                 nexterror();
204         }
205         if ((chan->qid.type & QTDIR) == 0 && ether->ifstat) {
206                 /*
207                  * With some controllers it is necessary to reach
208                  * into the chip to extract statistics.
209                  */
210                 if (NETTYPE(chan->qid.path) == Nifstatqid) {
211                         r = ether->ifstat(ether, buf, n, offset);
212                         goto out;
213                 }
214                 if (NETTYPE(chan->qid.path) == Nstatqid)
215                         ether->ifstat(ether, buf, 0, offset);
216         }
217         r = netifread(ether, chan, buf, n, offset);
218 out:
219         poperror();
220         runlock(&ether->rwlock);
221         return r;
222 }
223
224 static struct block *etherbread(struct chan *chan, size_t n, off64_t offset)
225 {
226         ERRSTACK(1);
227         struct block *b;
228         struct ether *ether;
229
230         ether = chan->aux;
231         rlock(&ether->rwlock);
232         if (waserror()) {
233                 runlock(&ether->rwlock);
234                 nexterror();
235         }
236         b = netifbread(ether, chan, n, offset);
237         poperror();
238         runlock(&ether->rwlock);
239         return b;
240 }
241
242 static size_t etherwstat(struct chan *chan, uint8_t *dp, size_t n)
243 {
244         ERRSTACK(1);
245         struct ether *ether;
246         int r;
247
248         ether = chan->aux;
249         rlock(&ether->rwlock);
250         if (waserror()) {
251                 runlock(&ether->rwlock);
252                 nexterror();
253         }
254         r = netifwstat(ether, chan, dp, n);
255         poperror();
256         runlock(&ether->rwlock);
257         return r;
258 }
259
260 static void etherrtrace(struct netfile *f, struct etherpkt *pkt, int len)
261 {
262         uint64_t i, n;
263         struct block *bp;
264
265         if (qwindow(f->in) <= 0)
266                 return;
267         if (len > 58)
268                 n = 58;
269         else
270                 n = len;
271         bp = block_alloc(68, MEM_ATOMIC);
272         if (bp == NULL)
273                 return;
274         memmove(bp->wp, pkt->d, n);
275         /* we're storing 8 bytes here (64 bit); old 9ns was 32 bit for msec */
276         i = milliseconds();
277         bp->wp[58] = len >> 8;
278         bp->wp[59] = len;
279         bp->wp[60] = i >> 56;
280         bp->wp[61] = i >> 48;
281         bp->wp[62] = i >> 40;
282         bp->wp[63] = i >> 32;
283         bp->wp[64] = i >> 24;
284         bp->wp[65] = i >> 16;
285         bp->wp[66] = i >> 8;
286         bp->wp[67] = i;
287         bp->wp += 68;
288         qpass(f->in, bp);
289 }
290
291 #ifdef CONFIG_RISCV
292 #warning "Potentially unaligned ethernet addrs!"
293 #endif
294
295 static inline int eaddrcmp(uint8_t *x, uint8_t *y)
296 {
297         uint16_t *a = (uint16_t *)x;
298         uint16_t *b = (uint16_t *)y;
299
300         return (a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]);
301 }
302
303 struct block *etheriq(struct ether *ether, struct block *bp, int fromwire)
304 {
305         struct etherpkt *pkt;
306         uint16_t type;
307         int multi, tome, fromme, vlanid, i;
308         struct netfile **ep, *f, **fp, *fx;
309         struct block *xbp;
310         struct ether *vlan;
311
312         ether->inpackets++;
313
314         pkt = (struct etherpkt *)bp->rp;
315         /* TODO: we might need to assert more for higher layers, or otherwise deal
316          * with extra data. */
317         assert(BHLEN(bp) >= offsetof(struct etherpkt, data));
318         type = (pkt->type[0] << 8) | pkt->type[1];
319         if (type == Type8021Q && ether->nvlan) {
320                 vlanid = nhgets(bp->rp + 2 * Eaddrlen + 2) & 0xFFF;
321                 if (vlanid) {
322                         for (i = 0; i < ARRAY_SIZE(ether->vlans); i++) {
323                                 vlan = ether->vlans[i];
324                                 if (vlan != NULL && vlan->vlanid == vlanid) {
325                                         /* might have a problem with extra data here */
326                                         assert(BHLEN(bp) >= 4 + 2 * Eaddrlen);
327                                         memmove(bp->rp + 4, bp->rp, 2 * Eaddrlen);
328                                         bp->rp += 4;
329                                         return etheriq(vlan, bp, fromwire);
330                                 }
331                         }
332                         /* allow normal type handling to accept or discard it */
333                 }
334         }
335
336         fx = 0;
337         ep = &ether->f[Ntypes];
338
339         multi = pkt->d[0] & 1;
340         /* check for valid multcast addresses */
341         if (multi && eaddrcmp(pkt->d, ether->bcast) != 0
342                 && ether->prom == 0) {
343                 if (!activemulti(ether, pkt->d, sizeof(pkt->d))) {
344                         if (fromwire) {
345                                 freeb(bp);
346                                 bp = 0;
347                         }
348                         return bp;
349                 }
350         }
351
352         /* is it for me? */
353         tome = eaddrcmp(pkt->d, ether->ea) == 0;
354         fromme = eaddrcmp(pkt->s, ether->ea) == 0;
355
356         /*
357          * Multiplex the packet to all the connections which want it.
358          * If the packet is not to be used subsequently (fromwire != 0),
359          * attempt to simply pass it into one of the connections, thereby
360          * saving a copy of the data (usual case hopefully).
361          */
362         for (fp = ether->f; fp < ep; fp++) {
363                 if ((f = *fp) && (f->type == type || f->type < 0))
364                         if (tome || multi || f->prom) {
365                                 /* Don't want to hear bridged packets */
366                                 if (f->bridge && !fromwire && !fromme)
367                                         continue;
368                                 if (f->headersonly) {
369                                         etherrtrace(f, pkt, BHLEN(bp));
370                                         continue;
371                                 }
372                                 if (fromwire && fx == 0) {
373                                         fx = f;
374                                         continue;
375                                 }
376                                 xbp = copyblock(bp, MEM_ATOMIC);
377                                 if (xbp == 0) {
378                                         ether->soverflows++;
379                                         continue;
380                                 }
381                                 if (qpass(f->in, xbp) < 0)
382                                         ether->soverflows++;
383                         }
384         }
385
386         if (fx) {
387                 if (qpass(fx->in, bp) < 0)
388                         ether->soverflows++;
389                 return 0;
390         }
391         if (fromwire) {
392                 freeb(bp);
393                 return 0;
394         }
395
396         return bp;
397 }
398
399 static int etheroq(struct ether *ether, struct block *bp)
400 {
401         int len, loopback;
402         struct etherpkt *pkt;
403         int8_t irq_state = 0;
404
405         ether->outpackets++;
406
407         if (!(ether->feat & NETF_SG))
408                 bp = linearizeblock(bp);
409         ptclcsum_finalize(bp, ether->feat);
410         /*
411          * Check if the packet has to be placed back onto the input queue,
412          * i.e. if it's a loopback or broadcast packet or the interface is
413          * in promiscuous mode.
414          * If it's a loopback packet indicate to etheriq that the data isn't
415          * needed and return, etheriq will pass-on or free the block.
416          * To enable bridging to work, only packets that were originated
417          * by this interface are fed back.
418          */
419         pkt = (struct etherpkt *)bp->rp;
420         len = BLEN(bp);
421         loopback = eaddrcmp(pkt->d, ether->ea) == 0;
422         if (loopback || eaddrcmp(pkt->d, ether->bcast) == 0 || ether->prom) {
423                 disable_irqsave(&irq_state);
424                 etheriq(ether, bp, 0);
425                 enable_irqsave(&irq_state);
426                 if (loopback) {
427                         freeb(bp);
428                         return len;
429                 }
430         }
431
432         if (ether->vlanid) {
433                 /* add tag */
434                 bp = padblock(bp, 2 + 2);
435                 memmove(bp->rp, bp->rp + 4, 2 * Eaddrlen);
436                 hnputs(bp->rp + 2 * Eaddrlen, Type8021Q);
437                 hnputs(bp->rp + 2 * Eaddrlen + 2, ether->vlanid & 0xFFF);       /* prio:3 0:1 vid:12 */
438                 ether = ether->ctlr;
439         }
440
441         if ((ether->feat & NETF_PADMIN) == 0 && BLEN(bp) < ether->min_mtu)
442                 bp = adjustblock(bp, ether->min_mtu);
443
444         qbwrite(ether->oq, bp);
445         if (ether->transmit != NULL)
446                 ether->transmit(ether);
447
448         return len;
449 }
450
451 static size_t etherwrite(struct chan *chan, void *buf, size_t n, off64_t unused)
452 {
453         ERRSTACK(2);
454         struct ether *ether;
455         struct block *bp;
456         int onoff;
457         struct cmdbuf *cb;
458         long l;
459
460         ether = chan->aux;
461         rlock(&ether->rwlock);
462         if (waserror()) {
463                 runlock(&ether->rwlock);
464                 nexterror();
465         }
466         if (NETTYPE(chan->qid.path) != Ndataqid) {
467                 l = netifwrite(ether, chan, buf, n);
468                 if (l >= 0)
469                         goto out;
470                 cb = parsecmd(buf, n);
471                 if (cb->nf < 1) {
472                         kfree(cb);
473                         error(EFAIL, "short control request");
474                 }
475                 if (strcmp(cb->f[0], "nonblocking") == 0) {
476                         if (cb->nf <= 1)
477                                 onoff = 1;
478                         else
479                                 onoff = atoi(cb->f[1]);
480                         if (ether->oq != NULL)
481                                 qdropoverflow(ether->oq, onoff);
482                         kfree(cb);
483                         goto out;
484                 }
485                 kfree(cb);
486                 if (ether->ctl != NULL) {
487                         l = ether->ctl(ether, buf, n);
488                         goto out;
489                 }
490                 error(EINVAL, ERROR_FIXME);
491         }
492
493         if (n > ether->mtu + ETHERHDRSIZE)
494                 error(E2BIG, ERROR_FIXME);
495         bp = block_alloc(n, MEM_WAIT);
496         if (waserror()) {
497                 freeb(bp);
498                 nexterror();
499         }
500         memmove(bp->rp, buf, n);
501         memmove(bp->rp + Eaddrlen, ether->ea, Eaddrlen);
502         bp->wp += n;
503         poperror();
504
505         l = etheroq(ether, bp);
506 out:
507         poperror();
508         runlock(&ether->rwlock);
509         return l;
510 }
511
512 static size_t etherbwrite(struct chan *chan, struct block *bp, off64_t unused)
513 {
514         ERRSTACK(1);
515         struct ether *ether;
516         long n;
517
518         n = BLEN(bp);
519         if (NETTYPE(chan->qid.path) != Ndataqid) {
520                 if (waserror()) {
521                         freeb(bp);
522                         nexterror();
523                 }
524                 n = etherwrite(chan, bp->rp, n, 0);
525                 poperror();
526                 freeb(bp);
527                 return n;
528         }
529         ether = chan->aux;
530         rlock(&ether->rwlock);
531         if (waserror()) {
532                 runlock(&ether->rwlock);
533                 nexterror();
534         }
535         if (n > ether->mtu + ETHERHDRSIZE && (bp->flag & Btso) == 0) {
536                 freeb(bp);
537                 error(E2BIG, ERROR_FIXME);
538         }
539         n = etheroq(ether, bp);
540         poperror();
541         runlock(&ether->rwlock);
542         return n;
543 }
544
545 static void nop(struct ether *unused)
546 {
547 }
548
549 static long vlanctl(struct ether *ether, void *buf, long n)
550 {
551         uint8_t ea[Eaddrlen];
552         struct ether *master;
553         struct cmdbuf *cb;
554         int i;
555
556         cb = parsecmd(buf, n);
557         if (cb->nf >= 2
558                 && strcmp(cb->f[0], "ea") == 0 && parseether(ea, cb->f[1]) == 0) {
559                 kfree(cb);
560                 memmove(ether->ea, ea, Eaddrlen);
561                 memmove(ether->addr, ether->ea, Eaddrlen);
562                 return 0;
563         }
564         if (cb->nf == 1 && strcmp(cb->f[0], "disable") == 0) {
565                 master = ether->ctlr;
566                 qlock(&master->vlq);
567                 for (i = 0; i < ARRAY_SIZE(master->vlans); i++)
568                         if (master->vlans[i] == ether) {
569                                 ether->vlanid = 0;
570                                 master->nvlan--;
571                                 break;
572                         }
573                 qunlock(&master->vlq);
574                 kfree(cb);
575                 return 0;
576         }
577         kfree(cb);
578         error(EINVAL, ERROR_FIXME);
579         return -1;      /* not reached */
580 }
581
582 static struct ether *vlanalloc(struct ether *ether, int id)
583 {
584         ERRSTACK(1);
585         struct ether *vlan;
586         int i, fid;
587         char name[KNAMELEN];
588
589         qlock(&ether->vlq);
590         if (waserror()) {
591                 qunlock(&ether->vlq);
592                 nexterror();
593         }
594         fid = -1;
595         for (i = 0; i < ARRAY_SIZE(ether->vlans); i++) {
596                 vlan = ether->vlans[i];
597                 if (vlan != NULL && vlan->vlanid == id) {
598                         poperror();
599                         qunlock(&ether->vlq);
600                         return vlan;
601                 }
602                 if (fid < 0 && (vlan == NULL || vlan->vlanid == 0))
603                         fid = i;
604         }
605         if (fid < 0)
606                 error(ENOENT, ERROR_FIXME);
607         snprintf(name, sizeof(name), "ether%d.%d", ether->ctlrno, id);
608         vlan = ether->vlans[fid];
609         if (vlan == NULL) {
610                 vlan = kzmalloc(sizeof(struct ether), 1);
611                 if (vlan == NULL)
612                         error(ENOMEM, ERROR_FIXME);
613                 rwinit(&vlan->rwlock);
614                 qlock_init(&vlan->vlq);
615                 netifinit(vlan, name, Ntypes, ether->limit);
616                 ether->vlans[fid] = vlan;       /* id is still zero, can't be matched */
617                 ether->nvlan++;
618         } else
619                 memmove(vlan->name, name, KNAMELEN - 1);
620         vlan->attach = nop;
621         vlan->transmit = NULL;
622         vlan->ctl = vlanctl;
623         vlan->irq = -1;
624         vlan->promiscuous = ether->promiscuous;
625         vlan->multicast = ether->multicast;
626         vlan->arg = vlan;
627         vlan->mbps = ether->mbps;
628         vlan->fullduplex = ether->fullduplex;
629         vlan->encry = ether->encry;
630         vlan->mtu = ether->mtu;
631         vlan->min_mtu = ether->min_mtu;
632         vlan->max_mtu = ether->max_mtu;
633         vlan->ctlrno = ether->ctlrno;
634         vlan->vlanid = id;
635         vlan->alen = Eaddrlen;
636         memmove(vlan->addr, ether->addr, sizeof(vlan->addr));
637         memmove(vlan->bcast, ether->bcast, sizeof(ether->bcast));
638         vlan->oq = NULL;
639         vlan->ctlr = ether;
640         vlan->vlanid = id;
641         poperror();
642         qunlock(&ether->vlq);
643         return vlan;
644 }
645
646 static struct {
647         char *type;
648         int (*reset) (struct ether *);
649 } cards[MaxEther + 1];
650
651 void addethercard(char *t, int (*r) (struct ether *))
652 {
653         static int ncard;
654
655         if (ncard == MaxEther)
656                 panic("too many ether cards");
657         cards[ncard].type = t;
658         cards[ncard].reset = r;
659         ncard++;
660 }
661
662 int parseether(uint8_t * to, char *from)
663 {
664         char nip[4];
665         char *p;
666         int i;
667
668         p = from;
669         for (i = 0; i < Eaddrlen; i++) {
670                 if (*p == 0)
671                         return -1;
672                 nip[0] = *p++;
673                 if (*p == 0)
674                         return -1;
675                 nip[1] = *p++;
676                 nip[2] = 0;
677                 to[i] = strtoul(nip, 0, 16);
678                 if (*p == ':')
679                         p++;
680         }
681         return 0;
682 }
683
684 static void etherreset(void)
685 {
686         struct ether *ether;
687         int i, n, ctlrno, qsize;
688         char name[KNAMELEN], buf[128];
689
690         for (ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++) {
691                 if (ether == 0)
692                         ether = kzmalloc(sizeof(struct ether), 0);
693                 memset(ether, 0, sizeof(struct ether));
694                 rwinit(&ether->rwlock);
695                 qlock_init(&ether->vlq);
696                 rendez_init(&ether->link_rz);
697                 ether->ctlrno = ctlrno;
698                 ether->mbps = 10;
699                 ether->mtu = ETHERMAXTU;
700                 ether->min_mtu = ETHERMINTU;
701                 ether->max_mtu = ETHERMAXTU;
702                 /* looked like irq type, we don't have these yet */
703                 //ether->netif.itype = -1;
704
705                 /* TODO: looks like they expected some init to be done here.  at the
706                  * very least, ether->type is 0 right now, and needs to be set.  looking
707                  * around online, it seems to find out ether config settings, so that we
708                  * can set some flags in the opt parseing below. */
709                 //if(archether(ctlrno, ether) <= 0)
710                 //  continue;
711
712                 for (n = 0; cards[n].type; n++) {
713 #if 0
714                         if (cistrcmp(cards[n].type, ether->type))
715                                 continue;
716                         for (i = 0; i < ether->nopt; i++) {
717                                 if (cistrncmp(ether->opt[i], "ea=", 3) == 0) {
718                                         if (parseether(ether->ea, &ether->opt[i][3]) == -1)
719                                                 memset(ether->ea, 0, Eaddrlen);
720                                 } else if (cistrcmp(ether->opt[i], "fullduplex") == 0 ||
721                                                    cistrcmp(ether->opt[i], "10BASE-TFD") == 0)
722                                         ether->fullduplex = 1;
723                                 else if (cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
724                                         ether->mbps = 100;
725                         }
726 #endif
727                         if (cards[n].reset(ether))
728                                 continue;
729                         /* might be fucked a bit - reset() doesn't know the type.  might not
730                          * even matter, except for debugging. */
731                         ether->type = cards[n].type;
732                         snprintf(name, sizeof(name), "ether%d", ctlrno);
733
734                         i = snprintf(buf, sizeof(buf),
735                                                  "#l%d: %s: %dMbps port 0x%x irq %u", ctlrno,
736                                                  ether->type, ether->mbps,
737                                      ether->port,
738                                                  ether->irq);
739                         /* Looks like this is for printing MMIO addrs */
740 #if 0
741                         if (ether->mem)
742                                 i += snprintf(buf + i, sizeof(buf) - i, " addr 0x%lx",
743                                                           PADDR(ether->mem));
744                         if (ether->size)
745                                 i += snprintf(buf + i, sizeof(buf) - i, " size 0x%lx",
746                                                           ether->size);
747 #endif
748                         i += snprintf(buf + i, sizeof(buf) - i,
749                                                   ": %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
750                                                   ether->ea[0], ether->ea[1], ether->ea[2],
751                                                   ether->ea[3], ether->ea[4], ether->ea[5]);
752                         snprintf(buf + i, sizeof(buf) - i, "\n");
753                         printk(buf);
754
755                         switch (ether->mbps) {
756
757                         case 1 ... 99:
758                                 qsize = 64 * 1024;
759                                 break;
760                         case 100 ... 999:
761                                 qsize = 256 * 1024;
762                                 break;
763                         case 1000 ... 9999:
764                                 qsize = 1024 * 1024;
765                                 break;
766                         default:
767                                 qsize = 8 * 1024 * 1024;
768                         }
769                         netifinit(ether, name, Ntypes, qsize);
770                         if (ether->oq == 0)
771                                 ether->oq = qopen(qsize, Qmsg, 0, 0);
772                         if (ether->oq == 0)
773                                 panic("etherreset %s", name);
774                         ether->alen = Eaddrlen;
775                         memmove(ether->addr, ether->ea, Eaddrlen);
776                         memset(ether->bcast, 0xFF, Eaddrlen);
777
778                         etherxx[ctlrno] = ether;
779                         ether = 0;
780                         break;
781                 }
782         }
783         if (ether)
784                 kfree(ether);
785 }
786
787 static void etherpower(int on)
788 {
789         int i;
790         struct ether *ether;
791
792         /* TODO: fix etherpower.  locking and ether->readers are broken. */
793         warn("%s needs attention.  had a rough porting from inferno", __FUNCTION__);
794         for (i = 0; i < MaxEther; i++) {
795                 if ((ether = etherxx[i]) == NULL || ether->power == NULL)
796                         continue;
797                 if (on) {
798                         /* brho: not sure what they are doing.  there seem to be certain
799                          * assumptions about calling etherpower.  i think they are using
800                          * canrlock to see if the lock is currently writelocked.  and if it
801                          * was not lockable, they would assume they had the write lock and
802                          * could unlock.  this is super fucked up. */
803                         if (canrlock(&ether->rwlock)) {
804                                 runlock(&ether->rwlock);        // brho added this
805                                 continue;
806                         }
807                         if (ether->power != NULL)
808                                 ether->power(ether, on);
809                         wunlock(&ether->rwlock);
810                 } else {
811                         /* readers isn't in the ether struct...
812                            if(ether->readers)
813                            continue;
814                          */
815                         wlock(&ether->rwlock);
816                         if (ether->power != NULL)
817                                 ether->power(ether, on);
818                         /* Keep locked until power goes back on */
819                 }
820         }
821 }
822
823 #define ETHERPOLY 0xedb88320
824
825 /* really slow 32 bit crc for ethers */
826 uint32_t ethercrc(uint8_t * p, int len)
827 {
828         int i, j;
829         uint32_t crc, b;
830
831         crc = 0xffffffff;
832         for (i = 0; i < len; i++) {
833                 b = *p++;
834                 for (j = 0; j < 8; j++) {
835                         crc = (crc >> 1) ^ (((crc ^ b) & 1) ? ETHERPOLY : 0);
836                         b >>= 1;
837                 }
838         }
839         return crc;
840 }
841
842 struct dev etherdevtab __devtab = {
843         .name = "ether",
844
845         .reset = etherreset,
846         .init = devinit,
847         .shutdown = ethershutdown,
848         .attach = etherattach,
849         .walk = etherwalk,
850         .stat = etherstat,
851         .open = etheropen,
852         .create = devcreate,
853         .close = etherclose,
854         .read = etherread,
855         .bread = etherbread,
856         .write = etherwrite,
857         .bwrite = etherbwrite,
858         .remove = devremove,
859         .wstat = etherwstat,
860         .power = etherpower,
861         .chaninfo = devchaninfo,
862 };