code: plan9front

Download patch

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;
 }