M mpc/devether.c => mpc/devether.c +21 -16
@@ 130,11 130,11 @@ etherrtrace(Netfile* f, Etherpkt* pkt, int len)
}
Block*
-etheriq(Ether* ether, Block* bp, int freebp)
+etheriq(Ether* ether, Block* bp, int fromwire)
{
Etherpkt *pkt;
ushort type;
- int len, multi, forme;
+ int len, multi, tome, fromme;
Netfile **ep, *f, **fp, *fx;
Block *xbp;
@@ 150,7 150,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
/* check for valid multcast addresses */
if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){
if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
- if(freebp){
+ if(fromwire){
freeb(bp);
bp = 0;
}
@@ 158,19 158,25 @@ etheriq(Ether* ether, Block* bp, int freebp)
}
}
- // is it for me?
- forme = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
+ /* is it for me? */
+ tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
+ fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
/*
* Multiplex the packet to all the connections which want it.
- * If the packet is not to be used subsequently (freebp != 0),
+ * 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) && (f->type == type || f->type < 0) && (forme || multi || f->prom)){
- if(f->type > -2){
- if(freebp && fx == 0)
+ if(f = *fp)
+ if(f->type == type || f->type < 0)
+ if(tome || multi || f->prom){
+ /* Don't want to hear bridged packets */
+ if(f->bridge && !fromwire && !fromme)
+ continue;
+ if(!f->headersonly){
+ if(fromwire && fx == 0)
fx = f;
else if(xbp = iallocb(len)){
memmove(xbp->wp, pkt, len);
@@ 190,7 196,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
ether->soverflows++;
return 0;
}
- if(freebp){
+ if(fromwire){
freeb(bp);
return 0;
}
@@ 201,7 207,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
static int
etheroq(Ether* ether, Block* bp)
{
- int len, loopback, s, mine;
+ int len, loopback, s;
Etherpkt *pkt;
ether->outpackets++;
@@ 217,19 223,18 @@ etheroq(Ether* ether, Block* bp)
*/
pkt = (Etherpkt*)bp->rp;
len = BLEN(bp);
- loopback = (memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0);
- mine = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
- if(mine)
+ loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
s = splhi();
- etheriq(ether, bp, loopback);
+ etheriq(ether, bp, 0);
splx(s);
}
if(!loopback){
qbwrite(ether->oq, bp);
ether->transmit(ether);
- }
+ } else
+ freeb(bp);
return len;
}
M mpc/etherwavelan.c => mpc/etherwavelan.c +81 -70
@@ 626,76 626,87 @@ int wavelan_diag(Ether *ether, int port)
int wavelan_hw_config(int base, Ether *ether)
{
- struct i82593_conf_block cfblk;
-
- memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
- cfblk.d6mod = FALSE; /* Run in i82593 advanced mode */
- cfblk.fifo_limit = 6; /* = 48 bytes rx and tx fifo thresholds */
- cfblk.forgnesi = FALSE; /* 0=82C501, 1=AMD7992B compatibility */
- cfblk.fifo_32 = 0;
- cfblk.throttle_enb = TRUE;
- cfblk.contin = TRUE; /* enable continuous mode */
- cfblk.cntrxint = FALSE; /* enable continuous mode receive interrupts */
- cfblk.addr_len = WAVELAN_ADDR_SIZE;
- cfblk.acloc = TRUE; /* Disable source addr insertion by i82593 */
- cfblk.preamb_len = 2; /* 7 byte preamble */
- cfblk.loopback = FALSE;
- cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */
- cfblk.exp_prio = 0; /* conform to 802.3 backoff algoritm */
- cfblk.bof_met = 0; /* conform to 802.3 backoff algoritm */
- cfblk.ifrm_spc = 6; /* 96 bit times interframe spacing */
- cfblk.slottim_low = 0x10 & 0x7; /* 512 bit times slot time */
- cfblk.slottim_hi = 0x10 >> 3;
- cfblk.max_retr = 15;
- cfblk.prmisc = FALSE; /* Promiscuous mode ?? */
- cfblk.bc_dis = FALSE; /* Enable broadcast reception */
- cfblk.crs_1 = TRUE; /* Transmit without carrier sense */
- cfblk.nocrc_ins = FALSE; /* i82593 generates CRC */
- cfblk.crc_1632 = FALSE; /* 32-bit Autodin-II CRC */
- cfblk.crs_cdt = FALSE; /* CD not to be interpreted as CS */
- cfblk.cs_filter = 0; /* CS is recognized immediately */
- cfblk.crs_src = FALSE; /* External carrier sense */
- cfblk.cd_filter = 0; /* CD is recognized immediately */
- cfblk.min_fr_len = 64 >> 2; /* Minimum frame length 64 bytes */
- cfblk.lng_typ = FALSE; /* Length field > 1500 = type field */
- cfblk.lng_fld = TRUE; /* Disable 802.3 length field check */
- cfblk.rxcrc_xf = TRUE; /* Don't transfer CRC to memory */
- cfblk.artx = TRUE; /* Disable automatic retransmission */
- cfblk.sarec = TRUE; /* Disable source addr trig of CD */
- cfblk.tx_jabber = TRUE; /* Disable jabber jam sequence */
- cfblk.hash_1 = FALSE; /* Use bits 0-5 in mc address hash */
- cfblk.lbpkpol = TRUE; /* Loopback pin active high */
- cfblk.fdx = FALSE; /* Disable full duplex operation */
- cfblk.dummy_6 = 0x3f; /* all ones */
- cfblk.mult_ia = FALSE; /* No multiple individual addresses */
- cfblk.dis_bof = FALSE; /* Disable the backoff algorithm ?! */
- cfblk.dummy_1 = TRUE; /* set to 1 */
- cfblk.tx_ifs_retrig = 3; /* Hmm... Disabled */
- cfblk.mc_all = FALSE; /* No multicast all mode */
- cfblk.rcv_mon = 0; /* Monitor mode disabled */
- cfblk.frag_acpt = TRUE;/* Do not accept fragments */
- cfblk.tstrttrs = FALSE; /* No start transmission threshold */
- cfblk.fretx = TRUE; /* FIFO automatic retransmission */
- cfblk.syncrqs = TRUE; /* Synchronous DRQ deassertion... */
- cfblk.sttlen = TRUE; /* 6 byte status registers */
- cfblk.rx_eop = TRUE; /* Signal EOP on packet reception */
- cfblk.tx_eop = TRUE; /* Signal EOP on packet transmission */
- cfblk.rbuf_size = RX_SIZE>>11; /* Set receive buffer size */
- cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */
-
- outb(PIORL(base), (TX_BASE & 0xff));
- outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX));
- outb(PIOP(base), (sizeof(struct i82593_conf_block) & 0xff)); /* lsb */
- outb(PIOP(base), (sizeof(struct i82593_conf_block) >> 8)); /* msb */
-
-// super sleazy - but it will do for now
-// outsb(PIOP(base), ((char *) &cfblk), sizeof(struct i82593_conf_block));
- {
- uchar buf[16];
- int i;
- for(i=0; i<16; i++)
- buf[i] = ((char *) &cfblk)[(i&~3)+(3-(i&3))];
- outsb(PIOP(base), buf, sizeof(struct i82593_conf_block));
+
+ /* the i82593_conf_block uses bit fields which are not
+ * machine independent. In particular this code does not work
+ * on the powerPC (bigendian)
+ */
+ if(0) {
+ struct i82593_conf_block cfblk;
+
+ memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
+ cfblk.d6mod = FALSE; /* Run in i82593 advanced mode */
+ cfblk.fifo_limit = 6; /* = 48 bytes rx and tx fifo thresholds */
+ cfblk.forgnesi = FALSE; /* 0=82C501, 1=AMD7992B compatibility */
+ cfblk.fifo_32 = 0;
+ cfblk.throttle_enb = TRUE;
+ cfblk.contin = TRUE; /* enable continuous mode */
+ cfblk.cntrxint = FALSE; /* enable continuous mode receive interrupts */
+ cfblk.addr_len = WAVELAN_ADDR_SIZE;
+ cfblk.acloc = TRUE; /* Disable source addr insertion by i82593 */
+ cfblk.preamb_len = 2; /* 7 byte preamble */
+ cfblk.loopback = FALSE;
+ cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */
+ cfblk.exp_prio = 0; /* conform to 802.3 backoff algoritm */
+ cfblk.bof_met = 0; /* conform to 802.3 backoff algoritm */
+ cfblk.ifrm_spc = 6; /* 96 bit times interframe spacing */
+ cfblk.slottim_low = 0x10 & 0x7; /* 512 bit times slot time */
+ cfblk.slottim_hi = 0x10 >> 3;
+ cfblk.max_retr = 15;
+ cfblk.prmisc = FALSE; /* Promiscuous mode ?? */
+ cfblk.bc_dis = FALSE; /* Enable broadcast reception */
+ cfblk.crs_1 = TRUE; /* Transmit without carrier sense */
+ cfblk.nocrc_ins = FALSE; /* i82593 generates CRC */
+ cfblk.crc_1632 = FALSE; /* 32-bit Autodin-II CRC */
+ cfblk.crs_cdt = FALSE; /* CD not to be interpreted as CS */
+ cfblk.cs_filter = 0; /* CS is recognized immediately */
+ cfblk.crs_src = FALSE; /* External carrier sense */
+ cfblk.cd_filter = 0; /* CD is recognized immediately */
+ cfblk.min_fr_len = 64 >> 2; /* Minimum frame length 64 bytes */
+ cfblk.lng_typ = FALSE; /* Length field > 1500 = type field */
+ cfblk.lng_fld = TRUE; /* Disable 802.3 length field check */
+ cfblk.rxcrc_xf = TRUE; /* Don't transfer CRC to memory */
+ cfblk.artx = TRUE; /* Disable automatic retransmission */
+ cfblk.sarec = TRUE; /* Disable source addr trig of CD */
+ cfblk.tx_jabber = TRUE; /* Disable jabber jam sequence */
+ cfblk.hash_1 = FALSE; /* Use bits 0-5 in mc address hash */
+ cfblk.lbpkpol = TRUE; /* Loopback pin active high */
+ cfblk.fdx = FALSE; /* Disable full duplex operation */
+ cfblk.dummy_6 = 0x3f; /* all ones */
+ cfblk.mult_ia = FALSE; /* No multiple individual addresses */
+ cfblk.dis_bof = FALSE; /* Disable the backoff algorithm ?! */
+ cfblk.dummy_1 = TRUE; /* set to 1 */
+ cfblk.tx_ifs_retrig = 3; /* Hmm... Disabled */
+ cfblk.mc_all = FALSE; /* No multicast all mode */
+ cfblk.rcv_mon = 0; /* Monitor mode disabled */
+ cfblk.frag_acpt = TRUE;/* Do not accept fragments */
+ cfblk.tstrttrs = FALSE; /* No start transmission threshold */
+ cfblk.fretx = TRUE; /* FIFO automatic retransmission */
+ cfblk.syncrqs = TRUE; /* Synchronous DRQ deassertion... */
+ cfblk.sttlen = TRUE; /* 6 byte status registers */
+ cfblk.rx_eop = TRUE; /* Signal EOP on packet reception */
+ cfblk.tx_eop = TRUE; /* Signal EOP on packet transmission */
+ cfblk.rbuf_size = RX_SIZE>>11; /* Set receive buffer size */
+ cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */
+ outb(PIORL(base), (TX_BASE & 0xff));
+ outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX));
+ outb(PIOP(base), (sizeof(struct i82593_conf_block) & 0xff)); /* lsb */
+ outb(PIOP(base), (sizeof(struct i82593_conf_block) >> 8)); /* msb */
+ outsb(PIOP(base), ((char *) &cfblk), sizeof(struct i82593_conf_block));
+ } else {
+ /*
+ * The following are the values that result in the above on
+ * the 386. Sleazy, but these values don't change and I
+ * don't have any docs anyway
+ */
+ uchar buf[16] = { 0x86, 0x80, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0x08,
+ 0x00, 0x40, 0xbe, 0x00, 0x3f, 0x47, 0xf1, 0x24};
+
+ outb(PIORL(base), (TX_BASE & 0xff));
+ outb(PIORH(base), (((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX));
+ outb(PIOP(base), (sizeof(buf) & 0xff)); /* lsb */
+ outb(PIOP(base), (sizeof(buf) >> 8)); /* msb */
+ outsb(PIOP(base), buf, sizeof(buf));
}
/* reset transmit DMA pointer */
M pc/devether.c => pc/devether.c +21 -16
@@ 130,11 130,11 @@ etherrtrace(Netfile* f, Etherpkt* pkt, int len)
}
Block*
-etheriq(Ether* ether, Block* bp, int freebp)
+etheriq(Ether* ether, Block* bp, int fromwire)
{
Etherpkt *pkt;
ushort type;
- int len, multi, forme;
+ int len, multi, tome, fromme;
Netfile **ep, *f, **fp, *fx;
Block *xbp;
@@ 150,7 150,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
/* check for valid multcast addresses */
if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){
if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
- if(freebp){
+ if(fromwire){
freeb(bp);
bp = 0;
}
@@ 158,19 158,25 @@ etheriq(Ether* ether, Block* bp, int freebp)
}
}
- // is it for me?
- forme = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
+ /* is it for me? */
+ tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
+ fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
/*
* Multiplex the packet to all the connections which want it.
- * If the packet is not to be used subsequently (freebp != 0),
+ * 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) && (f->type == type || f->type < 0) && (forme || multi || f->prom)){
- if(f->type > -2){
- if(freebp && fx == 0)
+ if(f = *fp)
+ if(f->type == type || f->type < 0)
+ if(tome || multi || f->prom){
+ /* Don't want to hear bridged packets */
+ if(f->bridge && !fromwire && !fromme)
+ continue;
+ if(!f->headersonly){
+ if(fromwire && fx == 0)
fx = f;
else if(xbp = iallocb(len)){
memmove(xbp->wp, pkt, len);
@@ 190,7 196,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
ether->soverflows++;
return 0;
}
- if(freebp){
+ if(fromwire){
freeb(bp);
return 0;
}
@@ 201,7 207,7 @@ etheriq(Ether* ether, Block* bp, int freebp)
static int
etheroq(Ether* ether, Block* bp)
{
- int len, loopback, s, mine;
+ int len, loopback, s;
Etherpkt *pkt;
ether->outpackets++;
@@ 217,19 223,18 @@ etheroq(Ether* ether, Block* bp)
*/
pkt = (Etherpkt*)bp->rp;
len = BLEN(bp);
- loopback = (memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0);
- mine = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
- if(mine)
+ loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
s = splhi();
- etheriq(ether, bp, loopback);
+ etheriq(ether, bp, 0);
splx(s);
}
if(!loopback){
qbwrite(ether->oq, bp);
ether->transmit(ether);
- }
+ } else
+ freeb(bp);
return len;
}
M port/devbridge.c => port/devbridge.c +2 -0
@@ 513,6 513,8 @@ portbind(Bridge *b, int argc, char *argv[])
devtab[ctl->type]->write(ctl, buf, strlen(buf), 0);
snprint(buf, sizeof(buf), "promiscuous");
devtab[ctl->type]->write(ctl, buf, strlen(buf), 0);
+ snprint(buf, sizeof(buf), "bridge");
+ devtab[ctl->type]->write(ctl, buf, strlen(buf), 0);
// open data port
port->data[0] = namec(path, Aopen, ORDWR, 0);
M port/netif.c => port/netif.c +10 -4
@@ 284,10 284,16 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
if(f->type < 0)
nif->all++;
} else if(matchtoken(buf, "promiscuous")){
- f->prom = 1;
- nif->prom++;
- if(nif->prom == 1 && nif->promiscuous != nil)
- nif->promiscuous(nif->arg, 1);
+ if(f->prom == 0){
+ if(nif->prom == 0 && nif->promiscuous != nil)
+ nif->promiscuous(nif->arg, 1);
+ f->prom = 1;
+ nif->prom++;
+ }
+ } else if(matchtoken(buf, "bridge")){
+ f->bridge = 1;
+ } else if(matchtoken(buf, "headersonly")){
+ f->headersonly = 1;
} else if((p = matchtoken(buf, "addmulti")) != 0){
if(parseaddr(binaddr, p, nif->alen) < 0)
error("bad address");
M port/netif.h => port/netif.h +2 -0
@@ 39,6 39,8 @@ struct Netfile
int type; /* multiplexor type */
int prom; /* promiscuous mode */
+ int bridge; /* bridge mode */
+ int headersonly; /* headers only - no data */
uchar maddr[8]; /* bitmask of multicast addresses requested */
int nmaddr; /* number of multicast addresses */