Date: Mon, 28 Oct 2013 23:47:53 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r257292 - in stable/10/sys: conf powerpc/conf powerpc/pseries Message-ID: <201310282347.r9SNlrQl091263@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Mon Oct 28 23:47:52 2013 New Revision: 257292 URL: http://svnweb.freebsd.org/changeset/base/257292 Log: MFC r256777-256779,256788: Add driver for POWER hypervisor interpartition ethernet. Approved by: re (glebius) Added: stable/10/sys/powerpc/pseries/phyp_llan.c - copied, changed from r256778, head/sys/powerpc/pseries/phyp_llan.c Modified: stable/10/sys/conf/files.powerpc stable/10/sys/powerpc/conf/GENERIC64 stable/10/sys/powerpc/pseries/phyp-hvcall.S Directory Properties: stable/10/sys/ (props changed) stable/10/sys/conf/ (props changed) Modified: stable/10/sys/conf/files.powerpc ============================================================================== --- stable/10/sys/conf/files.powerpc Mon Oct 28 23:42:44 2013 (r257291) +++ stable/10/sys/conf/files.powerpc Mon Oct 28 23:47:52 2013 (r257292) @@ -228,6 +228,7 @@ powerpc/ps3/ps3-hvcall.S optional ps3 sc powerpc/pseries/phyp-hvcall.S optional pseries powerpc64 powerpc/pseries/mmu_phyp.c optional pseries powerpc64 powerpc/pseries/phyp_console.c optional pseries powerpc64 uart +powerpc/pseries/phyp_llan.c optional llan powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus powerpc/pseries/platform_chrp.c optional pseries powerpc/pseries/plpar_iommu.c optional pseries powerpc64 Modified: stable/10/sys/powerpc/conf/GENERIC64 ============================================================================== --- stable/10/sys/powerpc/conf/GENERIC64 Mon Oct 28 23:42:44 2013 (r257291) +++ stable/10/sys/powerpc/conf/GENERIC64 Mon Oct 28 23:47:52 2013 (r257292) @@ -128,6 +128,7 @@ device em # Intel PRO/1000 Gigabit Eth device igb # Intel PRO/1000 PCIE Server Gigabit Family device ixgbe # Intel PRO/10GbE PCIE Ethernet Family device glc # Sony Playstation 3 Ethernet +device llan # IBM pSeries Virtual Ethernet # PCI Ethernet NICs that use the common MII bus controller code. device miibus # MII bus support Modified: stable/10/sys/powerpc/pseries/phyp-hvcall.S ============================================================================== --- stable/10/sys/powerpc/pseries/phyp-hvcall.S Mon Oct 28 23:42:44 2013 (r257291) +++ stable/10/sys/powerpc/pseries/phyp-hvcall.S Mon Oct 28 23:47:52 2013 (r257292) @@ -36,6 +36,8 @@ ASENTRY(phyp_hcall) mflr %r0 std %r0,16(%r1) + ld %r11,112(%r1) /* Last couple args into volatile regs*/ + ld %r12,120(%r1) hc /* invoke the hypervisor */ ld %r0,16(%r1) mtlr %r0 Copied and modified: stable/10/sys/powerpc/pseries/phyp_llan.c (from r256778, head/sys/powerpc/pseries/phyp_llan.c) ============================================================================== --- head/sys/powerpc/pseries/phyp_llan.c Sun Oct 20 01:31:09 2013 (r256778, copy source) +++ stable/10/sys/powerpc/pseries/phyp_llan.c Mon Oct 28 23:47:52 2013 (r257292) @@ -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,20 +382,19 @@ 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; } - error = phyp_hcall(H_SEND_LOGICAL_LAN, sc->unit, bufdescs[0], + phyp_hcall(H_SEND_LOGICAL_LAN, sc->unit, bufdescs[0], bufdescs[1], bufdescs[2], bufdescs[3], bufdescs[4], bufdescs[5], 0); -#if 0 - if (error) - sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* XXX: handle H_BUSY? */ - /* H_SEND_LOGICAL_LAN returning 0 implies completion of the send op */ -#endif + /* + * The hypercall returning implies completion -- or that the call will + * not complete. In principle, we should try a few times if we get back + * H_BUSY based on the continuation token in R4. For now, just drop + * the packet in such cases. + */ } static void @@ -425,9 +430,9 @@ llan_start_locked(struct ifnet *ifp) } } - bus_dmamap_load_mbuf(sc->tx_dma_tag, sc->tx_dma_map, //xfer->dmamap, + bus_dmamap_load_mbuf(sc->tx_dma_tag, sc->tx_dma_map, mb_head, llan_send_packet, sc, 0); - bus_dmamap_unload(sc->tx_dma_tag, sc->tx_dma_map); // XXX + bus_dmamap_unload(sc->tx_dma_tag, sc->tx_dma_map); m_freem(mb_head); } } @@ -443,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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310282347.r9SNlrQl091263>