From owner-svn-src-head@FreeBSD.ORG Wed Apr 3 23:39:55 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id A27AA3A6; Wed, 3 Apr 2013 23:39:55 +0000 (UTC) (envelope-from jfv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 85B9D876; Wed, 3 Apr 2013 23:39:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r33NdtVY021391; Wed, 3 Apr 2013 23:39:55 GMT (envelope-from jfv@svn.freebsd.org) Received: (from jfv@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r33Ndssw021388; Wed, 3 Apr 2013 23:39:54 GMT (envelope-from jfv@svn.freebsd.org) Message-Id: <201304032339.r33Ndssw021388@svn.freebsd.org> From: Jack F Vogel Date: Wed, 3 Apr 2013 23:39:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249074 - head/sys/dev/e1000 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Apr 2013 23:39:55 -0000 Author: jfv Date: Wed Apr 3 23:39:54 2013 New Revision: 249074 URL: http://svnweb.freebsd.org/changeset/base/249074 Log: Correct the multicast handling in the E1000 drivers as was done in ixgbe, thanks to Mike Karels for this fix. When exiting promiscuous mode MPE bit was being unconditionally cleared, this should not be done if we are in MAX multicast groups. Modified: head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_igb.c head/sys/dev/e1000/if_lem.c Modified: head/sys/dev/e1000/if_em.c ============================================================================== --- head/sys/dev/e1000/if_em.c Wed Apr 3 23:11:15 2013 (r249073) +++ head/sys/dev/e1000/if_em.c Wed Apr 3 23:39:54 2013 (r249074) @@ -94,7 +94,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.3.7"; +char em_driver_version[] = "7.3.8"; /********************************************************************* * PCI Device ID Table @@ -2133,12 +2133,37 @@ em_set_promisc(struct adapter *adapter) static void em_disable_promisc(struct adapter *adapter) { - u32 reg_rctl; + struct ifnet *ifp = adapter->ifp; + u32 reg_rctl; + int mcnt = 0; reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); - reg_rctl &= (~E1000_RCTL_UPE); - reg_rctl &= (~E1000_RCTL_MPE); + if (ifp->if_flags & IFF_ALLMULTI) + mcnt = MAX_NUM_MULTICAST_ADDRESSES; + else { + struct ifmultiaddr *ifma; +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else + if_maddr_rlock(ifp); +#endif + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) + break; + mcnt++; + } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else + if_maddr_runlock(ifp); +#endif + } + /* 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); } Modified: head/sys/dev/e1000/if_igb.c ============================================================================== --- head/sys/dev/e1000/if_igb.c Wed Apr 3 23:11:15 2013 (r249073) +++ head/sys/dev/e1000/if_igb.c Wed Apr 3 23:39:54 2013 (r249074) @@ -100,7 +100,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 2.3.9"; +char igb_driver_version[] = "version - 2.3.10"; /********************************************************************* @@ -374,9 +374,9 @@ SYSCTL_INT(_hw_igb, OID_AUTO, header_spl "Enable receive mbuf header split"); /* -** This will autoconfigure based on -** the number of CPUs and max supported MSI-X messages -** if left at 0. +** This will autoconfigure based on the +** number of CPUs and max supported +** MSIX messages if left at 0. */ static int igb_num_queues = 0; TUNABLE_INT("hw.igb.num_queues", &igb_num_queues); @@ -2096,7 +2096,9 @@ static void igb_disable_promisc(struct adapter *adapter) { struct e1000_hw *hw = &adapter->hw; + struct ifnet *ifp = adapter->ifp; u32 reg; + int mcnt = 0; if (adapter->vf_ifp) { e1000_promisc_set_vf(hw, e1000_promisc_disabled); @@ -2104,7 +2106,31 @@ igb_disable_promisc(struct adapter *adap } reg = E1000_READ_REG(hw, E1000_RCTL); reg &= (~E1000_RCTL_UPE); - reg &= (~E1000_RCTL_MPE); + if (ifp->if_flags & IFF_ALLMULTI) + mcnt = MAX_NUM_MULTICAST_ADDRESSES; + else { + struct ifmultiaddr *ifma; +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else + if_maddr_rlock(ifp); +#endif + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) + break; + mcnt++; + } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else + if_maddr_runlock(ifp); +#endif + } + /* Don't disable if in MAX groups */ + if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) + reg &= (~E1000_RCTL_MPE); E1000_WRITE_REG(hw, E1000_RCTL, reg); } Modified: head/sys/dev/e1000/if_lem.c ============================================================================== --- head/sys/dev/e1000/if_lem.c Wed Apr 3 23:11:15 2013 (r249073) +++ head/sys/dev/e1000/if_lem.c Wed Apr 3 23:39:54 2013 (r249074) @@ -85,7 +85,7 @@ /********************************************************************* * Legacy Em Driver version: *********************************************************************/ -char lem_driver_version[] = "1.0.5"; +char lem_driver_version[] = "1.0.6"; /********************************************************************* * PCI Device ID Table @@ -1856,12 +1856,37 @@ lem_set_promisc(struct adapter *adapter) static void lem_disable_promisc(struct adapter *adapter) { - u32 reg_rctl; + struct ifnet *ifp = adapter->ifp; + u32 reg_rctl; + int mcnt = 0; reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); - reg_rctl &= (~E1000_RCTL_UPE); - reg_rctl &= (~E1000_RCTL_MPE); + if (ifp->if_flags & IFF_ALLMULTI) + mcnt = MAX_NUM_MULTICAST_ADDRESSES; + else { + struct ifmultiaddr *ifma; +#if __FreeBSD_version < 800000 + IF_ADDR_LOCK(ifp); +#else + if_maddr_rlock(ifp); +#endif + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) + break; + mcnt++; + } +#if __FreeBSD_version < 800000 + IF_ADDR_UNLOCK(ifp); +#else + if_maddr_runlock(ifp); +#endif + } + /* 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); }