Compare commits

...

8 commits

Author SHA1 Message Date
Ori Bernstein
8b7a03c5e9 gefs: remove daed mkfile bits
when we imported gefs, we put the manpages in the right
place, and moved the paper to /sys/doc; we don't need
the rules to build and install them any more
2025-01-09 05:20:08 +00:00
Arne
b0e7312a62 gefs(8): fix indent of empty snapshot paragraph 2025-01-08 19:36:17 +00:00
cinap_lenrek
c6a91038b1 stats: add etherovf value (hw and software overflows on input queue) 2025-01-07 11:54:07 +00:00
cinap_lenrek
22d3ade384 devether: don't print link-status until netif is initialized 2025-01-07 11:52:48 +00:00
cinap_lenrek
705a2c3c28 netif: fix potential memory leak in netifwstat()
convM2D() might fault and raise error, leaking
sizeof(Dir)+n allocation.
2025-01-07 06:49:40 +00:00
cinap_lenrek
00c25292d7 devether: print mbps only on link-up
To avoid frequent prints of the current link speed,
which in case of wifi is adjusted based link quality,
print the link speed only on link up events.
2025-01-07 03:50:45 +00:00
cinap_lenrek
5dde462f96 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.
2025-01-07 03:10:35 +00:00
cinap_lenrek
682e47137a ether2114x: fix automatic media detection
We used to reject media info if FD was not specified
in plan9.ini. Instead, initialize fd override to -1
which makes us use it if the infoblock tells us to
and provide a "HD" option to force half-duplex mode.

This makes the media detection work on hyper-v.
2025-01-07 00:45:41 +00:00
28 changed files with 162 additions and 140 deletions

View file

@ -148,7 +148,7 @@ snapshot are required for the file system to work correctly, and may not be remo
.I dump:
This is the name used to mount a list of all snapshots.
Each snapshot in the file system will be listed in a directory.
.IP
.TP
.I empty:
This is a read-only empty snapshot.
It contains no files or directories.

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

@ -867,8 +867,8 @@ interrupt(Ureg*, void *arg)
* that and autonegotiation done below.
*/
if(irqe & IEphystschg){
ether->link = (reg->ps0 & PS0linkup) != 0;
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

@ -1623,7 +1623,7 @@ srom(Ctlr* ctlr)
}
}
ctlr->fd = 0;
ctlr->fd = -1;
ctlr->medium = -1;
return 0;
@ -1776,13 +1776,15 @@ reset(Ether* ether)
* (no MII) or the autonegotiation fails.
*/
for(i = 0; i < ether->nopt; i++){
if(cistrcmp(ether->opt[i], "HD") == 0){
ctlr->fd = 0;
continue;
}
if(cistrcmp(ether->opt[i], "FD") == 0){
ctlr->fd = 1;
continue;
}
for(x = 0; x < nelem(mediatable); x++){
debug("compare <%s> <%s>\n", mediatable[x],
ether->opt[i]);
if(cistrcmp(mediatable[x], ether->opt[i]))
continue;
ctlr->medium = x;
@ -1803,6 +1805,7 @@ reset(Ether* ether)
}
ether->mbps = media(ether, 1);
ether->link = ether->mbps != 0;
/*
* Initialise descriptor rings, ethernet address.

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

@ -410,6 +410,7 @@ etherprobe(int cardno, int ctlrno, char *conf)
ether->irq = -1;
ether->ctlrno = ctlrno;
ether->mbps = 10;
ether->link = 0;
ether->minmtu = ETHERMINTU;
ether->maxmtu = ETHERMAXTU;
@ -422,19 +423,15 @@ etherprobe(int cardno, int ctlrno, char *conf)
memmove(&ether->opt[0], &ether->opt[1], --ether->nopt*sizeof(ether->opt[0]));
} else if(isaconfig("ether", ctlrno, ether) == 0)
goto Nope;
for(cardno = 0; cards[cardno].type != nil; cardno++)
if(cistrcmp(cards[cardno].type, ether->type) == 0)
break;
if(cards[cardno].type == nil)
goto Nope;
for(i = 0; i < ether->nopt; i++){
if(strncmp(ether->opt[i], "ea=", 3) == 0){
if(parseether(ether->ea, &ether->opt[i][3]))
memset(ether->ea, 0, Eaddrlen);
}
}
for(cardno = 0; cards[cardno].type != nil; cardno++)
if(cistrcmp(cards[cardno].type, ether->type) == 0)
break;
}
if(cardno >= MaxEther || cards[cardno].type == nil)
goto Nope;
@ -471,12 +468,33 @@ ethersetspeed(Ether *ether, int mbps)
if(ether->mbps == mbps)
return;
ether->mbps = mbps;
if(mbps <= 0 || ether->oq == nil)
if(mbps <= 0 || ether->f == nil || ether->oq == nil)
return;
netifsetlimit(ether, etherqueuesize(ether));
qsetlimit(ether->oq, ether->limit);
}
void
ethersetlink(Ether *ether, int link)
{
link = !!link;
if(!!ether->link == link)
return;
ether->link = link;
if(ether->f == nil)
return;
if(link)
print("#l%d: %s: link up: %dMbps\n",
ether->ctlrno, ether->type, ether->mbps);
else
print("#l%d: %s: link down\n",
ether->ctlrno, ether->type);
}
static void netconsole(int);
static void

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

@ -418,11 +418,13 @@ netifwstat(Netif *nif, Chan *c, uchar *db, int n)
error(Eperm);
dir = smalloc(sizeof(Dir)+n);
m = convM2D(db, n, &dir[0], (char*)&dir[1]);
if(m == 0){
if(waserror()){
free(dir);
error(Eshortstat);
nexterror();
}
m = convM2D(db, n, &dir[0], (char*)&dir[1]);
if(m == 0)
error(Eshortstat);
if(!emptystr(dir[0].uid)){
strncpy(f->owner, dir[0].uid, KNAMELEN-1);
f->owner[KNAMELEN-1] = 0;
@ -430,6 +432,7 @@ netifwstat(Netif *nif, Chan *c, uchar *db, int n)
if(dir[0].mode != ~0UL)
f->mode = dir[0].mode;
free(dir);
poperror();
return m;
}

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

@ -1281,23 +1281,21 @@ rtl8169link(Ether* edev)
if(!((r = csr8r(ctlr, Phystatus)) & Linksts)){
if(edev->link) {
edev->link = 0;
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);
}

View file

@ -27,13 +27,3 @@ HFILES=\
atomic.h
</sys/src/cmd/mkone
</sys/doc/fonts
%.ps: %.ms
{ echo $FONTS; cat $stem.ms } | pic | tbl | eqn | troff -ms | lp -dstdout > $target
%.pdf: %.ps
ps2pdf $stem.ps $stem.pdf
man.install: gefs.4.man gefs.8.man
cp gefs.4.man /sys/man/4/gefs
cp gefs.8.man /sys/man/8/gefs

View file

@ -56,6 +56,8 @@ enum
Link,
Out,
Err0,
Overflows,
Soverflows,
};
struct Machine
@ -76,8 +78,8 @@ struct Machine
uvlong prevsysstat[10];
int nproc;
int lgproc;
uvlong netetherstats[8];
uvlong prevetherstats[8];
uvlong netetherstats[9];
uvlong prevetherstats[9];
uvlong batterystats[2];
uvlong temp[10];
@ -114,6 +116,7 @@ enum Menu2
Methererr,
Metherin,
Metherout,
Metherovf,
Mfault,
Midle,
Minintr,
@ -138,6 +141,7 @@ char *menu2str[Nmenu2+1] = {
"add ethererr",
"add etherin ",
"add etherout",
"add etherovf",
"add fault ",
"add idle ",
"add inintr ",
@ -159,6 +163,7 @@ char *menu2str[Nmenu2+1] = {
void contextval(Machine*, uvlong*, uvlong*, int),
etherval(Machine*, uvlong*, uvlong*, int),
ethererrval(Machine*, uvlong*, uvlong*, int),
etherovfval(Machine*, uvlong*, uvlong*, int),
etherinval(Machine*, uvlong*, uvlong*, int),
etheroutval(Machine*, uvlong*, uvlong*, int),
faultval(Machine*, uvlong*, uvlong*, int),
@ -186,6 +191,7 @@ void (*newvaluefn[Nmenu2])(Machine*, uvlong*, uvlong*, int init) = {
ethererrval,
etherinval,
etheroutval,
etherovfval,
faultval,
idleval,
inintrval,
@ -796,7 +802,7 @@ needstat(int init)
int
needether(int init)
{
return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr];
return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr] | present[Metherovf];
}
int
@ -1049,6 +1055,17 @@ ethererrval(Machine *m, uvlong *v, uvlong *vmax, int)
*vmax = (sleeptime/1000)*10;
}
void
etherovfval(Machine *m, uvlong *v, uvlong *vmax, int)
{
int i;
*v = 0;
for(i=Overflows; i<=Soverflows; i++)
*v += m->netetherstats[i]-m->prevetherstats[i];
*vmax = (sleeptime/1000)*10;
}
void
batteryval(Machine *m, uvlong *v, uvlong *vmax, int)
{
@ -1413,6 +1430,7 @@ main(int argc, char *argv[])
addgraph(Metherin);
addgraph(Metherout);
addgraph(Methererr);
addgraph(Metherovf);
break;
case 'p':
addgraph(Mtlbpurge);