From 9dc667427cb587609974f6402866419d7b7d1119 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 25 Jun 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-06-25 --- mpc/devether.c | 37 ++++++----- mpc/etherwavelan.c | 151 ++++++++++++++++++++++++--------------------- pc/devether.c | 37 ++++++----- port/devbridge.c | 2 + port/netif.c | 14 +++-- port/netif.h | 2 + 6 files changed, 137 insertions(+), 106 deletions(-) diff --git a/mpc/devether.c b/mpc/devether.c index e26b3a933b4c3681d9fe3e9443effcd6ced7c1b8..22bfea833b61cf42c474052771866455cc43ec22 100644 --- a/mpc/devether.c +++ b/mpc/devether.c @@ -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; } diff --git a/mpc/etherwavelan.c b/mpc/etherwavelan.c index 08f43f740bb5ba5f53908feafafe532cf4908be6..9f15dd277d77ef8cf30c1c64ccba5fb67e42b72f 100644 --- a/mpc/etherwavelan.c +++ b/mpc/etherwavelan.c @@ -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 */ diff --git a/pc/devether.c b/pc/devether.c index e26b3a933b4c3681d9fe3e9443effcd6ced7c1b8..22bfea833b61cf42c474052771866455cc43ec22 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -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; } diff --git a/port/devbridge.c b/port/devbridge.c index 4be66a3fec588ee01a458e2cd91c2536ead99e91..b526ac5a55b3ce0e5d0c4fc675a7fd28e6eab193 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -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); diff --git a/port/netif.c b/port/netif.c index 518e1ff10f4db9f6e5e58407ef772aa2beb95dab..1c9ecccaee41a847d4c61a1f47c9b35d73ddb48d 100644 --- a/port/netif.c +++ b/port/netif.c @@ -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"); diff --git a/port/netif.h b/port/netif.h index b7e21733d848dc2b30fa671390e1a66e611c8fef..b728071a3a512c0871b7a55f71020ae1c12a0a02 100644 --- a/port/netif.h +++ b/port/netif.h @@ -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 */