FreeBSD/sys/dev/vnic/nicvf_queues.c
/* Put an mbuf to a SQ for packet transfer. */
Put an mbuf to a SQ for packet transfer.
Put an mbuf to a SQ for packet transfer .
static int
nicvf_tx_mbuf_locked(struct snd_queue *sq, struct mbuf **mbufp)
{
	bus_dma_segment_t segs[256];
	struct snd_buff *snd_buff;
	size_t seg;
	int nsegs, qentry;
	int subdesc_cnt;
	int err;
	NICVF_TX_LOCK_ASSERT(sq);
	if (sq->free_cnt == 0)
		return (ENOBUFS);
	snd_buff = &sq->snd_buff[sq->tail];
	err = bus_dmamap_load_mbuf_sg(sq->snd_buff_dmat, snd_buff->dmap,
	    *mbufp, segs, &nsegs, BUS_DMA_NOWAIT);
	if (__predict_false(err != 0)) {
		m_freem(*mbufp);
		*mbufp = NULL;
		return (err);
	}
	subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT + nsegs - 1;
	if (subdesc_cnt > sq->free_cnt) {
		bus_dmamap_unload(sq->snd_buff_dmat, snd_buff->dmap);
		return (ENOBUFS);
	}
	qentry = nicvf_get_sq_desc(sq, subdesc_cnt);
	err = nicvf_sq_add_hdr_subdesc(sq, qentry, subdesc_cnt - 1, *mbufp,
	    (*mbufp)->m_pkthdr.len);
	if (err != 0) {
		nicvf_put_sq_desc(sq, subdesc_cnt);
		bus_dmamap_unload(sq->snd_buff_dmat, snd_buff->dmap);
		if (err == ENOBUFS) {
			m_freem(*mbufp);
			*mbufp = NULL;
		}
		return (err);
	}
	for (seg = 0; seg < nsegs; seg++) {
		qentry = nicvf_get_nxt_sqentry(sq, qentry);
		nicvf_sq_add_gather_subdesc(sq, qentry, segs[seg].ds_len,
		    segs[seg].ds_addr);
	}
	bus_dmamap_sync(sq->dmem.dmat, sq->dmem.dmap, BUS_DMASYNC_PREWRITE);
	dprintf(sq->nic->dev, "%s: sq->idx: %d, subdesc_cnt: %d\n",
	    __func__, sq->idx, subdesc_cnt);
	nicvf_queue_reg_write(sq->nic, NIC_QSET_SQ_0_7_DOOR,
	    sq->idx, subdesc_cnt);
	return (0);
}
static int nicvf_tx_mbuf_locked ( struct snd_queue * sq , struct mbuf * * mbufp ) { bus_dma_segment_t segs [ 256 ] ; struct snd_buff * snd_buff ; size_t seg ; int nsegs , qentry ; int subdesc_cnt ; int err ; NICVF_TX_LOCK_ASSERT ( sq ) ; if ( sq -> free_cnt == 0 ) return ( ENOBUFS ) ; snd_buff = & sq -> snd_buff [ sq -> tail ] ; err = bus_dmamap_load_mbuf_sg ( sq -> snd_buff_dmat , snd_buff -> dmap , * mbufp , segs , & nsegs , BUS_DMA_NOWAIT ) ; if ( __predict_false ( err != 0 ) ) { m_freem ( * mbufp ) ; * mbufp = NULL ; return ( err ) ; } subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT + nsegs - 1 ; if ( subdesc_cnt > sq -> free_cnt ) { bus_dmamap_unload ( sq -> snd_buff_dmat , snd_buff -> dmap ) ; return ( ENOBUFS ) ; } qentry = nicvf_get_sq_desc ( sq , subdesc_cnt ) ; err = nicvf_sq_add_hdr_subdesc ( sq , qentry , subdesc_cnt - 1 , * mbufp , ( * mbufp ) -> m_pkthdr . len ) ; if ( err != 0 ) { nicvf_put_sq_desc ( sq , subdesc_cnt ) ; bus_dmamap_unload ( sq -> snd_buff_dmat , snd_buff -> dmap ) ; if ( err == ENOBUFS ) { m_freem ( * mbufp ) ; * mbufp = NULL ; } return ( err ) ; } for ( seg = 0 ; seg < nsegs ; seg ++ ) { qentry = nicvf_get_nxt_sqentry ( sq , qentry ) ; nicvf_sq_add_gather_subdesc ( sq , qentry , segs [ seg ] . ds_len , segs [ seg ] . ds_addr ) ; } bus_dmamap_sync ( sq -> dmem . dmat , sq -> dmem . dmap , BUS_DMASYNC_PREWRITE ) ; dprintf ( sq -> nic -> dev , " \n " , __func__ , sq -> idx , subdesc_cnt ) ; nicvf_queue_reg_write ( sq -> nic , NIC_QSET_SQ_0_7_DOOR , sq -> idx , subdesc_cnt ) ; return ( 0 ) ; }
Put an mbuf to a SQ for packet transfer.
Put an mbuf to a SQ for packet transfer .
/* ARM64TODO: Add mbuf defragmenting if we lack maps */ /* Set how many subdescriptors is required */ /* ARM64TODO: Add mbuf defragmentation if we lack descriptors */ /* Add SQ header subdesc */ /* Add SQ gather subdescs */ /* make sure all memory stores are done before ringing doorbell */ /* Inform HW to xmit new packet */