Index: if_em.c =================================================================== RCS file: /home/ncvs/src/sys/dev/e1000/if_em.c,v --- if_em.c 10 Sep 2009 21:14:55 -0000 1.26 +++ if_em.c 17 Nov 2009 19:27:12 -0000 @@ -1277,6 +1277,17 @@ (IFF_PROMISC | IFF_ALLMULTI)) { em_disable_promisc(adapter); em_set_promisc(adapter); + /* em_set_multi() will set + multicast promiscuous mode + when there is a large number + of groups. Therefore, if we + play around with the + promiscuous flags, we should + call em_set_multi to give it + a chance to re-enable + multicast promiscuous mode, + if required. */ + em_set_multi(adapter); } } else em_init_locked(adapter); @@ -2555,12 +2566,20 @@ } if_maddr_runlock(ifp); + reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) { - reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); reg_rctl |= E1000_RCTL_MPE; - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); - } else + } else { + /* Turn off multicast promiscuous mode if it + is on and it doesn't need to be enabled + according to the if_flags. */ + if ((reg_rctl & E1000_RCTL_MPE) && + !(ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { + reg_rctl &= (~E1000_RCTL_MPE); + } e1000_update_mc_addr_list(&adapter->hw, mta, mcnt); + } + E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); if (adapter->hw.mac.type == e1000_82542 && adapter->hw.revision_id == E1000_REVISION_2) {