the mii standard is not arch-dependent, move it to port. mii needs to be sync'd with nix. Reference: /n/atom/patch/applied/pcportmii Date: Thu Jun 19 23:27:19 CES 2014 Signed-off-by: quanstro@quanstro.net # rm /sys/src/9/pc/ethermii.c # rm /sys/src/9/pc/ethermii.h # rm /sys/src/9/pcpae/ethermii.c # rm /sys/src/9/pcpae/ethermii.h --- /sys/src/9/port/ethermii.c Thu Jan 1 00:00:00 1970 +++ /sys/src/9/port/ethermii.c Thu Jun 19 23:26:18 2014 @@ -0,0 +1,300 @@ +#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 "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)<<16; + r |= mii->mir(mii, phyno, Phyidr2); + oui = (r>>10) & 0xffff; + if(oui == 0xffff || oui == 0) + continue; + + if((miiphy = malloc(sizeof(MiiPhy))) == nil) + continue; + + miiphy->mii = mii; + miiphy->phyno = phyno; + miiphy->phyid = r; + miiphy->oui = oui; + + 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, t; + + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr); + mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr | BmcrR); + for(t = 0; t < 1000; t++){ + bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr); + if(bmcr & BmcrR) + break; + microdelay(1); + } + if(bmcr & BmcrR) + return -1; + if(bmcr & BmcrI) + mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr & ~BmcrI); + 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"); + phy->link = 0; + phy->speed = 0; + return -1; + } + + bmsr = mii->mir(mii, phyno, Bmsr); + if(!(bmsr & BmsrLs)){ + // print("miistatus: link down\n"); + phy->link = 0; + phy->speed = 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"); + phy->link = 0; + phy->speed = 0; + 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; +} + +char* +miidumpphy(Mii* mii, char* p, char* e) +{ + int i, r; + + if(mii == nil || mii->curphy == nil) + return p; + + p = seprint(p, e, "phy: "); + for(i = 0; i < NMiiPhyr; i++){ + if(i && ((i & 0x07) == 0)) + p = seprint(p, e, "\n "); + r = mii->mir(mii, mii->curphy->phyno, i); + p = seprint(p, e, " %4.4ux", r); + } + p = seprint(p, e, "\n"); + + return p; +} + +void +miidetach(Mii* mii) +{ + int i; + + for(i = 0; i < NMiiPhy; i++){ + if(mii->phy[i] == nil) + continue; + free(mii); + mii->phy[i] = nil; + } + free(mii); +} + +Mii* +miiattach(void* ctlr, int mask, int (*r)(Mii*, int, int), int (*w)(Mii*, int, int, int)) +{ + Mii* m; + + if((m = malloc(sizeof(Mii))) == nil) + return nil; + m->ctlr = ctlr; + m->mir = r; + m->miw = w; + + if(mii(m, mask) == 0){ + free(m); + m = nil; + } + + return m; +} --- /sys/src/9/port/ethermii.h Thu Jan 1 00:00:00 1970 +++ /sys/src/9/port/ethermii.h Thu Jun 19 23:26:19 2014 @@ -0,0 +1,120 @@ +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 phyno; + int phyid; + int oui; + + int anar; + int fc; + int mscr; + + int link; + int speed; + int fd; + int rfc; + int tfc; +}; + +int mii(Mii*, int); /* depricated */ +Mii* miiattach(void*, int, int (*)(Mii*, int, int), int (*)(Mii*, int, int, int)); +void miidetach(Mii* mii); +int miiane(Mii*, int, int, int); +char* miidumpphy(Mii*, char*, char*); +int miimir(Mii*, int); +int miimiw(Mii*, int, int); +int miireset(Mii*); +int miistatus(Mii*); --- /sys/src/9/pc/etherigbe.c Thu Jun 19 23:26:23 2014 +++ /sys/src/9/pc/etherigbe.c Thu Jun 19 23:26:26 2014 @@ -26,7 +26,7 @@ #include "../port/netif.h" #include "etherif.h" -#include "ethermii.h" +#include "../port/ethermii.h" enum { i82542 = (0x1000<<16)|0x8086, --- /sys/src/9/pc/etherbcm.c Thu Jun 19 23:26:28 2014 +++ /sys/src/9/pc/etherbcm.c Thu Jun 19 23:26:30 2014 @@ -16,7 +16,7 @@ #include "../port/netif.h" #include "etherif.h" -#include "ethermii.h" +#include "../port/ethermii.h" #define dprint(...) do{ if(debug)print(__VA_ARGS__); }while(0) #define Rbsz ROUNDUP(1514+4, 4) --- /sys/src/9/pc/ether8169.c Thu Jun 19 23:26:32 2014 +++ /sys/src/9/pc/ether8169.c Thu Jun 19 23:26:34 2014 @@ -15,7 +15,7 @@ #include "io.h" #include "../port/error.h" -#include "ethermii.h" +#include "../port/ethermii.h" #include "../port/netif.h" #include "etherif.h" --- /sys/src/9/pcpae/etherigbe.c Thu Jun 19 23:26:38 2014 +++ /sys/src/9/pcpae/etherigbe.c Thu Jun 19 23:26:41 2014 @@ -26,7 +26,7 @@ #include "../port/netif.h" #include "etherif.h" -#include "ethermii.h" +#include "../port/ethermii.h" enum { i82542 = (0x1000<<16)|0x8086, --- /sys/src/9/pcpae/etherbcm.c Thu Jun 19 23:26:43 2014 +++ /sys/src/9/pcpae/etherbcm.c Thu Jun 19 23:26:44 2014 @@ -16,7 +16,7 @@ #include "../port/netif.h" #include "etherif.h" -#include "ethermii.h" +#include "../port/ethermii.h" #define dprint(...) do{ if(debug)print(__VA_ARGS__); }while(0) #define Rbsz ROUNDUP(1514+4, 4) --- /sys/src/9/pcpae/ether8169.c Thu Jun 19 23:26:47 2014 +++ /sys/src/9/pcpae/ether8169.c Thu Jun 19 23:26:49 2014 @@ -15,7 +15,7 @@ #include "io.h" #include "../port/error.h" -#include "ethermii.h" +#include "../port/ethermii.h" #include "../port/netif.h" #include "etherif.h"