FreeBSD/sys/dev/vnic/nicvf_queues.c
/* Allocate RBDR ring and populate receive buffers */
Allocate RBDR ring and populate receive buffers
Allocate RBDR ring and populate receive buffers
static int
nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr, int ring_len,
    int buf_size, int qidx)
{
	bus_dmamap_t dmap;
	bus_addr_t rbuf;
	struct rbdr_entry_t *desc;
	int idx;
	int err;
	err = nicvf_alloc_q_desc_mem(nic, &rbdr->dmem, ring_len,
	    sizeof(struct rbdr_entry_t), NICVF_RCV_BUF_ALIGN_BYTES);
	if (err != 0) {
		device_printf(nic->dev,
		    "Failed to create RBDR descriptors ring\n");
		return (err);
	}
	rbdr->desc = rbdr->dmem.base;
	rbdr->dma_size = buf_size - NICVF_RCV_BUF_ALIGN_BYTES;
	rbdr->enable = TRUE;
	rbdr->thresh = RBDR_THRESH;
	rbdr->nic = nic;
	rbdr->idx = qidx;
	if (buf_size > MCLBYTES) {
		device_printf(nic->dev,
		    "Buffer size to large for mbuf cluster\n");
		return (EINVAL);
	}
	err = bus_dma_tag_create(
	    bus_get_dma_tag(nic->dev),		
	    NICVF_RCV_BUF_ALIGN_BYTES,		
	    0,					
	    DMAP_MAX_PHYSADDR,			
	    DMAP_MIN_PHYSADDR,			
	    NULL, NULL,				
	    roundup2(buf_size, MCLBYTES),	
	    1,					
	    roundup2(buf_size, MCLBYTES),	
	    0,					
	    NULL, NULL,				
	    &rbdr->rbdr_buff_dmat);		
	if (err != 0) {
		device_printf(nic->dev,
		    "Failed to create busdma tag for RBDR buffers\n");
		return (err);
	}
	rbdr->rbdr_buff_dmaps = malloc(sizeof(*rbdr->rbdr_buff_dmaps) *
	    ring_len, M_NICVF, (M_WAITOK | M_ZERO));
	for (idx = 0; idx < ring_len; idx++) {
		err = bus_dmamap_create(rbdr->rbdr_buff_dmat, 0, &dmap);
		if (err != 0) {
			device_printf(nic->dev,
			    "Failed to create DMA map for RB\n");
			return (err);
		}
		rbdr->rbdr_buff_dmaps[idx] = dmap;
		err = nicvf_alloc_rcv_buffer(nic, rbdr, dmap, M_WAITOK,
		    DMA_BUFFER_LEN, &rbuf);
		if (err != 0)
			return (err);
		desc = GET_RBDR_DESC(rbdr, idx);
		desc->buf_addr = (rbuf >> NICVF_RCV_BUF_ALIGN);
	}
	TASK_INIT(&rbdr->rbdr_task, 0, nicvf_rbdr_task, rbdr);
	TASK_INIT(&rbdr->rbdr_task_nowait, 0, nicvf_rbdr_task_nowait, rbdr);
	rbdr->rbdr_taskq = taskqueue_create_fast("nicvf_rbdr_taskq", M_WAITOK,
	    taskqueue_thread_enqueue, &rbdr->rbdr_taskq);
	taskqueue_start_threads(&rbdr->rbdr_taskq, 1, PI_NET, "%s: rbdr_taskq",
	    device_get_nameunit(nic->dev));
	return (0);
}
static int nicvf_init_rbdr ( struct nicvf * nic , struct rbdr * rbdr , int ring_len , int buf_size , int qidx ) { bus_dmamap_t dmap ; bus_addr_t rbuf ; struct rbdr_entry_t * desc ; int idx ; int err ; err = nicvf_alloc_q_desc_mem ( nic , & rbdr -> dmem , ring_len , sizeof ( struct rbdr_entry_t ) , NICVF_RCV_BUF_ALIGN_BYTES ) ; if ( err != 0 ) { device_printf ( nic -> dev , " \n " ) ; return ( err ) ; } rbdr -> desc = rbdr -> dmem . base ; rbdr -> dma_size = buf_size - NICVF_RCV_BUF_ALIGN_BYTES ; rbdr -> enable = TRUE ; rbdr -> thresh = RBDR_THRESH ; rbdr -> nic = nic ; rbdr -> idx = qidx ; if ( buf_size > MCLBYTES ) { device_printf ( nic -> dev , " \n " ) ; return ( EINVAL ) ; } err = bus_dma_tag_create ( bus_get_dma_tag ( nic -> dev ) , NICVF_RCV_BUF_ALIGN_BYTES , 0 , DMAP_MAX_PHYSADDR , DMAP_MIN_PHYSADDR , NULL , NULL , roundup2 ( buf_size , MCLBYTES ) , 1 , roundup2 ( buf_size , MCLBYTES ) , 0 , NULL , NULL , & rbdr -> rbdr_buff_dmat ) ; if ( err != 0 ) { device_printf ( nic -> dev , " \n " ) ; return ( err ) ; } rbdr -> rbdr_buff_dmaps = malloc ( sizeof ( * rbdr -> rbdr_buff_dmaps ) * ring_len , M_NICVF , ( M_WAITOK | M_ZERO ) ) ; for ( idx = 0 ; idx < ring_len ; idx ++ ) { err = bus_dmamap_create ( rbdr -> rbdr_buff_dmat , 0 , & dmap ) ; if ( err != 0 ) { device_printf ( nic -> dev , " \n " ) ; return ( err ) ; } rbdr -> rbdr_buff_dmaps [ idx ] = dmap ; err = nicvf_alloc_rcv_buffer ( nic , rbdr , dmap , M_WAITOK , DMA_BUFFER_LEN , & rbuf ) ; if ( err != 0 ) return ( err ) ; desc = GET_RBDR_DESC ( rbdr , idx ) ; desc -> buf_addr = ( rbuf >> NICVF_RCV_BUF_ALIGN ) ; } TASK_INIT ( & rbdr -> rbdr_task , 0 , nicvf_rbdr_task , rbdr ) ; TASK_INIT ( & rbdr -> rbdr_task_nowait , 0 , nicvf_rbdr_task_nowait , rbdr ) ; rbdr -> rbdr_taskq = taskqueue_create_fast ( " " , M_WAITOK , taskqueue_thread_enqueue , & rbdr -> rbdr_taskq ) ; taskqueue_start_threads ( & rbdr -> rbdr_taskq , 1 , PI_NET , " " , device_get_nameunit ( nic -> dev ) ) ; return ( 0 ) ; }
Allocate RBDR ring and populate receive buffers
Allocate RBDR ring and populate receive buffers
/* Allocate rbdr descriptors ring */ /*
	 * Buffer size has to be in multiples of 128 bytes.
	 * Make room for metadata of size of one line (128 bytes).
	 */ /*
	 * Create DMA tag for Rx buffers.
	 * Each map created using this tag is intended to store Rx payload for
	 * one fragment and one header structure containing rbuf_info (thus
	 * additional 128 byte line since RB must be a multiple of 128 byte
	 * cache line).
	 */ /* parent tag */ /* alignment */ /* boundary */ /* lowaddr */ /* highaddr */ /* filtfunc, filtfuncarg */ /* maxsize */ /* nsegments */ /* maxsegsize */ /* flags */ /* lockfunc, lockfuncarg */ /* dmat */ /* Allocate taskqueue */