Some fixes for smsc usb ethernet and kernel etherusb driver (useful for Raspberry Pi): - don't assume etherusb is #l0 (so it can coexist with another ether adapter) - enable multicast by default for etherusb, since there's no interface available yet to turn it on dynamically (so ipv6 will work) - implement promiscuous and multicast modes for smsc Reference: /n/sources/patch/usbether-rpi Date: Sun May 29 16:09:35 CES 2016 Signed-off-by: miller@hamnavoe.com --- /sys/src/cmd/usb/ether/ether.c Sun May 29 16:05:43 2016 +++ /sys/src/cmd/usb/ether/ether.c Sun May 29 16:05:39 2016 @@ -1145,29 +1145,34 @@ static int kernelproxy(Ether *e) { - int ctlfd, n; + int ctlfd, n, i; + char ename[20]; char eaddr[13]; - ctlfd = open("#l0/ether0/clone", ORDWR); - if(ctlfd < 0){ - deprint(2, "%s: etherusb bind #l0: %r\n", argv0); - return -1; - } close(e->epin->dfd); close(e->epout->dfd); - seprintaddr(eaddr, eaddr+sizeof(eaddr), e->addr); - n = fprint(ctlfd, "bind %s #u/usb/ep%d.%d/data #u/usb/ep%d.%d/data %s %d %d", - e->name, e->dev->id, e->epin->id, e->dev->id, e->epout->id, - eaddr, e->bufsize, e->epout->maxpkt); - if(n < 0){ - deprint(2, "%s: etherusb bind #l0: %r\n", argv0); - opendevdata(e->epin, OREAD); - opendevdata(e->epout, OWRITE); + for(i = 0; i < 10; i++){ + sprint(ename, "#l%d/ether%d/clone", i, i); + ctlfd = open(ename, ORDWR); + if(ctlfd < 0){ + deprint(2, "%s: etherusb bind %.3s: %r\n", argv0, ename); + break; + } + seprintaddr(eaddr, eaddr+sizeof(eaddr), e->addr); + n = fprint(ctlfd, "bind %s #u/usb/ep%d.%d/data #u/usb/ep%d.%d/data %s %d %d", + e->name, e->dev->id, e->epin->id, e->dev->id, e->epout->id, + eaddr, e->bufsize, e->epout->maxpkt); + if(n < 0){ + deprint(2, "%s: etherusb bind %.3s: %r\n", argv0, ename); + close(ctlfd); + continue; + } close(ctlfd); - return -1; + return 0; } - close(ctlfd); - return 0; + opendevdata(e->epin, OREAD); + opendevdata(e->epout, OWRITE); + return -1; } int @@ -1222,8 +1227,18 @@ if(openeps(e, epin, epout) < 0) return -1; - if(kernelproxy(e) == 0) + if(kernelproxy(e) == 0){ + if(e->multicast != nil){ + /* + * Until there is an interface for the kernel etherusb driver + * to write to usb/ether ctl file, multicast needs to be on + * by default so ipv6 will work. + */ + e->nmcasts++; + e->multicast(e, nil, 1); + } return 0; + } e->fs = etherfs; snprint(e->fs.name, sizeof(e->fs.name), "etherU%d", devid); e->fs.dev = dev; --- /sys/src/cmd/usb/ether/smsc.c Sun May 29 16:05:47 2016 +++ /sys/src/cmd/usb/ether/smsc.c Sun May 29 16:05:45 2016 @@ -323,38 +323,34 @@ static int smscpromiscuous(Ether *e, int on) { - USED(on, e); -#ifdef TODO /* copied from asix */ + Dev *d; int rxctl; - deprint(2, "%s: smscpromiscuous %d\n", argv0, on); - rxctl = getrxctl(e->dev); - if(on != 0) - rxctl |= Rxctlprom; + d = e->dev; + rxctl = rr(d, Maccr); + if(on) + rxctl |= Prms; else - rxctl &= ~Rxctlprom; - return wr(e->dev, Cwrxctl, rxctl); -#endif - return -1; + rxctl &= ~Prms; + return wr(d, Maccr, rxctl); } static int smscmulticast(Ether *e, uchar *addr, int on) { - USED(addr, on, e); -#ifdef TODO /* needed for ipv6; copied from asix */ int rxctl; + Dev *d; + USED(addr, on); /* BUG: should write multicast filter */ - rxctl = getrxctl(e->dev); + d = e->dev; + rxctl = rr(d, Maccr); if(e->nmcasts != 0) - rxctl |= Rxctlamall; + rxctl |= Mcpas; else - rxctl &= ~Rxctlamall; + rxctl &= ~Mcpas; deprint(2, "%s: smscmulticast %d\n", argv0, e->nmcasts); - return wr(e->dev, Cwrxctl, rxctl); -#endif - return -1; + return wr(d, Maccr, rxctl); } static void