svn commit: r257292 - in stable/10/sys: conf powerpc/conf powerpc/pseries

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Oct 28 23:47:54 UTC 2013


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);
 }


More information about the svn-src-all mailing list