summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrad <brad@openbsd.org>2013-03-09 09:34:15 +0000
committerbrad <brad@openbsd.org>2013-03-09 09:34:15 +0000
commit003349b43763ee85db6acd1ac603690e8f6a96f6 (patch)
treeef0793ce12552a13c8636a6293fc5385b46d4209
parentfix target name (diff)
downloadwireguard-openbsd-003349b43763ee85db6acd1ac603690e8f6a96f6.tar.xz
wireguard-openbsd-003349b43763ee85db6acd1ac603690e8f6a96f6.zip
Rewrite the receive filter handling code and cleanup the ioctl bits.
ok sthen@
-rw-r--r--sys/dev/pci/if_ste.c129
-rw-r--r--sys/dev/pci/if_stereg.h3
2 files changed, 50 insertions, 82 deletions
diff --git a/sys/dev/pci/if_ste.c b/sys/dev/pci/if_ste.c
index 3315e99b298..9113bb7af21 100644
--- a/sys/dev/pci/if_ste.c
+++ b/sys/dev/pci/if_ste.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ste.c,v 1.51 2013/01/16 06:15:58 brad Exp $ */
+/* $OpenBSD: if_ste.c,v 1.52 2013/03/09 09:34:15 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -115,7 +115,7 @@ int ste_eeprom_wait(struct ste_softc *);
int ste_read_eeprom(struct ste_softc *, caddr_t, int,
int, int);
void ste_wait(struct ste_softc *);
-void ste_setmulti(struct ste_softc *);
+void ste_iff(struct ste_softc *);
int ste_init_rx_list(struct ste_softc *);
void ste_init_tx_list(struct ste_softc *);
@@ -502,52 +502,56 @@ ste_read_eeprom(struct ste_softc *sc, caddr_t dest, int off, int cnt, int swap)
}
void
-ste_setmulti(struct ste_softc *sc)
+ste_iff(struct ste_softc *sc)
{
- struct ifnet *ifp;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
struct arpcom *ac = &sc->arpcom;
struct ether_multi *enm;
struct ether_multistep step;
+ u_int32_t rxmode, hashes[2];
int h = 0;
- u_int32_t hashes[2] = { 0, 0 };
- ifp = &sc->arpcom.ac_if;
-allmulti:
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
- STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
- return;
- }
+ rxmode = CSR_READ_1(sc, STE_RX_MODE);
+ rxmode &= ~(STE_RXMODE_ALLMULTI | STE_RXMODE_BROADCAST |
+ STE_RXMODE_MULTIHASH | STE_RXMODE_PROMISC |
+ STE_RXMODE_UNICAST);
+ bzero(hashes, sizeof(hashes));
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ /*
+ * Always accept broadcast frames.
+ * Always accept frames destined to our station address.
+ */
+ rxmode |= STE_RXMODE_BROADCAST | STE_RXMODE_UNICAST;
- /* first, zot all the existing hash bits */
- CSR_WRITE_2(sc, STE_MAR0, 0);
- CSR_WRITE_2(sc, STE_MAR1, 0);
- CSR_WRITE_2(sc, STE_MAR2, 0);
- CSR_WRITE_2(sc, STE_MAR3, 0);
-
- /* now program new ones */
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
- ifp->if_flags |= IFF_ALLMULTI;
- goto allmulti;
+ if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
+ ifp->if_flags |= IFF_ALLMULTI;
+ rxmode |= STE_RXMODE_ALLMULTI;
+ if (ifp->if_flags & IFF_PROMISC)
+ rxmode |= STE_RXMODE_PROMISC;
+ } else {
+ rxmode |= STE_RXMODE_MULTIHASH;
+
+ /* now program new ones */
+ ETHER_FIRST_MULTI(step, ac, enm);
+ while (enm != NULL) {
+ h = ether_crc32_be(enm->enm_addrlo,
+ ETHER_ADDR_LEN) & 0x3F;
+
+ if (h < 32)
+ hashes[0] |= (1 << h);
+ else
+ hashes[1] |= (1 << (h - 32));
+
+ ETHER_NEXT_MULTI(step, enm);
}
- h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F;
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- ETHER_NEXT_MULTI(step, enm);
}
CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF);
CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF);
CSR_WRITE_2(sc, STE_MAR2, hashes[1] & 0xFFFF);
CSR_WRITE_2(sc, STE_MAR3, (hashes[1] >> 16) & 0xFFFF);
- STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_ALLMULTI);
- STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_MULTIHASH);
-
- return;
+ CSR_WRITE_1(sc, STE_RX_MODE, rxmode);
}
int
@@ -1100,24 +1104,8 @@ ste_init(void *xsc)
/* Set the TX reclaim threshold. */
CSR_WRITE_1(sc, STE_TX_RECLAIM_THRESH, (ETHER_MAX_DIX_LEN >> 4));
- /* Set up the RX filter. */
- CSR_WRITE_1(sc, STE_RX_MODE, STE_RXMODE_UNICAST);
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC) {
- STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
- } else {
- STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_PROMISC);
- }
-
- /* Set capture broadcast bit to accept broadcast frames. */
- if (ifp->if_flags & IFF_BROADCAST) {
- STE_SETBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
- } else {
- STE_CLRBIT1(sc, STE_RX_MODE, STE_RXMODE_BROADCAST);
- }
-
- ste_setmulti(sc);
+ /* Program promiscuous mode and multicast filters. */
+ ste_iff(sc);
/* Load the address of the RX list. */
STE_SETBIT4(sc, STE_DMACTL, STE_DMACTL_RXDMA_STALL);
@@ -1245,7 +1233,6 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct ste_softc *sc = ifp->if_softc;
struct ifaddr *ifa = (struct ifaddr *) data;
struct ifreq *ifr = (struct ifreq *) data;
- struct mii_data *mii;
int s, error = 0;
s = splnet();
@@ -1253,34 +1240,19 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
switch(command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
- switch (ifa->ifa_addr->sa_family) {
- case AF_INET:
+ if (!(ifp->if_flags & IFF_RUNNING))
ste_init(sc);
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET)
arp_ifinit(&sc->arpcom, ifa);
- break;
- default:
- ste_init(sc);
- break;
- }
+#endif
break;
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->ste_if_flags & IFF_PROMISC)) {
- STE_SETBIT1(sc, STE_RX_MODE,
- STE_RXMODE_PROMISC);
- } else if (ifp->if_flags & IFF_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->ste_if_flags & IFF_PROMISC) {
- STE_CLRBIT1(sc, STE_RX_MODE,
- STE_RXMODE_PROMISC);
- }
- if (ifp->if_flags & IFF_RUNNING &&
- (ifp->if_flags ^ sc->ste_if_flags) & IFF_ALLMULTI)
- ste_setmulti(sc);
- if (!(ifp->if_flags & IFF_RUNNING)) {
+ if (ifp->if_flags & IFF_RUNNING)
+ error = ENETRESET;
+ else {
sc->ste_tx_thresh = STE_TXSTART_THRESH;
ste_init(sc);
}
@@ -1288,14 +1260,11 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (ifp->if_flags & IFF_RUNNING)
ste_stop(sc);
}
- sc->ste_if_flags = ifp->if_flags;
- error = 0;
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
- mii = &sc->sc_mii;
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
break;
default:
@@ -1304,7 +1273,7 @@ ste_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (error == ENETRESET) {
if (ifp->if_flags & IFF_RUNNING)
- ste_setmulti(sc);
+ ste_iff(sc);
error = 0;
}
diff --git a/sys/dev/pci/if_stereg.h b/sys/dev/pci/if_stereg.h
index 863d3e683a8..a05fcef8fd6 100644
--- a/sys/dev/pci/if_stereg.h
+++ b/sys/dev/pci/if_stereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_stereg.h,v 1.11 2012/10/18 21:44:21 deraadt Exp $ */
+/* $OpenBSD: if_stereg.h,v 1.12 2013/03/09 09:34:15 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -507,7 +507,6 @@ struct ste_softc {
bus_space_handle_t ste_bhandle;
int ste_tx_thresh;
u_int8_t ste_link;
- int ste_if_flags;
struct ste_chain *ste_tx_prev;
struct ste_list_data *ste_ldata;
caddr_t ste_ldata_ptr;