ref: 21622cb6b9d0d169f1b87c20d5efe129e6e4e85d
parent: f542b27e49a8f25998e65befa6ddc74b456e669c
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jan 12 10:34:23 EST 2019
ether82563, ether82598, etherx550: round rbsz to multiple of 1K the max packet size is configured in 1K increments on these chips, which can result in the card receiving a 10K packet but the driver having only allocated 9.5K of buffer. this actually caued pool corruption with i210, i217, i218, i219, i350. for 82598 and x550, we explicitely round rbsz to avoid similar bugs in the future, even tho the Rbsz constant was already a multiple of 1K and is not affected by the bug.
--- a/sys/src/9/pc/ether82563.c
+++ b/sys/src/9/pc/ether82563.c
@@ -512,7 +512,7 @@
void *alloc; /* receive/transmit descriptors */
int nrd;
int ntd;
- uint rbsz;
+ int rbsz;
u32int *nic;
Lock imlock;
@@ -942,8 +942,6 @@
csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
else{i = ctlr->rbsz / 1024;
- if(ctlr->rbsz % 1024)
- i++;
if(cttab[ctlr->type].flag & F75){csr32w(ctlr, Rctl, Lpe|Dpf|Bsize2048|Bam|RdtmsHALF|Secrc);
if(ctlr->type != i82575)
@@ -1098,7 +1096,7 @@
microdelay(1);
}
if((phy & (MDIe|MDIready)) != MDIready){- print("%s: phy %d wedged %.8ux\n", cttab[c->type].name, phyno, phy);+ print("%s: phy %d wedged %.8ux\n", cname(c), phyno, phy);return ~0;
}
return phy & 0xffff;
@@ -2032,7 +2030,7 @@
}
ctlr->type = type;
ctlr->pcidev = p;
- ctlr->rbsz = cttab[type].mtu;
+ ctlr->rbsz = ROUND(cttab[type].mtu, 1024);
ctlr->port = p->mem[0].bar & ~0x0F;
if(i82563ctlrhead != nil)
i82563ctlrtail->next = ctlr;
@@ -2098,7 +2096,7 @@
edev->irq = ctlr->pcidev->intl;
edev->tbdf = ctlr->pcidev->tbdf;
edev->mbps = 1000;
- edev->maxmtu = ctlr->rbsz;
+ edev->maxmtu = cttab[ctlr->type].mtu;
memmove(edev->ea, ctlr->ra, Eaddrlen);
/*
--- a/sys/src/9/pc/ether82598.c
+++ b/sys/src/9/pc/ether82598.c
@@ -305,7 +305,7 @@
/* tweakable paramaters */
enum {- Rbsz = 12*1024,
+ Mtu = 12*1024,
Nrd = 256,
Ntd = 256,
Nrb = 256,
@@ -500,7 +500,7 @@
c->reg[Fctrl] |= Bam;
c->reg[Rxcsum] |= Ipcs;
- c->reg[Srrctl] = (c->rbsz + 1023)/1024;
+ c->reg[Srrctl] = c->rbsz / 1024;
c->reg[Mhadd] = c->rbsz << 16;
c->reg[Hlreg0] |= Jumboen;
@@ -902,7 +902,7 @@
c->io = io;
c->reg = (u32int*)mem;
c->regmsi = (u32int*)memmsi;
- c->rbsz = Rbsz;
+ c->rbsz = ROUND(Mtu, 1024);
if(reset(c)){ print("i82598: can't reset\n");free(c);
@@ -948,7 +948,7 @@
e->irq = c->p->intl;
e->tbdf = c->p->tbdf;
e->mbps = 10000;
- e->maxmtu = c->rbsz;
+ e->maxmtu = Mtu;
e->arg = e;
e->attach = attach;
--- a/sys/src/9/pc/etherx550.c
+++ b/sys/src/9/pc/etherx550.c
@@ -267,7 +267,7 @@
/* tweakable paramaters */
enum {- Rbsz = 12*1024,
+ Mtu = 12*1024,
Nrd = 256,
Ntd = 256,
Nrb = 256,
@@ -467,7 +467,7 @@
c->reg[Fctrl] |= Bam;
c->reg[Rxcsum] |= Ippcse;
- c->reg[Srrctl] = (c->rbsz + 1023)/1024;
+ c->reg[Srrctl] = c->rbsz / 1024;
c->reg[Maxfrs] = c->rbsz << 16;
c->reg[Hlreg0] |= Jumboen;
@@ -852,7 +852,7 @@
c->io = io;
c->reg = (u32int*)mem;
c->regmsi = (u32int*)memmsi;
- c->rbsz = Rbsz;
+ c->rbsz = ROUND(Mtu, 1024);
if(reset(c)){ print("iX550: can't reset\n");free(c);
@@ -898,7 +898,7 @@
e->irq = c->p->intl;
e->tbdf = c->p->tbdf;
e->mbps = 10000;
- e->maxmtu = c->rbsz;
+ e->maxmtu = Mtu;
e->arg = e;
e->attach = attach;
--
⑨