ref: 53275c70457ff396d52e75d953b8120618c904d1
parent: d0f824edc2fa69ab9fc9618a93fd6e3f15acb2b9
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;