devether: make link status prints consistent

Provide ethersetlink() function for norifying about
link status changes, which will do the printing
that includes the controller number.
This commit is contained in:
cinap_lenrek 2025-01-07 03:10:35 +00:00
parent 682e47137a
commit 5dde462f96
23 changed files with 113 additions and 112 deletions

View file

@ -1400,7 +1400,7 @@ linkdown(Ctlr *ctl)
if(edev == nil || ctl->status == Disconnected)
return;
ctl->status = Disconnected;
edev->link = 0;
ethersetlink(edev, 0);
/* send eof to aux/wpa */
for(i = 0; i < edev->nfile; i++){
f = edev->f[i];
@ -1550,7 +1550,7 @@ bcmevent(Ctlr *ctl, uchar *p, int len)
break;
case 16: /* E_LINK */
if(flags&1){ /* link up */
ctl->edev->link = 1;
ethersetlink(ctl->edev, 1);
break;
}
/* fall through */
@ -1812,8 +1812,8 @@ wljoin(Ctlr *ctl, char *ssid, int chan)
ctl->status = Connecting;
switch(waitjoin(ctl)){
case 0:
ctl->edev->link = 1;
ctl->status = Connected;
ethersetlink(ctl->edev, 1);
break;
case 3:
ctl->status = Disconnected;

View file

@ -770,8 +770,7 @@ linkproc(void *arg)
ethersetspeed(edev, phy->speed);
}
edev->link = link;
// print("#l%d: link %d speed %d\n", edev->ctlrno, edev->link, edev->mbps);
ethersetlink(edev, link);
}
}

View file

@ -111,7 +111,6 @@ ethproc(void *ved)
{
Ether *edev;
Ctlr *c;
char *sp, *dpl;
u16int v;
edev = ved;
@ -120,8 +119,7 @@ ethproc(void *ved)
mdwrite(c, MDCTRL, AUTONEG);
for(;;){
if((mdread(c, MDSTATUS) & LINK) == 0){
edev->link = 0;
print("eth: no link\n");
ethersetlink(edev, 0);
while((mdread(c, MDSTATUS) & LINK) == 0)
tsleep(&up->sleep, return0, nil, Linkdelay);
}
@ -131,26 +129,19 @@ ethproc(void *ved)
;
c->r[MAC_CONFIG] &= ~(1<<15);
ethersetspeed(edev, 1000);
sp = "1000BASE-T";
}else if((v & 0x20) != 0){
c->r[MAC_CONFIG] = c->r[MAC_CONFIG] | (1<<15|1<<14);
ethersetspeed(edev, 100);
sp = "100BASE-TX";
}else if((v & 0x10) != 0){
c->r[MAC_CONFIG] = c->r[MAC_CONFIG] & ~(1<<14) | 1<<15;
ethersetspeed(edev, 10);
sp = "10BASE-T";
}else
sp = "???";
}
if((v & 0x08) != 0){
dpl = "full";
c->r[MAC_CONFIG] |= 1<<11;
}else{
dpl = "half";
c->r[MAC_CONFIG] &= ~(1<<11);
}
edev->link = 1;
print("eth: %s %s duplex link\n", sp, dpl);
ethersetlink(edev, 1);
c->r[MAC_CONFIG] |= 1<<3 | 1<<2;
while((mdread(c, MDSTATUS) & LINK) != 0)
tsleep(&up->sleep, return0, nil, Linkdelay);

View file

@ -519,8 +519,7 @@ linkproc(void *arg)
wr(ctlr, ENET_RDAR, RDAR_ACTIVE);
}
edev->link = link;
print("#l%d: link %d speed %d\n", edev->ctlrno, edev->link, edev->mbps);
ethersetlink(edev, link);
}
}

View file

@ -866,9 +866,9 @@ interrupt(Ureg*, void *arg)
* thus we note the link change here, and check for
* that and autonegotiation done below.
*/
if(irqe & IEphystschg) {
ether->link = (reg->ps0 & PS0linkup) != 0;
if(irqe & IEphystschg){
ctlr->linkchg = 1;
ethersetlink(ether, reg->ps0 & PS0linkup);
}
if(irqe & IEtxerrq(Qno))
ether->oerrs++;
@ -895,8 +895,8 @@ interrupt(Ureg*, void *arg)
if(ctlr->linkchg && (reg->ps1 & PS1an_done)) {
handled++;
ether->link = (reg->ps0 & PS0linkup) != 0;
ctlr->linkchg = 0;
ethersetlink(ether, reg->ps0 & PS0linkup);
}
ctlr->newintrs++;

View file

@ -880,19 +880,21 @@ rtl8169link(Ether* edev)
ctlr = edev->ctlr;
r = csr8r(ctlr, Phystatus);
/*
* Maybe the link changed - do we care very much?
* Could stall transmits if no link, maybe?
*/
edev->link = (r & Linksts) != 0;
if(edev->link){
r = csr8r(ctlr, Phystatus);
if(r & Linksts){
if(r & Speed10)
ethersetspeed(edev, 10);
else if(r & Speed100)
ethersetspeed(edev, 100);
else if(r & Speed1000)
ethersetspeed(edev, 1000);
ethersetlink(edev, 1);
} else {
ethersetlink(edev, 0);
}
}

View file

@ -508,7 +508,7 @@ struct Ctlr {
uvlong port;
Pcidev *pcidev;
Ctlr *next;
int active;
Ether *edev;
int type;
u16int eeprom[0x40];
@ -851,7 +851,7 @@ i82563cleanup(Ctlr *c)
c->tb[tdh] = nil;
freeb(b);
}else
iprint("82563 tx underrun!\n");
iprint("#l%d: %s: tx underrun!\n", c->edev->ctlrno, cname(c));
c->tdba[tdh].status = 0;
}
@ -914,7 +914,7 @@ i82563replenish(Ctlr *ctlr)
for(rdt = ctlr->rdt; NEXT(rdt, ctlr->nrd) != ctlr->rdh; rdt = NEXT(rdt, ctlr->nrd)){
rd = &ctlr->rdba[rdt];
if(ctlr->rb[rdt] != nil){
iprint("82563: tx overrun\n");
iprint("#l%d: %s: tx overrun\n", ctlr->edev->ctlrno, cname(ctlr));
break;
}
i++;
@ -1097,7 +1097,7 @@ phyread(Ctlr *c, int phyno, int reg)
microdelay(1);
}
if((phy & (MDIe|MDIready)) != MDIready){
print("%s: phy %d wedged %.8ux\n", cname(c), phyno, phy);
print("#l%d: %s: phy %d wedged %.8ux\n", c->edev->ctlrno, cname(c), phyno, phy);
return ~0;
}
return phy & 0xffff;
@ -1143,18 +1143,18 @@ static uint
phywrite(Ctlr *c, uint phyno, uint reg, ushort v)
{
if(setpage(c, phyno, reg>>8, reg & 0xff) == ~0)
panic("%s: bad phy reg %.4ux", cname(c), reg);
panic("#l%d: %s: bad phy reg %.4ux", c->edev->ctlrno, cname(c), reg);
return phywrite0(c, phyno, reg & 0xff, v);
}
static void
phyerrata(Ether *e, Ctlr *c, uint phyno)
phyerrata(Ctlr *c, uint phyno)
{
if(e->mbps == 0){
if(c->edev->mbps == 0){
if(c->phyerrata == 0){
c->phyerrata++;
phywrite(c, phyno, Phyprst, Prst); /* try a port reset */
print("%s: phy port reset\n", cname(c));
print("#l%d: %s: phy port reset\n", c->edev->ctlrno, cname(c));
}
}else
c->phyerrata = 0;
@ -1174,10 +1174,11 @@ phyprobe(Ctlr *c, uint mask)
phy |= phyread(c, phyno, Phyid2) >> 10;
if(phy == 0xFFFFF || phy == 0)
continue;
print("%s: phy%d oui %#ux\n", cname(c), phyno, phy);
print("#l%d: %s: phy%d oui %#ux\n", c->edev->ctlrno, cname(c),
phyno, phy);
return phyno;
}
print("%s: no phy\n", cname(c));
print("#l%d: %s: no phy\n", c->edev->ctlrno, cname(c));
return ~0;
}
@ -1221,11 +1222,13 @@ phyl79proc(void *v)
break;
}
i = (phy>>8) & 3;
e->link = i != 3 && (phy & Link) != 0;
if(e->link)
if(i != 3 && (phy & Link) != 0){
ethersetspeed(e, speedtab[i]);
else
ethersetlink(e, 1);
}else{
ethersetlink(e, 0);
i = 3;
}
c->speeds[i]++;
lsleep(c, Lsc);
}
@ -1278,14 +1281,16 @@ phylproc(void *v)
if(a)
phywrite(c, phyno, Phyctl, phyread(c, phyno, Phyctl) | Ran | Ean);
next:
e->link = (phy & Rtlink) != 0;
if(e->link)
if(phy & Rtlink){
ethersetspeed(e, speedtab[i]);
else
ethersetlink(e, 1);
}else{
ethersetlink(e, 0);
i = 3;
}
c->speeds[i]++;
if(c->type == i82563)
phyerrata(e, c, phyno);
phyerrata(c, phyno);
lsleep(c, Lsc);
}
}
@ -1306,13 +1311,16 @@ pcslproc(void *v)
csr32w(c, Connsw, Enrgirq);
for(;;){
phy = csr32r(c, Pcsstat);
e->link = phy & Linkok;
i = 3;
if(e->link){
if(phy & Linkok){
i = (phy & 6) >> 1;
ethersetspeed(e, speedtab[i]);
}else if(phy & Anbad)
ethersetlink(e, 1);
}else {
ethersetlink(e, 0);
if(phy & Anbad)
csr32w(c, Pcsctl, csr32r(c, Pcsctl) | Pan | Prestart);
i = 3;
}
c->speeds[i]++;
lsleep(c, Lsc | Omed);
}
@ -1333,12 +1341,13 @@ serdeslproc(void *v)
rx = csr32r(c, Rxcw);
tx = csr32r(c, Txcw);
USED(tx);
e->link = (rx & 1<<31) != 0;
// e->link = (csr32r(c, Status) & Lu) != 0;
i = 3;
if(e->link){
if(rx & 1<<31){ /*(csr32r(c, Status) & Lu*/
i = 2;
ethersetspeed(e, speedtab[i]);
ethersetlink(e, 1);
} else {
ethersetlink(e, 0);
i = 3;
}
c->speeds[i]++;
lsleep(c, Lsc);
@ -1538,7 +1547,7 @@ eeread(Ctlr *ctlr, int adr)
while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
microdelay(5);
if (timeout < 0) {
print("%s: eeread timeout\n", cname(ctlr));
print("#l%d: %s: eeread timeout\n", ctlr->edev->ctlrno, cname(ctlr));
return -1;
}
return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
@ -1589,7 +1598,7 @@ done:
while((f->reg[Fsts] & Fdone) == 0 && timeout--)
microdelay(5);
if(timeout < 0){
print("%s: fread timeout\n", cname(c));
print("#l%d: %s: fread timeout\n", c->edev->ctlrno, cname(c));
return -1;
}
if(f->reg[Fsts] & (Fcerr|Ael))
@ -1626,7 +1635,7 @@ done:
while((f->reg32[Fsts/2] & Fdone) == 0 && timeout--)
microdelay(5);
if(timeout < 0){
print("%s: fread timeout\n", cname(c));
print("#l%d: %s: fread timeout\n", c->edev->ctlrno, cname(c));
return -1;
}
if(f->reg32[Fsts/2] & (Fcerr|Ael))
@ -1777,7 +1786,7 @@ i82563reset(Ctlr *ctlr)
r = eeload(ctlr);
if(r != 0 && r != 0xbaba){
print("%s: bad eeprom checksum - %#.4ux", cname(ctlr), r);
print("#l%d: %s: bad eeprom checksum - %#.4ux", ctlr->edev->ctlrno, cname(ctlr), r);
if(flag & Fbadcsum)
print("; ignored\n");
else {
@ -2101,12 +2110,12 @@ pnp(Ether *edev, int type)
for(ctlr = i82563ctlrhead; ; ctlr = ctlr->next){
if(ctlr == nil)
return -1;
if(ctlr->active)
if(ctlr->edev != nil)
continue;
if(type != -1 && ctlr->type != type)
continue;
if(edev->port == 0 || edev->port == ctlr->port){
ctlr->active = 1;
ctlr->edev = edev;
memmove(ctlr->ra, edev->ea, Eaddrlen);
if(setup(ctlr) == 0)
break;

View file

@ -384,11 +384,13 @@ lproc(void *v)
;
for (;;) {
r = c->reg[Links];
e->link = (r & Lnkup) != 0;
i = 0;
if(e->link){
if(r & Lnkup){
i = 1 + ((r & Lnkspd) != 0);
ethersetspeed(e, speedtab[i]);
ethersetlink(e, 1);
} else {
ethersetlink(e, 0);
i = 0;
}
c->speeds[i]++;
c->lim = 0;

View file

@ -333,15 +333,14 @@ checklink(Ether *edev)
ulong i;
int mbps;
mbps = 0;
ctlr = edev->ctlr;
miir(ctlr, PhyStatus); /* dummy read necessary */
if(!(miir(ctlr, PhyStatus) & PhyLinkStatus)) {
edev->link = 0;
ctlr->duplex = 1;
print("bcm: no link\n");
ethersetlink(edev, 0);
goto out;
}
edev->link = 1;
while((miir(ctlr, PhyStatus) & PhyAutoNegComplete) == 0);
i = miir(ctlr, PhyGbitStatus);
if(i & (Phy1000FD | Phy1000HD)) {
@ -354,13 +353,12 @@ checklink(Ether *edev)
mbps = 10;
ctlr->duplex = (i & Phy10FD) != 0;
} else {
edev->link = 0;
ctlr->duplex = 1;
print("bcm: link partner supports neither 10/100/1000 Mbps\n");
ethersetlink(edev, 0);
goto out;
}
print("bcm: %d Mbps link, %s duplex\n", mbps, ctlr->duplex ? "full" : "half");
ethersetspeed(edev, mbps);
ethersetlink(edev, 1);
out:
if(ctlr->duplex) csr32(ctlr, MACMode) &= ~MACHalfDuplex;
else csr32(ctlr, MACMode) |= MACHalfDuplex;

View file

@ -2118,6 +2118,8 @@ etherelnk3reset(Ether* ether)
intrenable(ether->irq, interrupt, ether, ether->tbdf, ether->name);
ether->link = ether->mbps != 0;
return 0;
}

View file

@ -583,17 +583,12 @@ ga620event(Ether *edev, int eci, int epi)
case 1:
ethersetspeed(edev, 1000);
break;
case 2:
print("#l%d: link down\n", edev->ctlrno);
break;
case 3:
/* it's 10 or 100 */
ethersetspeed(edev, 100);
break;
}
if (code != 2)
print("#l%d: %dMbps link up\n",
edev->ctlrno, edev->mbps);
ethersetlink(edev, code != 2);
break;
case 0x07: /* event error */
default:

View file

@ -1242,13 +1242,8 @@ checkstats(Ether *e, Ctlr *c, Stats *s)
return;
i = gbit32(s->linkstat);
if(c->linkstat != i){
e->link = i;
if(c->linkstat = i)
dprint("m10g: link up\n");
else
dprint("m10g: link down\n");
}
if(c->linkstat != i)
ethersetlink(e, c->linkstat = i);
i = gbit32(s->nrdma);
if(i != c->nrdma){
dprint("m10g: rdma timeout %ld\n", i);

View file

@ -713,9 +713,8 @@ vgbeinterrupt(Ureg *, void* arg)
print("vgbe: irq: PHY interrupt\n");
if(status & Isr_LinkStatus){
edev->link = (riob(ctlr, PhySts0) & PhySts_Link) ? 1 : 0;
ethersetlink(edev, riob(ctlr, PhySts0) & PhySts_Link);
vgbemiip(ctlr, 1);
print("vgbe: irq: link status change\n");
}
if(status & Isr_RxNoDesc)
print("vgbe: irq: ran out of Rx descriptors\n");

View file

@ -346,11 +346,13 @@ lproc(void *v)
;
for (;;) {
r = c->reg[Links];
e->link = (r & Lnkup) != 0;
i = 0;
if(e->link){
if(r & Lnkup){
i = 1 + ((r & Lnkspd) != 0);
ethersetspeed(e, speedtab[i]);
ethersetlink(e, 1);
} else {
ethersetlink(e, 0);
i = 0;
}
c->speeds[i]++;
c->lim = 0;

View file

@ -1365,10 +1365,12 @@ link(Ether *e)
i = phyread(c, Phyint);
s = phyread(c, Phylstat);
dprint("#l%d: yuk: link %.8ux %.8ux\n", e->ctlrno, i, s);
e->link = (s & Plink) != 0;
if(e->link)
if(s & Plink){
ethersetspeed(e, (c->feat&Ffiber)? 1000: spdtab[(s & Physpd) >> 14]);
dprint("#l%d: yuk: link %d spd %d\n", e->ctlrno, e->link, e->mbps);
ethersetlink(e, 1);
} else {
ethersetlink(e, 0);
}
}
static void

View file

@ -475,6 +475,17 @@ ethersetspeed(Ether *ether, int mbps)
return;
netifsetlimit(ether, etherqueuesize(ether));
qsetlimit(ether->oq, ether->limit);
print("#l%d: %s: speed %dMbps\n", ether->ctlrno, ether->type, mbps);
}
void
ethersetlink(Ether *ether, int link)
{
link = !!link;
if(!!ether->link == link)
return;
ether->link = link;
print("#l%d: %s: link %s\n", ether->ctlrno, ether->type, link? "up": "down");
}
static void netconsole(int);

View file

@ -52,6 +52,7 @@ struct Ether {
};
extern void ethersetspeed(Ether*, int);
extern void ethersetlink(Ether*, int);
extern void etheriq(Ether*, Block*);
extern void addethercard(char*, int(*)(Ether*));
extern ulong ethercrc(uchar*, int);

View file

@ -54,6 +54,7 @@ reset(Ether* ether)
{
if(ether->type==nil)
return -1;
ether->link = 0;
ether->mbps = 1000;
ether->attach = attach;
ether->multicast = multicast;

View file

@ -780,7 +780,6 @@ reset(Ether* edev)
edev->multicast = multicast;
edev->promiscuous = promiscuous;
pcisetbme(ctlr->pcidev);
intrenable(edev->irq, interrupt, edev, edev->tbdf, edev->name);

View file

@ -815,9 +815,13 @@ Scan:
/* maintain access point */
tmout = 0;
while((wn = wifi->bss) != nil){
ether->link = (wn->status == Sassoc) || (wn->status == Sblocked);
if(ether->link && (rate = wn->actrate) != nil)
if(wn->status == Sassoc || wn->status == Sblocked){
if((rate = wn->actrate) != nil)
ethersetspeed(ether, ((*rate & 0x7f)+3)/4);
ethersetlink(ether, 1);
} else {
ethersetlink(ether, 0);
}
now = MACHP(0)->ticks;
if(wn->status != Sneedauth && TK2SEC(now - wn->lastseen) > 20 || goodbss(wifi, wn) == 0){
wifideauth(wifi, wn);

View file

@ -867,10 +867,11 @@ fccltimer(Ureg*, Timer *t)
return;
}
if(phy->link == 0){
print("link lost\n");
ethersetlink(ether, 0);
return;
}
ethersetspeed(ether, phy->speed);
ethersetlink(ether, 1);
if(phy->fd != ctlr->duplex)
print("set duplex\n");

View file

@ -1280,24 +1280,22 @@ rtl8169link(Ether* edev)
ctlr = edev->ctlr;
if(!((r = csr8r(ctlr, Phystatus)) & Linksts)){
if (edev->link) {
edev->link = 0;
if(edev->link) {
csr8w(ctlr, Cr, Re);
iprint("#l%d: link down\n", edev->ctlrno);
ethersetlink(edev, 0);
}
return;
}
if(edev->link == 0) {
edev->link = 1;
csr8w(ctlr, Cr, Te|Re);
iprint("#l%d: link up\n", edev->ctlrno);
}
if(r & Speed10)
ethersetspeed(edev, 10);
else if(r & Speed100)
ethersetspeed(edev, 100);
else if(r & Speed1000)
ethersetspeed(edev, 1000);
if(edev->link == 0) {
csr8w(ctlr, Cr, Te|Re);
ethersetlink(edev, 1);
}
}
static void

View file

@ -141,7 +141,6 @@ ethproc(void *ved)
{
Ether *edev;
Ctlr *c;
char *sp, *dpl;
u16int v;
edev = ved;
@ -149,40 +148,32 @@ ethproc(void *ved)
mdwrite(c, MDCTRL, AUTONEG);
for(;;){
if((mdread(c, MDSTATUS) & LINK) == 0){
edev->link = 0;
print("eth: no link\n");
ethersetlink(edev, 0);
while((mdread(c, MDSTATUS) & LINK) == 0)
tsleep(&up->sleep, return0, nil, Linkdelay);
}
v = mdread(c, MDPHYCTRL);
if((v & 0x40) != 0){
sp = "1000BASE-T";
while((mdread(c, MDGSTATUS) & RECVOK) != RECVOK)
;
c->r[NET_CFG] |= GIGE_EN;
slcr[GEM0_CLK_CTRL] = 1 << 20 | 8 << 8 | 1;
ethersetspeed(edev, 1000);
}else if((v & 0x20) != 0){
sp = "100BASE-TX";
c->r[NET_CFG] = c->r[NET_CFG] & ~GIGE_EN | SPEED;
slcr[GEM0_CLK_CTRL] = 5 << 20 | 8 << 8 | 1;
ethersetspeed(edev, 100);
}else if((v & 0x10) != 0){
sp = "10BASE-T";
c->r[NET_CFG] = c->r[NET_CFG] & ~(GIGE_EN | SPEED);
slcr[GEM0_CLK_CTRL] = 20 << 20 | 20 << 8 | 1;
ethersetspeed(edev, 10);
}else
sp = "???";
}
if((v & 0x08) != 0){
dpl = "full";
c->r[NET_CFG] |= FDEN;
}else{
dpl = "half";
c->r[NET_CFG] &= ~FDEN;
}
edev->link = 1;
print("eth: %s %s duplex link\n", sp, dpl);
ethersetlink(edev, 1);
while((mdread(c, MDSTATUS) & LINK) != 0)
tsleep(&up->sleep, return0, nil, Linkdelay);
}