ref: 5fdd03036bcccfc1aca52e52aa8cfd153dba7909
dir: /nusb-ure/
patch for broken fucking ure piece of shit ass fuck usb ether card; incomplete since the fucking thing died diff -r ebaff70ba8fe sys/src/9/boot/nusbrc --- a/sys/src/9/boot/nusbrc Mon May 22 18:33:14 2017 +0200 +++ b/sys/src/9/boot/nusbrc Sat May 27 11:58:35 2017 +0200 @@ -23,6 +23,8 @@ nusb/ether -t aue $etherargs $id case 0bda8150 nusb/ether -t url $etherargs $id + case 0bda8151 + nusb/ether -t ure $etherargs $id case 18d14ee3 0bb40003 nusb/ether -t rndis $etherargs $id case * diff -r ebaff70ba8fe sys/src/cmd/nusb/ether/ether.c --- a/sys/src/cmd/nusb/ether/ether.c Mon May 22 18:33:14 2017 +0200 +++ b/sys/src/cmd/nusb/ether/ether.c Sat May 27 11:58:35 2017 +0200 @@ -808,6 +808,7 @@ extern int a88772init(Dev *); extern int smscinit(Dev *); extern int cdcinit(Dev *); +extern int ureinit(Dev *); extern int urlinit(Dev *); extern int rndisinit(Dev *); @@ -820,6 +821,7 @@ "a88178", a88178init, "a88772", a88772init, "aue", aueinit, + "ure", ureinit, "url", urlinit, "rndis", rndisinit, }; diff -r ebaff70ba8fe sys/src/cmd/nusb/ether/mkfile --- a/sys/src/cmd/nusb/ether/mkfile Mon May 22 18:33:14 2017 +0200 +++ b/sys/src/cmd/nusb/ether/mkfile Sat May 27 11:58:35 2017 +0200 @@ -5,7 +5,7 @@ TARG=ether HFILES= -OFILES=ether.$O cdc.$O smsc.$O asix.$O aue.$O url.$O rndis.$O +OFILES=ether.$O cdc.$O smsc.$O asix.$O aue.$O ure.$O url.$O rndis.$O </sys/src/cmd/mkone diff -r ebaff70ba8fe sys/src/cmd/nusb/ether/ure.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/src/cmd/nusb/ether/ure.c Sat May 27 11:58:35 2017 +0200 @@ -0,0 +1,442 @@ +/* + * Realtek RTL8152 10/100 USB Ethernet + */ +/* FIXME: note on submit: based on url.c and openbsd's ure(4) driver rev 1.3 + * + changes to nusbrc */ +#include <u.h> +#include <libc.h> +#include <thread.h> + +#include "usb.h" +#include "dat.h" + +enum { + Timeout = 1000, + Ver4c00 = 0x4c00, + Ver4c10 = 0x4c10, + + /* requests */ + Rqm = 0x05, /* request mem */ + Crm = 1, /* command read mem */ + Cwm = 2, /* command write mem */ + Cpla = 0x100, /* indices */ + Cusb = 0x000, + + /* registers */ + Idr = 0xc000, /* ether addr */ + Rcr = 0xc010, /* receive configuration */ + Ab = 1<<3, + Am = 1<<2, + Apm = 1<<1, + Aap = 1<<0, + Rfifo0 = 0xc0a0, /* rx fifo */ + Thr1n = 0x00080002, /* thr1 normal */ + Rfifo1 = 0xc0a4, + Thr2fl = 0x00000060, /* thr2 full speed */ + Thr2hi = 0x00000038, /* thr2 high speed */ + Rfifo2 = 0xc0a8, + Thr3fl = 0x00000078, /* thr3 full speed */ + Thr3hi = 0x00000048, /* thr3 high speed */ + Fmc = 0xc0b4, /* packet filter */ + Fcr = 1<<0, + Tun = 0xc0bc, /* teredo configuration */ + Tusel = 1<<15, /* select */ + Tuwak = 0x7f00, /* wake mask */ + Turs = 0x00fe, /* rs event mask */ + Tunm = Tusel | Tuwak | Turs, + Mar0 = 0xcd00, /* multicast addr */ + Mar4 = 0xcd04, + Bak = 0xd000, /* backup */ + Tutm = 0xd2cc, /* teredo timer */ + Wow = 0xd2e8, /* realwow timer */ + Led = 0xdd92, /* led control */ + Ledm = 7<<8, /* mode mask */ + Phimr = 0xe022, /* gphy intr imr */ + Ilnkch = 1<<3, /* speed down link change */ + Irxdv = 1<<2, /* speed down rxdv */ + Ispddn = 1<<1, /* speed down */ + Ists = 1<<0, /* status */ + Mcpwr = 0xe0c0, /* mac power control */ + D3clk = 1<<14, + Mcuclk = 0x07010f07, + Mcuclkm = 0x0f0f0f0f, + Wdt6 = 0xe428, + Wdtmd = 1<<0, /* wdt6 set mode */ + Tcr0 = 0xe610, + Fifoau = 1<<7, /* auto fifo */ + Tcr1 = 0xe612, + Ver = 0x7cf0, /* version mask */ + Tfifo = 0xe618, /* tx fifo */ + Thrn = 0x00400008, /* thr normal */ + Cr = 0xe813, /* command */ + Sr = 1<<4, /* software reset */ + Re = 1<<3, /* ethernet receive enable */ + Te = 1<<2, /* ethernet transmit enable */ + Phpwr = 0xe84c, /* phy power control */ + Txidl = 1<<7, /* tx 10m idle */ + Pfmpwm = 1<<6, + Oob = 0xe84f, /* oob control */ + Ook = 1<<7, /* now is oob */ + Ordy = 1<<1, /* link list ready */ + Cpcr = 0xe854, + Rxvlan = 1<<6, + Msc1 = 0xe85a, /* misc 1 */ + Rxdy = 1<<3, + Rocp = 0xe86c, /* ocp gphy base */ + Aldps = 0x2010, /* aldps configuration */ + Aldpsa = Aldps & 0xf000, + Aldpsr = Aldps & 0x0fff | 0xb000, + Pwsv = 1<<15, /* power save */ + Pdnps = 1<<9, + Lnk = 1<<8, /* link enable */ + Dis = 1<<4, /* dis sdsave */ + Sff7 = 0xe8de, /* sff status 7 */ + Inll = 1<<15, + Borw = 1<<14, + + Ucr = 0xd406, /* usb control */ + Noagg = 1<<4, /* disable rx aggregation */ + Txag = 0xd40a, /* tx aggregation */ + Maxth = 3<<0, /* max threshold */ + Urth = 0xd40c, /* rx buf threshold */ + Urthhi = 0x7a120180, + Pms = 0xd432, /* pm status */ + Rsm = 1<<0, /* resume indicate */ + Udma = 0xd434, + Txadj1 = 1<<8, /* tx size adjust 1 */ + Tstoff = 1<<0, /* test mode disable */ + Ups = 0xd800, + Cut = 1<<8 /* power cut */ +}; + +static int +mem(Dev *d, int cmd, int off, int index, uchar *buf, int len) +{ + int r, rc; + + if(d == nil) + return 0; + r = Rvendor | Rdev; + if(cmd == Crm) + r |= Rd2h; + else + r |= Rh2d; + rc = usbcmd(d, r, Rqm, off, index, buf, len); + if(rc < 0){ + fprint(2, "%s: mem(%d, %#.4x, %#.4x) failed\n", + argv0, cmd, off, index); + } + return rc; +} + +static int +rr8(Dev *d, int reg, int index) +{ + uchar v[4], m; + + m = (reg & 3) << 3; + reg &= ~3; + PUT4(v, 0); + if(mem(d, Crm, reg, index, v, sizeof v) < 0) + return 0; + fprint(2, "rr8 %ux %ux %ux\n", reg, index, GET4(v) >> m & 0xff); + return GET4(v) >> m & 0xff; +} + +static int +rr16(Dev *d, int reg, int index) +{ + uchar v[4], m; + + m = (reg & 2) << 3; + reg &= ~3; + PUT4(v, 0); + if(mem(d, Crm, reg, index, v, sizeof v) < 0) + return 0; + fprint(2, "rr16 %ux %ux %ux\n", reg, index, GET4(v) >> m & 0xffff); + return GET4(v) >> m & 0xffff; +} + +static int +rr32(Dev *d, int reg, int index) +{ + uchar v[4]; + + PUT4(v, 0); + if(mem(d, Crm, reg, index, v, sizeof v) < 0) + return 0; + fprint(2, "rr32 %ux %ux %ux\n", reg, index, GET4(v)); + return GET4(v); +} + +static int +wr8(Dev *d, int reg, int index, int val) +{ + uchar v[4], m; + u16int en; + + fprint(2, "wr8 %ux %ux %ux\n", reg, index, val); + en = 0x11; + m = reg & 3; + val &= 0xff; + if(reg & 3){ + en <<= m; + val <<= m << 3; + reg &= ~3; + } + PUT4(v, val); + if(mem(d, Cwm, reg, index | en, v, sizeof v) < 0) + return -1; + return 0; +} + +static int +wr16(Dev *d, int reg, int index, int val) +{ + uchar v[4], m; + u16int en; + + fprint(2, "wr16 %ux %ux %ux\n", reg, index, val); + en = 0x33; + m = reg & 2; + val &= 0xffff; + if(reg & 2){ + en <<= m; + val <<= m << 3; + reg &= ~3; + } + PUT4(v, val); + if(mem(d, Cwm, reg, index | en, v, sizeof v) < 0) + return -1; + return 0; +} + +static int +wr32(Dev *d, int reg, int index, int val) +{ + uchar v[4]; + + fprint(2, "wr32 %ux %ux %ux\n", reg, index, val); + PUT4(v, val); + if(mem(d, Cwm, reg, index | 0xff, v, sizeof v) < 0) + return -1; + return 0; +} + +static int +csr8(Dev *d, int reg, int index, int clr, int set) +{ + int v; + + v = rr8(d, reg, index) & ~clr | set; + return wr8(d, reg, index, v); +} + +static int +csr16(Dev *d, int reg, int index, int clr, int set) +{ + int v; + + v = rr16(d, reg, index) & ~clr | set; + return wr16(d, reg, index, v); +} + +static int +csr32(Dev *d, int reg, int index, int clr, int set) +{ + int v; + + v = rr32(d, reg, index) & ~clr | set; + return wr32(d, reg, index, v); +} + +static void +oobwait(Dev *d) +{ + int i; + + for(i=0; i<Timeout; i++){ + if(rr8(d, Oob, Cpla) & Ordy) + break; + sleep(10); + } + if(i == Timeout) + fprint(2, "%s: timeout waiting for OOB control\n", argv0); +} + +static void +reset(Dev *d) +{ + int i; + + wr8(d, Cr, Cpla, Sr); + for(i=0; i<Timeout; i++) { + if((rr8(d, Cr, Cpla) & Sr) == 0) + break; + sleep(10); + } + if(i >= Timeout) + fprint(2, "%s: reset failed\n", argv0); + sleep(100); +} + +static int +phyinit(Dev *d) +{ + int r, v; + uchar a[8]; + + reset(d); + v = rr16(d, Tcr1, Cpla) & Ver; + if(!setmac){ + r = v == Ver4c10 ? Bak : Idr; + if(mem(d, Crm, r, Cpla, a, sizeof a) < 0) + return -1; + memcpy(macaddr, a, sizeof macaddr); + } + + wr16(d, Rocp, Cpla, Aldpsa); + wr16(d, Aldpsr, Cpla, Pwsv | Pdnps | Lnk | Dis); + sleep(20); + + if(v == 0x4c00) + csr16(d, Led, Cpla, Ledm, 0); + csr16(d, Ups, Cusb, Cut, 0); + csr16(d, Pms, Cusb, Rsm, 0); + csr16(d, Phpwr, Cpla, 0, Txidl | Pfmpwm); + csr32(d, Mcpwr, Cpla, Mcuclkm, Mcuclk | D3clk); + wr16(d, Phimr, Cpla, Ists | Ispddn | Irxdv | Ilnkch); + csr16(d, Ucr, Cusb, 0, Noagg); + + wr16(d, Rocp, Cpla, Aldpsa); + wr16(d, Aldpsr, Cpla, Pwsv | Pdnps | Lnk | Dis); + sleep(20); + + csr16(d, Msc1, Cpla, 0, Rxdy); + csr32(d, Tun, Cpla, Tunm, 0); + wr16(d, Wdt6, Cpla, Wdtmd); + wr16(d, Wow, Cpla, 0); + wr32(d, Tutm, Cpla, 0); + csr32(d, Rcr, Cpla, Aap | Apm | Am | Ab, 0); + reset(d); + wr8(d, Cr, Cpla, 0); + + csr8(d, Oob, Cpla, Ook, 0); + csr16(d, Sff7, Cpla, Borw, 0); + oobwait(d); + csr16(d, Sff7, Cpla, 0, Inll); + oobwait(d); + + csr16(d, Cpcr, Cpla, Rxvlan, 0); + csr16(d, Tcr0, Cpla, Fifoau, 0); + wr32(d, Rfifo0, Cpla, Thr1n); + wr32(d, Rfifo1, Cpla, Thr2fl); + wr32(d, Rfifo2, Cpla, Thr3fl); + wr32(d, Tfifo, Cpla, Thrn); + wr8(d, Txag, Cusb, Maxth); + wr32(d, Urth, Cusb, Urthhi); + wr32(d, Udma, Cusb, Tstoff | Txadj1); + reset(d); + return 0; +} + +static int +urereceive(Dev *ep) +{ + Block *b; + int n; + + b = allocb(Maxpkt+24); + if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){ + freeb(b); + return -1; + } + b->wp += n; + fprint(2, "urerx %d\n", n); + while(BLEN(b) > 24){ + n = GET4(b->rp) & 0x7fff; + b->rp += 24; + if(n > BLEN(b)) + break; + etheriq(b, 1); + b->rp += n; + } + freeb(b); + return 0; +} + +static void +uretransmit(Dev *ep, Block *b) +{ + int n; + + n = BLEN(b); + fprint(2, "uretx %d\n", n); + b->rp -= 8; + PUT4(b->rp, n + 8 | 3 << 30); + PUT4(b->rp+4, 0); + write(ep->dfd, b->rp, 8+n); + freeb(b); + fprint(2, "done\n"); +} + +static int +urepromiscuous(Dev *d, int on) +{ + int c, s; + + c = 0; + s = 0; + if(on) + s |= Am | Aap; + else{ + c = Aap; + if(nmulti == 0) + c |= Am; + } + return csr16(d, Rcr, Cpla, c, s); +} + +static int +uremulticast(Dev *d, uchar*, int) +{ + int c, s; + + c = 0; + s = 0; + if(nmulti) + s |= Am; + else{ + if(nprom == 0) + c = Am; + } + return csr16(d, Rcr, Cpla, c, s); +} + +int +ureinit(Dev *d) +{ + uchar a[8]; + + if(phyinit(d) < 0) + return -1; + memset(a, 0, sizeof a); + memcpy(a, macaddr, sizeof macaddr); + if(mem(d, Cwm, Idr, Cpla | 0x3f, a, sizeof a) < 0) + return -1; + + csr16(d, Fmc, Cpla, Fcr, 0); + csr16(d, Fmc, Cpla, 0, Fcr); + csr8(d, Cr, Cpla, 0, Re | Te); + csr16(d, Msc1, Cpla, Rxdy, 0); + wr32(d, Rcr, Cpla, Apm); + wr32(d, Mar0, Cpla, 0); + wr32(d, Mar4, Cpla, 0); + wr32(d, Rcr, Cpla, Apm | Am); + + epreceive = urereceive; + eptransmit = uretransmit; + eppromiscuous = urepromiscuous; + epmulticast = uremulticast; + return 0; +}