summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_em.c
diff options
context:
space:
mode:
authorChristian Weisgerber <naddy@cvs.openbsd.org>2009-06-05 16:27:41 +0000
committerChristian Weisgerber <naddy@cvs.openbsd.org>2009-06-05 16:27:41 +0000
commita60864fe4e9e35c14714197a96687b820589824c (patch)
treeef1c5b3caecfa1bd80fcb1dc4047f4ab266e9b3f /sys/dev/pci/if_em.c
parent6c3ef1a2ea4a552a93af9adde4436df8dc99b12b (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.c77
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) {