Use etherusb kernel proxy (when available - so far only on Raspberry Pi) to pack/unpack and send/receive packets between usb pipes and kernel ether queues. Reference: /n/sources/patch/applied/usb-ether-kernelproxy-1 Date: Mon Nov 12 22:12:49 CET 2012 Signed-off-by: miller@hamnavoe.com --- /sys/src/cmd/usb/ether/ether.h Mon Nov 12 22:09:56 2012 +++ /sys/src/cmd/usb/ether/ether.h Mon Nov 12 22:09:54 2012 @@ -58,6 +58,8 @@ int (*multicast)(Ether*, uchar*, int); char* (*seprintstats)(char*, char*, Ether*); void (*free)(Ether*); + int bufsize; + char *name; void* aux; }; --- /sys/src/cmd/usb/ether/asix.c Mon Nov 12 22:10:00 2012 +++ /sys/src/cmd/usb/ether/asix.c Mon Nov 12 22:09:58 2012 @@ -474,7 +474,9 @@ return -1; } deprint(2, "%s: asix reset done\n", argv0); + ether->name = "asix"; ether->aux = emallocz(sizeof(Buf), 1); + ether->bufsize = Hdrsize+Maxpkt; ether->bread = asixbread; ether->bwrite = asixbwrite; ether->free = asixfree; --- /sys/src/cmd/usb/ether/ether.c Mon Nov 12 22:10:06 2012 +++ /sys/src/cmd/usb/ether/ether.c Mon Nov 12 22:10:03 2012 @@ -174,7 +174,7 @@ qunlock(e); } if(bp == nil){ - fprint(2, "%s: blocked waiting for allocbuf\n", argv0); + deprint(2, "%s: blocked waiting for allocbuf\n", argv0); bp = recvp(e->bc); } bp->rp = bp->data + Hdrsize; @@ -802,7 +802,7 @@ if(e->nblock == 0) sendp(e->wc, bp); else if(nbsendp(e->wc, bp) == 0){ - fprint(2, "%s: (out) packet lost\n", argv0); + deprint(2, "%s: (out) packet lost\n", argv0); e->noerrs++; freebuf(e, bp); } @@ -1038,7 +1038,7 @@ dbp->type = bp->type; } if(nbsendp(e->conns[i]->rc, dbp) == 0){ - fprint(2, "%s: (in) packet lost\n", argv0); + deprint(2, "%s: (in) packet lost\n", argv0); e->nierrs++; freebuf(e, dbp); } @@ -1142,6 +1142,34 @@ return -1; } +static int +kernelproxy(Ether *e) +{ + int ctlfd, n; + 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); + close(ctlfd); + return -1; + } + close(ctlfd); + return 0; +} + int ethermain(Dev *dev, int argc, char **argv) { @@ -1174,6 +1202,7 @@ e->dev = dev; dev->free = etherdevfree; memmove(e->addr, ea, Eaddrlen); + e->name = "cdc"; for(i = 0; i < nelem(ethers); i++) if(ethers[i](e) == 0) @@ -1188,9 +1217,13 @@ e->bwrite = etherbwrite; if(e->bread == nil) e->bread = etherbread; + if(e->bufsize == 0) + e->bufsize = Maxpkt; if(openeps(e, epin, epout) < 0) return -1; + if(kernelproxy(e) == 0) + 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 Mon Nov 12 22:10:10 2012 +++ /sys/src/cmd/usb/ether/smsc.c Mon Nov 12 22:10:07 2012 @@ -15,7 +15,7 @@ Resettime = 1000, E2pbusytime = 1000, Afcdefault = 0xF830A1, -// Hsburst = 37, +// Hsburst = 37, /* from original linux driver */ Hsburst = 8, Fsburst = 129, Defbulkdly = 0x2000, @@ -214,7 +214,7 @@ if(eepromr(d, MACoffset, ea, Eaddrlen) < 0) return -1; for(i = 0; i < Eaddrlen; i++) - if(ea[i] != 0){ + if(ea[i] != 0 && ea[i] != 0xFF){ memmove(buf, ea, Eaddrlen); break; } @@ -275,7 +275,7 @@ if(rbp->ndata < 4){ rbp->rp = rbp->data; rbp->ndata = read(e->epin->dfd, rbp->rp, Doburst? Hsburst*512: - sizeof(rbp->data)); + Maxpkt); if(rbp->ndata < 0) return -1; } @@ -342,7 +342,14 @@ return -1; } deprint(2, "%s: smsc reset done\n", argv0); - ether->aux = emallocz(sizeof(Buf) + Hsburst*512 - Maxpkt, 1); + ether->name = "smsc"; + if(Doburst){ + ether->bufsize = Hsburst*512; + ether->aux = emallocz(sizeof(Buf) + Hsburst*512 - Maxpkt, 1); + }else{ + ether->bufsize = Maxpkt; + ether->aux = emallocz(sizeof(Buf), 1); + } ether->free = smscfree; ether->bread = smscbread; ether->bwrite = smscbwrite;