setting the number of buffered packets to Nconn/2 doesn't make any sense. the amount of buffering is really related to how much latency reading then dispatching packets takes, not the number of queues. Reference: /n/atom/patch/applied/usbethermaxbuf Date: Thu Apr 24 18:57:12 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/usb/ether/aue.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/usb/ether/aue.c Thu Apr 24 18:55:26 2014 @@ -0,0 +1,215 @@ +/* +* admtek pegasus driver copy-pasted from bill paul's +* openbsd/freebsd aue(4) driver, with help +* from the datasheet and petko manolov's linux +* drivers/net/usb/pegasus.c driver +*/ +#include +#include +#include + +#include "usb.h" +#include "usbfs.h" +#include "ether.h" + +enum { + Readreg = 0xf0, + Writereg = 0xf1, + + Ctl0 = 0x00, + C0incrxcrc = 1 << 0, + C0allmulti = 1 << 1, + C0stopbackoff = 1 << 2, + C0rxstatappend = 1 << 3, + C0wakeonen = 1 << 4, + C0rxpauseen = 1 << 5, + C0rxen = 1 << 6, + C0txen = 1 << 7, + + Ctl1 = 0x01, + C1homelan = 1 << 2, + C1resetmac = 1 << 3, + C1speedsel = 1 << 4, + C1duplex = 1 << 5, + C1delayhome = 1 << 6, + + Ctl2 = 0x02, + C2ep3clr = 1 << 0, + C2rxbadpkt = 1 << 1, + C2prom = 1 << 2, + C2loopback = 1 << 3, + C2eepromwren = 1 << 4, + C2eepromload = 1 << 5, + + Par = 0x10, + + Eereg = 0x20, + Eedata = 0x21, + + Eectl = 0x23, + Eectlwr = 1 << 0, + Eectlrd = 1 << 1, + Eectldn = 1 << 2, + + Phyaddr = 0x25, + Phydata = 0x26, + + Phyctl = 0x28, + Phyctlphyreg = 0x1f, + Phyctlwr = 1 << 5, + Phyctlrd = 1 << 6, + Phyctldn = 1 << 7, + + Gpio0 = 0x7e, + Gpio1 = 0x7f, + Gpioin0 = 1 << 0, + Gpioout0 = 1 << 1, + Gpiosel0 = 1 << 2, + Gpioin1 = 1 << 3, + Gpioout1 = 1 << 4, + Gpiosel1 = 1 << 5, + + Rxerror = 0x1e << 16, + + Timeout = 1000 +}; + +static int csr8r(Dev *, int); +static int csr16r(Dev *, int); +static int csr8w(Dev *, int, int); +static int eeprom16r(Dev *, int); +static void reset(Dev *); + +static int +csr8r(Dev *d, int reg) +{ + int rc; + uchar v; + + rc = usbcmd(d, Rd2h|Rvendor|Rdev, Readreg, + 0, reg, &v, sizeof v); + if(rc < 0) { + fprint(2, "%s: csr8r(%#x): %r\n", + argv0, reg); + return 0; + } + return v; +} + +static int +csr16r(Dev *d, int reg) +{ + int rc; + uchar v[2]; + + rc = usbcmd(d, Rd2h|Rvendor|Rdev, Readreg, + 0, reg, v, sizeof v); + if(rc < 0) { + fprint(2, "%s: csr16r(%#x): %r\n", + argv0, reg); + return 0; + } + return GET2(v); +} + +static int +csr8w(Dev *d, int reg, int val) +{ + int rc; + uchar v; + + v = val; + rc = usbcmd(d, Rh2d|Rvendor|Rdev, Writereg, + val&0xff, reg, &v, sizeof v); + if(rc < 0) { + fprint(2, "%s: csr8w(%#x, %#x): %r\n", + argv0, reg, val); + } + return rc; +} + +static int +eeprom16r(Dev *d, int off) +{ + int i; + + csr8w(d, Eereg, off); + csr8w(d, Eectl, Eectlrd); + for(i = 0; i < Timeout; i++) { + if(csr8r(d, Eectl) & Eectldn) + break; + } + if(i >= Timeout) { + fprint(2, "%s: EEPROM read timed out\n", + argv0); + } + return csr16r(d, Eedata); +} + +static void +reset(Dev *d) +{ + int i; + + csr8w(d, Ctl1, csr8r(d, Ctl1)|C1resetmac); + for(i = 0; i < Timeout; i++) { + if(!(csr8r(d, Ctl1) & C1resetmac)) + break; + } + if(i >= Timeout) + fprint(2, "%s: reset failed\n", argv0); + csr8w(d, Gpio0, Gpiosel0|Gpiosel1); + csr8w(d, Gpio0, Gpiosel0|Gpiosel1|Gpioout0); + sleep(10); +} + +static long +auebread(Ether *e, Buf *b) +{ + uint hd; + int n, len; + + b->ndata = 0; + n = read(e->epin->dfd, b->data, Maxpkt); + if(n < 4) + return 0; + n -= 4; + hd = GET4(b->data+n); + len = hd & 0xfff; + if((hd & Rxerror) != 0 || len > n) + return 0; + b->ndata = n; + return 0; +} + +static long +auebwrite(Ether *e, Buf *b) +{ + b->rp -= 2; + PUT2(b->rp-2, b->ndata); + return write(e->epout->dfd, b->rp-2, b->ndata+2); +} + +int +auereset(Ether *e) +{ + int i, v; + Dev *d; + + /* missing device selection */ + d = e->dev; + reset(d); + for(i = 0; i < 3; i++) { + v = eeprom16r(d, i); + PUT2( e->addr+2*i, v); + } + for(i = 0; i < 6; i++) + csr8w(d, Par+i, e->addr[i]); + csr8w(d, Ctl2, csr8r(d, Ctl2)&~C2prom); + csr8w(d, Ctl0, C0rxstatappend|C0rxen); + csr8w(d, Ctl0, csr8r(d, Ctl0)|C0txen); + csr8w(d, Ctl2, csr8r(d, Ctl2)|C2ep3clr); + e->bwrite = auebwrite; + e->bread = auebread; + return 0; +} --- /sys/src/cmd/usb/ether/ether.c Thu Apr 24 18:55:27 2014 +++ /sys/src/cmd/usb/ether/ether.c Thu Apr 24 18:55:28 2014 @@ -119,9 +119,10 @@ Resetf ethers[] = { +// auereset, asixreset, smscreset, - rtl8150reset, +// rtl8150reset, cdcreset, /* keep last */ }; @@ -290,8 +291,8 @@ if(c->ref == 0) s = seprint(s, se, "c[%d]: free\n", i); else{ - s = seprint(s, se, "c[%d]: refs %ld t %#x h %d p %d\n", - c->nb, c->ref, c->type, c->headersonly, c->prom); + s = seprint(s, se, "c[%d]: refs %ld t %#x p %d\n", + c->nb, c->ref, c->type, c->prom); } } qunlock(e); @@ -710,10 +711,6 @@ incref(&e->prom); c->prom = 1; return prom(e, 1); - } - if(strncmp(buf, "headersonly", 11) == 0){ - c->headersonly = 1; - return 0; } if(strncmp(buf, "addmulti ", 9) == 0 || strncmp(buf, "remmulti ", 9) == 0){ if(parseaddr(addr, buf+9) < 0){ --- /sys/src/cmd/usb/ether/ether.h Thu Apr 24 18:55:29 2014 +++ /sys/src/cmd/usb/ether/ether.h Thu Apr 24 18:55:30 2014 @@ -21,6 +21,7 @@ Maxpkt = 2000, /* no jumbo packets here */ Nconns = 8, /* max number of connections */ + Nbuffer = 4, /* number of packets to buffer */ Nbufs = 32, /* max number of buffers */ Scether = 6, /* ethernet cdc subclass */ Fnheader = 0, /* Functions */ @@ -43,7 +44,6 @@ Ref; /* one per file in use */ int nb; int type; - int headersonly; int prom; Channel*rc; /* [2] of Buf* */ }; --- /sys/src/cmd/usb/ether/mkfile Thu Apr 24 18:55:30 2014 +++ /sys/src/cmd/usb/ether/mkfile Thu Apr 24 18:55:31 2014 @@ -6,6 +6,7 @@ LIBDOFILES=\ ether.$O\ + aue.$O\ asix.$O\ smsc.$O\ cdc.$O\ --- /sys/src/cmd/usb/ether/rtl8150.c Thu Apr 24 18:55:31 2014 +++ /sys/src/cmd/usb/ether/rtl8150.c Thu Apr 24 18:55:32 2014 @@ -280,7 +280,7 @@ fprint(2, "rtl8150: rx error: %#.4ux\n", hd); bp->ndata = 0; } else{ - memcpy(bp, sb.rp, sb.ndata); + memcpy(bp->rp, sb.rp, sb.ndata); bp->ndata = sb.ndata; sb.ndata = 0; }