From a1a6f26110b774e894bfc8a152fffff81aa3dc08 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 11 Jul 2019 07:47:39 +0200 Subject: kernel: move common ethermii to port/ --- sys/src/9/pc/ether8169.c | 3 +- sys/src/9/pc/etherdp83820.c | 3 +- sys/src/9/pc/etherigbe.c | 3 +- sys/src/9/pc/ethermii.c | 235 -------------------------------------------- sys/src/9/pc/ethermii.h | 116 ---------------------- sys/src/9/pc/ethervgbe.c | 3 +- sys/src/9/pc/ethervt6102.c | 3 +- sys/src/9/pc/ethervt6105m.c | 3 +- sys/src/9/pc/mkfile | 13 ++- sys/src/9/pc64/mkfile | 15 ++- sys/src/9/port/ethermii.c | 235 ++++++++++++++++++++++++++++++++++++++++++++ sys/src/9/port/ethermii.h | 116 ++++++++++++++++++++++ sys/src/9/port/portmkfile | 1 + sys/src/9/teg2/ether8169.c | 3 +- sys/src/9/teg2/ethermii.c | 235 -------------------------------------------- sys/src/9/teg2/ethermii.h | 116 ---------------------- 16 files changed, 372 insertions(+), 731 deletions(-) delete mode 100644 sys/src/9/pc/ethermii.c delete mode 100644 sys/src/9/pc/ethermii.h create mode 100644 sys/src/9/port/ethermii.c create mode 100644 sys/src/9/port/ethermii.h delete mode 100644 sys/src/9/teg2/ethermii.c delete mode 100644 sys/src/9/teg2/ethermii.h (limited to 'sys/src') diff --git a/sys/src/9/pc/ether8169.c b/sys/src/9/pc/ether8169.c index 1198b8396..bf6cf8ef4 100644 --- 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 */ diff --git a/sys/src/9/pc/etherdp83820.c b/sys/src/9/pc/etherdp83820.c index f2126cfda..35c6789cf 100644 --- 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 */ diff --git a/sys/src/9/pc/etherigbe.c b/sys/src/9/pc/etherigbe.c index 8b74896e7..bdba58b8c 100644 --- 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, diff --git a/sys/src/9/pc/ethermii.c b/sys/src/9/pc/ethermii.c deleted file mode 100644 index 16d766ef4..000000000 --- a/sys/src/9/pc/ethermii.c +++ /dev/null @@ -1,235 +0,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<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; -} diff --git a/sys/src/9/pc/ethermii.h b/sys/src/9/pc/ethermii.h deleted file mode 100644 index 02a45ee5f..000000000 --- a/sys/src/9/pc/ethermii.h +++ /dev/null @@ -1,116 +0,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*); diff --git a/sys/src/9/pc/ethervgbe.c b/sys/src/9/pc/ethervgbe.c index e2fe22d1b..3249549d0 100644 --- 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 diff --git a/sys/src/9/pc/ethervt6102.c b/sys/src/9/pc/ethervt6102.c index 0728e9d1d..b76d3be8b 100644 --- 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 */ diff --git a/sys/src/9/pc/ethervt6105m.c b/sys/src/9/pc/ethervt6105m.c index 3f51a6d64..bd1e4543c 100644 --- 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 */ diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile index 17964dd92..4a33c6739 100644 --- a/sys/src/9/pc/mkfile +++ b/sys/src/9/pc/mkfile @@ -123,13 +123,12 @@ devusb.$O usbuhci.$O usbohci.$O usbehci.$O usbehcipc.$O usbxhci.$O: ../port/usb. 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 diff --git a/sys/src/9/pc64/mkfile b/sys/src/9/pc64/mkfile index 541b1f7af..cdd5f20f8 100644 --- a/sys/src/9/pc64/mkfile +++ b/sys/src/9/pc64/mkfile @@ -85,7 +85,7 @@ install:V: $p$CONF # 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 @@ usbehci.$O usbehcipc.$O: usbehci.h 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 diff --git a/sys/src/9/port/ethermii.c b/sys/src/9/port/ethermii.c new file mode 100644 index 000000000..16d766ef4 --- /dev/null +++ b/sys/src/9/port/ethermii.c @@ -0,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<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; +} diff --git a/sys/src/9/port/ethermii.h b/sys/src/9/port/ethermii.h new file mode 100644 index 000000000..02a45ee5f --- /dev/null +++ b/sys/src/9/port/ethermii.h @@ -0,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*); diff --git a/sys/src/9/port/portmkfile b/sys/src/9/port/portmkfile index 5af9e0b7f..d7bdaf8b7 100644 --- a/sys/src/9/port/portmkfile +++ b/sys/src/9/port/portmkfile @@ -105,3 +105,4 @@ devusb.$O: ../port/usb.h 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 diff --git a/sys/src/9/teg2/ether8169.c b/sys/src/9/teg2/ether8169.c index bd04f15f3..d51816fcb 100644 --- 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 */ diff --git a/sys/src/9/teg2/ethermii.c b/sys/src/9/teg2/ethermii.c deleted file mode 100644 index 16d766ef4..000000000 --- a/sys/src/9/teg2/ethermii.c +++ /dev/null @@ -1,235 +0,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<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; -} diff --git a/sys/src/9/teg2/ethermii.h b/sys/src/9/teg2/ethermii.h deleted file mode 100644 index 02a45ee5f..000000000 --- a/sys/src/9/teg2/ethermii.h +++ /dev/null @@ -1,116 +0,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*); -- cgit v1.2.3