kw: use ethermii.c from port/ (thanks stuart)

This commit is contained in:
cinap_lenrek 2020-12-22 22:17:44 +01:00
parent 809a7402fc
commit f11526708e
4 changed files with 32 additions and 380 deletions

View file

@ -18,7 +18,7 @@
#include "../port/netif.h"
#include "../port/etherif.h"
#include "ethermii.h"
#include "../port/ethermii.h"
#include "../ip/ip.h"
#define MIIDBG if(0)iprint
@ -363,6 +363,36 @@ enum {
SmiRegaddrmask = 0x1f << SmiRegaddroff,
};
enum {
/* 88e1116-specific paged registers */
Scr = 16, /* special control register */
Ssr = 17, /* special status register */
Ier = 18, /* interrupt enable reg */
Isr = 19, /* interrupt status reg */
Escr = 20, /* extended special control reg */
Recr = 21, /* RX error counter reg */
Eadr = 22, /* extended address reg (page select) */
Globsts = 23, /* global status */
Impover = 24, /* RGMII output impedance override (page 2) */
Imptarg = 25, /* RGMII output impedance target (page 2) */
Scr2 = 26, /* special control register 2 */
};
enum { /* Scr page 0 */
Pwrdown = 0x0004, /* power down */
Mdix = 0x0060, /* MDI crossover mode */
Endetect = 0x0300, /* energy detect */
};
enum { /* Scr page 2 */
Rgmiipwrup = 0x0008, /* RGMII power up: must sw reset after */
};
enum { /* Recr page 2 */
Txtiming = 1<<4,
Rxtiming = 1<<5,
};
struct Gbereg {
ulong phy; /* PHY address */
ulong smi; /* serial mgmt. interface */

View file

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

View file

@ -1,143 +0,0 @@
typedef struct Mii Mii;
typedef struct MiiPhy MiiPhy;
enum { /* registers */
Bmcr = 0, /* Basic Mode Control */
Bmsr = 1, /* Basic Mode Status */
Phyidr1 = 2, /* PHY Identifier #1 */
Phyidr2 = 3, /* PHY Identifier #2 */
Anar = 4, /* Auto-Negotiation Advertisement */
Anlpar = 5, /* AN Link Partner Ability */
Aner = 6, /* AN Expansion */
Annptr = 7, /* AN Next Page TX */
Annprr = 8, /* AN Next Page RX */
Mscr = 9, /* Gb Control */
Mssr = 10, /* Gb Status */
Esr = 15, /* Extended Status */
/* 88e1116-specific paged registers */
Scr = 16, /* special control register */
Ssr = 17, /* special status register */
Ier = 18, /* interrupt enable reg */
Isr = 19, /* interrupt status reg */
Escr = 20, /* extended special control reg */
Recr = 21, /* RX error counter reg */
Eadr = 22, /* extended address reg (page select) */
Globsts = 23, /* global status */
Impover = 24, /* RGMII output impedance override (page 2) */
Imptarg = 25, /* RGMII output impedance target (page 2) */
Scr2 = 26, /* special control register 2 */
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 */
};
enum { /* Scr page 0 */
Pwrdown = 0x0004, /* power down */
Mdix = 0x0060, /* MDI crossover mode */
Endetect = 0x0300, /* energy detect */
};
enum { /* Scr page 2 */
Rgmiipwrup = 0x0008, /* RGMII power up: must sw reset after */
};
enum { /* Recr page 2 */
Txtiming = 1<<4,
Rxtiming = 1<<5,
};
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*);

View file

@ -122,7 +122,7 @@ arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O sdscsi.$O syscall.$O \
trap.$O: /$objtype/include/ureg.h
arch.$O syscall.$O main.$O: /sys/include/tos.h
archkw.$O devether.$O ether1116.$O ethermii.$O: \
ethermii.h ../port/etherif.h ../port/netif.h
../port/ethermii.h ../port/etherif.h ../port/netif.h
archkw.$O devflash.$O flashkw.$O: ../port/flashif.h
fpi.$O fpiarm.$O fpimem.$O: fpi.h
l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s arm.h mem.h