Index: sys/dev/e1000/if_em.c =================================================================== --- sys/dev/e1000/if_em.c +++ sys/dev/e1000/if_em.c @@ -303,7 +303,6 @@ static void em_disable_aspm(struct adapter *); int em_intr(void *arg); -static void em_disable_promisc(if_ctx_t ctx); /* MSI-X handlers */ static int em_if_msix_intr_assign(if_ctx_t, int); @@ -1636,11 +1635,20 @@ em_if_set_promisc(if_ctx_t ctx, int flags) { struct adapter *adapter = iflib_get_softc(ctx); + struct ifnet *ifp = iflib_get_ifp(ctx); u32 reg_rctl; - - em_disable_promisc(ctx); + int mcnt = 0; reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + reg_rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_UPE); + if (flags & IFF_ALLMULTI) + mcnt = MAX_NUM_MULTICAST_ADDRESSES; + else + mcnt = if_multiaddr_count(ifp, MAX_NUM_MULTICAST_ADDRESSES); + + if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) + reg_rctl &= (~E1000_RCTL_MPE); + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); if (flags & IFF_PROMISC) { reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); @@ -1656,35 +1664,12 @@ return (0); } -static void -em_disable_promisc(if_ctx_t ctx) -{ - struct adapter *adapter = iflib_get_softc(ctx); - struct ifnet *ifp = iflib_get_ifp(ctx); - u32 reg_rctl; - int mcnt = 0; - - reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); - reg_rctl &= (~E1000_RCTL_UPE); - if (if_getflags(ifp) & IFF_ALLMULTI) - mcnt = MAX_NUM_MULTICAST_ADDRESSES; - else - mcnt = if_multiaddr_count(ifp, MAX_NUM_MULTICAST_ADDRESSES); - /* Don't disable if in MAX groups */ - if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) - reg_rctl &= (~E1000_RCTL_MPE); - reg_rctl &= (~E1000_RCTL_SBP); - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); -} - - /********************************************************************* * Multicast Update * * This routine is called whenever multicast address list is updated. * **********************************************************************/ - static void em_if_multi_set(if_ctx_t ctx) { @@ -1711,11 +1696,20 @@ if_multiaddr_array(ifp, mta, &mcnt, MAX_NUM_MULTICAST_ADDRESSES); - if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { - reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); + reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); + if (if_getflags(ifp) & IFF_PROMISC) + reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); + else if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES || + if_getflags(ifp) & IFF_ALLMULTI) { reg_rctl |= E1000_RCTL_MPE; - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + reg_rctl &= ~E1000_RCTL_UPE; } else + reg_rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); + + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); + + if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) e1000_update_mc_addr_list(&adapter->hw, mta, mcnt); if (adapter->hw.mac.type == e1000_82542 &&