FreeBSD/tools/tools/netmap/pkt-gen.c
/*
 * create and enqueue a batch of packets on a ring.
 * On the last one set NS_REPORT to tell the driver to generate
 * an interrupt when done.
 */
create and enqueue a batch of packets on a ring.
On the last one set NS_REPORT to tell the driver to generate
an interrupt when done.
create and enqueue a batch of packets on a ring . On the last one set NS_REPORT to tell the driver to generate an interrupt when done .
static int
send_packets(struct netmap_ring *ring, struct pkt *pkt, void *frame,
		int size, struct glob_arg *g, u_int count, int options,
		u_int nfrags)
{
	u_int n, sent, cur = ring->cur;
	u_int fcnt;
	n = nm_ring_space(ring);
	if (n < count)
		count = n;
	if (count < nfrags) {
		D("truncating packet, no room for frags %d %d",
				count, nfrags);
	}
#if 0
	if (options & (OPT_COPY | OPT_PREFETCH) ) {
		for (sent = 0; sent < count; sent++) {
			struct netmap_slot *slot = &ring->slot[cur];
			char *p = NETMAP_BUF(ring, slot->buf_idx);
			__builtin_prefetch(p);
			cur = nm_ring_next(ring, cur);
		}
		cur = ring->cur;
	}
#endif
	for (fcnt = nfrags, sent = 0; sent < count; sent++) {
		struct netmap_slot *slot = &ring->slot[cur];
		char *p = NETMAP_BUF(ring, slot->buf_idx);
		slot->flags = 0;
		if (options & OPT_INDIRECT) {
			slot->flags |= NS_INDIRECT;
			slot->ptr = (uint64_t)frame;
		} else if (options & OPT_COPY) {
			nm_pkt_copy(frame, p, size);
			if (fcnt == nfrags)
				update_addresses(pkt, g);
		} else if (options & OPT_MEMCPY) {
			memcpy(p, frame, size);
			if (fcnt == nfrags)
				update_addresses(pkt, g);
		} else if (options & OPT_PREFETCH) {
			__builtin_prefetch(p);
		}
		if (options & OPT_DUMP)
			dump_payload(p, size, ring, cur);
		slot->len = size;
		if (--fcnt > 0)
			slot->flags |= NS_MOREFRAG;
		else
			fcnt = nfrags;
		if (sent == count - 1) {
			slot->flags &= ~NS_MOREFRAG;
			slot->flags |= NS_REPORT;
		}
		cur = nm_ring_next(ring, cur);
	}
	ring->head = ring->cur = cur;
	return (sent);
}
static int send_packets ( struct netmap_ring * ring , struct pkt * pkt , void * frame , int size , struct glob_arg * g , u_int count , int options , u_int nfrags ) { u_int n , sent , cur = ring -> cur ; u_int fcnt ; n = nm_ring_space ( ring ) ; if ( n < count ) count = n ; if ( count < nfrags ) { D ( " " , count , nfrags ) ; } #if 0 if ( options & ( OPT_COPY | OPT_PREFETCH ) ) { for ( sent = 0 ; sent < count ; sent ++ ) { struct netmap_slot * slot = & ring -> slot [ cur ] ; char * p = NETMAP_BUF ( ring , slot -> buf_idx ) ; __builtin_prefetch ( p ) ; cur = nm_ring_next ( ring , cur ) ; } cur = ring -> cur ; } #endif for ( fcnt = nfrags , sent = 0 ; sent < count ; sent ++ ) { struct netmap_slot * slot = & ring -> slot [ cur ] ; char * p = NETMAP_BUF ( ring , slot -> buf_idx ) ; slot -> flags = 0 ; if ( options & OPT_INDIRECT ) { slot -> flags |= NS_INDIRECT ; slot -> ptr = ( uint64_t ) frame ; } else if ( options & OPT_COPY ) { nm_pkt_copy ( frame , p , size ) ; if ( fcnt == nfrags ) update_addresses ( pkt , g ) ; } else if ( options & OPT_MEMCPY ) { memcpy ( p , frame , size ) ; if ( fcnt == nfrags ) update_addresses ( pkt , g ) ; } else if ( options & OPT_PREFETCH ) { __builtin_prefetch ( p ) ; } if ( options & OPT_DUMP ) dump_payload ( p , size , ring , cur ) ; slot -> len = size ; if ( -- fcnt > 0 ) slot -> flags |= NS_MOREFRAG ; else fcnt = nfrags ; if ( sent == count - 1 ) { slot -> flags &= ~ NS_MOREFRAG ; slot -> flags |= NS_REPORT ; } cur = nm_ring_next ( ring , cur ) ; } ring -> head = ring -> cur = cur ; return ( sent ) ; }
create and enqueue a batch of packets on a ring.
create and enqueue a batch of packets on a ring .