shithub: riscv

Download patch

ref: 606af7b470e56ceaab0139e52f299545f551c444
parent: 6a8125283c2812c71ecdd7f5f5f00bbf4dbb32c2
author: mia soweli <inbox@tachibana-labs.org>
date: Sat Apr 19 16:51:47 EDT 2025

ethermii: add support for up to 10g clause 45 phys

--- a/sys/src/9/port/ethermii.c
+++ b/sys/src/9/port/ethermii.c
@@ -204,6 +204,26 @@
 }
 
 int
+miianec45(MiiPhy* phy, int m)
+{
+	int r;
+
+	phy->mgcr = m;
+	phy->mgcr &= (MMDanmgcr2500T|MMDanmgcr5000T|MMDanmgcr10000T);
+
+	r = miimmdr(phy, MMDan, MMDanmgcr);
+	if (r == -1)
+		return -1;
+
+	r &= ~phy->mgcr;
+	r |= phy->mgcr;
+	if (miimmdw(phy, MMDan, MMDanmgcr, r) == -1)
+		return -1;
+
+	return 0;
+}
+
+int
 miistatus(MiiPhy* phy)
 {
 	int anlpar, bmsr, p, r;
@@ -277,6 +297,32 @@
 	}
 
 	phy->link = 1;
+	return 0;
+}
+
+int
+miistatusc45(MiiPhy *phy)
+{
+	int r;
+
+	r = miimmdr(phy, MMDan, MMDanmgsr);
+	if (r == -1)
+		return -1;
+
+	if (r & MMDanmgsr2500T) {
+		phy->speed = 2500;
+		phy->fd = 1;
+	}
+
+	if (r & MMDanmgsr5000T) {
+		phy->speed = 5000;
+		phy->fd = 1;
+	}
+
+	if (r & MMDanmgsr10000T) {
+		phy->speed = 10000;
+		phy->fd = 1;
+	}
 
 	return 0;
 }
--- a/sys/src/9/port/ethermii.h
+++ b/sys/src/9/port/ethermii.h
@@ -1,7 +1,8 @@
 typedef struct Mii Mii;
 typedef struct MiiPhy MiiPhy;
 
-enum {					/* registers */
+enum {
+	/* registers */
 	Bmcr		= 0x00,		/* Basic Mode Control */
 	Bmsr		= 0x01,		/* Basic Mode Status */
 	Phyidr1		= 0x02,		/* PHY Identifier #1 */
@@ -21,7 +22,15 @@
 	NMiiPhy		= 32,
 };
 
-enum {					/* Bmcr */
+enum {
+	/* MMD Auto Negotiation */
+	MMDan = 7,
+	MMDanmgcr = 0x20, /* Multi Gigabit BASE-T Control */
+	MMDanmgsr = 0x21, /* Multi Gigabit BASE-T Status */
+};
+
+enum {
+	/* Basic Mode Control */
 	BmcrSs1		= 0x0040,	/* Speed Select[1] */
 	BmcrCte		= 0x0080,	/* Collision Test Enable */
 	BmcrDm		= 0x0100,	/* Duplex Mode */
@@ -34,7 +43,8 @@
 	BmcrR		= 0x8000,	/* Reset */
 };
 
-enum {					/* Bmsr */
+enum {
+	/* Basic Mode Status */
 	BmsrEc		= 0x0001,	/* Extended Capability */
 	BmsrJd		= 0x0002,	/* Jabber Detect */
 	BmsrLs		= 0x0004,	/* Link Status */
@@ -52,7 +62,8 @@
 	Bmsr100T4	= 0x8000,	/* 100BASE-T4 Capable */
 };
 
-enum {					/* Anar/Anlpar */
+enum {
+	/* Auto-Negotiation Advertisement / Partner Ability */
 	Ana10HD		= 0x0020,	/* Advertise 10BASE-T */
 	Ana10FD		= 0x0040,	/* Advertise 10BASE-T FD */
 	AnaTXHD		= 0x0080,	/* Advertise 100BASE-TX */
@@ -65,17 +76,20 @@
 	AnaNp		= 0x8000,	/* Next Page Indication */
 };
 
-enum {					/* Mscr */
+enum {
+	/* MASTER-SLAVE Control */
 	Mscr1000THD	= 0x0100,	/* Advertise 1000BASE-T HD */
 	Mscr1000TFD	= 0x0200,	/* Advertise 1000BASE-T FD */
 };
 
-enum {					/* Mssr */
+enum {
+	/* MASTER-SLAVE Status */
 	Mssr1000THD	= 0x0400,	/* Link Partner 1000BASE-T HD able */
 	Mssr1000TFD	= 0x0800,	/* Link Partner 1000BASE-T FD able */
 };
 
-enum {					/* Esr */
+enum {
+	/* Extended Status */
 	Esr1000THD	= 0x1000,	/* 1000BASE-T HD Capable */
 	Esr1000TFD	= 0x2000,	/* 1000BASE-T FD Capable */
 	Esr1000XHD	= 0x4000,	/* 1000BASE-X HD Capable */
@@ -82,6 +96,18 @@
 	Esr1000XFD	= 0x8000,	/* 1000BASE-X FD Capable */
 };
 
+enum {
+	/* Multi Gigabit Base-T Control */
+	MMDanmgcr2500T	= 1<<7,	/* Advertise 2.5G BASE-T */
+	MMDanmgcr5000T	= 1<<8,	/* Advertise 5.0G BASE-T */
+	MMDanmgcr10000T	= 1<<12,	/* Advertise 10.0G BASE-T */
+
+	/* Multi Gigabit Base-T Status */
+	MMDanmgsr2500T	= 1<<5, /* 2.5G BASE-T Capable */
+	MMDanmgsr5000T	= 1<<6, /* 5.0G BASE-T Capable */
+	MMDanmgsr10000T	= 1<<11, /* 10.0G BASE-T Capable */
+};
+
 typedef struct Mii {
 	QLock;
 
@@ -105,6 +131,7 @@
 	int	anar;
 	int	fc;
 	int	mscr;
+	int	mgcr;
 
 	int	link;
 	int	speed;
@@ -115,10 +142,12 @@
 
 extern uint mii(Mii*, uint);
 extern int miiane(MiiPhy*, int, int, int);
+extern int miianec45(MiiPhy*, int);
 extern int miimir(MiiPhy*, int);
 extern int miimiw(MiiPhy*, int, int);
 extern int miireset(MiiPhy*);
 extern int miistatus(MiiPhy*);
+extern int miistatusc45(MiiPhy*);
 extern int miimmdr(MiiPhy*, int, int);
 extern int miimmdw(MiiPhy*, int, int, int);
 
--