socsvn commit: r305289 - soc2016/vincenzo/head/sys/dev/netmap

vincenzo at FreeBSD.org vincenzo at FreeBSD.org
Fri Jun 17 16:22:20 UTC 2016


Author: vincenzo
Date: Fri Jun 17 16:22:19 2016
New Revision: 305289
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305289

Log:
   freebsd: ptnet: implement basic if_transmit

Modified:
  soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c

Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Fri Jun 17 16:22:07 2016	(r305288)
+++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Fri Jun 17 16:22:19 2016	(r305289)
@@ -669,6 +669,8 @@
 		goto err_register;
 	}
 
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
 	return 0;
 
 err_register:
@@ -704,17 +706,107 @@
 	}
 	netmap_mem_deref(na_dr->nm_mem, na_dr);
 
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+
 	return 0;
 }
 
+static inline void
+ptnet_sync_tail(struct ptnet_ring *ptring, struct netmap_kring *kring)
+{
+	struct netmap_ring *ring = kring->ring;
+
+	/* Update hwcur and hwtail as known by the host. */
+        ptnetmap_guest_read_kring_csb(ptring, kring);
+
+	/* nm_sync_finalize */
+	ring->tail = kring->rtail = kring->nr_hwtail;
+}
+
 static int
 ptnet_transmit(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ptnet_softc *sc = ifp->if_softc;
+	struct netmap_adapter *na = &sc->ptna_dr.hwup.up;
+	struct ptnet_ring *ptring;
+	struct netmap_kring *kring;
+	struct netmap_ring *ring;
+	struct netmap_slot *slot;
+	struct ptnet_queue *pq;
+	unsigned int head;
+	unsigned int lim;
+	struct mbuf *mf;
+	int nmbuf_bytes;
+	uint8_t *nmbuf;
 
 	device_printf(sc->dev, "transmit %p\n", m);
+
+	pq = sc->queues + 0;
+	ptring = pq->ptring;
+	kring = na->tx_rings + 0;
+	ring = kring->ring;
+	lim = kring->nkr_num_slots - 1;
+
+	/* Update hwcur and hwtail (completed TX slots) as known by the host,
+	 * by reading from CSB. */
+	ptnet_sync_tail(ptring, kring);
+
+	head = ring->head;
+	slot = ring->slot + head;
+	nmbuf = NMB(na, slot);
+	nmbuf_bytes = 0;
+
+	for (mf = m; mf; mf = mf->m_next) {
+		uint8_t *mdata = mf->m_data;
+		int mlen = mf->m_len;
+
+		for (;;) {
+			int copy = NETMAP_BUF_SIZE(na) - nmbuf_bytes;
+
+			if (mlen < copy) {
+				copy = mlen;
+			}
+			memcpy(nmbuf, mdata, copy);
+
+			mdata += copy;
+			mlen -= copy;
+			nmbuf += copy;
+			nmbuf_bytes += copy;
+
+			if (!mlen) {
+				break;
+			}
+
+			slot->len = nmbuf_bytes;
+			slot->flags = NS_MOREFRAG;
+			head = nm_next(head, lim);
+			slot = ring->slot + head;
+			nmbuf = NMB(na, slot);
+			nmbuf_bytes = 0;
+		}
+	}
+
 	m_freem(m);
 
+	/* Complete last slot and update head. */
+	slot->len = nmbuf_bytes;
+	slot->flags = 0;
+	ring->head = ring->cur = nm_next(head, lim);
+
+	/* nm_txsync_prologue */
+	kring->rcur = kring->rhead = ring->head;
+
+	/* Tell the host to process the new packets, updating cur and
+	 * head in the CSB. */
+	ptnetmap_guest_write_kring_csb(ptring, kring->rcur,
+			kring->rhead);
+
+        /* Ask for a kick from a guest to the host if needed. */
+	if (NM_ACCESS_ONCE(ptring->host_need_kick)) {
+		ptring->sync_flags = NAF_FORCE_RECLAIM;
+		bus_write_4(sc->iomem, pq->kick, 0);
+	}
+
 	return 0;
 }
 


More information about the svn-soc-all mailing list