shithub: patch

ref: 801c6e1167653f01779b5643a3e3870e2de56dee
dir: patch/nusb-ure

View raw version
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;
+}