From owner-svn-src-all@FreeBSD.ORG Sun Oct 20 14:01:10 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 203AF4B6; Sun, 20 Oct 2013 14:01:10 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id F33702A31; Sun, 20 Oct 2013 14:01:09 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9KE19pU043746; Sun, 20 Oct 2013 14:01:09 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9KE19mj043744; Sun, 20 Oct 2013 14:01:09 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201310201401.r9KE19mj043744@svn.freebsd.org> From: Nathan Whitehorn Date: Sun, 20 Oct 2013 14:01:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r256788 - head/sys/powerpc/pseries X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Oct 2013 14:01:10 -0000 Author: nwhitehorn Date: Sun Oct 20 14:01:09 2013 New Revision: 256788 URL: http://svnweb.freebsd.org/changeset/base/256788 Log: Add multicast filter control. Modified: head/sys/powerpc/pseries/phyp_llan.c Modified: head/sys/powerpc/pseries/phyp_llan.c ============================================================================== --- head/sys/powerpc/pseries/phyp_llan.c Sun Oct 20 13:41:42 2013 (r256787) +++ head/sys/powerpc/pseries/phyp_llan.c Sun Oct 20 14:01:09 2013 (r256788) @@ -60,6 +60,11 @@ __FBSDID("$FreeBSD$"); #define LLAN_MAX_TX_PACKETS 100 #define LLAN_RX_BUF_LEN 8*PAGE_SIZE +#define LLAN_BUFDESC_VALID (1ULL << 63) +#define LLAN_ADD_MULTICAST 0x1 +#define LLAN_DEL_MULTICAST 0x2 +#define LLAN_CLEAR_MULTICAST 0x3 + struct llan_xfer { struct mbuf *rx_mbuf; bus_dmamap_t rx_dmamap; @@ -113,6 +118,7 @@ static int llan_ioctl(struct ifnet *ifp, static void llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err); static int llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx); +static int llan_set_multicast(struct llan_softc *sc); static devclass_t llan_devclass; static device_method_t llan_methods[] = { @@ -249,7 +255,7 @@ llan_init(void *xsc) sc->rx_dma_slot = 0; sc->rx_valid_val = 1; - rx_buf_desc = (1UL << 63); /* valid */ + rx_buf_desc = LLAN_BUFDESC_VALID; rx_buf_desc |= (sc->rx_buf_len << 32); rx_buf_desc |= sc->rx_buf_phys; memcpy(&macaddr, sc->mac_address, 8); @@ -307,7 +313,7 @@ llan_add_rxbuf(struct llan_softc *sc, st bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap, BUS_DMASYNC_PREREAD); - rx->rx_bufdesc = (1UL << 63); /* valid */ + rx->rx_bufdesc = LLAN_BUFDESC_VALID; rx->rx_bufdesc |= (((uint64_t)segs[0].ds_len) << 32); rx->rx_bufdesc |= segs[0].ds_addr; error = phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit, rx->rx_bufdesc); @@ -376,7 +382,7 @@ llan_send_packet(void *xsc, bus_dma_segm bzero(bufdescs, sizeof(bufdescs)); for (i = 0; i < nsegs; i++) { - bufdescs[i] = (1UL << 63); /* valid */ + bufdescs[i] = LLAN_BUFDESC_VALID; bufdescs[i] |= (((uint64_t)segs[i].ds_len) << 32); bufdescs[i] |= segs[i].ds_addr; } @@ -442,11 +448,50 @@ llan_start(struct ifnet *ifp) } static int +llan_set_multicast(struct llan_softc *sc) +{ + struct ifnet *ifp = sc->ifp; + struct ifmultiaddr *inm; + uint64_t macaddr; + + mtx_assert(&sc->io_lock, MA_OWNED); + + phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_CLEAR_MULTICAST, 0); + + if_maddr_rlock(ifp); + TAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) { + if (inm->ifma_addr->sa_family != AF_LINK) + continue; + + memcpy((uint8_t *)&macaddr + 2, + LLADDR((struct sockaddr_dl *)inm->ifma_addr), 6); + phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_ADD_MULTICAST, + macaddr); + } + if_maddr_runlock(ifp); + + return (0); +} + +static int llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - int err; + int err = 0; + struct llan_softc *sc = ifp->if_softc; - err = ether_ioctl(ifp, cmd, data); + switch (cmd) { + case SIOCADDMULTI: + case SIOCDELMULTI: + mtx_lock(&sc->io_lock); + if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + llan_set_multicast(sc); + mtx_unlock(&sc->io_lock); + break; + case SIOCSIFFLAGS: + default: + err = ether_ioctl(ifp, cmd, data); + break; + } return (err); }