summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2023-11-05 22:23:07 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2023-11-05 22:23:07 +0000
commit9973c9276dcb2ff075a78737c403750b0201655f (patch)
tree1cfd34cba7c14fd2e4f0aa77b2041271134853af
parent616f62253e1690a5f1e365d2122b300fc7922257 (diff)
nusb/ether: implement link status detection for smsc and lan78xx
-rw-r--r--sys/src/cmd/nusb/ether/dat.h1
-rw-r--r--sys/src/cmd/nusb/ether/ether.c9
-rw-r--r--sys/src/cmd/nusb/ether/lan78xx.c22
-rw-r--r--sys/src/cmd/nusb/ether/smsc.c20
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;
}