FreeBSD/sys/dev/bxe/bxe.c
/*
 * Allocate an mbuf and assign it to the receive scatter gather chain. The
 * caller must take care to save a copy of the existing mbuf in the SG mbuf
 * chain.
 */
Allocate an mbuf and assign it to the receive scatter gather chain. The
caller must take care to save a copy of the existing mbuf in the SG mbuf
chain.
Allocate an mbuf and assign it to the receive scatter gather chain . The caller must take care to save a copy of the existing mbuf in the SG mbuf chain .
static int
bxe_alloc_rx_sge_mbuf(struct bxe_fastpath *fp,
                      uint16_t            index)
{
    struct bxe_sw_rx_bd *sge_buf;
    struct eth_rx_sge *sge;
    bus_dma_segment_t segs[1];
    bus_dmamap_t map;
    struct mbuf *m;
    int nsegs;
    int rc = 0;
    m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, SGE_PAGE_SIZE);
    if (__predict_false(m == NULL)) {
        fp->eth_q_stats.mbuf_rx_sge_alloc_failed++;
        return (ENOMEM);
    }
    fp->eth_q_stats.mbuf_alloc_sge++;
    m->m_pkthdr.len = m->m_len = SGE_PAGE_SIZE;
    rc = bus_dmamap_load_mbuf_sg(fp->rx_sge_mbuf_tag,
                                 fp->rx_sge_mbuf_spare_map,
                                 m, segs, &nsegs, BUS_DMA_NOWAIT);
    if (__predict_false(rc != 0)) {
        fp->eth_q_stats.mbuf_rx_sge_mapping_failed++;
        m_freem(m);
        fp->eth_q_stats.mbuf_alloc_sge--;
        return (rc);
    }
    KASSERT((nsegs == 1), ("Too many segments, %d returned!", nsegs));
    sge_buf = &fp->rx_sge_mbuf_chain[index];
    if (sge_buf->m_map != NULL) {
        bus_dmamap_sync(fp->rx_sge_mbuf_tag, sge_buf->m_map,
                        BUS_DMASYNC_POSTREAD);
        bus_dmamap_unload(fp->rx_sge_mbuf_tag, sge_buf->m_map);
    }
    map = sge_buf->m_map;
    sge_buf->m_map = fp->rx_sge_mbuf_spare_map;
    fp->rx_sge_mbuf_spare_map = map;
    bus_dmamap_sync(fp->rx_sge_mbuf_tag, sge_buf->m_map,
                    BUS_DMASYNC_PREREAD);
    sge_buf->m = m;
    sge = &fp->rx_sge_chain[index];
    sge->addr_hi = htole32(U64_HI(segs[0].ds_addr));
    sge->addr_lo = htole32(U64_LO(segs[0].ds_addr));
    return (rc);
}
static int bxe_alloc_rx_sge_mbuf ( struct bxe_fastpath * fp , uint16_t index ) { struct bxe_sw_rx_bd * sge_buf ; struct eth_rx_sge * sge ; bus_dma_segment_t segs [ 1 ] ; bus_dmamap_t map ; struct mbuf * m ; int nsegs ; int rc = 0 ; m = m_getjcl ( M_NOWAIT , MT_DATA , M_PKTHDR , SGE_PAGE_SIZE ) ; if ( __predict_false ( m == NULL ) ) { fp -> eth_q_stats . mbuf_rx_sge_alloc_failed ++ ; return ( ENOMEM ) ; } fp -> eth_q_stats . mbuf_alloc_sge ++ ; m -> m_pkthdr . len = m -> m_len = SGE_PAGE_SIZE ; rc = bus_dmamap_load_mbuf_sg ( fp -> rx_sge_mbuf_tag , fp -> rx_sge_mbuf_spare_map , m , segs , & nsegs , BUS_DMA_NOWAIT ) ; if ( __predict_false ( rc != 0 ) ) { fp -> eth_q_stats . mbuf_rx_sge_mapping_failed ++ ; m_freem ( m ) ; fp -> eth_q_stats . mbuf_alloc_sge -- ; return ( rc ) ; } KASSERT ( ( nsegs == 1 ) , ( " " , nsegs ) ) ; sge_buf = & fp -> rx_sge_mbuf_chain [ index ] ; if ( sge_buf -> m_map != NULL ) { bus_dmamap_sync ( fp -> rx_sge_mbuf_tag , sge_buf -> m_map , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( fp -> rx_sge_mbuf_tag , sge_buf -> m_map ) ; } map = sge_buf -> m_map ; sge_buf -> m_map = fp -> rx_sge_mbuf_spare_map ; fp -> rx_sge_mbuf_spare_map = map ; bus_dmamap_sync ( fp -> rx_sge_mbuf_tag , sge_buf -> m_map , BUS_DMASYNC_PREREAD ) ; sge_buf -> m = m ; sge = & fp -> rx_sge_chain [ index ] ; sge -> addr_hi = htole32 ( U64_HI ( segs [ 0 ] . ds_addr ) ) ; sge -> addr_lo = htole32 ( U64_LO ( segs [ 0 ] . ds_addr ) ) ; return ( rc ) ; }
Allocate an mbuf and assign it to the receive scatter gather chain.
Allocate an mbuf and assign it to the receive scatter gather chain .
/* allocate a new SGE mbuf */ /* initialize the mbuf buffer length */ /* map the SGE mbuf into non-paged pool */ /* all mbufs must map to a single segment */ /* release any existing SGE mbuf mapping */ /* save the mbuf and mapping info for a future packet */