ref: a4688b03228dfdebcde34570b2a7b5c79db31c79
parent: 51550ba3d2d9a19c92ef2d3fd49cbff281064ba3
parent: a1a6f26110b774e894bfc8a152fffff81aa3dc08
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jul 11 03:49:52 EDT 2019
merge
--- a/sys/src/9/pc/ether8169.c
+++ b/sys/src/9/pc/ether8169.c
@@ -16,8 +16,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
enum { /* registers */
Idr0 = 0x00, /* MAC address */
--- a/sys/src/9/pc/etherdp83820.c
+++ b/sys/src/9/pc/etherdp83820.c
@@ -13,8 +13,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
enum { /* Registers */
Cr = 0x00, /* Command */
--- a/sys/src/9/pc/etherigbe.c
+++ b/sys/src/9/pc/etherigbe.c
@@ -25,8 +25,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
enum {
i82542 = (0x1000<<16)|0x8086,
--- a/sys/src/9/pc/ethermii.c
+++ /dev/null
@@ -1,235 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "../port/etherif.h"
-
-#include "ethermii.h"
-
-int
-mii(Mii* mii, int mask)
-{
- MiiPhy *miiphy;
- int bit, oui, phyno, r, rmask;
-
- /*
- * Probe through mii for PHYs in mask;
- * return the mask of those found in the current probe.
- * If the PHY has not already been probed, update
- * the Mii information.
- */
- rmask = 0;
- for(phyno = 0; phyno < NMiiPhy; phyno++){
- bit = 1<<phyno;
- if(!(mask & bit))
- continue;
- if(mii->mask & bit){
- rmask |= bit;
- continue;
- }
- if(mii->mir(mii, phyno, Bmsr) == -1)
- continue;
- r = mii->mir(mii, phyno, Phyidr1);
- oui = (r & 0x3FFF)<<6;
- r = mii->mir(mii, phyno, Phyidr2);
- oui |= r>>10;
- if(oui == 0xFFFFF || oui == 0)
- continue;
-
- if((miiphy = malloc(sizeof(MiiPhy))) == nil)
- continue;
-
- miiphy->mii = mii;
- miiphy->oui = oui;
- miiphy->phyno = phyno;
-
- miiphy->anar = ~0;
- miiphy->fc = ~0;
- miiphy->mscr = ~0;
-
- mii->phy[phyno] = miiphy;
- if(mii->curphy == nil)
- mii->curphy = miiphy;
- mii->mask |= bit;
- mii->nphy++;
-
- rmask |= bit;
- }
- return rmask;
-}
-
-int
-miimir(Mii* mii, int r)
-{
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- return mii->mir(mii, mii->curphy->phyno, r);
-}
-
-int
-miimiw(Mii* mii, int r, int data)
-{
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- return mii->miw(mii, mii->curphy->phyno, r, data);
-}
-
-int
-miireset(Mii* mii)
-{
- int bmcr;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr);
- bmcr |= BmcrR;
- mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr);
- microdelay(1);
-
- return 0;
-}
-
-int
-miiane(Mii* mii, int a, int p, int e)
-{
- int anar, bmsr, mscr, r, phyno;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- phyno = mii->curphy->phyno;
-
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & BmsrAna))
- return -1;
-
- if(a != ~0)
- anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
- else if(mii->curphy->anar != ~0)
- anar = mii->curphy->anar;
- else{
- anar = mii->mir(mii, phyno, Anar);
- anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
- if(bmsr & Bmsr10THD)
- anar |= Ana10HD;
- if(bmsr & Bmsr10TFD)
- anar |= Ana10FD;
- if(bmsr & Bmsr100TXHD)
- anar |= AnaTXHD;
- if(bmsr & Bmsr100TXFD)
- anar |= AnaTXFD;
- }
- mii->curphy->anar = anar;
-
- if(p != ~0)
- anar |= (AnaAP|AnaP) & p;
- else if(mii->curphy->fc != ~0)
- anar |= mii->curphy->fc;
- mii->curphy->fc = (AnaAP|AnaP) & anar;
-
- if(bmsr & BmsrEs){
- mscr = mii->mir(mii, phyno, Mscr);
- mscr &= ~(Mscr1000TFD|Mscr1000THD);
- if(e != ~0)
- mscr |= (Mscr1000TFD|Mscr1000THD) & e;
- else if(mii->curphy->mscr != ~0)
- mscr = mii->curphy->mscr;
- else{
- r = mii->mir(mii, phyno, Esr);
- if(r & Esr1000THD)
- mscr |= Mscr1000THD;
- if(r & Esr1000TFD)
- mscr |= Mscr1000TFD;
- }
- mii->curphy->mscr = mscr;
- mii->miw(mii, phyno, Mscr, mscr);
- }
- mii->miw(mii, phyno, Anar, anar);
-
- r = mii->mir(mii, phyno, Bmcr);
- if(!(r & BmcrR)){
- r |= BmcrAne|BmcrRan;
- mii->miw(mii, phyno, Bmcr, r);
- }
-
- return 0;
-}
-
-int
-miistatus(Mii* mii)
-{
- MiiPhy *phy;
- int anlpar, bmsr, p, r, phyno;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- phy = mii->curphy;
- phyno = phy->phyno;
-
- /*
- * Check Auto-Negotiation is complete and link is up.
- * (Read status twice as the Ls bit is sticky).
- */
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & (BmsrAnc|BmsrAna))) {
- // print("miistatus: auto-neg incomplete\n");
- return -1;
- }
-
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & BmsrLs)){
- // print("miistatus: link down\n");
- phy->link = 0;
- return -1;
- }
-
- phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
- if(phy->mscr){
- r = mii->mir(mii, phyno, Mssr);
- if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
- phy->speed = 1000;
- phy->fd = 1;
- }
- else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
- phy->speed = 1000;
- }
-
- anlpar = mii->mir(mii, phyno, Anlpar);
- if(phy->speed == 0){
- r = phy->anar & anlpar;
- if(r & AnaTXFD){
- phy->speed = 100;
- phy->fd = 1;
- }
- else if(r & AnaTXHD)
- phy->speed = 100;
- else if(r & Ana10FD){
- phy->speed = 10;
- phy->fd = 1;
- }
- else if(r & Ana10HD)
- phy->speed = 10;
- }
- if(phy->speed == 0) {
- // print("miistatus: phy speed 0\n");
- return -1;
- }
-
- if(phy->fd){
- p = phy->fc;
- r = anlpar & (AnaAP|AnaP);
- if(p == AnaAP && r == (AnaAP|AnaP))
- phy->tfc = 1;
- else if(p == (AnaAP|AnaP) && r == AnaAP)
- phy->rfc = 1;
- else if((p & AnaP) && (r & AnaP))
- phy->rfc = phy->tfc = 1;
- }
-
- phy->link = 1;
-
- return 0;
-}
--- a/sys/src/9/pc/ethermii.h
+++ /dev/null
@@ -1,116 +1,0 @@
-typedef struct Mii Mii;
-typedef struct MiiPhy MiiPhy;
-
-enum { /* registers */
- Bmcr = 0x00, /* Basic Mode Control */
- Bmsr = 0x01, /* Basic Mode Status */
- Phyidr1 = 0x02, /* PHY Identifier #1 */
- Phyidr2 = 0x03, /* PHY Identifier #2 */
- Anar = 0x04, /* Auto-Negotiation Advertisement */
- Anlpar = 0x05, /* AN Link Partner Ability */
- Aner = 0x06, /* AN Expansion */
- Annptr = 0x07, /* AN Next Page TX */
- Annprr = 0x08, /* AN Next Page RX */
- Mscr = 0x09, /* MASTER-SLAVE Control */
- Mssr = 0x0A, /* MASTER-SLAVE Status */
- Esr = 0x0F, /* Extended Status */
-
- NMiiPhyr = 32,
- NMiiPhy = 32,
-};
-
-enum { /* Bmcr */
- BmcrSs1 = 0x0040, /* Speed Select[1] */
- BmcrCte = 0x0080, /* Collision Test Enable */
- BmcrDm = 0x0100, /* Duplex Mode */
- BmcrRan = 0x0200, /* Restart Auto-Negotiation */
- BmcrI = 0x0400, /* Isolate */
- BmcrPd = 0x0800, /* Power Down */
- BmcrAne = 0x1000, /* Auto-Negotiation Enable */
- BmcrSs0 = 0x2000, /* Speed Select[0] */
- BmcrLe = 0x4000, /* Loopback Enable */
- BmcrR = 0x8000, /* Reset */
-};
-
-enum { /* Bmsr */
- BmsrEc = 0x0001, /* Extended Capability */
- BmsrJd = 0x0002, /* Jabber Detect */
- BmsrLs = 0x0004, /* Link Status */
- BmsrAna = 0x0008, /* Auto-Negotiation Ability */
- BmsrRf = 0x0010, /* Remote Fault */
- BmsrAnc = 0x0020, /* Auto-Negotiation Complete */
- BmsrPs = 0x0040, /* Preamble Suppression Capable */
- BmsrEs = 0x0100, /* Extended Status */
- Bmsr100T2HD = 0x0200, /* 100BASE-T2 HD Capable */
- Bmsr100T2FD = 0x0400, /* 100BASE-T2 FD Capable */
- Bmsr10THD = 0x0800, /* 10BASE-T HD Capable */
- Bmsr10TFD = 0x1000, /* 10BASE-T FD Capable */
- Bmsr100TXHD = 0x2000, /* 100BASE-TX HD Capable */
- Bmsr100TXFD = 0x4000, /* 100BASE-TX FD Capable */
- Bmsr100T4 = 0x8000, /* 100BASE-T4 Capable */
-};
-
-enum { /* Anar/Anlpar */
- Ana10HD = 0x0020, /* Advertise 10BASE-T */
- Ana10FD = 0x0040, /* Advertise 10BASE-T FD */
- AnaTXHD = 0x0080, /* Advertise 100BASE-TX */
- AnaTXFD = 0x0100, /* Advertise 100BASE-TX FD */
- AnaT4 = 0x0200, /* Advertise 100BASE-T4 */
- AnaP = 0x0400, /* Pause */
- AnaAP = 0x0800, /* Asymmetrical Pause */
- AnaRf = 0x2000, /* Remote Fault */
- AnaAck = 0x4000, /* Acknowledge */
- AnaNp = 0x8000, /* Next Page Indication */
-};
-
-enum { /* Mscr */
- Mscr1000THD = 0x0100, /* Advertise 1000BASE-T HD */
- Mscr1000TFD = 0x0200, /* Advertise 1000BASE-T FD */
-};
-
-enum { /* Mssr */
- Mssr1000THD = 0x0400, /* Link Partner 1000BASE-T HD able */
- Mssr1000TFD = 0x0800, /* Link Partner 1000BASE-T FD able */
-};
-
-enum { /* Esr */
- Esr1000THD = 0x1000, /* 1000BASE-T HD Capable */
- Esr1000TFD = 0x2000, /* 1000BASE-T FD Capable */
- Esr1000XHD = 0x4000, /* 1000BASE-X HD Capable */
- Esr1000XFD = 0x8000, /* 1000BASE-X FD Capable */
-};
-
-typedef struct Mii {
- Lock;
- int nphy;
- int mask;
- MiiPhy* phy[NMiiPhy];
- MiiPhy* curphy;
-
- void* ctlr;
- int (*mir)(Mii*, int, int);
- int (*miw)(Mii*, int, int, int);
-} Mii;
-
-typedef struct MiiPhy {
- Mii* mii;
- int oui;
- int phyno;
-
- int anar;
- int fc;
- int mscr;
-
- int link;
- int speed;
- int fd;
- int rfc;
- int tfc;
-};
-
-extern int mii(Mii*, int);
-extern int miiane(Mii*, int, int, int);
-extern int miimir(Mii*, int);
-extern int miimiw(Mii*, int, int);
-extern int miireset(Mii*);
-extern int miistatus(Mii*);
--- a/sys/src/9/pc/ethervgbe.c
+++ b/sys/src/9/pc/ethervgbe.c
@@ -30,8 +30,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
#define DEBUG
--- a/sys/src/9/pc/ethervt6102.c
+++ b/sys/src/9/pc/ethervt6102.c
@@ -18,8 +18,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
enum {
Par0 = 0x00, /* Ethernet Address */
--- a/sys/src/9/pc/ethervt6105m.c
+++ b/sys/src/9/pc/ethervt6105m.c
@@ -21,8 +21,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
enum {
Par0 = 0x00, /* Ethernet Address */
--- a/sys/src/9/pc/mkfile
+++ b/sys/src/9/pc/mkfile
@@ -123,13 +123,12 @@
usbehci.$O usbehcipc.$O: usbehci.h
trap.$O: /sys/include/tos.h
uartaxp.$O: uartaxp.i
-ethermii.$O: ethermii.h
-ether8169.$O: ethermii.h
-etherdp83820.$O: ethermii.h
-etherigbe.$O: ethermii.h
-ethervgbe.$O: ethermii.h
-ethervt6102.$O: ethermii.h
-ethervt6105m.$O: ethermii.h
+ether8169.$O: ../port/ethermii.h
+etherdp83820.$O: ../port/ethermii.h
+etherigbe.$O: ../port/ethermii.h
+ethervgbe.$O: ../port/ethermii.h
+ethervt6102.$O: ../port/ethermii.h
+ethervt6105m.$O: ../port/ethermii.h
etherm10g.$O: etherm10g2k.i etherm10g4k.i
etheriwl.$O: ../port/wifi.h
etherwpi.$O: ../port/wifi.h
--- a/sys/src/9/pc64/mkfile
+++ b/sys/src/9/pc64/mkfile
@@ -85,7 +85,7 @@
# copies generated by the rule below
-PCHEADERS=usbehci.h screen.h ethermii.h mp.h io.h ahci.h \
+PCHEADERS=usbehci.h screen.h mp.h io.h ahci.h \
yukdump.h
REPCH=`{echo $PCHEADERS | sed 's/\.h//g; s/ /|/g'}
@@ -124,13 +124,12 @@
trap.$O: /sys/include/tos.h
-ethermii.$O: ethermii.h
-ether8169.$O: ethermii.h
-etherdp83820.$O: ethermii.h
-etherigbe.$O: ethermii.h
-ethervgbe.$O: ethermii.h
-ethervt6102.$O: ethermii.h
-ethervt6105m.$O: ethermii.h
+ether8169.$O: ../port/ethermii.h
+etherdp83820.$O: ../port/ethermii.h
+etherigbe.$O: ../port/ethermii.h
+ethervgbe.$O: ../port/ethermii.h
+ethervt6102.$O: ../port/ethermii.h
+ethervt6105m.$O: ../port/ethermii.h
etheriwl.$O: ../port/wifi.h
etherwpi.$O: ../port/wifi.h
--- a/sys/src/9/port/devuart.c
+++ b/sys/src/9/port/devuart.c
@@ -644,7 +644,7 @@
{
Uart *p = v;
- if(p->blocked)
+ if(!p->enabled || p->blocked)
return;
ilock(&p->tlock);
--- /dev/null
+++ b/sys/src/9/port/ethermii.c
@@ -1,0 +1,235 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+#include "../port/netif.h"
+#include "../port/etherif.h"
+
+#include "ethermii.h"
+
+int
+mii(Mii* mii, int mask)
+{
+ MiiPhy *miiphy;
+ int bit, oui, phyno, r, rmask;
+
+ /*
+ * Probe through mii for PHYs in mask;
+ * return the mask of those found in the current probe.
+ * If the PHY has not already been probed, update
+ * the Mii information.
+ */
+ rmask = 0;
+ for(phyno = 0; phyno < NMiiPhy; phyno++){
+ bit = 1<<phyno;
+ if(!(mask & bit))
+ continue;
+ if(mii->mask & bit){
+ rmask |= bit;
+ continue;
+ }
+ if(mii->mir(mii, phyno, Bmsr) == -1)
+ continue;
+ r = mii->mir(mii, phyno, Phyidr1);
+ oui = (r & 0x3FFF)<<6;
+ r = mii->mir(mii, phyno, Phyidr2);
+ oui |= r>>10;
+ if(oui == 0xFFFFF || oui == 0)
+ continue;
+
+ if((miiphy = malloc(sizeof(MiiPhy))) == nil)
+ continue;
+
+ miiphy->mii = mii;
+ miiphy->oui = oui;
+ miiphy->phyno = phyno;
+
+ miiphy->anar = ~0;
+ miiphy->fc = ~0;
+ miiphy->mscr = ~0;
+
+ mii->phy[phyno] = miiphy;
+ if(mii->curphy == nil)
+ mii->curphy = miiphy;
+ mii->mask |= bit;
+ mii->nphy++;
+
+ rmask |= bit;
+ }
+ return rmask;
+}
+
+int
+miimir(Mii* mii, int r)
+{
+ if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
+ return -1;
+ return mii->mir(mii, mii->curphy->phyno, r);
+}
+
+int
+miimiw(Mii* mii, int r, int data)
+{
+ if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
+ return -1;
+ return mii->miw(mii, mii->curphy->phyno, r, data);
+}
+
+int
+miireset(Mii* mii)
+{
+ int bmcr;
+
+ if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
+ return -1;
+ bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr);
+ bmcr |= BmcrR;
+ mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr);
+ microdelay(1);
+
+ return 0;
+}
+
+int
+miiane(Mii* mii, int a, int p, int e)
+{
+ int anar, bmsr, mscr, r, phyno;
+
+ if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
+ return -1;
+ phyno = mii->curphy->phyno;
+
+ bmsr = mii->mir(mii, phyno, Bmsr);
+ if(!(bmsr & BmsrAna))
+ return -1;
+
+ if(a != ~0)
+ anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
+ else if(mii->curphy->anar != ~0)
+ anar = mii->curphy->anar;
+ else{
+ anar = mii->mir(mii, phyno, Anar);
+ anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
+ if(bmsr & Bmsr10THD)
+ anar |= Ana10HD;
+ if(bmsr & Bmsr10TFD)
+ anar |= Ana10FD;
+ if(bmsr & Bmsr100TXHD)
+ anar |= AnaTXHD;
+ if(bmsr & Bmsr100TXFD)
+ anar |= AnaTXFD;
+ }
+ mii->curphy->anar = anar;
+
+ if(p != ~0)
+ anar |= (AnaAP|AnaP) & p;
+ else if(mii->curphy->fc != ~0)
+ anar |= mii->curphy->fc;
+ mii->curphy->fc = (AnaAP|AnaP) & anar;
+
+ if(bmsr & BmsrEs){
+ mscr = mii->mir(mii, phyno, Mscr);
+ mscr &= ~(Mscr1000TFD|Mscr1000THD);
+ if(e != ~0)
+ mscr |= (Mscr1000TFD|Mscr1000THD) & e;
+ else if(mii->curphy->mscr != ~0)
+ mscr = mii->curphy->mscr;
+ else{
+ r = mii->mir(mii, phyno, Esr);
+ if(r & Esr1000THD)
+ mscr |= Mscr1000THD;
+ if(r & Esr1000TFD)
+ mscr |= Mscr1000TFD;
+ }
+ mii->curphy->mscr = mscr;
+ mii->miw(mii, phyno, Mscr, mscr);
+ }
+ mii->miw(mii, phyno, Anar, anar);
+
+ r = mii->mir(mii, phyno, Bmcr);
+ if(!(r & BmcrR)){
+ r |= BmcrAne|BmcrRan;
+ mii->miw(mii, phyno, Bmcr, r);
+ }
+
+ return 0;
+}
+
+int
+miistatus(Mii* mii)
+{
+ MiiPhy *phy;
+ int anlpar, bmsr, p, r, phyno;
+
+ if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
+ return -1;
+ phy = mii->curphy;
+ phyno = phy->phyno;
+
+ /*
+ * Check Auto-Negotiation is complete and link is up.
+ * (Read status twice as the Ls bit is sticky).
+ */
+ bmsr = mii->mir(mii, phyno, Bmsr);
+ if(!(bmsr & (BmsrAnc|BmsrAna))) {
+ // print("miistatus: auto-neg incomplete\n");
+ return -1;
+ }
+
+ bmsr = mii->mir(mii, phyno, Bmsr);
+ if(!(bmsr & BmsrLs)){
+ // print("miistatus: link down\n");
+ phy->link = 0;
+ return -1;
+ }
+
+ phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
+ if(phy->mscr){
+ r = mii->mir(mii, phyno, Mssr);
+ if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
+ phy->speed = 1000;
+ phy->fd = 1;
+ }
+ else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
+ phy->speed = 1000;
+ }
+
+ anlpar = mii->mir(mii, phyno, Anlpar);
+ if(phy->speed == 0){
+ r = phy->anar & anlpar;
+ if(r & AnaTXFD){
+ phy->speed = 100;
+ phy->fd = 1;
+ }
+ else if(r & AnaTXHD)
+ phy->speed = 100;
+ else if(r & Ana10FD){
+ phy->speed = 10;
+ phy->fd = 1;
+ }
+ else if(r & Ana10HD)
+ phy->speed = 10;
+ }
+ if(phy->speed == 0) {
+ // print("miistatus: phy speed 0\n");
+ return -1;
+ }
+
+ if(phy->fd){
+ p = phy->fc;
+ r = anlpar & (AnaAP|AnaP);
+ if(p == AnaAP && r == (AnaAP|AnaP))
+ phy->tfc = 1;
+ else if(p == (AnaAP|AnaP) && r == AnaAP)
+ phy->rfc = 1;
+ else if((p & AnaP) && (r & AnaP))
+ phy->rfc = phy->tfc = 1;
+ }
+
+ phy->link = 1;
+
+ return 0;
+}
--- /dev/null
+++ b/sys/src/9/port/ethermii.h
@@ -1,0 +1,116 @@
+typedef struct Mii Mii;
+typedef struct MiiPhy MiiPhy;
+
+enum { /* registers */
+ Bmcr = 0x00, /* Basic Mode Control */
+ Bmsr = 0x01, /* Basic Mode Status */
+ Phyidr1 = 0x02, /* PHY Identifier #1 */
+ Phyidr2 = 0x03, /* PHY Identifier #2 */
+ Anar = 0x04, /* Auto-Negotiation Advertisement */
+ Anlpar = 0x05, /* AN Link Partner Ability */
+ Aner = 0x06, /* AN Expansion */
+ Annptr = 0x07, /* AN Next Page TX */
+ Annprr = 0x08, /* AN Next Page RX */
+ Mscr = 0x09, /* MASTER-SLAVE Control */
+ Mssr = 0x0A, /* MASTER-SLAVE Status */
+ Esr = 0x0F, /* Extended Status */
+
+ NMiiPhyr = 32,
+ NMiiPhy = 32,
+};
+
+enum { /* Bmcr */
+ BmcrSs1 = 0x0040, /* Speed Select[1] */
+ BmcrCte = 0x0080, /* Collision Test Enable */
+ BmcrDm = 0x0100, /* Duplex Mode */
+ BmcrRan = 0x0200, /* Restart Auto-Negotiation */
+ BmcrI = 0x0400, /* Isolate */
+ BmcrPd = 0x0800, /* Power Down */
+ BmcrAne = 0x1000, /* Auto-Negotiation Enable */
+ BmcrSs0 = 0x2000, /* Speed Select[0] */
+ BmcrLe = 0x4000, /* Loopback Enable */
+ BmcrR = 0x8000, /* Reset */
+};
+
+enum { /* Bmsr */
+ BmsrEc = 0x0001, /* Extended Capability */
+ BmsrJd = 0x0002, /* Jabber Detect */
+ BmsrLs = 0x0004, /* Link Status */
+ BmsrAna = 0x0008, /* Auto-Negotiation Ability */
+ BmsrRf = 0x0010, /* Remote Fault */
+ BmsrAnc = 0x0020, /* Auto-Negotiation Complete */
+ BmsrPs = 0x0040, /* Preamble Suppression Capable */
+ BmsrEs = 0x0100, /* Extended Status */
+ Bmsr100T2HD = 0x0200, /* 100BASE-T2 HD Capable */
+ Bmsr100T2FD = 0x0400, /* 100BASE-T2 FD Capable */
+ Bmsr10THD = 0x0800, /* 10BASE-T HD Capable */
+ Bmsr10TFD = 0x1000, /* 10BASE-T FD Capable */
+ Bmsr100TXHD = 0x2000, /* 100BASE-TX HD Capable */
+ Bmsr100TXFD = 0x4000, /* 100BASE-TX FD Capable */
+ Bmsr100T4 = 0x8000, /* 100BASE-T4 Capable */
+};
+
+enum { /* Anar/Anlpar */
+ Ana10HD = 0x0020, /* Advertise 10BASE-T */
+ Ana10FD = 0x0040, /* Advertise 10BASE-T FD */
+ AnaTXHD = 0x0080, /* Advertise 100BASE-TX */
+ AnaTXFD = 0x0100, /* Advertise 100BASE-TX FD */
+ AnaT4 = 0x0200, /* Advertise 100BASE-T4 */
+ AnaP = 0x0400, /* Pause */
+ AnaAP = 0x0800, /* Asymmetrical Pause */
+ AnaRf = 0x2000, /* Remote Fault */
+ AnaAck = 0x4000, /* Acknowledge */
+ AnaNp = 0x8000, /* Next Page Indication */
+};
+
+enum { /* Mscr */
+ Mscr1000THD = 0x0100, /* Advertise 1000BASE-T HD */
+ Mscr1000TFD = 0x0200, /* Advertise 1000BASE-T FD */
+};
+
+enum { /* Mssr */
+ Mssr1000THD = 0x0400, /* Link Partner 1000BASE-T HD able */
+ Mssr1000TFD = 0x0800, /* Link Partner 1000BASE-T FD able */
+};
+
+enum { /* Esr */
+ Esr1000THD = 0x1000, /* 1000BASE-T HD Capable */
+ Esr1000TFD = 0x2000, /* 1000BASE-T FD Capable */
+ Esr1000XHD = 0x4000, /* 1000BASE-X HD Capable */
+ Esr1000XFD = 0x8000, /* 1000BASE-X FD Capable */
+};
+
+typedef struct Mii {
+ Lock;
+ int nphy;
+ int mask;
+ MiiPhy* phy[NMiiPhy];
+ MiiPhy* curphy;
+
+ void* ctlr;
+ int (*mir)(Mii*, int, int);
+ int (*miw)(Mii*, int, int, int);
+} Mii;
+
+typedef struct MiiPhy {
+ Mii* mii;
+ int oui;
+ int phyno;
+
+ int anar;
+ int fc;
+ int mscr;
+
+ int link;
+ int speed;
+ int fd;
+ int rfc;
+ int tfc;
+};
+
+extern int mii(Mii*, int);
+extern int miiane(Mii*, int, int, int);
+extern int miimir(Mii*, int);
+extern int miimiw(Mii*, int, int);
+extern int miireset(Mii*);
+extern int miistatus(Mii*);
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -105,3 +105,4 @@
devether.$O ethersink.$O: ../port/etherif.h ../port/netif.h
wifi.$O: ../port/etherif.h ../port/netif.h ../port/wifi.h /sys/include/libsec.h
wifi.$O: ../ip/ip.h ../ip/ipv6.h
+ethermii.$O: ../port/ethermii.h
--- a/sys/src/9/teg2/ether8169.c
+++ b/sys/src/9/teg2/ether8169.c
@@ -16,8 +16,7 @@
#include "../port/error.h"
#include "../port/netif.h"
#include "../port/etherif.h"
-
-#include "ethermii.h"
+#include "../port/ethermii.h"
typedef struct Ctlr Ctlr;
typedef struct D D; /* Transmit/Receive Descriptor */
--- a/sys/src/9/teg2/ethermii.c
+++ /dev/null
@@ -1,235 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-#include "../port/netif.h"
-#include "../port/etherif.h"
-
-#include "ethermii.h"
-
-int
-mii(Mii* mii, int mask)
-{
- MiiPhy *miiphy;
- int bit, oui, phyno, r, rmask;
-
- /*
- * Probe through mii for PHYs in mask;
- * return the mask of those found in the current probe.
- * If the PHY has not already been probed, update
- * the Mii information.
- */
- rmask = 0;
- for(phyno = 0; phyno < NMiiPhy; phyno++){
- bit = 1<<phyno;
- if(!(mask & bit))
- continue;
- if(mii->mask & bit){
- rmask |= bit;
- continue;
- }
- if(mii->mir(mii, phyno, Bmsr) == -1)
- continue;
- r = mii->mir(mii, phyno, Phyidr1);
- oui = (r & 0x3FFF)<<6;
- r = mii->mir(mii, phyno, Phyidr2);
- oui |= r>>10;
- if(oui == 0xFFFFF || oui == 0)
- continue;
-
- if((miiphy = malloc(sizeof(MiiPhy))) == nil)
- continue;
-
- miiphy->mii = mii;
- miiphy->oui = oui;
- miiphy->phyno = phyno;
-
- miiphy->anar = ~0;
- miiphy->fc = ~0;
- miiphy->mscr = ~0;
-
- mii->phy[phyno] = miiphy;
- if(mii->curphy == nil)
- mii->curphy = miiphy;
- mii->mask |= bit;
- mii->nphy++;
-
- rmask |= bit;
- }
- return rmask;
-}
-
-int
-miimir(Mii* mii, int r)
-{
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- return mii->mir(mii, mii->curphy->phyno, r);
-}
-
-int
-miimiw(Mii* mii, int r, int data)
-{
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- return mii->miw(mii, mii->curphy->phyno, r, data);
-}
-
-int
-miireset(Mii* mii)
-{
- int bmcr;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr);
- bmcr |= BmcrR;
- mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr);
- microdelay(1);
-
- return 0;
-}
-
-int
-miiane(Mii* mii, int a, int p, int e)
-{
- int anar, bmsr, mscr, r, phyno;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- phyno = mii->curphy->phyno;
-
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & BmsrAna))
- return -1;
-
- if(a != ~0)
- anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
- else if(mii->curphy->anar != ~0)
- anar = mii->curphy->anar;
- else{
- anar = mii->mir(mii, phyno, Anar);
- anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
- if(bmsr & Bmsr10THD)
- anar |= Ana10HD;
- if(bmsr & Bmsr10TFD)
- anar |= Ana10FD;
- if(bmsr & Bmsr100TXHD)
- anar |= AnaTXHD;
- if(bmsr & Bmsr100TXFD)
- anar |= AnaTXFD;
- }
- mii->curphy->anar = anar;
-
- if(p != ~0)
- anar |= (AnaAP|AnaP) & p;
- else if(mii->curphy->fc != ~0)
- anar |= mii->curphy->fc;
- mii->curphy->fc = (AnaAP|AnaP) & anar;
-
- if(bmsr & BmsrEs){
- mscr = mii->mir(mii, phyno, Mscr);
- mscr &= ~(Mscr1000TFD|Mscr1000THD);
- if(e != ~0)
- mscr |= (Mscr1000TFD|Mscr1000THD) & e;
- else if(mii->curphy->mscr != ~0)
- mscr = mii->curphy->mscr;
- else{
- r = mii->mir(mii, phyno, Esr);
- if(r & Esr1000THD)
- mscr |= Mscr1000THD;
- if(r & Esr1000TFD)
- mscr |= Mscr1000TFD;
- }
- mii->curphy->mscr = mscr;
- mii->miw(mii, phyno, Mscr, mscr);
- }
- mii->miw(mii, phyno, Anar, anar);
-
- r = mii->mir(mii, phyno, Bmcr);
- if(!(r & BmcrR)){
- r |= BmcrAne|BmcrRan;
- mii->miw(mii, phyno, Bmcr, r);
- }
-
- return 0;
-}
-
-int
-miistatus(Mii* mii)
-{
- MiiPhy *phy;
- int anlpar, bmsr, p, r, phyno;
-
- if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
- return -1;
- phy = mii->curphy;
- phyno = phy->phyno;
-
- /*
- * Check Auto-Negotiation is complete and link is up.
- * (Read status twice as the Ls bit is sticky).
- */
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & (BmsrAnc|BmsrAna))) {
- // print("miistatus: auto-neg incomplete\n");
- return -1;
- }
-
- bmsr = mii->mir(mii, phyno, Bmsr);
- if(!(bmsr & BmsrLs)){
- // print("miistatus: link down\n");
- phy->link = 0;
- return -1;
- }
-
- phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
- if(phy->mscr){
- r = mii->mir(mii, phyno, Mssr);
- if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
- phy->speed = 1000;
- phy->fd = 1;
- }
- else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
- phy->speed = 1000;
- }
-
- anlpar = mii->mir(mii, phyno, Anlpar);
- if(phy->speed == 0){
- r = phy->anar & anlpar;
- if(r & AnaTXFD){
- phy->speed = 100;
- phy->fd = 1;
- }
- else if(r & AnaTXHD)
- phy->speed = 100;
- else if(r & Ana10FD){
- phy->speed = 10;
- phy->fd = 1;
- }
- else if(r & Ana10HD)
- phy->speed = 10;
- }
- if(phy->speed == 0) {
- // print("miistatus: phy speed 0\n");
- return -1;
- }
-
- if(phy->fd){
- p = phy->fc;
- r = anlpar & (AnaAP|AnaP);
- if(p == AnaAP && r == (AnaAP|AnaP))
- phy->tfc = 1;
- else if(p == (AnaAP|AnaP) && r == AnaAP)
- phy->rfc = 1;
- else if((p & AnaP) && (r & AnaP))
- phy->rfc = phy->tfc = 1;
- }
-
- phy->link = 1;
-
- return 0;
-}
--- a/sys/src/9/teg2/ethermii.h
+++ /dev/null
@@ -1,116 +1,0 @@
-typedef struct Mii Mii;
-typedef struct MiiPhy MiiPhy;
-
-enum { /* registers */
- Bmcr = 0x00, /* Basic Mode Control */
- Bmsr = 0x01, /* Basic Mode Status */
- Phyidr1 = 0x02, /* PHY Identifier #1 */
- Phyidr2 = 0x03, /* PHY Identifier #2 */
- Anar = 0x04, /* Auto-Negotiation Advertisement */
- Anlpar = 0x05, /* AN Link Partner Ability */
- Aner = 0x06, /* AN Expansion */
- Annptr = 0x07, /* AN Next Page TX */
- Annprr = 0x08, /* AN Next Page RX */
- Mscr = 0x09, /* MASTER-SLAVE Control */
- Mssr = 0x0A, /* MASTER-SLAVE Status */
- Esr = 0x0F, /* Extended Status */
-
- NMiiPhyr = 32,
- NMiiPhy = 32,
-};
-
-enum { /* Bmcr */
- BmcrSs1 = 0x0040, /* Speed Select[1] */
- BmcrCte = 0x0080, /* Collision Test Enable */
- BmcrDm = 0x0100, /* Duplex Mode */
- BmcrRan = 0x0200, /* Restart Auto-Negotiation */
- BmcrI = 0x0400, /* Isolate */
- BmcrPd = 0x0800, /* Power Down */
- BmcrAne = 0x1000, /* Auto-Negotiation Enable */
- BmcrSs0 = 0x2000, /* Speed Select[0] */
- BmcrLe = 0x4000, /* Loopback Enable */
- BmcrR = 0x8000, /* Reset */
-};
-
-enum { /* Bmsr */
- BmsrEc = 0x0001, /* Extended Capability */
- BmsrJd = 0x0002, /* Jabber Detect */
- BmsrLs = 0x0004, /* Link Status */
- BmsrAna = 0x0008, /* Auto-Negotiation Ability */
- BmsrRf = 0x0010, /* Remote Fault */
- BmsrAnc = 0x0020, /* Auto-Negotiation Complete */
- BmsrPs = 0x0040, /* Preamble Suppression Capable */
- BmsrEs = 0x0100, /* Extended Status */
- Bmsr100T2HD = 0x0200, /* 100BASE-T2 HD Capable */
- Bmsr100T2FD = 0x0400, /* 100BASE-T2 FD Capable */
- Bmsr10THD = 0x0800, /* 10BASE-T HD Capable */
- Bmsr10TFD = 0x1000, /* 10BASE-T FD Capable */
- Bmsr100TXHD = 0x2000, /* 100BASE-TX HD Capable */
- Bmsr100TXFD = 0x4000, /* 100BASE-TX FD Capable */
- Bmsr100T4 = 0x8000, /* 100BASE-T4 Capable */
-};
-
-enum { /* Anar/Anlpar */
- Ana10HD = 0x0020, /* Advertise 10BASE-T */
- Ana10FD = 0x0040, /* Advertise 10BASE-T FD */
- AnaTXHD = 0x0080, /* Advertise 100BASE-TX */
- AnaTXFD = 0x0100, /* Advertise 100BASE-TX FD */
- AnaT4 = 0x0200, /* Advertise 100BASE-T4 */
- AnaP = 0x0400, /* Pause */
- AnaAP = 0x0800, /* Asymmetrical Pause */
- AnaRf = 0x2000, /* Remote Fault */
- AnaAck = 0x4000, /* Acknowledge */
- AnaNp = 0x8000, /* Next Page Indication */
-};
-
-enum { /* Mscr */
- Mscr1000THD = 0x0100, /* Advertise 1000BASE-T HD */
- Mscr1000TFD = 0x0200, /* Advertise 1000BASE-T FD */
-};
-
-enum { /* Mssr */
- Mssr1000THD = 0x0400, /* Link Partner 1000BASE-T HD able */
- Mssr1000TFD = 0x0800, /* Link Partner 1000BASE-T FD able */
-};
-
-enum { /* Esr */
- Esr1000THD = 0x1000, /* 1000BASE-T HD Capable */
- Esr1000TFD = 0x2000, /* 1000BASE-T FD Capable */
- Esr1000XHD = 0x4000, /* 1000BASE-X HD Capable */
- Esr1000XFD = 0x8000, /* 1000BASE-X FD Capable */
-};
-
-typedef struct Mii {
- Lock;
- int nphy;
- int mask;
- MiiPhy* phy[NMiiPhy];
- MiiPhy* curphy;
-
- void* ctlr;
- int (*mir)(Mii*, int, int);
- int (*miw)(Mii*, int, int, int);
-} Mii;
-
-typedef struct MiiPhy {
- Mii* mii;
- int oui;
- int phyno;
-
- int anar;
- int fc;
- int mscr;
-
- int link;
- int speed;
- int fd;
- int rfc;
- int tfc;
-};
-
-extern int mii(Mii*, int);
-extern int miiane(Mii*, int, int, int);
-extern int miimir(Mii*, int);
-extern int miimiw(Mii*, int, int);
-extern int miireset(Mii*);
-extern int miistatus(Mii*);