ref: 225cc4af5c5be518460b204aaba7beb9e013d6a7
parent: 805fe4660e71ebb2fc18b5da1fee50b02b9a8b4e
author: ppatience0 <[email protected]>
date: Tue Oct 1 22:25:43 EDT 2013
nusb/ether: add rtl8150 driver, remove unused includes
--- a/sys/src/9/boot/nusbrc
+++ b/sys/src/9/boot/nusbrc
@@ -18,6 +18,8 @@
nusb/ether -t a88178 $etherargs $1 &
case 2001abc1
nusb/ether -t aue $etherargs $1 &
+ case 0bda8150
+ nusb/ether -t url $etherargs $1 &
case *
switch($4){
case *03
--- a/sys/src/cmd/nusb/ether/asix.c
+++ b/sys/src/cmd/nusb/ether/asix.c
@@ -8,10 +8,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
-#include <auth.h>
-#include <fcall.h>
-#include <9p.h>
#include "usb.h"
#include "dat.h"
--- a/sys/src/cmd/nusb/ether/aue.c
+++ b/sys/src/cmd/nusb/ether/aue.c
@@ -7,10 +7,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
-#include <auth.h>
-#include <fcall.h>
-#include <9p.h>
#include "usb.h"
#include "dat.h"
@@ -80,7 +76,6 @@
static int csr8r(Dev *, int);
static int csr16r(Dev *, int);
static int csr8w(Dev *, int, int);
-static int csr16w(Dev *, int, int);
static int eeprom16r(Dev *, int);
static void reset(Dev *);
static int aueread(Dev *, uchar *, int);
@@ -129,22 +124,6 @@
val&0xff, reg, &v, sizeof v);
if(rc < 0) {
fprint(2, "%s: csr8w(%#x, %#x): %r\n",
- argv0, reg, val);
- }
- return rc;
-}
-
-static int
-csr16w(Dev *d, int reg, int val)
-{
- int rc;
- uchar v[2];
-
- PUT2(v, val);
- rc = usbcmd(d, Rh2d|Rvendor|Rdev, Writereg,
- val&0xffff, reg, v, sizeof v);
- if(rc < 0) {
- fprint(2, "%s: csr16w(%#x, %#x): %r\n",
argv0, reg, val);
}
return rc;
--- a/sys/src/cmd/nusb/ether/cdc.c
+++ b/sys/src/cmd/nusb/ether/cdc.c
@@ -5,10 +5,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
-#include <auth.h>
-#include <fcall.h>
-#include <9p.h>
#include <ip.h>
#include "usb.h"
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -1,8 +1,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
-#include <auth.h>
#include <fcall.h>
#include <9p.h>
#include <ip.h>
@@ -758,6 +756,7 @@
extern int a88772init(Dev *);
extern int smscinit(Dev *);
extern int cdcinit(Dev *);
+extern int urlinit(Dev *);
static struct {
char *name;
@@ -768,6 +767,7 @@
"a88178", a88178init,
"a88772", a88772init,
"aue", aueinit,
+ "url", urlinit,
};
void
--- a/sys/src/cmd/nusb/ether/mkfile
+++ b/sys/src/cmd/nusb/ether/mkfile
@@ -5,7 +5,7 @@
TARG=ether
HFILES=
-OFILES=ether.$O cdc.$O smsc.$O asix.$O aue.$O
+OFILES=ether.$O cdc.$O smsc.$O asix.$O aue.$O url.$O
</sys/src/cmd/mkone
--- a/sys/src/cmd/nusb/ether/smsc.c
+++ b/sys/src/cmd/nusb/ether/smsc.c
@@ -5,11 +5,6 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
-#include <auth.h>
-#include <fcall.h>
-#include <9p.h>
-#include <ip.h>
#include "usb.h"
#include "dat.h"
--- /dev/null
+++ b/sys/src/cmd/nusb/ether/url.c
@@ -1,0 +1,337 @@
+/*
+* realtek rtl8150 10/100 usb ethernet device driver
+*
+* copy-pasted from shingo watanabe's openbsd url(4) driver
+* and bill paul's and shunsuke akiyama's freebsd rue(4) driver
+*/
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+
+#include "usb.h"
+#include "dat.h"
+
+enum {
+ Timeout = 50,
+ Mfl = 60, /* min frame len */
+};
+
+enum { /* requests */
+ Rqm = 0x05, /* request mem */
+ Crm = 1, /* command read mem */
+ Cwm = 2, /* command write mem */
+};
+
+enum { /* registers */
+ Idr0 = 0x120, /* ether addr, load from 93c46 */
+ Idr1 = 0x121,
+ Idr2 = 0x122,
+ Idr3 = 0x123,
+ Idr4 = 0x124,
+ Idr5 = 0x125,
+
+ Mar0 = 0x126, /* multicast addr */
+ Mar1 = 0x127,
+ Mar2 = 0x128,
+ Mar3 = 0x129,
+ Mar4 = 0x12a,
+ Mar5 = 0x12b,
+ Mar6 = 0x12c,
+ Mar7 = 0x12d,
+
+ Cr = 0x12e, /* command */
+ Tcr = 0x12f, /* transmit control */
+ Rcr = 0x130, /* receive configuration */
+ Tsr = 0x132,
+ Rsr = 0x133,
+ Con0 = 0x135,
+ Con1 = 0x136,
+ Msr = 0x137, /* media status */
+ Phyar = 0x138, /* mii phy addr select */
+ Phydr = 0x139, /* mii phy data */
+ Phycr = 0x13b, /* mii phy control */
+ Gppc = 0x13d,
+ Wcr = 0x13e, /* wake count */
+ Bmcr = 0x140, /* basic mode control */
+ Bmsr = 0x142, /* basic mode status */
+ Anar = 0x144, /* an advertisement */
+ Anlp = 0x146, /* an link partner ability */
+ Aner = 0x148,
+ Nwtr = 0x14a, /* nway test */
+ Cscr = 0x14c,
+
+ Crc0 = 0x14e,
+ Crc1 = 0x150,
+ Crc2 = 0x152,
+ Crc3 = 0x154,
+ Crc4 = 0x156,
+
+ Bm0 = 0x158, /* byte mask */
+ Bm1 = 0x160,
+ Bm2 = 0x168,
+ Bm3 = 0x170,
+ Bm4 = 0x178,
+
+ Phy1 = 0x180,
+ Phy2 = 0x184,
+ Tw1 = 0x186
+};
+
+enum { /* Cr */
+ We = 1 << 5, /* eeprom write enable */
+ Sr = 1 << 4, /* software reset */
+ Re = 1 << 3, /* ethernet receive enable */
+ Te = 1 << 2, /* ethernet transmit enable */
+ Ep3ce = 1 << 1, /* enable clr of perf counter */
+ Al = 1 << 0 /* auto-load contents of 93c46 */
+};
+
+enum { /* Tcr */
+ Tr1 = 1 << 7, /* tx retry count */
+ Tr0 = 1 << 6,
+ Ifg1 = 1 << 4, /* interframe gap time */
+ Ifg0 = 1 << 3,
+ Nocrc = 1 << 0 /* no crc appended */
+};
+
+enum { /* Rcr */
+ Tail = 1 << 7,
+ Aer = 1 << 6,
+ Ar = 1 << 5,
+ Am = 1 << 4,
+ Ab = 1 << 3,
+ Ad = 1 << 2,
+ Aam = 1 << 1,
+ Aap = 1 << 0
+};
+
+enum { /* Msr */
+ Tfce = 1 << 7,
+ Rfce = 1 << 6,
+ Mdx = 1 << 4, /* duplex */
+ S100 = 1 << 3, /* speed 100 */
+ Lnk = 1 << 2,
+ Tpf = 1 << 1,
+ Rpf = 1 << 0
+};
+
+enum { /* Phyar */
+ Phyamsk = 0x1f
+};
+
+enum { /* Phycr */
+ Phyown = 1 << 6, /* own bit */
+ Rwcr = 1 << 5, /* mii mgmt data r/w control */
+ Phyoffmsk = 0x1f /* phy register offset */
+};
+
+enum { /* Bmcr */
+ Spd = 0x2000, /* speed set */
+ Bdx = 0x0100 /* duplex */
+};
+
+enum { /* Anar */
+ Ap = 0x0400 /* pause */
+};
+
+enum { /* Anlp */
+ Lpp = 0x0400 /* pause */
+};
+
+enum { /* eeprom address declarations */
+ Ebase = 0x1200,
+ Eidr0 = Ebase + 0x02,
+ Eidr1 = Ebase + 0x03,
+ Eidr2 = Ebase + 0x03,
+ Eidr3 = Ebase + 0x03,
+ Eidr4 = Ebase + 0x03,
+ Eidr5 = Ebase + 0x03,
+ Eint = Ebase + 0x17 /* interval */
+};
+
+enum { /* receive header */
+ Bcm = 0x0fff, /* rx bytes count mask */
+ Vpm = 0x1000, /* valid packet mask */
+ Rpm = 0x2000, /* runt packet mask */
+ Ppm = 0x4000, /* physical match packet mask */
+ Mpm = 0x8000 /* multicast packet mask */
+};
+
+static int mem(Dev *, int, int, uchar *, int);
+static int csr8r(Dev *, int);
+static int csr16r(Dev *, int);
+static int csr8w(Dev *, int, int);
+static int csr16w(Dev *, int, int);
+static int csr32w(Dev *, int, int);
+static void reset(Dev *);
+static int urlread(Dev *, uchar *, int);
+static void urlwrite(Dev *, uchar *, int);
+int urlinit(Dev *);
+
+static int
+mem(Dev *d, int cmd, int off, 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, 0, buf, len);
+ if(rc < 0) {
+ fprint(2, "%s: mem(%d, %#.4x) failed\n",
+ argv0, cmd, off);
+ }
+ return rc;
+}
+
+static int
+csr8r(Dev *d, int reg)
+{
+ uchar v;
+
+ v = 0;
+ if(mem(d, Crm, reg, &v, sizeof v) < 0)
+ return 0;
+ return v;
+}
+
+static int
+csr16r(Dev *d, int reg)
+{
+ uchar v[2];
+
+ PUT2(v, 0);
+ if(mem(d, Crm, reg, v, sizeof v) < 0)
+ return 0;
+ return GET2(v);
+}
+
+static int
+csr8w(Dev *d, int reg, int val)
+{
+ uchar v;
+
+ v = val;
+ if(mem(d, Cwm, reg, &v, sizeof v) < 0)
+ return -1;
+ return 0;
+}
+
+static int
+csr16w(Dev *d, int reg, int val)
+{
+ uchar v[2];
+
+ PUT2(v, val);
+ if(mem(d, Cwm, reg, v, sizeof v) < 0)
+ return -1;
+ return 0;
+}
+
+static int
+csr32w(Dev *d, int reg, int val)
+{
+ uchar v[4];
+
+ PUT4(v, val);
+ if(mem(d, Cwm, reg, v, sizeof v) < 0)
+ return -1;
+ return 0;
+}
+
+static void
+reset(Dev *d)
+{
+ int i, r;
+
+ r = csr8r(d, Cr) | Sr;
+ csr8w(d, Cr, r);
+
+ for(i = 0; i < Timeout; i++) {
+ if((csr8r(d, Cr) & Sr) == 0)
+ break;
+ sleep(10);
+ }
+ if(i >= Timeout)
+ fprint(2, "%s: reset failed\n", argv0);
+
+ sleep(100);
+}
+
+static int
+urlread(Dev *ep, uchar *p, int plen)
+{
+ int n;
+ uint hd;
+ uchar *q;
+
+ if(nbin < 4)
+ nbin = read(ep->dfd, bin, sizeof bin);
+ if(nbin < 0)
+ return -1;
+ if(nbin < 4)
+ return 0;
+ n = nbin - 4;
+ if(n < 6) {
+ nbin = 0;
+ return 0;
+ }
+ q = bin + n;
+ hd = GET2(q);
+ if((hd & Vpm) == 0) {
+ fprint(2, "url: rx error: %#.4ux\n", hd);
+ n = 0;
+ } else {
+ if(n > plen)
+ n = plen;
+ if(n > 0)
+ memmove(p, bin, n);
+ }
+ nbin = 0;
+ return n;
+}
+
+static void
+urlwrite(Dev *ep, uchar *p, int n)
+{
+ if(n > sizeof bout)
+ n = sizeof bout;
+ memmove(bout, p, n);
+ if(n < Mfl) {
+ memset(bout+n, 0, Mfl-n);
+ n = Mfl;
+ }
+ write(ep->dfd, bout, n);
+}
+
+int
+urlinit(Dev *d)
+{
+ int i, r;
+
+ reset(d);
+ if(mem(d, Crm, Idr0, macaddr, sizeof macaddr) < 0)
+ return -1;
+
+ reset(d);
+ for(i = 0; i < sizeof macaddr; i++)
+ csr8w(d, Idr0+i, macaddr[i]);
+
+ csr8w(d, Tcr, Tr1|Tr0|Ifg1|Ifg0);
+ csr16w(d, Rcr, Tail|Ad|Ab);
+
+ r = csr16r(d, Rcr) & ~(Am | Aam | Aap);
+ csr16w(d, Rcr, r);
+ csr32w(d, Mar0, 0);
+ csr32w(d, Mar4, 0);
+
+ csr8w(d, Cr, Te|Re);
+
+ epwrite = urlwrite;
+ epread = urlread;
+ return 0;
+}