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.
This commit is contained in:
cinap_lenrek 2020-12-17 20:55:59 +01:00
parent 5016ac0c63
commit 318fe6a702
2 changed files with 82 additions and 67 deletions

View file

@ -116,12 +116,13 @@ enum { /* CSR12 - General-Purpose Port */
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 @@ typedef struct Ctlr {
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 @@ txstart(Ether* ether)
{
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 @@ txstart(Ether* ether)
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 @@ interrupt(Ureg*, void* arg)
{
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 @@ interrupt(Ureg*, void* arg)
* 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 @@ interrupt(Ureg*, void* arg)
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 @@ interrupt(Ureg*, void* arg)
* 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 @@ static void
ctlrinit(Ether* ether)
{
Ctlr *ctlr;
Des *des;
ulong *des;
Block *bp;
int i;
uchar bi[Eaddrlen*2];
@ -584,23 +590,31 @@ ctlrinit(Ether* ether)
* 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 @@ ctlrinit(Ether* ether)
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");

View file

@ -48,7 +48,7 @@ link
# devi82365
cputemp pci
# ether2000 ether8390
# ether2114x pci
ether2114x pci
# ether589 etherelnk3
ether79c970 pci
# ether8003 ether8390