ref: 45adb253790f75a5d55d7b42a1e8da1c05989c03
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;
+}