FreeBSD/sys/dev/cxgb/cxgb_sge.c
/**
 *	refill_fl - refill an SGE free-buffer list
 *	@sc: the controller softc
 *	@q: the free-list to refill
 *	@n: the number of new buffers to allocate
 *
 *	(Re)populate an SGE free-buffer list with up to @n new packet buffers.
 *	The caller must assure that @n does not exceed the queue's capacity.
 */
refill an SGE free-buffer list
@sc: the controller softc
@q: the free-list to refill
@n: the number of new buffers to allocate

(Re)populate an SGE free-buffer list with up to @n new packet buffers.
The caller must assure that @n does not exceed the queue's capacity.
refill an SGE free - buffer list @sc : the controller softc @q : the free - list to refill @n : the number of new buffers to allocate ( Re ) populate an SGE free - buffer list with up to @n new packet buffers . The caller must assure that @n does not exceed the queue ' s capacity .
static void
refill_fl(adapter_t *sc, struct sge_fl *q, int n)
{
	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
	struct rx_desc *d = &q->desc[q->pidx];
	struct refill_fl_cb_arg cb_arg;
	struct mbuf *m;
	caddr_t cl;
	int err;
	cb_arg.error = 0;
	while (n--) {
		if (q->zone == zone_pack) {
			if ((m = m_getcl(M_NOWAIT, MT_NOINIT, M_PKTHDR)) == NULL)
				break;
			cl = m->m_ext.ext_buf;			
		} else {
			if ((cl = m_cljget(NULL, M_NOWAIT, q->buf_size)) == NULL)
				break;
			if ((m = m_gethdr(M_NOWAIT, MT_NOINIT)) == NULL) {
				uma_zfree(q->zone, cl);
				break;
			}
		}
		if ((sd->flags & RX_SW_DESC_MAP_CREATED) == 0) {
			if ((err = bus_dmamap_create(q->entry_tag, 0, &sd->map))) {
				log(LOG_WARNING, "bus_dmamap_create failed %d\n", err);
				uma_zfree(q->zone, cl);
				goto done;
			}
			sd->flags |= RX_SW_DESC_MAP_CREATED;
		}
#if !defined(__i386__) && !defined(__amd64__)
		err = bus_dmamap_load(q->entry_tag, sd->map,
		    cl, q->buf_size, refill_fl_cb, &cb_arg, 0);
		if (err != 0 || cb_arg.error) {
			if (q->zone != zone_pack)
				uma_zfree(q->zone, cl);
			m_free(m);
			goto done;
		}
#else
		cb_arg.seg.ds_addr = pmap_kextract((vm_offset_t)cl);
#endif		
		sd->flags |= RX_SW_DESC_INUSE;
		sd->rxsd_cl = cl;
		sd->m = m;
		d->addr_lo = htobe32(cb_arg.seg.ds_addr & 0xffffffff);
		d->addr_hi = htobe32(((uint64_t)cb_arg.seg.ds_addr >>32) & 0xffffffff);
		d->len_gen = htobe32(V_FLD_GEN1(q->gen));
		d->gen2 = htobe32(V_FLD_GEN2(q->gen));
		d++;
		sd++;
		if (++q->pidx == q->size) {
			q->pidx = 0;
			q->gen ^= 1;
			sd = q->sdesc;
			d = q->desc;
		}
		q->credits++;
		q->db_pending++;
	}
done:
	if (q->db_pending >= 32) {
		q->db_pending = 0;
		t3_write_reg(sc, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
	}
}
static void refill_fl ( adapter_t * sc , struct sge_fl * q , int n ) { struct rx_sw_desc * sd = & q -> sdesc [ q -> pidx ] ; struct rx_desc * d = & q -> desc [ q -> pidx ] ; struct refill_fl_cb_arg cb_arg ; struct mbuf * m ; caddr_t cl ; int err ; cb_arg . error = 0 ; while ( n -- ) { if ( q -> zone == zone_pack ) { if ( ( m = m_getcl ( M_NOWAIT , MT_NOINIT , M_PKTHDR ) ) == NULL ) break ; cl = m -> m_ext . ext_buf ; } else { if ( ( cl = m_cljget ( NULL , M_NOWAIT , q -> buf_size ) ) == NULL ) break ; if ( ( m = m_gethdr ( M_NOWAIT , MT_NOINIT ) ) == NULL ) { uma_zfree ( q -> zone , cl ) ; break ; } } if ( ( sd -> flags & RX_SW_DESC_MAP_CREATED ) == 0 ) { if ( ( err = bus_dmamap_create ( q -> entry_tag , 0 , & sd -> map ) ) ) { log ( LOG_WARNING , " \n " , err ) ; uma_zfree ( q -> zone , cl ) ; goto done ; } sd -> flags |= RX_SW_DESC_MAP_CREATED ; } #if ! defined ( __i386__ ) && ! defined ( __amd64__ ) err = bus_dmamap_load ( q -> entry_tag , sd -> map , cl , q -> buf_size , refill_fl_cb , & cb_arg , 0 ) ; if ( err != 0 || cb_arg . error ) { if ( q -> zone != zone_pack ) uma_zfree ( q -> zone , cl ) ; m_free ( m ) ; goto done ; } #else cb_arg . seg . ds_addr = pmap_kextract ( ( vm_offset_t ) cl ) ; #endif sd -> flags |= RX_SW_DESC_INUSE ; sd -> rxsd_cl = cl ; sd -> m = m ; d -> addr_lo = htobe32 ( cb_arg . seg . ds_addr & 0xffffffff ) ; d -> addr_hi = htobe32 ( ( ( uint64_t ) cb_arg . seg . ds_addr >> 32 ) & 0xffffffff ) ; d -> len_gen = htobe32 ( V_FLD_GEN1 ( q -> gen ) ) ; d -> gen2 = htobe32 ( V_FLD_GEN2 ( q -> gen ) ) ; d ++ ; sd ++ ; if ( ++ q -> pidx == q -> size ) { q -> pidx = 0 ; q -> gen ^= 1 ; sd = q -> sdesc ; d = q -> desc ; } q -> credits ++ ; q -> db_pending ++ ; } done : if ( q -> db_pending >= 32 ) { q -> db_pending = 0 ; t3_write_reg ( sc , A_SG_KDOORBELL , V_EGRCNTX ( q -> cntxt_id ) ) ; } }
refill_fl - refill an SGE free-buffer list
      @sc: the controller softc
      @q: the free-list to refill
      @n: the number of new buffers to allocate
refill_fl - refill an SGE free - buffer list @sc : the controller softc @q : the free - list to refill @n : the number of new buffers to allocate
/*
		 * We allocate an uninitialized mbuf + cluster, mbuf is
		 * initialized after rx.
		 */