diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-11-05 22:23:07 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-11-05 22:23:07 +0000 |
commit | 9973c9276dcb2ff075a78737c403750b0201655f (patch) | |
tree | 1cfd34cba7c14fd2e4f0aa77b2041271134853af | |
parent | 616f62253e1690a5f1e365d2122b300fc7922257 (diff) |
nusb/ether: implement link status detection for smsc and lan78xx
-rw-r--r-- | sys/src/cmd/nusb/ether/dat.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/nusb/ether/ether.c | 9 | ||||
-rw-r--r-- | sys/src/cmd/nusb/ether/lan78xx.c | 22 | ||||
-rw-r--r-- | sys/src/cmd/nusb/ether/smsc.c | 20 |
4 files changed, 45 insertions, 7 deletions
diff --git a/sys/src/cmd/nusb/ether/dat.h b/sys/src/cmd/nusb/ether/dat.h index 69848d182..40b37e834 100644 --- a/sys/src/cmd/nusb/ether/dat.h +++ b/sys/src/cmd/nusb/ether/dat.h @@ -63,3 +63,4 @@ int (*epreceive)(Dev*); void (*eptransmit)(Dev*, Block*); int (*eppromiscuous)(Dev*, int); int (*epmulticast)(Dev*, uchar*, int); +int (*eplinkspeed)(Dev*); diff --git a/sys/src/cmd/nusb/ether/ether.c b/sys/src/cmd/nusb/ether/ether.c index d28a19f53..ffe6c641a 100644 --- a/sys/src/cmd/nusb/ether/ether.c +++ b/sys/src/cmd/nusb/ether/ether.c @@ -315,6 +315,7 @@ fsread(Req *r) char buf[200]; char e[ERRMAX]; ulong path; + int mbps; path = r->fid->qid.path; @@ -335,13 +336,17 @@ fsread(Req *r) break; case Qstats: + if(eplinkspeed == nil) + mbps = 10; /* default */ + else + mbps = (*eplinkspeed)(epctl); snprint(buf, sizeof(buf), "in: %d\n" - "link: 1\n" /* for stats(8) */ + "link: %d\n" /* for stats(8) */ "out: %d\n" "mbps: %d\n" "addr: %E\n", - stats.in, stats.out, 10, macaddr); + stats.in, mbps != 0, stats.out, mbps, macaddr); readstr(r, buf); respond(r, nil); break; diff --git a/sys/src/cmd/nusb/ether/lan78xx.c b/sys/src/cmd/nusb/ether/lan78xx.c index 6dea7d7e8..3f7c1d190 100644 --- a/sys/src/cmd/nusb/ether/lan78xx.c +++ b/sys/src/cmd/nusb/ether/lan78xx.c @@ -97,7 +97,9 @@ enum { Fulldpx = 1<<8, Speed1000= 1<<6, Bmsr = 1, - Advertise = 4, + BmsrLs = 0x0004, /* Link Status */ + Anar = 4, + Anlpar = 5, Adcsma = 0x0001, Ad10h = 0x0020, Ad10f = 0x0040, @@ -110,6 +112,9 @@ enum { Ctrl1000 = 9, Ad1000h = 0x0400, Ad1000f = 0x0200, + Mssr = 10, + Mssr1000THD= 0x0400, /* Link Partner 1000BASE-T HD able */ + Mssr1000TFD= 0x0800, /* Link Partner 1000BASE-T FD able */ Ledmodes = 29, Led0shift = 0, Led1shift = 4, @@ -202,7 +207,7 @@ phyinit(Dev *d) break; sleep(10); } - miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym); + miiwr(d, Anar, Adcsma|Adall|Adpause|Adpauseasym); miiwr(d, Ctrl1000, Ad1000f); miiwr(d, Phyintmask, 0); miiwr(d, Ledmodes, (Linkact<<Led1shift) | (Link1000<<Led0shift)); @@ -298,6 +303,18 @@ lan78xxmulticast(Dev *d, uchar *, int) return wr(d, Rfectl, rxctl); } +static int +lan78xxlinkspeed(Dev *d) +{ + if((miird(d, Bmsr) & BmsrLs) == 0) + return 0; /* link down */ + if(miird(d, Mssr) & (Mssr1000THD|Mssr1000TFD)) + return 1000; + if(miird(d, Anlpar) & (Ad100h|Ad100f)) + return 100; + return 10; +} + int lan78xxinit(Dev *d) { @@ -361,6 +378,7 @@ lan78xxinit(Dev *d) epreceive = lan78xxreceive; eppromiscuous = lan78xxpromiscuous; epmulticast = lan78xxmulticast; + eplinkspeed = lan78xxlinkspeed; return 0; } diff --git a/sys/src/cmd/nusb/ether/smsc.c b/sys/src/cmd/nusb/ether/smsc.c index 87c59e917..573c307e6 100644 --- a/sys/src/cmd/nusb/ether/smsc.c +++ b/sys/src/cmd/nusb/ether/smsc.c @@ -85,7 +85,9 @@ enum { Anrestart= 1<<9, Fulldpx = 1<<8, Bmsr = 1, - Advertise = 4, + BmsrLs = 0x0004, /* Link Status */ + Anar = 4, + Anlpar = 5, Adcsma = 0x0001, Ad10h = 0x0020, Ad10f = 0x0040, @@ -94,6 +96,7 @@ enum { Adpause = 0x0400, Adpauseasym= 0x0800, Adall = Ad10h|Ad10f|Ad100h|Ad100f, + Phyintsrc = 29, Phyintmask = 30, Anegcomp= 1<<6, @@ -180,8 +183,8 @@ phyinit(Dev *d) break; sleep(10); } - miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym); -// miiwr(d, Advertise, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym); + miiwr(d, Anar, Adcsma|Adall|Adpause|Adpauseasym); +// miiwr(d, Anar, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym); miird(d, Phyintsrc); miiwr(d, Phyintmask, Anegcomp|Linkdown); miiwr(d, Bmcr, miird(d, Bmcr)|Anenable|Anrestart); @@ -275,6 +278,16 @@ smscmulticast(Dev *d, uchar *, int) return wr(d, Maccr, rxctl); } +static int +smsclinkspeed(Dev *d) +{ + if((miird(d, Bmsr) & BmsrLs) == 0) + return 0; + if(miird(d, Anlpar) & (Ad100h|Ad100f)) + return 100; + return 10; +} + int smscinit(Dev *d) { @@ -314,6 +327,7 @@ smscinit(Dev *d) epreceive = smscreceive; eppromiscuous = smscpromiscuous; epmulticast = smscmulticast; + eplinkspeed = smsclinkspeed; return 0; } |