diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2009-06-05 16:27:41 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2009-06-05 16:27:41 +0000 |
commit | a60864fe4e9e35c14714197a96687b820589824c (patch) | |
tree | ef1c5b3caecfa1bd80fcb1dc4047f4ab266e9b3f /sys/dev/pci/if_em.c | |
parent | 6c3ef1a2ea4a552a93af9adde4436df8dc99b12b (diff) |
tidy up promiscuous mode and multicast handling; from Brad; ok sthen@
Diffstat (limited to 'sys/dev/pci/if_em.c')
-rw-r--r-- | sys/dev/pci/if_em.c | 77 |
1 files changed, 20 insertions, 57 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 79de604936a..44a016b5385 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/* $OpenBSD: if_em.c,v 1.211 2009/06/04 05:08:43 claudio Exp $ */ +/* $OpenBSD: if_em.c,v 1.212 2009/06/05 16:27:40 naddy Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -187,8 +187,7 @@ void em_receive_checksum(struct em_softc *, struct em_rx_desc *, void em_transmit_checksum_setup(struct em_softc *, struct mbuf *, u_int32_t *, u_int32_t *); #endif -void em_set_promisc(struct em_softc *); -void em_set_multi(struct em_softc *); +void em_iff(struct em_softc *); #ifdef EM_DEBUG void em_print_hw_stats(struct em_softc *); #endif @@ -572,24 +571,14 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)"); if (ifp->if_flags & IFF_UP) { - /* - * If only the PROMISC or ALLMULTI flag changes, then - * don't do a full re-init of the chip, just update - * the Rx filter. - */ - if ((ifp->if_flags & IFF_RUNNING) && - ((ifp->if_flags ^ sc->if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) != 0) { - em_set_promisc(sc); - } else { - if (!(ifp->if_flags & IFF_RUNNING)) - em_init(sc); - } + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else + em_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) em_stop(sc); } - sc->if_flags = ifp->if_flags; break; case SIOCSIFMEDIA: @@ -611,7 +600,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) { em_disable_intr(sc); - em_set_multi(sc); + em_iff(sc); if (sc->hw.mac_type == em_82542_rev2_0) em_initialize_receive_unit(sc); em_enable_intr(sc); @@ -749,9 +738,6 @@ em_init(void *arg) } em_initialize_transmit_unit(sc); - /* Setup Multicast table */ - em_set_multi(sc); - /* Prepare receive descriptors and buffers */ if (em_setup_receive_structures(sc)) { printf("%s: Could not setup receive structures\n", @@ -762,8 +748,8 @@ em_init(void *arg) } em_initialize_receive_unit(sc); - /* Don't lose promiscuous settings */ - em_set_promisc(sc); + /* Program promiscuous mode and multicast filters. */ + em_iff(sc); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -1298,44 +1284,17 @@ em_82547_tx_fifo_reset(struct em_softc *sc) } void -em_set_promisc(struct em_softc *sc) -{ - u_int32_t reg_rctl; - struct ifnet *ifp = &sc->interface_data.ac_if; - - reg_rctl = E1000_READ_REG(&sc->hw, RCTL); - - if (ifp->if_flags & IFF_PROMISC) { - reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); - } else if (ifp->if_flags & IFF_ALLMULTI) { - reg_rctl |= E1000_RCTL_MPE; - reg_rctl &= ~E1000_RCTL_UPE; - } else { - reg_rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); - } - E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl); -} - -/********************************************************************* - * Multicast Update - * - * This routine is called whenever multicast address list is updated. - * - **********************************************************************/ - -void -em_set_multi(struct em_softc *sc) +em_iff(struct em_softc *sc) { - u_int32_t reg_rctl = 0; - u_int8_t mta[MAX_NUM_MULTICAST_ADDRESSES * ETH_LENGTH_OF_ADDRESS]; struct ifnet *ifp = &sc->interface_data.ac_if; struct arpcom *ac = &sc->interface_data; + u_int32_t reg_rctl = 0; + u_int8_t mta[MAX_NUM_MULTICAST_ADDRESSES * ETH_LENGTH_OF_ADDRESS]; struct ether_multi *enm; struct ether_multistep step; int i = 0; - IOCTL_DEBUGOUT("em_set_multi: begin"); - ifp->if_flags &= ~IFF_ALLMULTI; + IOCTL_DEBUGOUT("em_iff: begin"); if (sc->hw.mac_type == em_82542_rev2_0) { reg_rctl = E1000_READ_REG(&sc->hw, RCTL); @@ -1347,13 +1306,17 @@ em_set_multi(struct em_softc *sc) } reg_rctl = E1000_READ_REG(&sc->hw, RCTL); - if (ac->ac_multirangecnt > 0 || + reg_rctl &= ~(E1000_RCTL_MPE | E1000_RCTL_UPE); + ifp->if_flags &= ~IFF_ALLMULTI; + + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 || ac->ac_multicnt > MAX_NUM_MULTICAST_ADDRESSES) { ifp->if_flags |= IFF_ALLMULTI; reg_rctl |= E1000_RCTL_MPE; + if (ifp->if_flags & IFF_PROMISC) + reg_rctl |= E1000_RCTL_UPE; } else { ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { bcopy(enm->enm_addrlo, mta + i, ETH_LENGTH_OF_ADDRESS); i += ETH_LENGTH_OF_ADDRESS; @@ -1362,8 +1325,8 @@ em_set_multi(struct em_softc *sc) } em_mc_addr_list_update(&sc->hw, mta, ac->ac_multicnt, 0, 1); - reg_rctl &= ~E1000_RCTL_MPE; } + E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl); if (sc->hw.mac_type == em_82542_rev2_0) { |