FreeBSD/sys/dev/bxe/bxe.c
/*
 * The current mbuf is part of an aggregation. Move the mbuf into the TPA
 * aggregation queue, put an empty mbuf back onto the receive chain, and mark
 * the current aggregation queue as in-progress.
 */
The current mbuf is part of an aggregation. Move the mbuf into the TPA
aggregation queue, put an empty mbuf back onto the receive chain, and mark
the current aggregation queue as in-progress.
The current mbuf is part of an aggregation . Move the mbuf into the TPA aggregation queue put an empty mbuf back onto the receive chain and mark the current aggregation queue as in - progress .
static void
bxe_tpa_start(struct bxe_softc            *sc,
              struct bxe_fastpath         *fp,
              uint16_t                    queue,
              uint16_t                    cons,
              uint16_t                    prod,
              struct eth_fast_path_rx_cqe *cqe)
{
    struct bxe_sw_rx_bd tmp_bd;
    struct bxe_sw_rx_bd *rx_buf;
    struct eth_rx_bd *rx_bd;
    int max_agg_queues;
    struct bxe_sw_tpa_info *tpa_info = &fp->rx_tpa_info[queue];
    uint16_t index;
    BLOGD(sc, DBG_LRO, "fp[%02d].tpa[%02d] TPA START "
                       "cons=%d prod=%d\n",
          fp->index, queue, cons, prod);
    max_agg_queues = MAX_AGG_QS(sc);
    KASSERT((queue < max_agg_queues),
            ("fp[%02d] invalid aggr queue (%d >= %d)!",
             fp->index, queue, max_agg_queues));
    KASSERT((tpa_info->state == BXE_TPA_STATE_STOP),
            ("fp[%02d].tpa[%02d] starting aggr on queue not stopped!",
             fp->index, queue));
    tmp_bd = tpa_info->bd;
    if (tmp_bd.m == NULL) {
        uint32_t *tmp;
        tmp = (uint32_t *)cqe;
        BLOGE(sc, "fp[%02d].tpa[%02d] cons[%d] prod[%d]mbuf not allocated!\n",
              fp->index, queue, cons, prod);
        BLOGE(sc, "cqe [0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x]\n",
            *tmp, *(tmp+1), *(tmp+2), *(tmp+3), *(tmp+4), *(tmp+5), *(tmp+6), *(tmp+7)); 
        return;
    }
    tpa_info->state            = BXE_TPA_STATE_START;
    tpa_info->placement_offset = cqe->placement_offset;
    tpa_info->parsing_flags    = le16toh(cqe->pars_flags.flags);
    tpa_info->vlan_tag         = le16toh(cqe->vlan_tag);
    tpa_info->len_on_bd        = le16toh(cqe->len_on_bd);
    fp->rx_tpa_queue_used |= (1 << queue);
    index = (sc->max_rx_bufs != RX_BD_USABLE) ?
                prod : cons;
    tpa_info->bd = fp->rx_mbuf_chain[cons];
    if (cons != index) {
        rx_buf = &fp->rx_mbuf_chain[cons];
        if (rx_buf->m_map != NULL) {
            bus_dmamap_sync(fp->rx_mbuf_tag, rx_buf->m_map,
                            BUS_DMASYNC_POSTREAD);
            bus_dmamap_unload(fp->rx_mbuf_tag, rx_buf->m_map);
        }
        fp->rx_mbuf_chain[cons].m = NULL;
    }
    fp->rx_mbuf_chain[index] = tmp_bd;
    rx_bd = &fp->rx_chain[index];
    rx_bd->addr_hi = htole32(U64_HI(tpa_info->seg.ds_addr));
    rx_bd->addr_lo = htole32(U64_LO(tpa_info->seg.ds_addr));
}
static void bxe_tpa_start ( struct bxe_softc * sc , struct bxe_fastpath * fp , uint16_t queue , uint16_t cons , uint16_t prod , struct eth_fast_path_rx_cqe * cqe ) { struct bxe_sw_rx_bd tmp_bd ; struct bxe_sw_rx_bd * rx_buf ; struct eth_rx_bd * rx_bd ; int max_agg_queues ; struct bxe_sw_tpa_info * tpa_info = & fp -> rx_tpa_info [ queue ] ; uint16_t index ; BLOGD ( sc , DBG_LRO , " " " \n " , fp -> index , queue , cons , prod ) ; max_agg_queues = MAX_AGG_QS ( sc ) ; KASSERT ( ( queue < max_agg_queues ) , ( " " , fp -> index , queue , max_agg_queues ) ) ; KASSERT ( ( tpa_info -> state == BXE_TPA_STATE_STOP ) , ( " " , fp -> index , queue ) ) ; tmp_bd = tpa_info -> bd ; if ( tmp_bd . m == NULL ) { uint32_t * tmp ; tmp = ( uint32_t * ) cqe ; BLOGE ( sc , " \n " , fp -> index , queue , cons , prod ) ; BLOGE ( sc , " \n " , * tmp , * ( tmp + 1 ) , * ( tmp + 2 ) , * ( tmp + 3 ) , * ( tmp + 4 ) , * ( tmp + 5 ) , * ( tmp + 6 ) , * ( tmp + 7 ) ) ; return ; } tpa_info -> state = BXE_TPA_STATE_START ; tpa_info -> placement_offset = cqe -> placement_offset ; tpa_info -> parsing_flags = le16toh ( cqe -> pars_flags . flags ) ; tpa_info -> vlan_tag = le16toh ( cqe -> vlan_tag ) ; tpa_info -> len_on_bd = le16toh ( cqe -> len_on_bd ) ; fp -> rx_tpa_queue_used |= ( 1 << queue ) ; index = ( sc -> max_rx_bufs != RX_BD_USABLE ) ? prod : cons ; tpa_info -> bd = fp -> rx_mbuf_chain [ cons ] ; if ( cons != index ) { rx_buf = & fp -> rx_mbuf_chain [ cons ] ; if ( rx_buf -> m_map != NULL ) { bus_dmamap_sync ( fp -> rx_mbuf_tag , rx_buf -> m_map , BUS_DMASYNC_POSTREAD ) ; bus_dmamap_unload ( fp -> rx_mbuf_tag , rx_buf -> m_map ) ; } fp -> rx_mbuf_chain [ cons ] . m = NULL ; } fp -> rx_mbuf_chain [ index ] = tmp_bd ; rx_bd = & fp -> rx_chain [ index ] ; rx_bd -> addr_hi = htole32 ( U64_HI ( tpa_info -> seg . ds_addr ) ) ; rx_bd -> addr_lo = htole32 ( U64_LO ( tpa_info -> seg . ds_addr ) ) ; }
The current mbuf is part of an aggregation.
The current mbuf is part of an aggregation .
/* copy the existing mbuf and mapping from the TPA pool */ /* XXX Error handling? */ /* change the TPA queue to the start state */ /*
     * If all the buffer descriptors are filled with mbufs then fill in
     * the current consumer index with a new BD. Else if a maximum Rx
     * buffer limit is imposed then fill in the next producer index.
     */ /* move the received mbuf and mapping to TPA pool */ /* release any existing RX BD mbuf mappings */ /*
         * We get here when the maximum number of rx buffers is less than
         * RX_BD_USABLE. The mbuf is already saved above so it's OK to NULL
         * it out here without concern of a memory leak.
         */ /* update the Rx SW BD with the mbuf info from the TPA pool */ /* update the Rx BD with the empty mbuf phys address from the TPA pool */