devether: mux bridges, portable netconsole
This commit is contained in:
parent
a2e8246ffc
commit
729c9c39d9
|
@ -643,7 +643,7 @@ receive(Ether *ether)
|
|||
* in memory (mv-s104860-u0 §8.3.4.1)
|
||||
*/
|
||||
b->rp += 2;
|
||||
etheriq(ether, b, 1);
|
||||
etheriq(ether, b);
|
||||
etheractive(ether);
|
||||
if (i % (Nrx / 2) == 0) {
|
||||
rxreplenish(ctlr);
|
||||
|
|
|
@ -468,7 +468,7 @@ interrupt(Ureg*, void* arg)
|
|||
else if(bp = iallocb(Rbsz)){
|
||||
len = ((des->status & Fl)>>16)-4;
|
||||
des->bp->wp = des->bp->rp+len;
|
||||
etheriq(ether, des->bp, 1);
|
||||
etheriq(ether, des->bp);
|
||||
des->bp = bp;
|
||||
des->addr = PCIWADDR(bp->rp);
|
||||
}
|
||||
|
|
|
@ -642,7 +642,7 @@ smcreceive(Ether *edev)
|
|||
|
||||
/* and push the Block upstream */
|
||||
if (ctlr->inited)
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
else
|
||||
freeb(bp);
|
||||
|
||||
|
|
|
@ -477,7 +477,7 @@ interrupt(Ureg*, void* arg)
|
|||
else if(bp = iallocb(Rbsz)){
|
||||
len = ((des->status & Fl)>>16)-4;
|
||||
des->bp->wp = des->bp->rp+len;
|
||||
etheriq(ether, des->bp, 1);
|
||||
etheriq(ether, des->bp);
|
||||
des->bp = bp;
|
||||
des->addr = PCIWADDR(bp->rp);
|
||||
}
|
||||
|
|
|
@ -424,7 +424,7 @@ intrloop:
|
|||
if(bb != nil){
|
||||
len = (dre->md2 & 0x0FFF)-4;
|
||||
bb->wp = bb->rp+len;
|
||||
etheriq(ether, bb, 1);
|
||||
etheriq(ether, bb);
|
||||
}
|
||||
dre->addr = PADDR(bp->rp);
|
||||
}
|
||||
|
|
|
@ -583,7 +583,7 @@ rtl8139receive(Ether* edev)
|
|||
bp->wp += length;
|
||||
}
|
||||
bp->wp -= 4;
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
|
||||
capr = ROUNDUP(capr, 4);
|
||||
|
|
|
@ -970,7 +970,7 @@ rtl8169receive(Ether* edev)
|
|||
bp->flag |= Bipck;
|
||||
break;
|
||||
}
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}else{
|
||||
if(!(control & Res))
|
||||
ctlr->frag++;
|
||||
|
|
|
@ -851,7 +851,7 @@ gc82543recv(Ether* edev, int icr)
|
|||
ctlr->rb[rdh] = nil;
|
||||
bp->wp += rdesc->length;
|
||||
bp->next = nil;
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
|
||||
if(ctlr->rb[rdh] != nil){
|
||||
|
|
|
@ -655,7 +655,7 @@ receive(Ether* ether)
|
|||
bp = xbp;
|
||||
}
|
||||
if(pbp != nil)
|
||||
etheriq(ether, pbp, 1);
|
||||
etheriq(ether, pbp);
|
||||
}
|
||||
else{
|
||||
rfd->count = 0;
|
||||
|
|
|
@ -1062,7 +1062,7 @@ i82563rproc(void *arg)
|
|||
bp->checksum = rd->checksum;
|
||||
bp->flag |= Bpktck;
|
||||
}
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
} else
|
||||
freeb(bp);
|
||||
ctlr->rb[rdh] = nil;
|
||||
|
|
|
@ -584,7 +584,7 @@ loop1:
|
|||
b->checksum = r->cksum;
|
||||
}
|
||||
// r->status = 0;
|
||||
etheriq(e, b, 1);
|
||||
etheriq(e, b);
|
||||
c->rdfree--;
|
||||
rdh = Next(rdh, m);
|
||||
goto loop1; /* UGH */
|
||||
|
|
|
@ -545,7 +545,7 @@ interrupt(Ureg*, void* arg)
|
|||
freeb(des->bp);
|
||||
}else{
|
||||
des->bp->wp = des->bp->rp+len;
|
||||
etheriq(ether, des->bp, 1);
|
||||
etheriq(ether, des->bp);
|
||||
}
|
||||
des->bp = bp;
|
||||
des->addr = PADDR(bp->rp);
|
||||
|
|
|
@ -439,7 +439,7 @@ receive(Ether* ether)
|
|||
/*
|
||||
* Copy the packet to whoever wants it.
|
||||
*/
|
||||
etheriq(ether, bp, 1);
|
||||
etheriq(ether, bp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -414,7 +414,7 @@ bcmreceive(Ether *edev)
|
|||
if(pkt[3] & FrameError) {
|
||||
freeb(bp); /* dump erroneous packets */
|
||||
} else {
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -839,7 +839,7 @@ dp83820interrupt(Ureg*, void* arg)
|
|||
bp = desc->bp;
|
||||
desc->bp = nil;
|
||||
bp->wp += cmdsts & SizeMASK;
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
else if(0 && !(cmdsts & Ok)){
|
||||
iprint("dp83820: rx %8.8uX:", cmdsts);
|
||||
|
|
|
@ -834,7 +834,7 @@ receive905(Ether* ether)
|
|||
else if(bp = iallocb(sizeof(Etherpkt)+4)){
|
||||
len = pd->control & rxBytes;
|
||||
pd->bp->wp = pd->bp->rp+len;
|
||||
etheriq(ether, pd->bp, 1);
|
||||
etheriq(ether, pd->bp);
|
||||
pd->bp = bp;
|
||||
pd->addr = PADDR(bp->rp);
|
||||
coherence();
|
||||
|
@ -944,7 +944,7 @@ receive(Ether* ether)
|
|||
if(ctlr->busmaster == 1)
|
||||
ctlr->rbp->wp = startdma(ether, PADDR(bp->rp));
|
||||
|
||||
etheriq(ether, ctlr->rbp, 1);
|
||||
etheriq(ether, ctlr->rbp);
|
||||
ctlr->rbp = bp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -626,7 +626,7 @@ ga620receive(Ether* edev)
|
|||
if(!(rbd->flags & Ferror) && len != 0){
|
||||
bp = rbd->opaque;
|
||||
bp->wp = bp->rp+len;
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
else
|
||||
freeb(rbd->opaque);
|
||||
|
|
|
@ -1142,7 +1142,7 @@ igberproc(void* arg)
|
|||
bp->checksum = rd->checksum;
|
||||
bp->flag |= Bpktck;
|
||||
}
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
}
|
||||
else if(ctlr->rb[rdh] != nil){
|
||||
freeb(ctlr->rb[rdh]);
|
||||
|
|
|
@ -1087,7 +1087,7 @@ m10rx(void *v)
|
|||
replenish(&c->bg);
|
||||
sleep(&c->rxrendez, rxcansleep, c);
|
||||
while(b = nextblock(c))
|
||||
etheriq(e, b, 1);
|
||||
etheriq(e, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ receive(Ether* ether)
|
|||
bp->wp++;
|
||||
}
|
||||
|
||||
etheriq(ether, bp, 1);
|
||||
etheriq(ether, bp);
|
||||
ether->inpackets++;
|
||||
outs(port + MmuCmd, McRelease);
|
||||
}
|
||||
|
|
|
@ -531,7 +531,7 @@ vgberxeof(Ether* edev)
|
|||
/* plant new block, might fail if out of memory */
|
||||
if(vgbenewrx(ctlr, i) == 0){
|
||||
block->wp = block->rp + length;
|
||||
etheriq(edev, block, 1);
|
||||
etheriq(edev, block);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ rxproc(void *v)
|
|||
blocks[i] = nil;
|
||||
|
||||
b->wp = b->rp + u->len - VheaderSize;
|
||||
etheriq(edev, b, 1);
|
||||
etheriq(edev, b);
|
||||
q->lastused++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -720,7 +720,7 @@ vt6102receive(Ether* edev)
|
|||
else if(bp = iallocb(Rdbsz+3)){
|
||||
len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
|
||||
ds->bp->wp = ds->bp->rp+len;
|
||||
etheriq(edev, ds->bp, 1);
|
||||
etheriq(edev, ds->bp);
|
||||
bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
|
||||
ds->addr = PCIWADDR(bp->rp);
|
||||
ds->bp = bp;
|
||||
|
|
|
@ -865,7 +865,7 @@ vt6105Mreceive(Ether* edev)
|
|||
}
|
||||
len = ((ds->status & LengthMASK)>>LengthSHIFT)-4;
|
||||
ds->bp->wp = ds->bp->rp+len;
|
||||
etheriq(edev, ds->bp, 1);
|
||||
etheriq(edev, ds->bp);
|
||||
bp->rp = (uchar*)ROUNDUP((ulong)bp->rp, 4);
|
||||
ds->addr = PCIWADDR(bp->rp);
|
||||
ds->bp = bp;
|
||||
|
|
|
@ -1430,7 +1430,7 @@ rx(Ether *e, uint l, uint x, uint flag)
|
|||
}else{
|
||||
b->wp += l;
|
||||
b->flag |= flag;
|
||||
etheriq(e, b, 1);
|
||||
etheriq(e, b);
|
||||
}
|
||||
unstarve(&c->rxmit);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,6 @@ char* mtrr(uvlong, uvlong, char *);
|
|||
void mtrrclock(void);
|
||||
int mtrrprint(char *, long);
|
||||
void mtrrsync(void);
|
||||
void netconsole(void);
|
||||
uchar nvramread(int);
|
||||
void nvramwrite(int, uchar);
|
||||
void outb(int, int);
|
||||
|
|
|
@ -60,7 +60,6 @@ main(void)
|
|||
}else
|
||||
links();
|
||||
chandevreset();
|
||||
netconsole();
|
||||
pageinit();
|
||||
userinit();
|
||||
schedinit();
|
||||
|
|
|
@ -452,7 +452,7 @@ w_rxdone(Ether* ether)
|
|||
}
|
||||
|
||||
ctlr->nrx++;
|
||||
etheriq(ether,bp,1);
|
||||
etheriq(ether, bp);
|
||||
ctlr->signal = ((ctlr->signal*15)+((f.qinfo>>8) & 0xFF))/16;
|
||||
ctlr->noise = ((ctlr->noise*15)+(f.qinfo & 0xFF))/16;
|
||||
return;
|
||||
|
|
|
@ -111,7 +111,6 @@ char* mtrr(uvlong, uvlong, char *);
|
|||
void mtrrclock(void);
|
||||
int mtrrprint(char *, long);
|
||||
void mtrrsync(void);
|
||||
void netconsole(void);
|
||||
void noteret(void);
|
||||
uchar nvramread(int);
|
||||
void nvramwrite(int, uchar);
|
||||
|
|
|
@ -329,7 +329,6 @@ main()
|
|||
}else
|
||||
links();
|
||||
chandevreset();
|
||||
netconsole();
|
||||
preallocpages();
|
||||
pageinit();
|
||||
userinit();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../port/etherif.h"
|
||||
|
||||
extern int eipfmt(Fmt*);
|
||||
extern ushort ipcsum(uchar *);
|
||||
|
||||
static Ether *etherxx[MaxEther];
|
||||
|
||||
|
@ -70,7 +71,12 @@ ethercreate(Chan*, char*, int, ulong)
|
|||
static void
|
||||
etherclose(Chan* chan)
|
||||
{
|
||||
netifclose(etherxx[chan->dev], chan);
|
||||
Ether *ether = etherxx[chan->dev];
|
||||
|
||||
if(NETTYPE(chan->qid.path) == Ndataqid && ether->f[NETID(chan->qid.path)]->bridge)
|
||||
memset(ether->mactab, 0, sizeof(ether->mactab));
|
||||
|
||||
netifclose(ether, chan);
|
||||
}
|
||||
|
||||
static long
|
||||
|
@ -109,152 +115,154 @@ etherwstat(Chan* chan, uchar* dp, int n)
|
|||
static void
|
||||
etherrtrace(Netfile* f, Etherpkt* pkt, int len)
|
||||
{
|
||||
int i, n;
|
||||
Block *bp;
|
||||
|
||||
if(qwindow(f->in) <= 0)
|
||||
return;
|
||||
if(len > 58)
|
||||
n = 58;
|
||||
else
|
||||
n = len;
|
||||
bp = iallocb(64);
|
||||
if(bp == nil)
|
||||
return;
|
||||
memmove(bp->wp, pkt->d, n);
|
||||
i = TK2MS(MACHP(0)->ticks);
|
||||
bp->wp[58] = len>>8;
|
||||
bp->wp[59] = len;
|
||||
bp->wp[60] = i>>24;
|
||||
bp->wp[61] = i>>16;
|
||||
bp->wp[62] = i>>8;
|
||||
bp->wp[63] = i;
|
||||
memmove(bp->wp, pkt, len < 64 ? len : 64);
|
||||
if(f->type != -2){
|
||||
u32int ms = TK2MS(MACHP(0)->ticks);
|
||||
bp->wp[58] = len>>8;
|
||||
bp->wp[59] = len;
|
||||
bp->wp[60] = ms>>24;
|
||||
bp->wp[61] = ms>>16;
|
||||
bp->wp[62] = ms>>8;
|
||||
bp->wp[63] = ms;
|
||||
}
|
||||
bp->wp += 64;
|
||||
qpass(f->in, bp);
|
||||
}
|
||||
|
||||
Block*
|
||||
etheriq(Ether* ether, Block* bp, int fromwire)
|
||||
static Macent*
|
||||
macent(Ether *ether, uchar *ea)
|
||||
{
|
||||
u32int h = (ea[0] | ea[1]<<8 | ea[2]<<16 | ea[3]<<24) ^ (ea[4] | ea[5]<<8);
|
||||
return ðer->mactab[h % nelem(ether->mactab)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplex the packet to all the connections which want it.
|
||||
* If the packet is not to be used subsequently (tome || from == nil),
|
||||
* attempt to simply pass it into one of the connections, thereby
|
||||
* saving a copy of the data (usual case hopefully).
|
||||
*/
|
||||
static Block*
|
||||
ethermux(Ether *ether, Block *bp, Netfile **from)
|
||||
{
|
||||
Etherpkt *pkt;
|
||||
ushort type;
|
||||
int len, multi, tome, fromme;
|
||||
Netfile **ep, *f, **fp, *fx;
|
||||
Block *xbp;
|
||||
Etherpkt *pkt;
|
||||
Netfile *f, *x, **fp;
|
||||
int len, multi, tome, port, type, dispose;
|
||||
|
||||
ether->inpackets++;
|
||||
|
||||
pkt = (Etherpkt*)bp->rp;
|
||||
len = BLEN(bp);
|
||||
type = (pkt->type[0]<<8)|pkt->type[1];
|
||||
fx = 0;
|
||||
ep = ðer->f[Ntypes];
|
||||
|
||||
multi = pkt->d[0] & 1;
|
||||
/* check for valid multicast addresses */
|
||||
if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){
|
||||
if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
|
||||
if(fromwire){
|
||||
freeb(bp);
|
||||
bp = 0;
|
||||
}
|
||||
if(len < ETHERHDRSIZE)
|
||||
goto Drop;
|
||||
pkt = (Etherpkt*)bp->rp;
|
||||
if(!(multi = pkt->d[0] & 1)){
|
||||
tome = memcmp(pkt->d, ether->ea, Eaddrlen) == 0;
|
||||
if(!tome && from != nil && ether->prom == 0)
|
||||
return bp;
|
||||
} else {
|
||||
tome = 0;
|
||||
if(from == nil && ether->prom == 0
|
||||
&& memcmp(pkt->d, ether->bcast, Eaddrlen) != 0
|
||||
&& !activemulti(ether, pkt->d, Eaddrlen))
|
||||
goto Drop;
|
||||
}
|
||||
|
||||
port = -1;
|
||||
if(ether->prom){
|
||||
if((from == nil || (*from)->bridge) && (pkt->s[0] & 1) == 0){
|
||||
Macent *t = macent(ether, pkt->s);
|
||||
t->port = from == nil ? 0 : 1+(from - ether->f);
|
||||
memmove(t->ea, pkt->s, Eaddrlen);
|
||||
}
|
||||
if(!tome && !multi){
|
||||
Macent *t = macent(ether, pkt->d);
|
||||
if(memcmp(t->ea, pkt->d, Eaddrlen) == 0)
|
||||
port = t->port;
|
||||
}
|
||||
}
|
||||
|
||||
/* is it for me? */
|
||||
tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
|
||||
fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
|
||||
x = nil;
|
||||
type = (pkt->type[0]<<8)|pkt->type[1];
|
||||
dispose = tome || from == nil || port > 0;
|
||||
|
||||
/*
|
||||
* Multiplex the packet to all the connections which want it.
|
||||
* If the packet is not to be used subsequently (fromwire != 0),
|
||||
* attempt to simply pass it into one of the connections, thereby
|
||||
* saving a copy of the data (usual case hopefully).
|
||||
*/
|
||||
for(fp = ether->f; fp < ep; fp++){
|
||||
if(f = *fp)
|
||||
if(f->type == type || f->type < 0)
|
||||
if(tome || multi || f->prom){
|
||||
/* Don't want to hear loopback or bridged packets */
|
||||
if(f->bridge && (tome || !fromwire && !fromme))
|
||||
for(fp = ether->f; fp < ðer->f[Ntypes]; fp++){
|
||||
if((f = *fp) == nil)
|
||||
continue;
|
||||
if(f->type != type && f->type >= 0)
|
||||
continue;
|
||||
if(!tome && !multi && !f->prom)
|
||||
continue;
|
||||
if(f->bridge){
|
||||
if(tome || fp == from)
|
||||
continue;
|
||||
if(port >= 0 && port != 1+(fp - ether->f))
|
||||
continue;
|
||||
if(!f->headersonly){
|
||||
if(fromwire && fx == 0)
|
||||
fx = f;
|
||||
else if(xbp = iallocb(len)){
|
||||
memmove(xbp->wp, pkt, len);
|
||||
xbp->wp += len;
|
||||
xbp->flag = bp->flag;
|
||||
if(qpass(f->in, xbp) < 0) {
|
||||
// print("soverflow for f->in\n");
|
||||
ether->soverflows++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// print("soverflow iallocb\n");
|
||||
ether->soverflows++;
|
||||
}
|
||||
}
|
||||
else
|
||||
etherrtrace(f, pkt, len);
|
||||
}
|
||||
}
|
||||
|
||||
if(fx){
|
||||
if(qpass(fx->in, bp) < 0) {
|
||||
// print("soverflow for fx->in\n");
|
||||
if(f->headersonly || f->type == -2){
|
||||
etherrtrace(f, pkt, len);
|
||||
continue;
|
||||
}
|
||||
if(dispose && x == nil)
|
||||
x = f;
|
||||
else if((xbp = iallocb(len)) != nil){
|
||||
memmove(xbp->wp, pkt, len);
|
||||
xbp->wp += len;
|
||||
xbp->flag = bp->flag;
|
||||
if(qpass(f->in, xbp) < 0)
|
||||
ether->soverflows++;
|
||||
} else
|
||||
ether->soverflows++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(fromwire){
|
||||
freeb(bp);
|
||||
return 0;
|
||||
if(x != nil){
|
||||
if(qpass(x->in, bp) < 0)
|
||||
ether->soverflows++;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if(dispose){
|
||||
Drop: freeb(bp);
|
||||
return nil;
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
|
||||
static int
|
||||
etheroq(Ether* ether, Block* bp)
|
||||
void
|
||||
etheriq(Ether* ether, Block* bp)
|
||||
{
|
||||
int len, loopback;
|
||||
Etherpkt *pkt;
|
||||
ether->inpackets++;
|
||||
ethermux(ether, bp, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
etheroq(Ether* ether, Block* bp, Netfile **from)
|
||||
{
|
||||
if((*from)->bridge == 0)
|
||||
memmove(((Etherpkt*)bp->rp)->s, ether->ea, Eaddrlen);
|
||||
|
||||
bp = ethermux(ether, bp, from);
|
||||
if(bp == nil)
|
||||
return;
|
||||
|
||||
ether->outpackets++;
|
||||
|
||||
/*
|
||||
* Check if the packet has to be placed back onto the input queue,
|
||||
* i.e. if it's a loopback or broadcast packet or the interface is
|
||||
* in promiscuous mode.
|
||||
* If it's a loopback packet indicate to etheriq that the data isn't
|
||||
* needed and return, etheriq will pass-on or free the block.
|
||||
* To enable bridging to work, only packets that were originated
|
||||
* by this interface are fed back.
|
||||
*/
|
||||
pkt = (Etherpkt*)bp->rp;
|
||||
len = BLEN(bp);
|
||||
loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
|
||||
if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom)
|
||||
if(etheriq(ether, bp, loopback) == 0)
|
||||
return len;
|
||||
|
||||
qbwrite(ether->oq, bp);
|
||||
if(ether->transmit != nil)
|
||||
ether->transmit(ether);
|
||||
return len;
|
||||
}
|
||||
|
||||
static long
|
||||
etherwrite(Chan* chan, void* buf, long n, vlong)
|
||||
{
|
||||
Ether *ether;
|
||||
Ether *ether = etherxx[chan->dev];
|
||||
Block *bp;
|
||||
int nn, onoff;
|
||||
Cmdbuf *cb;
|
||||
|
||||
ether = etherxx[chan->dev];
|
||||
if(NETTYPE(chan->qid.path) != Ndataqid) {
|
||||
nn = netifwrite(ether, chan, buf, n);
|
||||
if(nn >= 0)
|
||||
|
@ -287,21 +295,19 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
|
|||
nexterror();
|
||||
}
|
||||
memmove(bp->rp, buf, n);
|
||||
if(!ether->f[NETID(chan->qid.path)]->bridge)
|
||||
memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
|
||||
poperror();
|
||||
bp->wp += n;
|
||||
|
||||
return etheroq(ether, bp);
|
||||
etheroq(ether, bp, ðer->f[NETID(chan->qid.path)]);
|
||||
return n;
|
||||
}
|
||||
|
||||
static long
|
||||
etherbwrite(Chan* chan, Block* bp, ulong)
|
||||
{
|
||||
Ether *ether;
|
||||
long n;
|
||||
long n = BLEN(bp);
|
||||
|
||||
n = BLEN(bp);
|
||||
if(NETTYPE(chan->qid.path) != Ndataqid){
|
||||
if(waserror()) {
|
||||
freeb(bp);
|
||||
|
@ -312,8 +318,8 @@ etherbwrite(Chan* chan, Block* bp, ulong)
|
|||
freeb(bp);
|
||||
return n;
|
||||
}
|
||||
ether = etherxx[chan->dev];
|
||||
|
||||
ether = etherxx[chan->dev];
|
||||
if(n > ether->maxmtu){
|
||||
freeb(bp);
|
||||
error(Etoobig);
|
||||
|
@ -322,8 +328,8 @@ etherbwrite(Chan* chan, Block* bp, ulong)
|
|||
freeb(bp);
|
||||
error(Etoosmall);
|
||||
}
|
||||
|
||||
return etheroq(ether, bp);
|
||||
etheroq(ether, bp, ðer->f[NETID(chan->qid.path)]);
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct {
|
||||
|
@ -422,6 +428,8 @@ etherprobe(int cardno, int ctlrno)
|
|||
return ether;
|
||||
}
|
||||
|
||||
static void netconsole(int);
|
||||
|
||||
static void
|
||||
etherreset(void)
|
||||
{
|
||||
|
@ -436,22 +444,23 @@ etherreset(void)
|
|||
etherxx[ctlrno] = ether;
|
||||
}
|
||||
|
||||
if(getconf("*noetherprobe"))
|
||||
return;
|
||||
|
||||
cardno = ctlrno = 0;
|
||||
while(cards[cardno].type != nil && ctlrno < MaxEther){
|
||||
if(etherxx[ctlrno] != nil){
|
||||
if(getconf("*noetherprobe") == nil){
|
||||
cardno = ctlrno = 0;
|
||||
while(cards[cardno].type != nil && ctlrno < MaxEther){
|
||||
if(etherxx[ctlrno] != nil){
|
||||
ctlrno++;
|
||||
continue;
|
||||
}
|
||||
if((ether = etherprobe(cardno, ctlrno)) == nil){
|
||||
cardno++;
|
||||
continue;
|
||||
}
|
||||
etherxx[ctlrno] = ether;
|
||||
ctlrno++;
|
||||
continue;
|
||||
}
|
||||
if((ether = etherprobe(cardno, ctlrno)) == nil){
|
||||
cardno++;
|
||||
continue;
|
||||
}
|
||||
etherxx[ctlrno] = ether;
|
||||
ctlrno++;
|
||||
}
|
||||
|
||||
netconsole(1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -460,6 +469,8 @@ ethershutdown(void)
|
|||
Ether *ether;
|
||||
int i;
|
||||
|
||||
netconsole(0);
|
||||
|
||||
for(i = 0; i < MaxEther; i++){
|
||||
ether = etherxx[i];
|
||||
if(ether == nil)
|
||||
|
@ -524,9 +535,7 @@ struct Netconsole {
|
|||
};
|
||||
static Netconsole *netcons;
|
||||
|
||||
extern ushort ipcsum(uchar *);
|
||||
|
||||
void
|
||||
static void
|
||||
netconsputc(Uart *, int c)
|
||||
{
|
||||
char *p;
|
||||
|
@ -556,13 +565,11 @@ netconsputc(Uart *, int c)
|
|||
netcons->ether->transmit(netcons->ether);
|
||||
}
|
||||
|
||||
PhysUart netconsphys = {
|
||||
.putc = netconsputc,
|
||||
};
|
||||
Uart netconsuart = { .phys = &netconsphys };
|
||||
static PhysUart netconsphys = { .putc = netconsputc };
|
||||
static Uart netconsuart = { .phys = &netconsphys };
|
||||
|
||||
void
|
||||
netconsole(void)
|
||||
static void
|
||||
netconsole(int on)
|
||||
{
|
||||
char *p;
|
||||
char *r;
|
||||
|
@ -572,8 +579,15 @@ netconsole(void)
|
|||
u64int dstmac;
|
||||
Netconsole *nc;
|
||||
|
||||
if(!on){
|
||||
if(consuart == &netconsuart)
|
||||
consuart = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
if((p = getconf("console")) == nil || strncmp(p, "net ", 4) != 0)
|
||||
return;
|
||||
|
||||
p += 4;
|
||||
for(i = 0; i < 4; i++){
|
||||
srcip[i] = strtol(p, &r, 0);
|
||||
|
|
|
@ -3,6 +3,13 @@ enum {
|
|||
Ntypes = 8,
|
||||
};
|
||||
|
||||
typedef struct Macent Macent;
|
||||
struct Macent
|
||||
{
|
||||
uchar ea[Eaddrlen];
|
||||
ushort port;
|
||||
};
|
||||
|
||||
typedef struct Ether Ether;
|
||||
struct Ether {
|
||||
ISAConf; /* hardware info */
|
||||
|
@ -11,7 +18,6 @@ struct Ether {
|
|||
int ctlrno;
|
||||
int minmtu;
|
||||
int maxmtu;
|
||||
uchar ea[Eaddrlen];
|
||||
|
||||
void (*attach)(Ether*); /* filled in by reset routine */
|
||||
void (*detach)(Ether*);
|
||||
|
@ -25,9 +31,12 @@ struct Ether {
|
|||
Queue* oq;
|
||||
|
||||
Netif;
|
||||
|
||||
uchar ea[Eaddrlen];
|
||||
Macent mactab[127]; /* for bridge */
|
||||
};
|
||||
|
||||
extern Block* etheriq(Ether*, Block*, int);
|
||||
extern void etheriq(Ether*, Block*);
|
||||
extern void addethercard(char*, int(*)(Ether*));
|
||||
extern ulong ethercrc(uchar*, int);
|
||||
extern int parseether(uchar*, char*);
|
||||
|
|
|
@ -139,7 +139,7 @@ wifiiq(Wifi *wifi, Block *b)
|
|||
|
||||
dmatproxy(b, 0, wifi->ether->ea, &wifi->dmat);
|
||||
|
||||
etheriq(wifi->ether, b, 1);
|
||||
etheriq(wifi->ether, b);
|
||||
return;
|
||||
}
|
||||
drop:
|
||||
|
|
|
@ -367,7 +367,7 @@ interrupt(Ureg*, void *arg)
|
|||
dczap(b->rp, len);
|
||||
if(nb = iallocb(Bufsize)){
|
||||
b->wp += len;
|
||||
etheriq(ether, b, 1);
|
||||
etheriq(ether, b);
|
||||
b = nb;
|
||||
b->rp = (uchar*)(((ulong)b->rp + CACHELINESZ-1) & ~(CACHELINESZ-1));
|
||||
b->wp = b->rp;
|
||||
|
|
|
@ -176,7 +176,7 @@ interrupt(Ureg*, void*arg)
|
|||
memmove(b->wp, pkt, len+sizeof(ushort));
|
||||
b->rp += sizeof(ushort);
|
||||
b->wp = b->rp + len;
|
||||
etheriq(ether, b, 1);
|
||||
etheriq(ether, b);
|
||||
}else
|
||||
ether->soverflows++;
|
||||
rx=*ersr&Ersr_rxfpmask;
|
||||
|
|
|
@ -250,7 +250,7 @@ rxproc(void *arg)
|
|||
b = allocb(n);
|
||||
b->wp += n;
|
||||
memmove(b->rp, p->base+2, n);
|
||||
etheriq(edev, b, 1);
|
||||
etheriq(edev, b);
|
||||
}
|
||||
p->addr = PADDR(p->base);
|
||||
p->count = Ioc|Empty|Rbsize;
|
||||
|
|
|
@ -828,7 +828,7 @@ qpkt(Ether *edev, int rdh, ulong control)
|
|||
|
||||
allcache->invse(bp->rp, len); /* clear any stale cached packet */
|
||||
ckrderrs(ctlr, bp, control);
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
|
||||
if(Debug > 1)
|
||||
iprint("R%d ", len);
|
||||
|
|
|
@ -248,7 +248,7 @@ vifrecvdone(Ether *ether, netif_rx_response_t *rr)
|
|||
bp->list = 0;
|
||||
if (rr->flags & NETRXF_data_validated)
|
||||
bp->flag |= Btcpck|Budpck;
|
||||
etheriq(ether, bp, 1);
|
||||
etheriq(ether, bp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ ethrx(Ether *edev)
|
|||
bp->wp = bp->rp + (r[1] & 0x1fff);
|
||||
invaldse(bp->rp, bp->wp);
|
||||
inval2pa(PADDR(bp->rp), PADDR(bp->wp));
|
||||
etheriq(edev, bp, 1);
|
||||
etheriq(edev, bp);
|
||||
c->rxconsi = (c->rxconsi + 1) & (RXRING - 1);
|
||||
replenish(c);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue