mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
Compare commits
8 commits
8b7a03c5e9
...
c4c1ce1093
Author | SHA1 | Date | |
---|---|---|---|
|
c4c1ce1093 | ||
|
d73932922b | ||
|
8c86e440c2 | ||
|
0336b2fad3 | ||
|
4730816fa4 | ||
|
511cd4dc31 | ||
|
09b5619466 | ||
|
3459c8cb8e |
32 changed files with 556 additions and 2019 deletions
|
@ -1401,13 +1401,17 @@ linkdown(Ctlr *ctl)
|
|||
return;
|
||||
ctl->status = Disconnected;
|
||||
ethersetlink(edev, 0);
|
||||
|
||||
/* send eof to aux/wpa */
|
||||
for(i = 0; i < edev->nfile; i++){
|
||||
f = edev->f[i];
|
||||
if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
|
||||
if(f == nil || !f->inuse || f->type != 0x888e || waserror())
|
||||
continue;
|
||||
qflush(f->in);
|
||||
qwrite(f->in, 0, 0);
|
||||
poperror();
|
||||
}
|
||||
qflush(edev->oq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -242,6 +242,8 @@ struct Ctlr
|
|||
Lock;
|
||||
u32int *regs;
|
||||
|
||||
Bpool pool[1];
|
||||
|
||||
Desc rd[256];
|
||||
Desc td[256];
|
||||
|
||||
|
@ -315,9 +317,10 @@ setdma(Desc *d, void *v)
|
|||
}
|
||||
|
||||
static void
|
||||
replenish(Desc *d)
|
||||
replenish(Ctlr *c, Desc *d)
|
||||
{
|
||||
d->b = allocb(Rbsz);
|
||||
while((d->b = iallocbp(c->pool)) == nil)
|
||||
resrcwait("out of genet rx buffers");
|
||||
dmaflush(1, d->b->rp, Rbsz);
|
||||
setdma(d, d->b->rp);
|
||||
}
|
||||
|
@ -355,7 +358,7 @@ recvproc(void *arg)
|
|||
b = d->b;
|
||||
dmaflush(0, b->rp, Rbsz);
|
||||
s = REG(d->d[0]);
|
||||
replenish(d);
|
||||
replenish(ctlr, d);
|
||||
coherence();
|
||||
ctlr->rx->rp = (ctlr->rx->rp + 1) & 0xFFFF;
|
||||
REG(ctlr->rx->regs[RxRP]) = ctlr->rx->rp;
|
||||
|
@ -503,15 +506,22 @@ allocbufs(Ctlr *ctlr)
|
|||
{
|
||||
int i;
|
||||
|
||||
if(ctlr->pool->size == 0){
|
||||
ctlr->pool->size = Rbsz;
|
||||
growbp(ctlr->pool, nelem(ctlr->rd)*4);
|
||||
}
|
||||
|
||||
if(scratch == nil){
|
||||
scratch = allocb(Rbsz);
|
||||
scratch = iallocbp(ctlr->pool);
|
||||
if(scratch == nil)
|
||||
error("out of rx buffers");
|
||||
memset(scratch->rp, 0xFF, Rbsz);
|
||||
dmaflush(1, scratch->rp, Rbsz);
|
||||
}
|
||||
|
||||
for(i = 0; i < nelem(ctlr->rd); i++){
|
||||
ctlr->rd[i].d = &ctlr->regs[RdmaOffset + i*3];
|
||||
replenish(&ctlr->rd[i]);
|
||||
replenish(ctlr, &ctlr->rd[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < nelem(ctlr->td); i++){
|
||||
|
|
|
@ -216,6 +216,8 @@ struct Ctlr
|
|||
u32int *regs;
|
||||
u32int intmask;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
struct {
|
||||
Block *b[256];
|
||||
Descr *d;
|
||||
|
@ -441,7 +443,9 @@ rxproc(void *arg)
|
|||
etheriq(edev, b);
|
||||
|
||||
/* replenish */
|
||||
b = allocb(R_BUF_SIZE);
|
||||
while((b = iallocbp(&ctlr->pool)) == nil)
|
||||
resrcwait("out of imx rx buffers");
|
||||
|
||||
ctlr->rx->b[i] = b;
|
||||
dmaflush(1, b->rp, R_BUF_SIZE);
|
||||
d->addr = PADDR(b->rp);
|
||||
|
@ -569,11 +573,23 @@ attach(Ether *edev)
|
|||
|
||||
if(ctlr->rx->d == nil)
|
||||
ctlr->rx->d = ucalloc(sizeof(Descr) * nelem(ctlr->rx->b));
|
||||
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = R_BUF_SIZE;
|
||||
ctlr->pool.align = BLOCKALIGN;
|
||||
growbp(&ctlr->pool, 4*nelem(ctlr->rx->b));
|
||||
}
|
||||
|
||||
for(i=0; i<nelem(ctlr->rx->b); i++){
|
||||
Block *b = allocb(R_BUF_SIZE);
|
||||
Block *b = ctlr->rx->b[i];
|
||||
if(b == nil){
|
||||
b = iallocbp(&ctlr->pool);
|
||||
if(b == nil)
|
||||
error("out of rx buffers");
|
||||
ctlr->rx->b[i] = b;
|
||||
d = &ctlr->rx->d[i];
|
||||
}
|
||||
dmaflush(1, b->rp, R_BUF_SIZE);
|
||||
d = &ctlr->rx->d[i];
|
||||
d->addr = PADDR(b->rp);
|
||||
d->status = RD_E;
|
||||
}
|
||||
|
|
|
@ -49,11 +49,6 @@ typedef struct Mibstats Mibstats;
|
|||
typedef struct Rx Rx;
|
||||
typedef struct Tx Tx;
|
||||
|
||||
static struct {
|
||||
Lock;
|
||||
Block *head;
|
||||
} freeblocks;
|
||||
|
||||
/* hardware receive buffer descriptor */
|
||||
struct Rx {
|
||||
ulong cs;
|
||||
|
@ -129,6 +124,8 @@ struct Ctlr {
|
|||
Lock initlock;
|
||||
int init;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
Rx *rx; /* receive descriptors */
|
||||
Block *rxb[Nrx]; /* blocks belonging to the descriptors */
|
||||
int rxhead; /* descr ethernet will write to next */
|
||||
|
@ -514,36 +511,6 @@ static uchar zeroea[Eaddrlen];
|
|||
|
||||
static void getmibstats(Ctlr *);
|
||||
|
||||
static void
|
||||
rxfreeb(Block *b)
|
||||
{
|
||||
b->wp = b->rp =
|
||||
(uchar*)((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1));
|
||||
assert(((uintptr)b->rp & (Bufalign - 1)) == 0);
|
||||
b->free = rxfreeb;
|
||||
|
||||
ilock(&freeblocks);
|
||||
b->next = freeblocks.head;
|
||||
freeblocks.head = b;
|
||||
iunlock(&freeblocks);
|
||||
}
|
||||
|
||||
static Block *
|
||||
rxallocb(void)
|
||||
{
|
||||
Block *b;
|
||||
|
||||
ilock(&freeblocks);
|
||||
b = freeblocks.head;
|
||||
if(b != nil) {
|
||||
freeblocks.head = b->next;
|
||||
b->next = nil;
|
||||
b->free = rxfreeb;
|
||||
}
|
||||
iunlock(&freeblocks);
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
rxkick(Ctlr *ctlr)
|
||||
{
|
||||
|
@ -575,12 +542,9 @@ rxreplenish(Ctlr *ctlr)
|
|||
Block *b;
|
||||
|
||||
while(ctlr->rxb[ctlr->rxtail] == nil) {
|
||||
b = rxallocb();
|
||||
if(b == nil) {
|
||||
iprint("#l%d: rxreplenish out of buffers\n",
|
||||
ctlr->ether->ctlrno);
|
||||
b = iallocbp(&ctlr->pool);
|
||||
if(b == nil)
|
||||
break;
|
||||
}
|
||||
|
||||
ctlr->rxb[ctlr->rxtail] = b;
|
||||
|
||||
|
@ -1437,26 +1401,9 @@ static void
|
|||
ctlralloc(Ctlr *ctlr)
|
||||
{
|
||||
int i;
|
||||
Block *b;
|
||||
Rx *r;
|
||||
Tx *t;
|
||||
|
||||
ilock(&freeblocks);
|
||||
for(i = 0; i < Nrxblks; i++) {
|
||||
b = iallocb(Rxblklen+Bufalign-1);
|
||||
if(b == nil) {
|
||||
iprint("ether1116: no memory for rx buffers\n");
|
||||
break;
|
||||
}
|
||||
b->wp = b->rp = (uchar*)
|
||||
((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1));
|
||||
assert(((uintptr)b->rp & (Bufalign - 1)) == 0);
|
||||
b->free = rxfreeb;
|
||||
b->next = freeblocks.head;
|
||||
freeblocks.head = b;
|
||||
}
|
||||
iunlock(&freeblocks);
|
||||
|
||||
/*
|
||||
* allocate uncached rx ring descriptors because rings are shared
|
||||
* with the ethernet controller and more than one fits in a cache line.
|
||||
|
@ -1473,6 +1420,12 @@ ctlralloc(Ctlr *ctlr)
|
|||
ctlr->rxb[i] = nil;
|
||||
}
|
||||
ctlr->rxtail = ctlr->rxhead = 0;
|
||||
|
||||
/* allocate private buffer pool */
|
||||
ctlr->pool.size = Rxblklen;
|
||||
ctlr->pool.align = Bufalign;
|
||||
growbp(&ctlr->pool, Nrx*4);
|
||||
|
||||
rxreplenish(ctlr);
|
||||
|
||||
/* allocate uncached tx ring descriptors */
|
||||
|
|
|
@ -306,6 +306,8 @@ typedef struct Ctlr {
|
|||
int rdt; /* tail - consumer index (host) */
|
||||
int nrq;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
int tcr; /* transmit configuration register */
|
||||
int rcr; /* receive configuration register */
|
||||
int imr;
|
||||
|
@ -646,11 +648,9 @@ rtl8169replenish(Ctlr* ctlr)
|
|||
|
||||
x = ctlr->rdt;
|
||||
while(NEXT(x, ctlr->nrd) != ctlr->rdh){
|
||||
bp = iallocb(Mps);
|
||||
if(bp == nil){
|
||||
iprint("rtl8169: no available buffers\n");
|
||||
bp = iallocbp(&ctlr->pool);
|
||||
if(bp == nil)
|
||||
break;
|
||||
}
|
||||
ctlr->rb[x] = bp;
|
||||
ctlr->nrq++;
|
||||
pa = PCIWADDR(bp->rp);
|
||||
|
@ -698,7 +698,10 @@ rtl8169init(Ether* edev)
|
|||
ctlr->rb[i] = nil;
|
||||
freeb(bp);
|
||||
}
|
||||
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = Mps;
|
||||
growbp(&ctlr->pool, ctlr->nrd*4);
|
||||
}
|
||||
rtl8169replenish(ctlr);
|
||||
|
||||
cplusc = csr16r(ctlr, Cplusc);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -518,6 +518,8 @@ struct Ctlr {
|
|||
int ntd;
|
||||
int rbsz;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
u32int *nic;
|
||||
Lock imlock;
|
||||
int im; /* interrupt mask */
|
||||
|
@ -907,24 +909,25 @@ static void
|
|||
i82563replenish(Ctlr *ctlr)
|
||||
{
|
||||
uint rdt, i;
|
||||
uvlong pa;
|
||||
Block *bp;
|
||||
Rd *rd;
|
||||
|
||||
i = 0;
|
||||
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("#l%d: %s: tx overrun\n", ctlr->edev->ctlrno, cname(ctlr));
|
||||
if(ctlr->rb[rdt] != nil)
|
||||
break;
|
||||
bp = iallocbp(&ctlr->pool);
|
||||
if(bp == nil)
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
bp = allocb(ctlr->rbsz + Rbalign);
|
||||
bp->rp = bp->wp = (uchar*)ROUND((uintptr)bp->base, Rbalign);
|
||||
ctlr->rb[rdt] = bp;
|
||||
rd->addr[0] = PCIWADDR(bp->rp);
|
||||
rd->addr[1] = 0;
|
||||
pa = PCIWADDR(bp->rp);
|
||||
rd->addr[0] = pa;
|
||||
rd->addr[1] = pa>>32;
|
||||
rd->status = 0;
|
||||
ctlr->rdfree++;
|
||||
i++;
|
||||
}
|
||||
if(i != 0){
|
||||
coherence();
|
||||
|
@ -977,6 +980,13 @@ i82563rxinit(Ctlr *ctlr)
|
|||
ctlr->rb[i] = nil;
|
||||
freeb(bp);
|
||||
}
|
||||
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = ctlr->rbsz;
|
||||
ctlr->pool.align = Rbalign;
|
||||
growbp(&ctlr->pool, Nrb);
|
||||
}
|
||||
|
||||
if(cttab[ctlr->type].flag & F75)
|
||||
csr32w(ctlr, Rxdctl, 1<<WthreshSHIFT | 8<<PthreshSHIFT | 1<<HthreshSHIFT | Enable);
|
||||
else
|
||||
|
@ -1007,6 +1017,7 @@ i82563rproc(void *arg)
|
|||
ctlr = edev->ctlr;
|
||||
|
||||
i82563rxinit(ctlr);
|
||||
|
||||
csr32w(ctlr, Rctl, csr32r(ctlr, Rctl) | Ren);
|
||||
if(cttab[ctlr->type].flag & F75){
|
||||
csr32w(ctlr, Rxdctl, csr32r(ctlr, Rxdctl) | Enable);
|
||||
|
|
|
@ -362,6 +362,8 @@ typedef struct Ctlr {
|
|||
|
||||
Mii* mii;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
Lock rdlock; /* receive */
|
||||
Desc* rd;
|
||||
int nrd;
|
||||
|
@ -395,9 +397,6 @@ typedef struct Ctlr {
|
|||
static Ctlr* dp83820ctlrhead;
|
||||
static Ctlr* dp83820ctlrtail;
|
||||
|
||||
static Lock dp83820rblock; /* free receive Blocks */
|
||||
static Block* dp83820rbpool;
|
||||
|
||||
static char* dp83820mibs[Nmibd] = {
|
||||
"RXErroredPkts",
|
||||
"RXFCSErrors",
|
||||
|
@ -497,30 +496,20 @@ dp83820miimiw(Mii* mii, int pa, int ra, int data)
|
|||
}
|
||||
|
||||
static Block *
|
||||
dp83820rballoc(Desc* desc)
|
||||
dp83820rballoc(Ctlr *ctlr, Desc* desc)
|
||||
{
|
||||
Block *bp;
|
||||
|
||||
bp = desc->bp;
|
||||
if(bp == nil){
|
||||
desc->bp = iallocbp(&ctlr->pool);
|
||||
if(desc->bp == nil){
|
||||
ilock(&dp83820rblock);
|
||||
if((bp = dp83820rbpool) == nil){
|
||||
iunlock(&dp83820rblock);
|
||||
desc->bp = nil;
|
||||
desc->cmdsts = Own;
|
||||
return nil;
|
||||
}
|
||||
dp83820rbpool = bp->next;
|
||||
bp->next = nil;
|
||||
iunlock(&dp83820rblock);
|
||||
|
||||
desc->bufptr = PCIWADDR(bp->rp);
|
||||
desc->bp = bp;
|
||||
}
|
||||
else{
|
||||
bp = desc->bp;
|
||||
bp->rp = bp->lim - Rbsz;
|
||||
bp->wp = bp->rp;
|
||||
}
|
||||
|
||||
coherence();
|
||||
desc->cmdsts = Intr|Rbsz;
|
||||
|
@ -528,18 +517,6 @@ dp83820rballoc(Desc* desc)
|
|||
return bp;
|
||||
}
|
||||
|
||||
static void
|
||||
dp83820rbfree(Block *bp)
|
||||
{
|
||||
bp->rp = bp->lim - Rbsz;
|
||||
bp->wp = bp->rp;
|
||||
|
||||
ilock(&dp83820rblock);
|
||||
bp->next = dp83820rbpool;
|
||||
dp83820rbpool = bp;
|
||||
iunlock(&dp83820rblock);
|
||||
}
|
||||
|
||||
static void
|
||||
dp83820halt(Ctlr* ctlr)
|
||||
{
|
||||
|
@ -635,6 +612,11 @@ dp83820init(Ether* edev)
|
|||
|
||||
dp83820halt(ctlr);
|
||||
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = Rbsz;
|
||||
growbp(&ctlr->pool, ctlr->nrb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receiver
|
||||
*/
|
||||
|
@ -646,7 +628,7 @@ dp83820init(Ether* edev)
|
|||
for(i = 0; i < ctlr->nrd; i++){
|
||||
desc = &ctlr->rd[i];
|
||||
desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
|
||||
if(dp83820rballoc(desc) == nil)
|
||||
if(dp83820rballoc(ctlr, desc) == nil)
|
||||
continue;
|
||||
}
|
||||
csr32w(ctlr, Rxdphi, 0);
|
||||
|
@ -698,7 +680,6 @@ dp83820init(Ether* edev)
|
|||
static void
|
||||
dp83820attach(Ether* edev)
|
||||
{
|
||||
Block *bp;
|
||||
Ctlr *ctlr;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
|
@ -739,14 +720,6 @@ dp83820attach(Ether* edev)
|
|||
ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
|
||||
if(ctlr->alloc == nil)
|
||||
error(Enomem);
|
||||
|
||||
for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
|
||||
if((bp = allocb(Rbsz)) == nil)
|
||||
break;
|
||||
bp->free = dp83820rbfree;
|
||||
dp83820rbfree(bp);
|
||||
}
|
||||
|
||||
dp83820init(edev);
|
||||
|
||||
qunlock(&ctlr->alock);
|
||||
|
@ -848,7 +821,7 @@ dp83820interrupt(Ureg*, void* arg)
|
|||
iprint(" %2.2uX", bp->rp[i]);
|
||||
iprint("\n");
|
||||
}
|
||||
dp83820rballoc(desc);
|
||||
dp83820rballoc(ctlr, desc);
|
||||
|
||||
x = NEXT(x, ctlr->nrd);
|
||||
desc = &ctlr->rd[x];
|
||||
|
|
|
@ -492,6 +492,8 @@ typedef struct Ctlr {
|
|||
uchar ra[Eaddrlen]; /* receive address */
|
||||
ulong mta[128]; /* multicast table array */
|
||||
|
||||
Bpool pool;
|
||||
|
||||
Rendez rrendez;
|
||||
int rim;
|
||||
int rdfree;
|
||||
|
@ -858,6 +860,7 @@ igbetxinit(Ctlr* ctlr)
|
|||
{
|
||||
int i, r;
|
||||
Block *bp;
|
||||
uvlong pa;
|
||||
|
||||
csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
|
||||
switch(ctlr->id){
|
||||
|
@ -887,8 +890,9 @@ igbetxinit(Ctlr* ctlr)
|
|||
csr32w(ctlr, Ait, 0);
|
||||
csr32w(ctlr, Txdmac, 0);
|
||||
|
||||
csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
|
||||
csr32w(ctlr, Tdbah, 0);
|
||||
pa = PCIWADDR(ctlr->tdba);
|
||||
csr32w(ctlr, Tdbal, pa);
|
||||
csr32w(ctlr, Tdbah, pa >> 32);
|
||||
csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
|
||||
ctlr->tdh = PREV(0, ctlr->ntd);
|
||||
csr32w(ctlr, Tdh, 0);
|
||||
|
@ -942,6 +946,7 @@ igbetransmit(Ether* edev)
|
|||
Block *bp;
|
||||
Ctlr *ctlr;
|
||||
int tdh, tdt;
|
||||
uvlong pa;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
|
||||
|
@ -969,7 +974,9 @@ igbetransmit(Ether* edev)
|
|||
if((bp = qget(edev->oq)) == nil)
|
||||
break;
|
||||
td = &ctlr->tdba[tdt];
|
||||
td->addr[0] = PCIWADDR(bp->rp);
|
||||
pa = PCIWADDR(bp->rp);
|
||||
td->addr[0] = pa;
|
||||
td->addr[1] = pa >> 32;
|
||||
td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
|
||||
td->control |= Dext|Ifcs|Teop|DtypeDD;
|
||||
ctlr->tb[tdt] = bp;
|
||||
|
@ -995,17 +1002,19 @@ igbereplenish(Ctlr* ctlr)
|
|||
Rd *rd;
|
||||
int rdt;
|
||||
Block *bp;
|
||||
uvlong pa;
|
||||
|
||||
rdt = ctlr->rdt;
|
||||
while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
|
||||
rd = &ctlr->rdba[rdt];
|
||||
if(ctlr->rb[rdt] == nil){
|
||||
bp = allocb(Rbsz);
|
||||
bp->rp = bp->lim - Rbsz;
|
||||
bp->wp = bp->rp;
|
||||
bp = iallocbp(&ctlr->pool);
|
||||
if(bp == nil)
|
||||
break;
|
||||
ctlr->rb[rdt] = bp;
|
||||
rd->addr[0] = PCIWADDR(bp->rp);
|
||||
rd->addr[1] = 0;
|
||||
pa = PCIWADDR(bp->rp);
|
||||
rd->addr[0] = pa;
|
||||
rd->addr[1] = pa >> 32;
|
||||
}
|
||||
coherence();
|
||||
rd->status = 0;
|
||||
|
@ -1021,12 +1030,14 @@ igberxinit(Ctlr* ctlr)
|
|||
{
|
||||
int i;
|
||||
Block *bp;
|
||||
uvlong pa;
|
||||
|
||||
/* temporarily keep Mpe on */
|
||||
csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
|
||||
|
||||
csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
|
||||
csr32w(ctlr, Rdbah, 0);
|
||||
pa = PCIWADDR(ctlr->rdba);
|
||||
csr32w(ctlr, Rdbal, pa);
|
||||
csr32w(ctlr, Rdbah, pa >> 32);
|
||||
csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
|
||||
ctlr->rdh = 0;
|
||||
csr32w(ctlr, Rdh, 0);
|
||||
|
@ -1041,6 +1052,10 @@ igberxinit(Ctlr* ctlr)
|
|||
freeb(bp);
|
||||
}
|
||||
}
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = Rbsz;
|
||||
growbp(&ctlr->pool, Nrb);
|
||||
}
|
||||
igbereplenish(ctlr);
|
||||
|
||||
switch(ctlr->id){
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#define pcicapdbg(...)
|
||||
#define malign(n) mallocalign((n), 4*KiB, 0, 0)
|
||||
|
||||
#include "etherm10g2k.i"
|
||||
#include "etherm10g4k.i"
|
||||
#include "../pc/etherm10g2k.i"
|
||||
#include "../pc/etherm10g4k.i"
|
||||
|
||||
static int debug = 0;
|
||||
static char Etimeout[] = "timeout";
|
||||
|
@ -137,18 +137,8 @@ typedef struct {
|
|||
} Tx;
|
||||
|
||||
typedef struct {
|
||||
Lock;
|
||||
Block *head;
|
||||
uint size; /* buffer size of each block */
|
||||
uint n; /* n free buffers */
|
||||
uint cnt;
|
||||
} Bpool;
|
||||
Bpool pool;
|
||||
|
||||
static Bpool smpool = { .size = 128, };
|
||||
static Bpool bgpool = { .size = Maxmtu, };
|
||||
|
||||
typedef struct {
|
||||
Bpool *pool; /* free buffers */
|
||||
ulong *lanai; /* rx ring; we have no permanent host shadow */
|
||||
Block **host; /* called "info" in myricom driver */
|
||||
// uchar *wcfifo; /* cmd submission fifo */
|
||||
|
@ -253,51 +243,6 @@ enum {
|
|||
PcieMRD = 0x7000, /* maximum read size */
|
||||
};
|
||||
|
||||
static int
|
||||
pcicap(Pcidev *p, int cap)
|
||||
{
|
||||
int i, c, off;
|
||||
|
||||
pcicapdbg("pcicap: %x:%d\n", p->vid, p->did);
|
||||
off = 0x34; /* 0x14 for cardbus */
|
||||
for(i = 48; i--; ){
|
||||
pcicapdbg("\t" "loop %x\n", off);
|
||||
off = pcicfgr8(p, off);
|
||||
pcicapdbg("\t" "pcicfgr8 %x\n", off);
|
||||
if(off < 0x40)
|
||||
break;
|
||||
off &= ~3;
|
||||
c = pcicfgr8(p, off);
|
||||
pcicapdbg("\t" "pcicfgr8 %x\n", c);
|
||||
if(c == 0xff)
|
||||
break;
|
||||
if(c == cap)
|
||||
return off;
|
||||
off++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function doesn't work because pcicgr32 doesn't have access
|
||||
* to the pcie extended configuration space.
|
||||
*/
|
||||
static int
|
||||
pciecap(Pcidev *p, int cap)
|
||||
{
|
||||
uint off, i;
|
||||
|
||||
off = 0x100;
|
||||
while(((i = pcicfgr32(p, off)) & 0xffff) != cap){
|
||||
off = i >> 20;
|
||||
print("m10g: pciecap offset = %ud", off);
|
||||
if(off < 0x100 || off >= 4*KiB - 1)
|
||||
return 0;
|
||||
}
|
||||
print("m10g: pciecap found = %ud", off);
|
||||
return off;
|
||||
}
|
||||
|
||||
static int
|
||||
setpcie(Pcidev *p)
|
||||
{
|
||||
|
@ -328,7 +273,7 @@ whichfw(Pcidev *p)
|
|||
lanes = (cap>>4) & 0x3f;
|
||||
|
||||
/* check AERC register. we need it on. */
|
||||
off = pciecap(p, PcieAERC);
|
||||
off = pcicap(p, PcieAERC);
|
||||
print("; offset %d returned\n", off);
|
||||
cap = 0;
|
||||
if(off != 0){
|
||||
|
@ -486,7 +431,6 @@ cmd(Ctlr *c, int type, uvlong data)
|
|||
iprint("m10g: cmd timeout [%ux %ux] cmd=%d\n",
|
||||
cmd->i[0], cmd->i[1], type);
|
||||
error(Etimeout);
|
||||
return ~0; /* silence! */
|
||||
}
|
||||
|
||||
ulong
|
||||
|
@ -525,7 +469,6 @@ maccmd(Ctlr *c, int type, uchar *m)
|
|||
iprint("m10g: maccmd timeout [%ux %ux] cmd=%d\n",
|
||||
cmd->i[0], cmd->i[1], type);
|
||||
error(Etimeout);
|
||||
return ~0; /* silence! */
|
||||
}
|
||||
|
||||
/* remove this garbage after testing */
|
||||
|
@ -564,7 +507,6 @@ dmatestcmd(Ctlr *c, int type, uvlong addr, int len)
|
|||
tsleep(&up->sleep, return0, 0, 5);
|
||||
}
|
||||
error(Etimeout);
|
||||
return ~0; /* silence! */
|
||||
}
|
||||
|
||||
ulong
|
||||
|
@ -594,8 +536,6 @@ rdmacmd(Ctlr *c, int on)
|
|||
tsleep(&up->sleep, return0, 0, 1);
|
||||
}
|
||||
error(Etimeout);
|
||||
iprint("m10g: rdmacmd timeout\n");
|
||||
return ~0; /* silence! */
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -741,7 +681,6 @@ reset(Ether *e, Ctlr *c)
|
|||
if(waserror()){
|
||||
print("m10g: reset error\n");
|
||||
nexterror();
|
||||
return -1;
|
||||
}
|
||||
|
||||
chkfw(c);
|
||||
|
@ -811,7 +750,7 @@ setmem(Pcidev *p, Ctlr *c)
|
|||
print("m10g: can't map %llux\n", raddr);
|
||||
return -1;
|
||||
}
|
||||
dprint("%llux <- vmap(mem[0].size = %d)\n", raddr, p->mem[0].size);
|
||||
dprint("%llux <- vmap(mem[0].size = %llud)\n", raddr, p->mem[0].size);
|
||||
c->port = raddr;
|
||||
c->ram = mem;
|
||||
c->cmd = malign(sizeof *c->cmd);
|
||||
|
@ -836,81 +775,35 @@ setmem(Pcidev *p, Ctlr *c)
|
|||
static Rx*
|
||||
whichrx(Ctlr *c, int sz)
|
||||
{
|
||||
if(sz <= smpool.size)
|
||||
if(sz <= c->sm.pool.size)
|
||||
return &c->sm;
|
||||
return &c->bg;
|
||||
}
|
||||
|
||||
static Block*
|
||||
balloc(Rx* rx)
|
||||
{
|
||||
Block *bp;
|
||||
|
||||
ilock(rx->pool);
|
||||
if((bp = rx->pool->head) != nil){
|
||||
rx->pool->head = bp->next;
|
||||
bp->next = nil;
|
||||
rx->pool->n--;
|
||||
}
|
||||
iunlock(rx->pool);
|
||||
return bp;
|
||||
}
|
||||
|
||||
static void
|
||||
rbfree(Block *b, Bpool *p)
|
||||
{
|
||||
b->rp = b->wp = (uchar*)PGROUND((uintptr)b->base);
|
||||
b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
|
||||
|
||||
ilock(p);
|
||||
b->next = p->head;
|
||||
p->head = b;
|
||||
p->n++;
|
||||
p->cnt++;
|
||||
iunlock(p);
|
||||
}
|
||||
|
||||
static void
|
||||
smbfree(Block *b)
|
||||
{
|
||||
rbfree(b, &smpool);
|
||||
}
|
||||
|
||||
static void
|
||||
bgbfree(Block *b)
|
||||
{
|
||||
rbfree(b, &bgpool);
|
||||
}
|
||||
|
||||
static void
|
||||
replenish(Rx *rx)
|
||||
{
|
||||
ulong buf[16], i, idx, e;
|
||||
Bpool *p;
|
||||
uvlong pa;
|
||||
Block *b;
|
||||
|
||||
p = rx->pool;
|
||||
if(p->n < 8)
|
||||
return;
|
||||
memset(buf, 0, sizeof buf);
|
||||
e = (rx->i - rx->cnt) & ~7;
|
||||
e += rx->n;
|
||||
while(p->n >= 8 && e){
|
||||
while(e){
|
||||
idx = rx->cnt & rx->m;
|
||||
for(i = 0; i < 8; i++){
|
||||
b = balloc(rx);
|
||||
buf[i*2] = pbit32((uvlong)PCIWADDR(b->wp) >> 32);
|
||||
buf[i*2+1] = pbit32(PCIWADDR(b->wp));
|
||||
while((b = iallocbp(&rx->pool)) == nil)
|
||||
resrcwait("out of m10g rx buffers");
|
||||
pa = PCIWADDR(b->wp);
|
||||
buf[i*2+0] = pbit32(pa >> 32);
|
||||
buf[i*2+1] = pbit32(pa);
|
||||
rx->host[idx+i] = b;
|
||||
assert(b);
|
||||
}
|
||||
memmove(rx->lanai + 2*idx, buf, sizeof buf);
|
||||
memmove(rx->lanai + 2*idx, buf, sizeof(buf));
|
||||
coherence();
|
||||
rx->cnt += 8;
|
||||
e -= 8;
|
||||
}
|
||||
if(e && p->n > 7+1)
|
||||
print("m10g: should panic? pool->n = %d", p->n);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -947,8 +840,7 @@ emalign(int sz)
|
|||
static void
|
||||
open0(Ether *e, Ctlr *c)
|
||||
{
|
||||
Block *b;
|
||||
int i, sz, entries;
|
||||
int entries;
|
||||
|
||||
entries = cmd(c, CGsendrgsz, 0) / sizeof *c->tx.lanai;
|
||||
c->tx.lanai = (Send*)(c->ram + cmd(c, CGsendoff, 0));
|
||||
|
@ -958,35 +850,24 @@ open0(Ether *e, Ctlr *c)
|
|||
c->tx.m = entries-1;
|
||||
|
||||
entries = cmd(c, CGrxrgsz, 0)/8;
|
||||
c->sm.pool = &smpool;
|
||||
cmd(c, CSsmallsz, c->sm.pool->size);
|
||||
c->sm.pool.size = 128;
|
||||
c->sm.pool.align = BY2PG;
|
||||
cmd(c, CSsmallsz, c->sm.pool.size);
|
||||
c->sm.lanai = (ulong*)(c->ram + cmd(c, CGsmallrxoff, 0));
|
||||
c->sm.n = entries;
|
||||
c->sm.m = entries-1;
|
||||
c->sm.host = emalign(entries * sizeof *c->sm.host);
|
||||
|
||||
c->bg.pool = &bgpool;
|
||||
c->bg.pool->size = nextpow(2 + e->maxmtu); /* 2-byte alignment pad */
|
||||
cmd(c, CSbigsz, c->bg.pool->size);
|
||||
c->bg.pool.size = nextpow(2 + e->maxmtu); /* 2-byte alignment pad */
|
||||
c->bg.pool.align = BY2PG;
|
||||
cmd(c, CSbigsz, c->bg.pool.size);
|
||||
c->bg.lanai = (ulong*)(c->ram + cmd(c, CGbigrxoff, 0));
|
||||
c->bg.n = entries;
|
||||
c->bg.m = entries-1;
|
||||
c->bg.host = emalign(entries * sizeof *c->bg.host);
|
||||
|
||||
sz = c->sm.pool->size + BY2PG;
|
||||
for(i = 0; i < c->sm.n; i++){
|
||||
if((b = allocb(sz)) == 0)
|
||||
break;
|
||||
b->free = smbfree;
|
||||
freeb(b);
|
||||
}
|
||||
sz = c->bg.pool->size + BY2PG;
|
||||
for(i = 0; i < c->bg.n; i++){
|
||||
if((b = allocb(sz)) == 0)
|
||||
break;
|
||||
b->free = bgbfree;
|
||||
freeb(b);
|
||||
}
|
||||
growbp(&c->sm.pool, c->sm.n);
|
||||
growbp(&c->bg.pool, c->bg.n);
|
||||
|
||||
cmd(c, CSstatsdma, c->statsprt);
|
||||
c->linkstat = ~0;
|
||||
|
@ -1332,17 +1213,6 @@ m10gdetach(Ctlr *c)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
lstcount(Block *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for(; b; b = b->next)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static char*
|
||||
m10gifstat(void *arg, char *p, char *e)
|
||||
{
|
||||
|
@ -1364,9 +1234,7 @@ m10gifstat(void *arg, char *p, char *e)
|
|||
"tx pkt = %lud\n" "tx bytes = %lld\n"
|
||||
"tx cnt = %ud\n" "tx n = %ud\n" "tx i = %ud\n"
|
||||
"sm cnt = %ud\n" "sm i = %ud\n" "sm n = %ud\n"
|
||||
"sm lst = %ud\n"
|
||||
"bg cnt = %ud\n" "bg i = %ud\n" "bg n = %ud\n"
|
||||
"bg lst = %ud\n"
|
||||
"segsz = %lud\n" "coal = %lud\n",
|
||||
gbit32(s.txcnt), gbit32(s.linkstat), gbit32(s.dlink),
|
||||
gbit32(s.derror), gbit32(s.drunt), gbit32(s.doverrun),
|
||||
|
@ -1374,8 +1242,8 @@ m10gifstat(void *arg, char *p, char *e)
|
|||
s.txstopped, s.down, s.updated, s.valid,
|
||||
c->tx.npkt, c->tx.nbytes,
|
||||
c->tx.cnt, c->tx.n, c->tx.i,
|
||||
c->sm.cnt, c->sm.i, c->sm.pool->n, lstcount(c->sm.pool->head),
|
||||
c->bg.cnt, c->bg.i, c->bg.pool->n, lstcount(c->bg.pool->head),
|
||||
c->sm.cnt, c->sm.i, c->sm.n,
|
||||
c->bg.cnt, c->bg.i, c->bg.n,
|
||||
c->tx.segsz, gbit32((uchar*)c->coal));
|
||||
}
|
||||
|
||||
|
@ -1595,9 +1463,7 @@ m10gpnp(Ether *e)
|
|||
|
||||
e->attach = m10gattach;
|
||||
e->transmit = m10gtransmit;
|
||||
e->interrupt = m10ginterrupt;
|
||||
e->ctl = m10gctl;
|
||||
// e->power = m10gpower;
|
||||
e->shutdown = m10gshutdown;
|
||||
|
||||
e->arg = e;
|
||||
|
@ -1605,6 +1471,8 @@ m10gpnp(Ether *e)
|
|||
e->promiscuous = m10gpromiscuous;
|
||||
e->multicast = m10gmulticast;
|
||||
|
||||
intrenable(e->irq, m10ginterrupt, e, e->tbdf, e->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -335,6 +335,8 @@ struct Ctlr
|
|||
uchar maddrs[32][Eaddrlen];
|
||||
uint camidx;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
RxDesc* rx_ring;
|
||||
Block* rx_blocks[RxCount];
|
||||
|
||||
|
@ -531,7 +533,7 @@ vgbenewrx(Ctlr* ctlr, int i)
|
|||
Block* block;
|
||||
RxDesc* desc;
|
||||
|
||||
block = iallocb(RxSize);
|
||||
block = iallocbp(&ctlr->pool);
|
||||
if(block == nil)
|
||||
return -1;
|
||||
|
||||
|
@ -659,6 +661,25 @@ vgbetxeof(Ether* edev)
|
|||
wiob(ctlr, TxCsrS, TxCsr_Wakeup);
|
||||
}
|
||||
|
||||
static void
|
||||
vgbelink(Ether *edev)
|
||||
{
|
||||
Ctlr *ctlr;
|
||||
uchar status;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
status = riob(ctlr, PhySts0);
|
||||
|
||||
if(status & PhySts_Speed1000)
|
||||
ethersetspeed(edev, 1000);
|
||||
else if(status & PhySts_Speed10)
|
||||
ethersetspeed(edev, 10);
|
||||
else
|
||||
ethersetspeed(edev, 100);
|
||||
|
||||
ethersetlink(edev, status & PhySts_Link);
|
||||
}
|
||||
|
||||
static void
|
||||
vgbeinterrupt(Ureg *, void* arg)
|
||||
{
|
||||
|
@ -713,7 +734,7 @@ vgbeinterrupt(Ureg *, void* arg)
|
|||
print("vgbe: irq: PHY interrupt\n");
|
||||
|
||||
if(status & Isr_LinkStatus){
|
||||
ethersetlink(edev, riob(ctlr, PhySts0) & PhySts_Link);
|
||||
vgbelink(edev);
|
||||
vgbemiip(ctlr, 1);
|
||||
}
|
||||
if(status & Isr_RxNoDesc)
|
||||
|
@ -835,6 +856,9 @@ vgbeattach(Ether* edev)
|
|||
ctlr->rx_ring = rxdesc;
|
||||
ctlr->tx_ring = txdesc;
|
||||
|
||||
ctlr->pool.size = RxSize;
|
||||
growbp(&ctlr->pool, RxCount*4);
|
||||
|
||||
/* Allocate Rx blocks, initialize Rx ring. */
|
||||
for(i = 0; i < RxCount; i++)
|
||||
vgbenewrx(ctlr, i);
|
||||
|
@ -1258,8 +1282,6 @@ vgbepnp(Ether* edev)
|
|||
edev->port = ctlr->port;
|
||||
edev->irq = ctlr->pdev->intl;
|
||||
edev->tbdf = ctlr->pdev->tbdf;
|
||||
edev->mbps = 1000;
|
||||
edev->link = (riob(ctlr, PhySts0) & PhySts_Link) ? 1 : 0;
|
||||
memmove(edev->ea, ctlr->ea, Eaddrlen);
|
||||
edev->attach = vgbeattach;
|
||||
edev->transmit = vgbetransmit;
|
||||
|
@ -1270,6 +1292,8 @@ vgbepnp(Ether* edev)
|
|||
edev->ctl = vgbectl;
|
||||
edev->arg = edev;
|
||||
|
||||
vgbelink(edev);
|
||||
|
||||
intrenable(edev->irq, vgbeinterrupt, edev, edev->tbdf, edev->name);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -156,6 +156,8 @@ struct Ctlr {
|
|||
ulong feat;
|
||||
int nqueue;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
/* virtioether has 3 queues: rx, tx and ctl */
|
||||
Vqueue queue[3];
|
||||
};
|
||||
|
@ -275,6 +277,9 @@ rxproc(void *v)
|
|||
header = smalloc(VheaderSize);
|
||||
blocks = smalloc(sizeof(Block*) * (q->qsize/2));
|
||||
|
||||
ctlr->pool.size = ETHERMAXTU;
|
||||
growbp(&ctlr->pool, q->qsize*2);
|
||||
|
||||
for(i = 0; i < q->qsize/2; i++){
|
||||
j = i << 1;
|
||||
q->desc[j].addr = PADDR(header);
|
||||
|
@ -300,7 +305,7 @@ rxproc(void *v)
|
|||
i = q->avail->idx & (q->qmask >> 1);
|
||||
if(blocks[i] != nil)
|
||||
break;
|
||||
if((b = iallocb(ETHERMAXTU)) == nil)
|
||||
if((b = iallocbp(&ctlr->pool)) == nil)
|
||||
break;
|
||||
blocks[i] = b;
|
||||
j = (i << 1) | 1;
|
||||
|
|
|
@ -308,6 +308,8 @@ typedef struct Ctlr {
|
|||
int nrd;
|
||||
int ntd;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
Ds* rd;
|
||||
Ds* rdh;
|
||||
|
||||
|
@ -359,10 +361,6 @@ static Ctlr* vt6105Mctlrtail;
|
|||
#define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w)))
|
||||
#define csr32w(c, r, w) (outl((c)->port+(r), (ulong)(w)))
|
||||
|
||||
static Lock vt6105Mrblock; /* receive Block freelist */
|
||||
static Block* vt6105Mrbpool;
|
||||
static uint vt6105Mrbpoolsz;
|
||||
|
||||
typedef struct Regs Regs;
|
||||
typedef struct Regs {
|
||||
char* name;
|
||||
|
@ -472,7 +470,6 @@ vt6105Mifstat(void *arg, char *p, char *e)
|
|||
p = seprint(p, e, "tuok: %ud\n", ctlr->tuok);
|
||||
p = seprint(p, e, "ipok: %ud\n", ctlr->ipok);
|
||||
|
||||
p = seprint(p, e, "rbpoolsz: %ud\n", vt6105Mrbpoolsz);
|
||||
p = seprint(p, e, "totalt: %uld\n", ctlr->totalt);
|
||||
|
||||
for(i = 0; regs[i].name != nil; i++){
|
||||
|
@ -574,38 +571,6 @@ enable:
|
|||
pexit("vt6105Mlproc: done", 1);
|
||||
}
|
||||
|
||||
static void
|
||||
vt6105Mrbfree(Block* bp)
|
||||
{
|
||||
bp->rp = bp->lim - (Rdbsz+3);
|
||||
bp->wp = bp->rp;
|
||||
bp->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
|
||||
|
||||
ilock(&vt6105Mrblock);
|
||||
bp->next = vt6105Mrbpool;
|
||||
vt6105Mrbpool = bp;
|
||||
iunlock(&vt6105Mrblock);
|
||||
}
|
||||
|
||||
static Block*
|
||||
vt6105Mrballoc(void)
|
||||
{
|
||||
Block *bp;
|
||||
|
||||
ilock(&vt6105Mrblock);
|
||||
if((bp = vt6105Mrbpool) != nil){
|
||||
vt6105Mrbpool = bp->next;
|
||||
bp->next = nil;
|
||||
}
|
||||
iunlock(&vt6105Mrblock);
|
||||
|
||||
if(bp == nil && (bp = iallocb(Rdbsz+3)) != nil){
|
||||
bp->free = vt6105Mrbfree;
|
||||
vt6105Mrbpoolsz++;
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
|
||||
static void
|
||||
vt6105Mattach(Ether* edev)
|
||||
{
|
||||
|
@ -655,6 +620,12 @@ vt6105Mattach(Ether* edev)
|
|||
nexterror();
|
||||
}
|
||||
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = Rdbsz;
|
||||
ctlr->pool.align = 4;
|
||||
growbp(&ctlr->pool, ctlr->nrd);
|
||||
}
|
||||
|
||||
prev = (Ds*)(alloc + (ctlr->nrd-1)*dsz);
|
||||
for(i = 0; i < ctlr->nrd; i++){
|
||||
ds = (Ds*)alloc;
|
||||
|
@ -663,10 +634,8 @@ vt6105Mattach(Ether* edev)
|
|||
ds->control = Ipkt|Tcpkt|Udpkt|Rdbsz;
|
||||
ds->branch = PCIWADDR(alloc);
|
||||
|
||||
ds->bp = vt6105Mrballoc();
|
||||
if(ds->bp == nil)
|
||||
error("vt6105M: can't allocate receive ring\n");
|
||||
ds->bp->rp = (uchar*)ROUNDUP((ulong)ds->bp->rp, 4);
|
||||
if((ds->bp = iallocbp(&ctlr->pool)) == nil)
|
||||
error(Enomem);
|
||||
ds->addr = PCIWADDR(ds->bp->rp);
|
||||
|
||||
ds->next = (Ds*)alloc;
|
||||
|
@ -853,7 +822,7 @@ vt6105Mreceive(Ether* edev)
|
|||
ctlr->rxstats[i]++;
|
||||
}
|
||||
}
|
||||
else if(bp = vt6105Mrballoc()){
|
||||
else if(bp = iallocbp(&ctlr->pool)){
|
||||
if(ds->control & Tuok){
|
||||
ds->bp->flag |= Btcpck|Budpck;
|
||||
ctlr->tuok++;
|
||||
|
@ -865,7 +834,6 @@ vt6105Mreceive(Ether* edev)
|
|||
len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
|
||||
ds->bp->wp = ds->bp->rp+len;
|
||||
etheriq(edev, ds->bp);
|
||||
bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
|
||||
ds->addr = PCIWADDR(bp->rp);
|
||||
ds->bp = bp;
|
||||
}
|
||||
|
|
|
@ -696,6 +696,7 @@ struct Ctlr {
|
|||
Block *tbring[Tringcnt];
|
||||
Sring rx;
|
||||
Block *rbring[Rringcnt];
|
||||
Bpool pool;
|
||||
Kproc txmit;
|
||||
Kproc rxmit;
|
||||
Kproc iproc;
|
||||
|
@ -1197,6 +1198,10 @@ rxinit(Ether *e)
|
|||
qrwrite(c, Qr + Qcsr, Qsumen);
|
||||
}
|
||||
macwrite32(c, Gfrxctl, Gftroff);
|
||||
|
||||
c->pool.size = c->rbsz;
|
||||
c->pool.align = Rbalign;
|
||||
growbp(&c->pool, Nrb);
|
||||
}
|
||||
|
||||
/* debug; remove */
|
||||
|
@ -1235,13 +1240,13 @@ replenish(Ether *e, Ctlr *c)
|
|||
if(lim > 128)
|
||||
lim = 128; /* hw limit? */
|
||||
for(n = 0; n < lim; n++){
|
||||
b = iallocb(c->rbsz + Rbalign);
|
||||
if(b == nil || getnslot(r, &wp, tab, 1 + is64()) == -1){
|
||||
b = iallocbp(&c->pool);
|
||||
if(b == nil)
|
||||
break;
|
||||
if(getnslot(r, &wp, tab, 1 + is64()) == -1){
|
||||
freeb(b);
|
||||
break;
|
||||
}
|
||||
b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
|
||||
|
||||
t = tab[is64()];
|
||||
if(rxscrew(e, r, t, wp) == -1){
|
||||
freeb(b);
|
||||
|
|
|
@ -55,8 +55,6 @@ link
|
|||
ether8003 ether8390
|
||||
ether8139 pci
|
||||
ether8169 pci ethermii
|
||||
# should be obsoleted by igbe
|
||||
# ether82543gc pci
|
||||
ether82557 pci
|
||||
ether82563 pci
|
||||
ether82598 pci
|
||||
|
@ -68,6 +66,7 @@ link
|
|||
etherelnk3 pci
|
||||
etherga620 pci
|
||||
etherigbe pci ethermii
|
||||
# etherm10g pci
|
||||
ethervgbe pci ethermii
|
||||
ethervt6102 pci ethermii
|
||||
ethervt6105m pci ethermii
|
||||
|
|
|
@ -121,6 +121,10 @@ sd53c8xx.$O: ../pc/sd53c8xx.i
|
|||
../pc/sd53c8xx.i: ../pc/sd53c8xx.n
|
||||
cd ../pc && mk sd53c8xx.i
|
||||
|
||||
etherm10g.$O: ../pc/etherm10g2k.i ../pc/etherm10g4k.i
|
||||
../pc/etherm10g%.i: ../pc/etherm10g%.fw
|
||||
cd ../pc && mk etherm10g$stem.i
|
||||
|
||||
$SDEV pmmc.$O: ../port/sd.h
|
||||
sdiahci.$O: ahci.h
|
||||
devaoe.$O sdaoe.$O: ../port/aoe.h
|
||||
|
|
|
@ -66,6 +66,7 @@ link
|
|||
# etherelnk3 pci
|
||||
# etherga620 pci
|
||||
etherigbe pci ethermii
|
||||
# etherm10g pci
|
||||
# ethervgbe pci ethermii
|
||||
# ethervt6102 pci ethermii
|
||||
# ethervt6105m pci ethermii
|
||||
|
|
|
@ -13,31 +13,24 @@ enum
|
|||
};
|
||||
|
||||
static Block*
|
||||
_allocb(int size)
|
||||
_allocb(ulong size, ulong align)
|
||||
{
|
||||
Block *b;
|
||||
uintptr addr;
|
||||
|
||||
size += Tlrspc;
|
||||
size = ROUND(size, BLOCKALIGN);
|
||||
if((b = mallocz(sizeof(Block)+BLOCKALIGN+Hdrspc+size, 0)) == nil)
|
||||
size = ROUND(size+Tlrspc, align);
|
||||
if((b = mallocz(sizeof(Block)+Hdrspc+size+align-1, 0)) == nil)
|
||||
return nil;
|
||||
|
||||
b->next = nil;
|
||||
b->list = nil;
|
||||
b->free = nil;
|
||||
b->pool = nil;
|
||||
b->flag = 0;
|
||||
|
||||
/* align start of data portion by rounding up */
|
||||
addr = (uintptr)b;
|
||||
addr = ROUND(addr + sizeof(Block), BLOCKALIGN);
|
||||
b->base = (uchar*)addr;
|
||||
b->base = (uchar*)ROUND((uintptr)&b[1], (uintptr)align);
|
||||
|
||||
/* align end of data portion by rounding down */
|
||||
b->lim = (uchar*)b + msize(b);
|
||||
addr = (uintptr)b->lim;
|
||||
addr &= ~(BLOCKALIGN-1);
|
||||
b->lim = (uchar*)addr;
|
||||
b->lim = (uchar*)(((uintptr)b + msize(b)) & ~((uintptr)align-1));
|
||||
|
||||
/* leave room at beginning for added headers */
|
||||
b->wp = b->rp = b->lim - size;
|
||||
|
@ -55,7 +48,7 @@ allocb(int size)
|
|||
*/
|
||||
if(up == nil)
|
||||
panic("allocb without up: %#p", getcallerpc(&size));
|
||||
while((b = _allocb(size)) == nil){
|
||||
while((b = _allocb(size, BLOCKALIGN)) == nil){
|
||||
if(up->nlocks || m->ilockdepth || !islo()){
|
||||
xsummary();
|
||||
mallocsummary();
|
||||
|
@ -76,7 +69,7 @@ iallocb(int size)
|
|||
{
|
||||
Block *b;
|
||||
|
||||
if((b = _allocb(size)) == nil){
|
||||
if((b = _allocb(size, BLOCKALIGN)) == nil){
|
||||
static ulong nerr;
|
||||
if((nerr++%10000)==0){
|
||||
if(nerr > 10000000){
|
||||
|
@ -97,20 +90,20 @@ iallocb(int size)
|
|||
void
|
||||
freeb(Block *b)
|
||||
{
|
||||
Bpool *p;
|
||||
void *dead = (void*)Bdead;
|
||||
|
||||
if(b == nil)
|
||||
return;
|
||||
|
||||
/*
|
||||
* drivers which perform non cache coherent DMA manage their own buffer
|
||||
* pool of uncached buffers and provide their own free routine.
|
||||
*/
|
||||
if(b->free != nil) {
|
||||
if((p = b->pool) != nil) {
|
||||
b->next = nil;
|
||||
b->list = nil;
|
||||
|
||||
b->free(b);
|
||||
b->rp = b->wp = b->lim - ROUND(p->size+Tlrspc, p->align);
|
||||
b->flag = BINTR;
|
||||
ilock(p);
|
||||
b->list = p->head;
|
||||
p->head = b;
|
||||
iunlock(p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -121,10 +114,82 @@ freeb(Block *b)
|
|||
b->wp = dead;
|
||||
b->lim = dead;
|
||||
b->base = dead;
|
||||
b->pool = dead;
|
||||
|
||||
free(b);
|
||||
}
|
||||
|
||||
static ulong
|
||||
_alignment(ulong align)
|
||||
{
|
||||
if(align <= BLOCKALIGN)
|
||||
return BLOCKALIGN;
|
||||
|
||||
/* make it a power of two */
|
||||
align--;
|
||||
align |= align>>1;
|
||||
align |= align>>2;
|
||||
align |= align>>4;
|
||||
align |= align>>8;
|
||||
align |= align>>16;
|
||||
align++;
|
||||
|
||||
return align;
|
||||
}
|
||||
|
||||
Block*
|
||||
iallocbp(Bpool *p)
|
||||
{
|
||||
Block *b;
|
||||
|
||||
ilock(p);
|
||||
if((b = p->head) != nil){
|
||||
p->head = b->list;
|
||||
b->list = nil;
|
||||
iunlock(p);
|
||||
} else {
|
||||
iunlock(p);
|
||||
p->align = _alignment(p->align);
|
||||
b = _allocb(p->size, p->align);
|
||||
if(b == nil)
|
||||
return nil;
|
||||
setmalloctag(b, getcallerpc(&p));
|
||||
b->pool = p;
|
||||
b->flag = BINTR;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void
|
||||
growbp(Bpool *p, int n)
|
||||
{
|
||||
ulong size;
|
||||
Block *b;
|
||||
uchar *a;
|
||||
|
||||
if(n < 1)
|
||||
return;
|
||||
if((b = malloc(sizeof(Block)*n)) == nil)
|
||||
return;
|
||||
p->align = _alignment(p->align);
|
||||
size = ROUND(p->size+Hdrspc+Tlrspc, p->align);
|
||||
if((a = mallocalign(size*n, p->align, 0, 0)) == nil){
|
||||
free(b);
|
||||
return;
|
||||
}
|
||||
setmalloctag(b, getcallerpc(&p));
|
||||
while(n > 0){
|
||||
b->base = a;
|
||||
a += size;
|
||||
b->lim = a;
|
||||
b->pool = p;
|
||||
freeb(b);
|
||||
b++;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
checkb(Block *b, char *msg)
|
||||
{
|
||||
|
@ -132,14 +197,14 @@ checkb(Block *b, char *msg)
|
|||
|
||||
if(b == dead)
|
||||
panic("checkb b %s %#p", msg, b);
|
||||
if(b->base == dead || b->lim == dead || b->next == dead
|
||||
if(b->base == dead || b->lim == dead
|
||||
|| b->next == dead || b->list == dead || b->pool == dead
|
||||
|| b->rp == dead || b->wp == dead){
|
||||
print("checkb: base %#p lim %#p next %#p\n",
|
||||
b->base, b->lim, b->next);
|
||||
print("checkb: base %#p lim %#p next %#p list %#p pool %#p\n",
|
||||
b->base, b->lim, b->next, b->list, b->pool);
|
||||
print("checkb: rp %#p wp %#p\n", b->rp, b->wp);
|
||||
panic("checkb dead: %s", msg);
|
||||
}
|
||||
|
||||
if(b->base > b->lim)
|
||||
panic("checkb 0 %s %#p %#p", msg, b->base, b->lim);
|
||||
if(b->rp < b->base)
|
||||
|
|
|
@ -21,6 +21,9 @@ static Ether *etherprobe(int cardno, int ctlrno, char *conf);
|
|||
|
||||
static void dmatproxy(Block*, int, uchar*, DMAT*);
|
||||
|
||||
static int etheroqsize(Ether*);
|
||||
static int etheriqsize(Ether*);
|
||||
|
||||
Chan*
|
||||
etherattach(char* spec)
|
||||
{
|
||||
|
@ -88,10 +91,17 @@ static void
|
|||
etherclose(Chan* chan)
|
||||
{
|
||||
Ether *ether = etherxx[chan->dev];
|
||||
Netfile *f;
|
||||
|
||||
if(NETTYPE(chan->qid.path) == Ndataqid && ether->f[NETID(chan->qid.path)]->bridge)
|
||||
if(NETTYPE(chan->qid.path) == Ndataqid){
|
||||
f = ether->f[NETID(chan->qid.path)];
|
||||
if(f->bridge || f->bypass)
|
||||
memset(ether->mactab, 0, sizeof(ether->mactab));
|
||||
|
||||
if(f->bypass){
|
||||
qsetlimit(ether->oq, etheroqsize(ether));
|
||||
netifsetlimit(ether, etheriqsize(ether));
|
||||
}
|
||||
}
|
||||
netifclose(ether, chan);
|
||||
}
|
||||
|
||||
|
@ -212,15 +222,21 @@ ethermux(Ether *ether, Block *bp, Netfile **from)
|
|||
etherrtrace(f, pkt, len);
|
||||
continue;
|
||||
}
|
||||
if(dispose && x == nil)
|
||||
if(dispose && x == nil){
|
||||
x = f;
|
||||
else if((xbp = iallocb(len)) != nil){
|
||||
continue;
|
||||
}
|
||||
if(bp->pool != nil && len <= bp->pool->size)
|
||||
xbp = iallocbp(bp->pool);
|
||||
else
|
||||
xbp = iallocb(len);
|
||||
if(xbp != nil){
|
||||
memmove(xbp->wp, pkt, len);
|
||||
xbp->wp += len;
|
||||
xbp->flag = bp->flag;
|
||||
if(qpass(f->in, xbp) < 0)
|
||||
ether->soverflows++;
|
||||
} else
|
||||
xbp->flag |= bp->flag & ~(BINTR|BFREE);
|
||||
if(qpass(f->in, xbp) >= 0)
|
||||
continue;
|
||||
}
|
||||
ether->soverflows++;
|
||||
}
|
||||
if(x != nil){
|
||||
|
@ -289,8 +305,14 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
|
|||
|
||||
if(NETTYPE(chan->qid.path) != Ndataqid) {
|
||||
nn = netifwrite(ether, chan, buf, n);
|
||||
if(nn >= 0)
|
||||
if(nn >= 0){
|
||||
/* ignore mbps and use large input queue size when bypassed */
|
||||
if(ether->f[NETID(chan->qid.path)]->bypass){
|
||||
qflush(ether->oq);
|
||||
netifsetlimit(ether, MB);
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
cb = parsecmd(buf, n);
|
||||
if(cb->f[0] && strcmp(cb->f[0], "nonblocking") == 0){
|
||||
if(cb->nf <= 1)
|
||||
|
@ -374,30 +396,28 @@ addethercard(char* t, int (*r)(Ether*))
|
|||
}
|
||||
|
||||
static int
|
||||
etherqueuesize(Ether *ether)
|
||||
etheroqsize(Ether *ether)
|
||||
{
|
||||
int lg, mb;
|
||||
ulong bsz;
|
||||
int b, q;
|
||||
|
||||
/* compute log10(mbps) into lg */
|
||||
for(lg = 0, mb = ether->mbps; mb >= 10; lg++)
|
||||
mb /= 10;
|
||||
if (lg > 0)
|
||||
lg--;
|
||||
if (lg > 14) /* 2^(14+17) = 2³¹ */
|
||||
lg = 14;
|
||||
/* allocate larger output queues for higher-speed interfaces */
|
||||
bsz = 1UL << (lg + 17); /* 2¹⁷ = 128K, bsz = 2ⁿ × 128K */
|
||||
while (bsz > mainmem->maxsize / 8 && bsz > 128*1024)
|
||||
bsz /= 2;
|
||||
if(0) print("#l%d: %d Mbps -> queue size %lud\n", ether->ctlrno, ether->mbps, bsz);
|
||||
return (int)bsz;
|
||||
b = ether->mbps * 2*125; /* 2ms */
|
||||
for(q = 128*1024; q < b; q <<= 1)
|
||||
;
|
||||
if(mainmem->maxsize / 8 < q)
|
||||
q = mainmem->maxsize / 8;
|
||||
return q;
|
||||
}
|
||||
|
||||
static int
|
||||
etheriqsize(Ether *ether)
|
||||
{
|
||||
return etheroqsize(ether) * 2;
|
||||
}
|
||||
|
||||
static Ether*
|
||||
etherprobe(int cardno, int ctlrno, char *conf)
|
||||
{
|
||||
int i;
|
||||
int i, q;
|
||||
Ether *ether;
|
||||
|
||||
ether = malloc(sizeof(Ether));
|
||||
|
@ -447,14 +467,15 @@ Nope:
|
|||
print("#l%d: %s: %dMbps port 0x%lluX irq %d ea %E\n",
|
||||
ctlrno, ether->type, ether->mbps, (uvlong)ether->port, ether->irq, ether->ea);
|
||||
|
||||
netifinit(ether, ether->name, Ntypes, etherqueuesize(ether));
|
||||
q = etheroqsize(ether);
|
||||
if(ether->oq == nil){
|
||||
ether->oq = qopen(ether->limit, Qmsg, 0, 0);
|
||||
ether->oq = qopen(q, Qmsg, 0, 0);
|
||||
if(ether->oq == nil)
|
||||
panic("etherreset %s: can't allocate output queue", ether->name);
|
||||
} else {
|
||||
qsetlimit(ether->oq, ether->limit);
|
||||
qsetlimit(ether->oq, q);
|
||||
}
|
||||
netifinit(ether, ether->name, Ntypes, etheriqsize(ether));
|
||||
ether->alen = Eaddrlen;
|
||||
memmove(ether->addr, ether->ea, Eaddrlen);
|
||||
memset(ether->bcast, 0xFF, Eaddrlen);
|
||||
|
@ -468,12 +489,10 @@ ethersetspeed(Ether *ether, int mbps)
|
|||
if(ether->mbps == mbps)
|
||||
return;
|
||||
ether->mbps = mbps;
|
||||
|
||||
if(mbps <= 0 || ether->f == nil || ether->oq == nil)
|
||||
if(mbps <= 0 || ether->f == nil || ether->oq == nil || ether->bypass)
|
||||
return;
|
||||
|
||||
netifsetlimit(ether, etherqueuesize(ether));
|
||||
qsetlimit(ether->oq, ether->limit);
|
||||
qsetlimit(ether->oq, etheroqsize(ether));
|
||||
netifsetlimit(ether, etheriqsize(ether));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -483,10 +502,9 @@ ethersetlink(Ether *ether, int link)
|
|||
if(!!ether->link == link)
|
||||
return;
|
||||
ether->link = link;
|
||||
|
||||
if(ether->f == nil)
|
||||
if(ether->f == nil || ether->bypass)
|
||||
return;
|
||||
|
||||
memset(ether->mactab, 0, sizeof(ether->mactab));
|
||||
if(link)
|
||||
print("#l%d: %s: link up: %dMbps\n",
|
||||
ether->ctlrno, ether->type, ether->mbps);
|
||||
|
|
|
@ -197,6 +197,8 @@ struct Ctlr {
|
|||
ulong feat[2];
|
||||
int nqueue;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
/* virtioether has 3 queues: rx, tx and ctl */
|
||||
Vqueue queue[3];
|
||||
};
|
||||
|
@ -316,6 +318,9 @@ rxproc(void *v)
|
|||
header = smalloc(VheaderSize);
|
||||
blocks = smalloc(sizeof(Block*) * (q->qsize/2));
|
||||
|
||||
ctlr->pool.size = ETHERMAXTU;
|
||||
growbp(&ctlr->pool, q->qsize*2);
|
||||
|
||||
for(i = 0; i < q->qsize/2; i++){
|
||||
j = i << 1;
|
||||
q->desc[j].addr = PADDR(header);
|
||||
|
@ -341,7 +346,7 @@ rxproc(void *v)
|
|||
i = q->avail->idx & (q->qmask >> 1);
|
||||
if(blocks[i] != nil)
|
||||
break;
|
||||
if((b = iallocb(ETHERMAXTU)) == nil)
|
||||
if((b = iallocbp(&ctlr->pool)) == nil)
|
||||
break;
|
||||
blocks[i] = b;
|
||||
j = (i << 1) | 1;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#include "../port/netif.h"
|
||||
|
||||
static int netown(Netfile*, char*, int);
|
||||
static int openfile(Netif*, int);
|
||||
static int openfile(Netif*, int, int);
|
||||
static char* matchtoken(char*, char*);
|
||||
static char* netmulti(Netif*, Netfile*, uchar*, int);
|
||||
static void netmulti(Netif*, Netfile*, uchar*, int);
|
||||
static int parseaddr(uchar*, char*, int);
|
||||
|
||||
/*
|
||||
|
@ -39,14 +39,14 @@ netifsetlimit(Netif *nif, int limit)
|
|||
int i;
|
||||
|
||||
qlock(nif);
|
||||
if(nif->limit != limit){
|
||||
nif->limit = limit;
|
||||
for(i = 0; i < nif->nfile; i++){
|
||||
f = nif->f[i];
|
||||
if(f == nil)
|
||||
if(f == nil || !f->inuse)
|
||||
continue;
|
||||
qlock(f);
|
||||
qsetlimit(f->in, nif->limit);
|
||||
qunlock(f);
|
||||
}
|
||||
}
|
||||
qunlock(nif);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ netifgen(Chan *c, char*, Dirtab *vp, int, int i, Dir *dp)
|
|||
i -= 4;
|
||||
if(i >= nif->nfile)
|
||||
return -1;
|
||||
if(nif->f[i] == 0)
|
||||
if(nif->f[i] == nil)
|
||||
return 0;
|
||||
q.type = QTDIR;
|
||||
q.path = NETQID(i, N3rdqid);
|
||||
|
@ -129,7 +129,7 @@ netifgen(Chan *c, char*, Dirtab *vp, int, int i, Dir *dp)
|
|||
|
||||
/* third level */
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
if(f == 0)
|
||||
if(f == nil)
|
||||
return 0;
|
||||
if(*f->owner){
|
||||
o = f->owner;
|
||||
|
@ -181,9 +181,7 @@ Chan*
|
|||
netifopen(Netif *nif, Chan *c, int omode)
|
||||
{
|
||||
int id;
|
||||
Netfile *f;
|
||||
|
||||
id = 0;
|
||||
if(c->qid.type & QTDIR){
|
||||
if(omode != OREAD)
|
||||
error(Eperm);
|
||||
|
@ -192,24 +190,16 @@ netifopen(Netif *nif, Chan *c, int omode)
|
|||
case Ndataqid:
|
||||
case Nctlqid:
|
||||
id = NETID(c->qid.path);
|
||||
openfile(nif, id);
|
||||
openfile(nif, id, omode);
|
||||
break;
|
||||
case Ncloneqid:
|
||||
id = openfile(nif, -1);
|
||||
id = openfile(nif, -1, omode);
|
||||
c->qid.path = NETQID(id, Nctlqid);
|
||||
break;
|
||||
default:
|
||||
if(omode != OREAD)
|
||||
error(Ebadarg);
|
||||
}
|
||||
switch(NETTYPE(c->qid.path)){
|
||||
case Ndataqid:
|
||||
case Nctlqid:
|
||||
f = nif->f[id];
|
||||
if(netown(f, up->user, omode&7) < 0)
|
||||
error(Eperm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
c->mode = openmode(omode);
|
||||
c->flag |= COPEN;
|
||||
|
@ -315,7 +305,7 @@ typeinuse(Netif *nif, int type)
|
|||
efp = &nif->f[nif->nfile];
|
||||
for(fp = nif->f; fp < efp; fp++){
|
||||
f = *fp;
|
||||
if(f == 0)
|
||||
if(f == nil)
|
||||
continue;
|
||||
if(f->type == type)
|
||||
return 1;
|
||||
|
@ -346,8 +336,8 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
|
|||
qunlock(nif);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(nif);
|
||||
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
if((p = matchtoken(buf, "connect")) != 0){
|
||||
type = strtoul(p, 0, 0);
|
||||
|
@ -359,7 +349,7 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
|
|||
} else if(matchtoken(buf, "promiscuous")){
|
||||
if(f->prom == 0){
|
||||
if(nif->prom == 0 && nif->promiscuous != nil)
|
||||
nif->promiscuous(nif->arg, 1);
|
||||
(*nif->promiscuous)(nif->arg, 1);
|
||||
f->prom = 1;
|
||||
nif->prom++;
|
||||
}
|
||||
|
@ -370,7 +360,7 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
|
|||
if(type < 5)
|
||||
type = 5;
|
||||
if(nif->scanbs != nil)
|
||||
nif->scanbs(nif->arg, type);
|
||||
(*nif->scanbs)(nif->arg, type);
|
||||
f->scan = type;
|
||||
nif->scan++;
|
||||
}
|
||||
|
@ -386,16 +376,12 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
|
|||
} else if((p = matchtoken(buf, "addmulti")) != nil){
|
||||
if(parseaddr(binaddr, p, nif->alen) < 0)
|
||||
error("bad address");
|
||||
p = netmulti(nif, f, binaddr, 1);
|
||||
if(p)
|
||||
error(p);
|
||||
netmulti(nif, f, binaddr, 1);
|
||||
} else if((p = matchtoken(buf, "delmulti")) != nil
|
||||
||(p = matchtoken(buf, "remmulti")) != nil){
|
||||
if(parseaddr(binaddr, p, nif->alen) < 0)
|
||||
error("bad address");
|
||||
p = netmulti(nif, f, binaddr, 0);
|
||||
if(p)
|
||||
error(p);
|
||||
netmulti(nif, f, binaddr, 0);
|
||||
} else
|
||||
n = -1;
|
||||
qunlock(nif);
|
||||
|
@ -406,17 +392,10 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
|
|||
int
|
||||
netifwstat(Netif *nif, Chan *c, uchar *db, int n)
|
||||
{
|
||||
Dir *dir;
|
||||
Netfile *f;
|
||||
Dir *dir;
|
||||
int m;
|
||||
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
if(f == 0)
|
||||
error(Enonexist);
|
||||
|
||||
if(netown(f, up->user, OWRITE) < 0)
|
||||
error(Eperm);
|
||||
|
||||
dir = smalloc(sizeof(Dir)+n);
|
||||
if(waserror()){
|
||||
free(dir);
|
||||
|
@ -425,14 +404,26 @@ netifwstat(Netif *nif, Chan *c, uchar *db, int n)
|
|||
m = convM2D(db, n, &dir[0], (char*)&dir[1]);
|
||||
if(m == 0)
|
||||
error(Eshortstat);
|
||||
if(waserror()){
|
||||
qunlock(nif);
|
||||
nexterror();
|
||||
}
|
||||
qlock(nif);
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
if(f == nil)
|
||||
error(Enonexist);
|
||||
if(netown(f, up->user, OWRITE) < 0)
|
||||
error(Eperm);
|
||||
if(!emptystr(dir[0].uid)){
|
||||
strncpy(f->owner, dir[0].uid, KNAMELEN-1);
|
||||
f->owner[KNAMELEN-1] = 0;
|
||||
}
|
||||
if(dir[0].mode != ~0UL)
|
||||
f->mode = dir[0].mode;
|
||||
qunlock(nif);
|
||||
free(dir);
|
||||
poperror();
|
||||
poperror();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -456,56 +447,51 @@ netifclose(Netif *nif, Chan *c)
|
|||
if(t != Ndataqid && t != Nctlqid)
|
||||
return;
|
||||
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
qlock(f);
|
||||
if(--(f->inuse) == 0){
|
||||
if(f->bypass){
|
||||
qlock(nif);
|
||||
nif->bypass = nil;
|
||||
f = nif->f[NETID(c->qid.path)];
|
||||
if(f == nil || --(f->inuse) != 0){
|
||||
qunlock(nif);
|
||||
return;
|
||||
}
|
||||
if(f->bypass){
|
||||
nif->bypass = nil;
|
||||
f->bypass = 0;
|
||||
}
|
||||
if(f->prom){
|
||||
qlock(nif);
|
||||
if(--(nif->prom) == 0 && nif->promiscuous != nil)
|
||||
nif->promiscuous(nif->arg, 0);
|
||||
qunlock(nif);
|
||||
if(--(nif->prom) == 0 && nif->promiscuous != nil && !waserror()){
|
||||
(*nif->promiscuous)(nif->arg, 0);
|
||||
poperror();
|
||||
}
|
||||
f->prom = 0;
|
||||
}
|
||||
if(f->scan){
|
||||
qlock(nif);
|
||||
if(--(nif->scan) == 0 && nif->scanbs != nil)
|
||||
nif->scanbs(nif->arg, 0);
|
||||
qunlock(nif);
|
||||
if(--(nif->scan) == 0 && nif->scanbs != nil && !waserror()){
|
||||
(*nif->scanbs)(nif->arg, 0);
|
||||
poperror();
|
||||
}
|
||||
f->prom = 0;
|
||||
f->scan = 0;
|
||||
}
|
||||
if(f->nmaddr){
|
||||
qlock(nif);
|
||||
t = 0;
|
||||
for(ap = nif->maddr; ap; ap = ap->next){
|
||||
if(f->maddr[t/8] & (1<<(t%8)))
|
||||
for(ap = nif->maddr; ap != nil; ap = ap->next){
|
||||
if(f->maddr[t/8] & (1<<(t%8)) && !waserror()){
|
||||
netmulti(nif, f, ap->addr, 0);
|
||||
poperror();
|
||||
}
|
||||
}
|
||||
qunlock(nif);
|
||||
f->nmaddr = 0;
|
||||
}
|
||||
if(f->type < 0){
|
||||
qlock(nif);
|
||||
--(nif->all);
|
||||
qunlock(nif);
|
||||
}
|
||||
if(f->type < 0)
|
||||
nif->all--;
|
||||
f->owner[0] = 0;
|
||||
f->type = 0;
|
||||
f->bridge = 0;
|
||||
f->headersonly = 0;
|
||||
qclose(f->in);
|
||||
}
|
||||
qunlock(f);
|
||||
qunlock(nif);
|
||||
}
|
||||
|
||||
Lock netlock;
|
||||
|
||||
static int
|
||||
netown(Netfile *p, char *o, int omode)
|
||||
{
|
||||
|
@ -513,7 +499,6 @@ netown(Netfile *p, char *o, int omode)
|
|||
int mode;
|
||||
int t;
|
||||
|
||||
lock(&netlock);
|
||||
if(*p->owner){
|
||||
if(strncmp(o, p->owner, KNAMELEN) == 0) /* User */
|
||||
mode = p->mode;
|
||||
|
@ -523,18 +508,14 @@ netown(Netfile *p, char *o, int omode)
|
|||
mode = p->mode<<6; /* Other */
|
||||
|
||||
t = access[omode&3];
|
||||
if((t & mode) == t){
|
||||
unlock(&netlock);
|
||||
if((t & mode) == t)
|
||||
return 0;
|
||||
} else {
|
||||
unlock(&netlock);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
strncpy(p->owner, o, KNAMELEN-1);
|
||||
p->owner[KNAMELEN-1] = 0;
|
||||
p->mode = 0660;
|
||||
unlock(&netlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,51 +524,48 @@ netown(Netfile *p, char *o, int omode)
|
|||
* If id < 0, return an unused ether device.
|
||||
*/
|
||||
static int
|
||||
openfile(Netif *nif, int id)
|
||||
openfile(Netif *nif, int id, int omode)
|
||||
{
|
||||
Netfile *f, **fp, **efp;
|
||||
|
||||
if(id >= 0){
|
||||
f = nif->f[id];
|
||||
if(f == 0)
|
||||
error(Enodev);
|
||||
qlock(f);
|
||||
qreopen(f->in);
|
||||
f->inuse++;
|
||||
qunlock(f);
|
||||
return id;
|
||||
}
|
||||
|
||||
qlock(nif);
|
||||
if(waserror()){
|
||||
qunlock(nif);
|
||||
nexterror();
|
||||
}
|
||||
if(id >= 0){
|
||||
f = nif->f[id];
|
||||
if(f == nil)
|
||||
error(Enodev);
|
||||
if(netown(f, up->user, omode&7) < 0)
|
||||
error(Eperm);
|
||||
f->inuse++;
|
||||
qreopen(f->in);
|
||||
qsetlimit(f->in, nif->limit);
|
||||
qunlock(nif);
|
||||
poperror();
|
||||
return id;
|
||||
}
|
||||
efp = &nif->f[nif->nfile];
|
||||
for(fp = nif->f; fp < efp; fp++){
|
||||
f = *fp;
|
||||
if(f == 0){
|
||||
if(f == nil){
|
||||
f = malloc(sizeof(Netfile));
|
||||
if(f == 0)
|
||||
if(f == nil)
|
||||
exhausted("memory");
|
||||
f->in = qopen(nif->limit, Qmsg, 0, 0);
|
||||
if(f->in == nil){
|
||||
free(f);
|
||||
exhausted("memory");
|
||||
}
|
||||
coherence();
|
||||
*fp = f;
|
||||
qlock(f);
|
||||
} else {
|
||||
qlock(f);
|
||||
if(f->inuse){
|
||||
qunlock(f);
|
||||
} else if(f->inuse)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f->inuse = 1;
|
||||
qreopen(f->in);
|
||||
qsetlimit(f->in, nif->limit);
|
||||
netown(f, up->user, 0);
|
||||
qunlock(f);
|
||||
qunlock(nif);
|
||||
poperror();
|
||||
return fp - nif->f;
|
||||
|
@ -691,13 +669,9 @@ activemulti(Netif *nif, uchar *addr, int alen)
|
|||
{
|
||||
Netaddr *hp;
|
||||
|
||||
for(hp = nif->mhash[hash(addr, alen)]; hp; hp = hp->hnext)
|
||||
if(memcmp(addr, hp->addr, alen) == 0){
|
||||
if(hp->ref)
|
||||
return 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
for(hp = nif->mhash[hash(addr, alen)]; hp != nil; hp = hp->hnext)
|
||||
if(memcmp(addr, hp->addr, alen) == 0)
|
||||
return hp->ref > 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -727,19 +701,19 @@ parseaddr(uchar *to, char *from, int alen)
|
|||
/*
|
||||
* keep track of multicast addresses
|
||||
*/
|
||||
static char*
|
||||
static void
|
||||
netmulti(Netif *nif, Netfile *f, uchar *addr, int add)
|
||||
{
|
||||
Netaddr **l, *ap;
|
||||
int i;
|
||||
ulong h;
|
||||
int i;
|
||||
|
||||
if(nif->multicast == nil)
|
||||
return "interface does not support multicast";
|
||||
error("interface does not support multicast");
|
||||
|
||||
l = &nif->maddr;
|
||||
i = 0;
|
||||
for(ap = *l; ap; ap = *l){
|
||||
l = &nif->maddr;
|
||||
for(ap = *l; ap != nil; ap = *l){
|
||||
if(memcmp(addr, ap->addr, nif->alen) == 0)
|
||||
break;
|
||||
i++;
|
||||
|
@ -747,20 +721,23 @@ netmulti(Netif *nif, Netfile *f, uchar *addr, int add)
|
|||
}
|
||||
|
||||
if(add){
|
||||
if(ap == 0){
|
||||
*l = ap = smalloc(sizeof(*ap));
|
||||
if(ap == nil){
|
||||
ap = malloc(sizeof(*ap));
|
||||
if(ap == nil)
|
||||
error(Enomem);
|
||||
memmove(ap->addr, addr, nif->alen);
|
||||
ap->next = 0;
|
||||
ap->ref = 1;
|
||||
h = hash(addr, nif->alen);
|
||||
h = hash(ap->addr, nif->alen);
|
||||
ap->hnext = nif->mhash[h];
|
||||
ap->ref = 1;
|
||||
coherence();
|
||||
nif->mhash[h] = ap;
|
||||
*l = ap;
|
||||
} else {
|
||||
ap->ref++;
|
||||
}
|
||||
if(ap->ref == 1){
|
||||
nif->nmaddr++;
|
||||
nif->multicast(nif->arg, addr, 1);
|
||||
(*nif->multicast)(nif->arg, addr, 1);
|
||||
}
|
||||
if(i < 8*sizeof(f->maddr)){
|
||||
if((f->maddr[i/8] & (1<<(i%8))) == 0)
|
||||
|
@ -768,12 +745,12 @@ netmulti(Netif *nif, Netfile *f, uchar *addr, int add)
|
|||
f->maddr[i/8] |= 1<<(i%8);
|
||||
}
|
||||
} else {
|
||||
if(ap == 0 || ap->ref == 0)
|
||||
return 0;
|
||||
if(ap == nil || ap->ref == 0)
|
||||
return;
|
||||
ap->ref--;
|
||||
if(ap->ref == 0){
|
||||
nif->nmaddr--;
|
||||
nif->multicast(nif->arg, addr, 0);
|
||||
(*nif->multicast)(nif->arg, addr, 0);
|
||||
}
|
||||
if(i < 8*sizeof(f->maddr)){
|
||||
if((f->maddr[i/8] & (1<<(i%8))) != 0)
|
||||
|
@ -781,5 +758,4 @@ netmulti(Netif *nif, Netfile *f, uchar *addr, int add)
|
|||
f->maddr[i/8] &= ~(1<<(i%8));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ enum
|
|||
*/
|
||||
struct Netfile
|
||||
{
|
||||
QLock;
|
||||
|
||||
int inuse;
|
||||
ulong mode;
|
||||
char owner[KNAMELEN];
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
typedef struct Alarms Alarms;
|
||||
typedef struct Block Block;
|
||||
typedef struct Bpool Bpool;
|
||||
typedef struct Chan Chan;
|
||||
typedef struct Cmdbuf Cmdbuf;
|
||||
typedef struct Cmdtab Cmdtab;
|
||||
|
@ -151,7 +152,7 @@ struct Block
|
|||
uchar* wp; /* first empty byte */
|
||||
uchar* lim; /* 1 past the end of the buffer */
|
||||
uchar* base; /* start of the buffer */
|
||||
void (*free)(Block*);
|
||||
Bpool* pool;
|
||||
ushort flag;
|
||||
ushort checksum; /* IP checksum of complete packet (minus media header) */
|
||||
};
|
||||
|
@ -159,6 +160,15 @@ struct Block
|
|||
#define BLEN(s) ((s)->wp - (s)->rp)
|
||||
#define BALLOC(s) ((s)->lim - (s)->base)
|
||||
|
||||
struct Bpool
|
||||
{
|
||||
ulong size; /* block size */
|
||||
ulong align; /* block alignment */
|
||||
|
||||
Lock;
|
||||
Block *head; /* freelist head */
|
||||
};
|
||||
|
||||
struct Chan
|
||||
{
|
||||
Ref;
|
||||
|
|
|
@ -130,11 +130,13 @@ uintptr getmalloctag(void*);
|
|||
uintptr getrealloctag(void*);
|
||||
_Noreturn void gotolabel(Label*);
|
||||
char* getconfenv(void);
|
||||
void growbp(Bpool*, int);
|
||||
long hostdomainwrite(char*, int);
|
||||
long hostownerwrite(char*, int);
|
||||
void (*hwrandbuf)(void*, ulong);
|
||||
void hzsched(void);
|
||||
Block* iallocb(int);
|
||||
Block* iallocbp(Bpool*);
|
||||
uintptr ibrk(uintptr, int);
|
||||
void ilock(Lock*);
|
||||
_Noreturn void interrupted(void);
|
||||
|
|
|
@ -300,7 +300,12 @@ copyblock(Block *bp, int count)
|
|||
assert(count >= 0);
|
||||
|
||||
QDEBUG checkb(bp, "copyblock 0");
|
||||
if(bp->pool == nil
|
||||
|| count > bp->pool->size
|
||||
|| (nbp = iallocbp(bp->pool)) == nil)
|
||||
nbp = allocb(count);
|
||||
nbp->flag |= bp->flag & ~(BINTR|BFREE);
|
||||
|
||||
for(; count > 0 && bp != nil; bp = bp->next){
|
||||
l = BLEN(bp);
|
||||
if(l > count)
|
||||
|
|
|
@ -580,7 +580,9 @@ wifideauth(Wifi *wifi, Wnode *wn)
|
|||
freewifikeys(wifi, wn);
|
||||
wn->aid = 0;
|
||||
|
||||
if(wn == wifi->bss){
|
||||
if(wn != wifi->bss)
|
||||
return;
|
||||
|
||||
/* notify driver about node aid association */
|
||||
(*wifi->transmit)(wifi, wn, nil);
|
||||
|
||||
|
@ -588,19 +590,21 @@ wifideauth(Wifi *wifi, Wnode *wn)
|
|||
ether = wifi->ether;
|
||||
for(i=0; i<ether->nfile; i++){
|
||||
f = ether->f[i];
|
||||
if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
|
||||
if(f == nil || !f->inuse || f->type != 0x888e || waserror())
|
||||
continue;
|
||||
qflush(f->in);
|
||||
qwrite(f->in, 0, 0);
|
||||
poperror();
|
||||
}
|
||||
qflush(ether->oq);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if a node qualifies as our bss matching bssid and essid */
|
||||
static int
|
||||
goodbss(Wifi *wifi, Wnode *wn)
|
||||
{
|
||||
if(wifi->ether->bypass)
|
||||
return 0; /* we'r bypassed, dont try to associate */
|
||||
if(memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) != 0){
|
||||
if(memcmp(wifi->bssid, wn->bssid, Eaddrlen) != 0)
|
||||
return 0; /* bssid doesnt match */
|
||||
|
@ -803,7 +807,7 @@ wifsproc(void *arg)
|
|||
Scan:
|
||||
/* scan for access point */
|
||||
while(wifi->bss == nil){
|
||||
ether->link = 0;
|
||||
ethersetlink(ether, 0);
|
||||
wnscan.channel = 1 + ((wnscan.channel+4) % 13);
|
||||
wifiprobe(wifi, &wnscan);
|
||||
do {
|
||||
|
@ -819,11 +823,10 @@ Scan:
|
|||
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){
|
||||
if(wn->status != Sneedauth && TK2SEC(now - wn->lastseen) > 20
|
||||
|| goodbss(wifi, wn) == 0){
|
||||
wifideauth(wifi, wn);
|
||||
wifi->bss = nil;
|
||||
break;
|
||||
|
@ -833,10 +836,9 @@ Scan:
|
|||
wifideauth(wifi, wn); /* stuck in auth, start over */
|
||||
if(wn->status == Sconn || wn->status == Sunauth)
|
||||
sendauth(wifi, wn);
|
||||
if(wn->status == Sauth){
|
||||
if(wn->status == Sauth)
|
||||
sendassoc(wifi, wn);
|
||||
}
|
||||
}
|
||||
tsleep(&up->sleep, return0, 0, 500);
|
||||
}
|
||||
goto Scan;
|
||||
|
|
|
@ -316,8 +316,6 @@ struct Ctlr {
|
|||
int ntdfree;
|
||||
int ntq;
|
||||
|
||||
int nrb;
|
||||
|
||||
// Lock rlock; /* receive */
|
||||
Rendez rrendez;
|
||||
D* rd; /* descriptor ring */
|
||||
|
@ -328,6 +326,8 @@ struct Ctlr {
|
|||
int rdt; /* tail - consumer index (host) */
|
||||
int nrdfree;
|
||||
|
||||
Bpool pool;
|
||||
|
||||
Lock reglock;
|
||||
int tcr; /* transmit configuration register */
|
||||
int rcr; /* receive configuration register */
|
||||
|
@ -353,9 +353,6 @@ struct Ctlr {
|
|||
static Ctlr* rtl8169ctlrhead;
|
||||
static Ctlr* rtl8169ctlrtail;
|
||||
|
||||
static Lock rblock; /* free receive Blocks */
|
||||
static Block* rbpool;
|
||||
|
||||
#define csr8r(c, r) (*((uchar *) ((c)->nic)+(r)))
|
||||
#define csr16r(c, r) (*((u16int *)((c)->nic)+((r)/2)))
|
||||
#define csr32p(c, r) ((u32int *) ((c)->nic)+((r)/4))
|
||||
|
@ -453,32 +450,6 @@ rtl8169mii(Ctlr* ctlr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static Block*
|
||||
rballoc(void)
|
||||
{
|
||||
Block *bp;
|
||||
|
||||
ilock(&rblock);
|
||||
if((bp = rbpool) != nil){
|
||||
rbpool = bp->next;
|
||||
bp->next = nil;
|
||||
}
|
||||
iunlock(&rblock);
|
||||
return bp;
|
||||
}
|
||||
|
||||
static void
|
||||
rbfree(Block *bp)
|
||||
{
|
||||
bp->wp = bp->rp = bp->lim - Mps;
|
||||
bp->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
|
||||
|
||||
ilock(&rblock);
|
||||
bp->next = rbpool;
|
||||
rbpool = bp;
|
||||
iunlock(&rblock);
|
||||
}
|
||||
|
||||
static void
|
||||
rtl8169promiscuous(void* arg, int on)
|
||||
{
|
||||
|
@ -700,6 +671,7 @@ rtl8169replenish(Ether *edev)
|
|||
Block *bp;
|
||||
Ctlr *ctlr;
|
||||
D *d;
|
||||
uvlong pa;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
if (ctlr->nrd == 0) {
|
||||
|
@ -718,15 +690,14 @@ rtl8169replenish(Ether *edev)
|
|||
break;
|
||||
}
|
||||
if(ctlr->rb[rdt] == nil){
|
||||
bp = rballoc();
|
||||
if(bp == nil){
|
||||
iprint("rtl8169: no available buffers\n");
|
||||
bp = iallocbp(&ctlr->pool);
|
||||
if(bp == nil)
|
||||
break;
|
||||
}
|
||||
ctlr->rb[rdt] = bp;
|
||||
d->addrhi = 0;
|
||||
pa = PCIWADDR(bp->rp);
|
||||
d->addrhi = pa >> 32;
|
||||
coherence();
|
||||
d->addrlo = PCIWADDR(bp->rp);
|
||||
d->addrlo = pa;
|
||||
coherence();
|
||||
} else
|
||||
iprint("8169: replenish: rx overrun\n");
|
||||
|
@ -1199,9 +1170,8 @@ rtl8169init(Ether* edev)
|
|||
static void
|
||||
rtl8169attach(Ether* edev)
|
||||
{
|
||||
int timeo, s, i;
|
||||
int timeo, s;
|
||||
char name[KNAMELEN];
|
||||
Block *bp;
|
||||
Ctlr *ctlr;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
|
@ -1233,13 +1203,9 @@ rtl8169attach(Ether* edev)
|
|||
ctlr->rb == nil || ctlr->dtcc == nil)
|
||||
error(Enomem);
|
||||
|
||||
/* allocate private receive-buffer pool */
|
||||
ctlr->nrb = Nrb;
|
||||
for(i = 0; i < Nrb; i++){
|
||||
if((bp = allocb(Mps)) == nil)
|
||||
error(Enomem);
|
||||
bp->free = rbfree;
|
||||
freeb(bp);
|
||||
if(ctlr->pool.size == 0){
|
||||
ctlr->pool.size = Mps;
|
||||
growbp(&ctlr->pool, Nrb);
|
||||
}
|
||||
|
||||
rtl8169init(edev);
|
||||
|
|
|
@ -236,18 +236,13 @@ vifrecvdone(Ether *ether, netif_rx_response_t *rr)
|
|||
vifrecv(ctlr, rx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctlr->receives++;
|
||||
memmove(bp->base, rx->page + rr->offset, len);
|
||||
vifrecv(ctlr, rx);
|
||||
|
||||
bp->rp = bp->base;
|
||||
bp->wp = bp->rp + len;
|
||||
bp->free = 0;
|
||||
bp->next = 0;
|
||||
bp->list = 0;
|
||||
if (rr->flags & NETRXF_data_validated)
|
||||
bp->flag |= Btcpck|Budpck;
|
||||
bp->rp = bp->base;
|
||||
bp->wp = bp->rp + len;
|
||||
memmove(bp->rp, rx->page + rr->offset, len);
|
||||
vifrecv(ctlr, rx);
|
||||
etheriq(ether, bp);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -596,7 +596,7 @@ static void
|
|||
put4(long v)
|
||||
{
|
||||
if(dlm && curp != P && reloca != nil){
|
||||
dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1);
|
||||
dynreloc(reloca->sym, curp->pc + andptr - &and[0] + !!rexflag, 1);
|
||||
reloca = nil;
|
||||
}
|
||||
andptr[0] = v;
|
||||
|
@ -610,7 +610,7 @@ static void
|
|||
put8(vlong v)
|
||||
{
|
||||
if(dlm && curp != P && reloca != nil){
|
||||
dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1); /* TO DO */
|
||||
dynreloc(reloca->sym, curp->pc + andptr - &and[0] + !!rexflag, 1); /* TO DO */
|
||||
reloca = nil;
|
||||
}
|
||||
andptr[0] = v;
|
||||
|
|
|
@ -141,7 +141,7 @@ int pnames(uchar*, int, char*);
|
|||
int gnames(char*, int, uchar*, int);
|
||||
Ndb* opendatabase(void);
|
||||
void ndb2conf(Ndb *db, uchar *ip);
|
||||
void putndb(int);
|
||||
int putndb(int);
|
||||
void refresh(void);
|
||||
ulong randint(ulong low, ulong hi);
|
||||
int validip(uchar*);
|
||||
|
|
|
@ -587,7 +587,7 @@ static int
|
|||
recvrahost(uchar buf[], int pktlen, ulong now)
|
||||
{
|
||||
char dnsdomain[sizeof(conf.dnsdomain)];
|
||||
int m, n, optype, seen;
|
||||
int m, n, optype, seen, needrefresh;
|
||||
Lladdropt *llao;
|
||||
Mtuopt *mtuo;
|
||||
Prefixopt *prfo;
|
||||
|
@ -705,12 +705,14 @@ recvrahost(uchar buf[], int pktlen, ulong now)
|
|||
|
||||
/* remove expired prefixes */
|
||||
issuedel6(&conf);
|
||||
ipmove(conf.laddr, IPnoaddr);
|
||||
|
||||
/* managed netork: prefixes are acquired with dhcpv6 */
|
||||
/* managed network: prefixes are acquired with dhcpv6 */
|
||||
if(dodhcp && conf.mflag)
|
||||
return 0;
|
||||
|
||||
/* process new prefixes */
|
||||
needrefresh = 0;
|
||||
m = sizeof *ra;
|
||||
while(pktlen - m >= 8) {
|
||||
n = m;
|
||||
|
@ -819,10 +821,10 @@ recvrahost(uchar buf[], int pktlen, ulong now)
|
|||
if(validip(conf.gaddr))
|
||||
adddefroute(conf.gaddr, conf.lladdr, conf.laddr, conf.raddr, conf.mask);
|
||||
|
||||
putndb(1);
|
||||
refresh();
|
||||
needrefresh |= 1<<(putndb(1) != 0);
|
||||
}
|
||||
|
||||
if(needrefresh > 1 || (needrefresh == 0 && putndb(0)))
|
||||
refresh();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -749,7 +749,7 @@ putnames(char *p, char *e, char *attr, char *s)
|
|||
}
|
||||
|
||||
/* make an ndb entry and put it into /net/ndb for the servers to see */
|
||||
void
|
||||
int
|
||||
putndb(int doadd)
|
||||
{
|
||||
static char buf[16*1024];
|
||||
|
@ -757,9 +757,11 @@ putndb(int doadd)
|
|||
Ndbtuple *t, *nt;
|
||||
Ndb *db;
|
||||
int fd;
|
||||
static uchar csum[SHA1dlen];
|
||||
uchar newcsum[SHA1dlen];
|
||||
|
||||
if(beprimary == 0 || noconfig)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
p = buf;
|
||||
e = buf + sizeof buf;
|
||||
|
@ -811,7 +813,8 @@ putndb(int doadd)
|
|||
if(nt != nil && (ipnet == nil || strcmp(nt->val, ipnet) != 0)
|
||||
|| nt == nil && ((nt = ndbfindattr(t, t, "ip")) == nil
|
||||
|| parseip(ip, nt->val) == -1
|
||||
|| ipcmp(ip, conf.laddr) != 0 && myip(allifcs, ip))){
|
||||
|| (!doadd || !validip(conf.laddr) || ipcmp(ip, conf.laddr) != 0)
|
||||
&& myip(allifcs, ip))){
|
||||
if(p > buf)
|
||||
p = seprint(p, e, "\n");
|
||||
for(nt = t; nt != nil; nt = nt->entry)
|
||||
|
@ -822,10 +825,18 @@ putndb(int doadd)
|
|||
}
|
||||
ndbclose(db);
|
||||
}
|
||||
|
||||
/* only write if something has changed since last time */
|
||||
sha1((uchar *)buf, p-buf, newcsum, nil);
|
||||
if(memcmp(csum, newcsum, SHA1dlen) == 0)
|
||||
return 0;
|
||||
memcpy(csum, newcsum, SHA1dlen);
|
||||
|
||||
if((fd = open(file, OWRITE|OTRUNC)) < 0)
|
||||
return;
|
||||
return 0;
|
||||
write(fd, buf, p-buf);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
Loading…
Reference in a new issue