ref: 9973c9276dcb2ff075a78737c403750b0201655f
parent: 616f62253e1690a5f1e365d2122b300fc7922257
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Nov 5 17:23:07 EST 2023
nusb/ether: implement link status detection for smsc and lan78xx
--- a/sys/src/cmd/nusb/ether/dat.h
+++ b/sys/src/cmd/nusb/ether/dat.h
@@ -63,3 +63,4 @@
void (*eptransmit)(Dev*, Block*);
int (*eppromiscuous)(Dev*, int);
int (*epmulticast)(Dev*, uchar*, int);
+int (*eplinkspeed)(Dev*);
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -315,6 +315,7 @@
char buf[200];
char e[ERRMAX];
ulong path;
+ int mbps;
path = r->fid->qid.path;
@@ -335,13 +336,17 @@
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;
--- a/sys/src/cmd/nusb/ether/lan78xx.c
+++ b/sys/src/cmd/nusb/ether/lan78xx.c
@@ -97,7 +97,9 @@
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 @@
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 @@
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 @@
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 @@
epreceive = lan78xxreceive;
eppromiscuous = lan78xxpromiscuous;
epmulticast = lan78xxmulticast;
+ eplinkspeed = lan78xxlinkspeed;
return 0;
}
--- a/sys/src/cmd/nusb/ether/smsc.c
+++ b/sys/src/cmd/nusb/ether/smsc.c
@@ -85,7 +85,9 @@
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 @@
Adpause = 0x0400,
Adpauseasym= 0x0800,
Adall = Ad10h|Ad10f|Ad100h|Ad100f,
+
Phyintsrc = 29,
Phyintmask = 30,
Anegcomp= 1<<6,
@@ -180,8 +183,8 @@
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 @@
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 @@
epreceive = smscreceive;
eppromiscuous = smscpromiscuous;
epmulticast = smscmulticast;
+ eplinkspeed = smsclinkspeed;
return 0;
}