nusb/ether: implement link status detection for smsc and lan78xx

This commit is contained in:
cinap_lenrek 2023-11-05 22:23:07 +00:00
parent 616f62253e
commit 9973c9276d
4 changed files with 45 additions and 7 deletions

View file

@ -63,3 +63,4 @@ int (*epreceive)(Dev*);
void (*eptransmit)(Dev*, Block*);
int (*eppromiscuous)(Dev*, int);
int (*epmulticast)(Dev*, uchar*, int);
int (*eplinkspeed)(Dev*);

View file

@ -315,6 +315,7 @@ fsread(Req *r)
char buf[200];
char e[ERRMAX];
ulong path;
int mbps;
path = r->fid->qid.path;
@ -335,13 +336,17 @@ fsread(Req *r)
break;
case Qstats:
if(eplinkspeed == nil)
mbps = 10; /* default */
else
mbps = (*eplinkspeed)(epctl);
snprint(buf, sizeof(buf),
"in: %d\n"
"link: 1\n" /* for stats(8) */
"link: %d\n" /* for stats(8) */
"out: %d\n"
"mbps: %d\n"
"addr: %E\n",
stats.in, stats.out, 10, macaddr);
stats.in, mbps != 0, stats.out, mbps, macaddr);
readstr(r, buf);
respond(r, nil);
break;

View file

@ -97,7 +97,9 @@ enum {
Fulldpx = 1<<8,
Speed1000= 1<<6,
Bmsr = 1,
Advertise = 4,
BmsrLs = 0x0004, /* Link Status */
Anar = 4,
Anlpar = 5,
Adcsma = 0x0001,
Ad10h = 0x0020,
Ad10f = 0x0040,
@ -110,6 +112,9 @@ enum {
Ctrl1000 = 9,
Ad1000h = 0x0400,
Ad1000f = 0x0200,
Mssr = 10,
Mssr1000THD= 0x0400, /* Link Partner 1000BASE-T HD able */
Mssr1000TFD= 0x0800, /* Link Partner 1000BASE-T FD able */
Ledmodes = 29,
Led0shift = 0,
Led1shift = 4,
@ -202,7 +207,7 @@ phyinit(Dev *d)
break;
sleep(10);
}
miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym);
miiwr(d, Anar, Adcsma|Adall|Adpause|Adpauseasym);
miiwr(d, Ctrl1000, Ad1000f);
miiwr(d, Phyintmask, 0);
miiwr(d, Ledmodes, (Linkact<<Led1shift) | (Link1000<<Led0shift));
@ -298,6 +303,18 @@ lan78xxmulticast(Dev *d, uchar *, int)
return wr(d, Rfectl, rxctl);
}
static int
lan78xxlinkspeed(Dev *d)
{
if((miird(d, Bmsr) & BmsrLs) == 0)
return 0; /* link down */
if(miird(d, Mssr) & (Mssr1000THD|Mssr1000TFD))
return 1000;
if(miird(d, Anlpar) & (Ad100h|Ad100f))
return 100;
return 10;
}
int
lan78xxinit(Dev *d)
{
@ -361,6 +378,7 @@ lan78xxinit(Dev *d)
epreceive = lan78xxreceive;
eppromiscuous = lan78xxpromiscuous;
epmulticast = lan78xxmulticast;
eplinkspeed = lan78xxlinkspeed;
return 0;
}

View file

@ -85,7 +85,9 @@ enum {
Anrestart= 1<<9,
Fulldpx = 1<<8,
Bmsr = 1,
Advertise = 4,
BmsrLs = 0x0004, /* Link Status */
Anar = 4,
Anlpar = 5,
Adcsma = 0x0001,
Ad10h = 0x0020,
Ad10f = 0x0040,
@ -94,6 +96,7 @@ enum {
Adpause = 0x0400,
Adpauseasym= 0x0800,
Adall = Ad10h|Ad10f|Ad100h|Ad100f,
Phyintsrc = 29,
Phyintmask = 30,
Anegcomp= 1<<6,
@ -180,8 +183,8 @@ phyinit(Dev *d)
break;
sleep(10);
}
miiwr(d, Advertise, Adcsma|Adall|Adpause|Adpauseasym);
// miiwr(d, Advertise, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym);
miiwr(d, Anar, Adcsma|Adall|Adpause|Adpauseasym);
// miiwr(d, Anar, Adcsma|Ad10f|Ad10h|Adpause|Adpauseasym);
miird(d, Phyintsrc);
miiwr(d, Phyintmask, Anegcomp|Linkdown);
miiwr(d, Bmcr, miird(d, Bmcr)|Anenable|Anrestart);
@ -275,6 +278,16 @@ smscmulticast(Dev *d, uchar *, int)
return wr(d, Maccr, rxctl);
}
static int
smsclinkspeed(Dev *d)
{
if((miird(d, Bmsr) & BmsrLs) == 0)
return 0;
if(miird(d, Anlpar) & (Ad100h|Ad100f))
return 100;
return 10;
}
int
smscinit(Dev *d)
{
@ -314,6 +327,7 @@ smscinit(Dev *d)
epreceive = smscreceive;
eppromiscuous = smscpromiscuous;
epmulticast = smscmulticast;
eplinkspeed = smsclinkspeed;
return 0;
}