ref: 318fe6a702b5c118ce271b616c115648ae6d7448
parent: 5016ac0c63c3b4db1dcdace0c6136b0ac88abeea
author: cinap_lenrek <[email protected]>
date: Thu Dec 17 15:55:59 EST 2020
ether2114x: vetting the driver for pc64 the tulip driver is used in microsofts hypver-v as the legacy ethernet adapter for pxe booting. to make the driver work on pc64, we need to store the Block* pointers in a separate array instead of stuffing them into buffer address 2 of the hardware descriptor. also, enable the driver in the pc64 kernel.
--- a/sys/src/9/pc/ether2114x.c
+++ b/sys/src/9/pc/ether2114x.c
@@ -116,12 +116,13 @@
Gpc = 0x00000100, /* General Purpose Control */
};
-typedef struct Des {
- int status;
- int control;
- ulong addr;
- Block* bp;
-} Des;
+enum {
+ Dstatus,
+ Dcontrol,
+ Daddr1,
+ Daddr2,
+ Dsize,
+};
enum { /* status */
Of = 0x00000001, /* Rx: OverFlow */
@@ -227,18 +228,20 @@
Lock lock;
- Des* rdr; /* receive descriptor ring */
+ Block **rbp;
+ ulong *rdr; /* receive descriptor ring */
int nrdr; /* size of rdr */
int rdrx; /* index into rdr */
Lock tlock;
- Des* tdr; /* transmit descriptor ring */
+ Block *setupbp;
+ Block **tbp;
+ ulong *tdr; /* transmit descriptor ring */
int ntdr; /* size of tdr */
int tdrh; /* host index into tdr */
int tdri; /* interface index into tdr */
int ntq; /* descriptors active */
int ntqmax;
- Block* setupbp;
ulong of; /* receive statistics */
ulong ce;
@@ -375,14 +378,13 @@
{
Ctlr *ctlr;
Block *bp;
- Des *des;
- int control;
+ ulong *des, control;
ctlr = ether->ctlr;
while(ctlr->ntq < (ctlr->ntdr-1)){
- if(ctlr->setupbp){
+ if(ctlr->setupbp != nil){
bp = ctlr->setupbp;
- ctlr->setupbp = 0;
+ ctlr->setupbp = nil;
control = Ic|Set|BLEN(bp);
}
else{
@@ -391,15 +393,15 @@
break;
control = Ic|Lseg|Fseg|BLEN(bp);
}
-
- ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
- des = &ctlr->tdr[ctlr->tdrh];
- des->bp = bp;
- des->addr = PCIWADDR(bp->rp);
- des->control |= control;
+ ctlr->tbp[ctlr->tdrh] = bp;
+ des = &ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)*Dsize];
+ des[Dcontrol] &= ~Ic;
+ des = &ctlr->tdr[ctlr->tdrh*Dsize];
+ des[Daddr1] = PCIWADDR(bp->rp);
+ des[Dcontrol] |= control;
ctlr->ntq++;
coherence();
- des->status = Own;
+ des[Dstatus] = Own;
csr32w(ctlr, 1, 0);
ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
}
@@ -424,9 +426,8 @@
{
Ctlr *ctlr;
Ether *ether;
- int len, status;
- Des *des;
- Block *bp;
+ Block **bpp, *bp;
+ ulong *des, status, len;
ether = arg;
ctlr = ether->ctlr;
@@ -459,37 +460,39 @@
* Received packets.
*/
if(status & Ri){
- des = &ctlr->rdr[ctlr->rdrx];
- while(!(des->status & Own)){
- if(des->status & Es){
- if(des->status & Of)
+ for(;;){
+ des = &ctlr->rdr[ctlr->rdrx*Dsize];
+ if(des[Dstatus] & Own)
+ break;
+
+ if(des[Dstatus] & Es){
+ if(des[Dstatus] & Of)
ctlr->of++;
- if(des->status & Ce)
+ if(des[Dstatus] & Ce)
ctlr->ce++;
- if(des->status & Cs)
+ if(des[Dstatus] & Cs)
ctlr->cs++;
- if(des->status & Tl)
+ if(des[Dstatus] & Tl)
ctlr->tl++;
- if(des->status & Rf)
+ if(des[Dstatus] & Rf)
ctlr->rf++;
- if(des->status & De)
+ if(des[Dstatus] & De)
ctlr->de++;
}
- else if(bp = iallocb(Rbsz)){
- len = ((des->status & Fl)>>16)-4;
- des->bp->wp = des->bp->rp+len;
- etheriq(ether, des->bp);
- des->bp = bp;
- des->addr = PCIWADDR(bp->rp);
+ else if((bp = iallocb(Rbsz)) != nil){
+ bpp = &ctlr->rbp[ctlr->rdrx];
+ len = ((des[Dstatus] & Fl)>>16)-4;
+ (*bpp)->wp += len;
+ etheriq(ether, *bpp);
+ *bpp = bp;
+ des[Daddr1] = PCIWADDR(bp->rp);
}
-
- des->control &= Er;
- des->control |= Rbsz;
+ des[Dcontrol] &= Er;
+ des[Dcontrol] |= Rbsz;
coherence();
- des->status = Own;
+ des[Dstatus] = Own;
ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
- des = &ctlr->rdr[ctlr->rdrx];
}
status &= ~Ri;
}
@@ -529,28 +532,31 @@
ilock(&ctlr->tlock);
while(ctlr->ntq){
- des = &ctlr->tdr[ctlr->tdri];
- if(des->status & Own)
+ des = &ctlr->tdr[ctlr->tdri*Dsize];
+ if(des[Dstatus] & Own)
break;
- if(des->status & Es){
- if(des->status & Uf)
+ if(des[Dstatus] & Es){
+ if(des[Dstatus] & Uf)
ctlr->uf++;
- if(des->status & Ec)
+ if(des[Dstatus] & Ec)
ctlr->ec++;
- if(des->status & Lc)
+ if(des[Dstatus] & Lc)
ctlr->lc++;
- if(des->status & Nc)
+ if(des[Dstatus] & Nc)
ctlr->nc++;
- if(des->status & Lo)
+ if(des[Dstatus] & Lo)
ctlr->lo++;
- if(des->status & To)
+ if(des[Dstatus] & To)
ctlr->to++;
ether->oerrs++;
}
+ des[Dcontrol] &= Er;
+ coherence();
- freeb(des->bp);
- des->control &= Er;
+ bpp = &ctlr->tbp[ctlr->tdri];
+ freeb(*bpp);
+ *bpp = nil;
ctlr->ntq--;
ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
@@ -562,7 +568,7 @@
* Anything left not catered for?
*/
if(status)
- panic("#l%d: status %8.8uX", ether->ctlrno, status);
+ panic("#l%d: status %8.8luX", ether->ctlrno, status);
}
}
@@ -570,7 +576,7 @@
ctlrinit(Ether* ether)
{
Ctlr *ctlr;
- Des *des;
+ ulong *des;
Block *bp;
int i;
uchar bi[Eaddrlen*2];
@@ -584,23 +590,31 @@
* create and post a setup packet to initialise
* the physical ethernet address.
*/
- ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
- for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
- des->bp = iallocb(Rbsz);
- if(des->bp == nil)
+ ctlr->rbp = xspanalloc(ctlr->nrdr*sizeof(Block*), 0, 0);
+ ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(ulong)*Dsize, 8*sizeof(ulong), 0);
+ for(i = 0; i < ctlr->nrdr; i++){
+ bp = iallocb(Rbsz);
+ if(bp == nil)
panic("can't allocate ethernet receive ring");
- des->status = Own;
- des->control = Rbsz;
- des->addr = PCIWADDR(des->bp->rp);
+ ctlr->rbp[i] = bp;
+ des = &ctlr->rdr[i*Dsize];
+ des[Dstatus] = Own;
+ des[Dcontrol] = Rbsz;
+ des[Daddr1] = PCIWADDR(bp->rp);
}
- ctlr->rdr[ctlr->nrdr-1].control |= Er;
+ ctlr->rdr[(ctlr->nrdr-1)*Dsize + Dcontrol] |= Er;
ctlr->rdrx = 0;
+ coherence();
csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
- ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
- ctlr->tdr[ctlr->ntdr-1].control |= Er;
+ ctlr->tbp = xspanalloc(ctlr->ntdr*sizeof(Block*), 0, 0);
+ ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(ulong)*Dsize, 8*sizeof(ulong), 0);
+ for(i = 0; i < ctlr->ntdr; i++)
+ ctlr->tbp[i] = nil;
+ ctlr->tdr[(ctlr->ntdr-1)*Dsize + Dcontrol] |= Er;
ctlr->tdrh = 0;
ctlr->tdri = 0;
+ coherence();
csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
/*
@@ -619,6 +633,7 @@
bi[i*4+2] = ether->ea[i*2+1];
bi[i*4+3] = ether->ea[i*2];
}
+
bp = iallocb(Eaddrlen*2*16);
if(bp == nil)
panic("can't allocate ethernet setup buffer");
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -48,7 +48,7 @@
# devi82365
cputemp pci
# ether2000 ether8390
-# ether2114x pci
+ ether2114x pci
# ether589 etherelnk3
ether79c970 pci
# ether8003 ether8390