X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_rx.c;h=2c73260a782d5b436a69d532e8be35c2ddcf524d;hb=efb15738c7003cf0381888396a94af495cb7f1b0;hp=a4aae1bab6dde4e1dc0149b72c31519c4fcb8169;hpb=01764b20c2ffd4b5755a6da40b307a12d8185b46;p=dpdk.git diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index a4aae1bab6..2c73260a78 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -384,6 +384,7 @@ sfc_rxq_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq) static sfc_dp_rx_qsize_up_rings_t sfc_efx_rx_qsize_up_rings; static int sfc_efx_rx_qsize_up_rings(uint16_t nb_rx_desc, + __rte_unused struct rte_mempool *mb_pool, unsigned int *rxq_entries, unsigned int *evq_entries, unsigned int *rxq_max_fill_level) @@ -516,7 +517,8 @@ struct sfc_dp_rx sfc_efx_rx = { .type = SFC_DP_RX, .hw_fw_caps = 0, }, - .features = SFC_DP_RX_FEAT_SCATTER, + .features = SFC_DP_RX_FEAT_SCATTER | + SFC_DP_RX_FEAT_CHECKSUM, .qsize_up_rings = sfc_efx_rx_qsize_up_rings, .qcreate = sfc_efx_rx_qcreate, .qdestroy = sfc_efx_rx_qdestroy, @@ -671,6 +673,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index) rxq_info = &sa->rxq_info[sw_index]; rxq = rxq_info->rxq; + SFC_ASSERT(rxq != NULL); SFC_ASSERT(rxq->state == SFC_RXQ_INITIALIZED); evq = rxq->evq; @@ -679,10 +682,37 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index) if (rc != 0) goto fail_ev_qstart; - rc = efx_rx_qcreate(sa->nic, rxq->hw_index, 0, rxq_info->type, - &rxq->mem, rxq_info->entries, - 0 /* not used on EF10 */, rxq_info->type_flags, - evq->common, &rxq->common); + switch (rxq_info->type) { + case EFX_RXQ_TYPE_DEFAULT: + rc = efx_rx_qcreate(sa->nic, rxq->hw_index, 0, rxq_info->type, + &rxq->mem, rxq_info->entries, 0 /* not used on EF10 */, + rxq_info->type_flags, evq->common, &rxq->common); + break; + case EFX_RXQ_TYPE_ES_SUPER_BUFFER: { + struct rte_mempool *mp = rxq->refill_mb_pool; + struct rte_mempool_info mp_info; + + rc = rte_mempool_ops_get_info(mp, &mp_info); + if (rc != 0) { + /* Positive errno is used in the driver */ + rc = -rc; + goto fail_mp_get_info; + } + if (mp_info.contig_block_size <= 0) { + rc = EINVAL; + goto fail_bad_contig_block_size; + } + rc = efx_rx_qcreate_es_super_buffer(sa->nic, rxq->hw_index, 0, + mp_info.contig_block_size, rxq->buf_size, + mp->header_size + mp->elt_size + mp->trailer_size, + sa->rxd_wait_timeout_ns, + &rxq->mem, rxq_info->entries, rxq_info->type_flags, + evq->common, &rxq->common); + break; + } + default: + rc = ENOTSUP; + } if (rc != 0) goto fail_rx_qcreate; @@ -713,6 +743,8 @@ fail_dp_qstart: sfc_rx_qflush(sa, sw_index); fail_rx_qcreate: +fail_bad_contig_block_size: +fail_mp_get_info: sfc_ev_qstop(evq); fail_ev_qstart: @@ -732,7 +764,7 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index) rxq_info = &sa->rxq_info[sw_index]; rxq = rxq_info->rxq; - if (rxq->state == SFC_RXQ_INITIALIZED) + if (rxq == NULL || rxq->state == SFC_RXQ_INITIALIZED) return; SFC_ASSERT(rxq->state & SFC_RXQ_STARTED); @@ -761,10 +793,12 @@ sfc_rx_get_dev_offload_caps(struct sfc_adapter *sa) uint64_t caps = 0; caps |= DEV_RX_OFFLOAD_JUMBO_FRAME; - caps |= DEV_RX_OFFLOAD_CRC_STRIP; - caps |= DEV_RX_OFFLOAD_IPV4_CKSUM; - caps |= DEV_RX_OFFLOAD_UDP_CKSUM; - caps |= DEV_RX_OFFLOAD_TCP_CKSUM; + + if (sa->dp_rx->features & SFC_DP_RX_FEAT_CHECKSUM) { + caps |= DEV_RX_OFFLOAD_IPV4_CKSUM; + caps |= DEV_RX_OFFLOAD_UDP_CKSUM; + caps |= DEV_RX_OFFLOAD_TCP_CKSUM; + } if (encp->enc_tunnel_encapsulations_supported && (sa->dp_rx->features & SFC_DP_RX_FEAT_TUNNELS)) @@ -784,51 +818,11 @@ sfc_rx_get_queue_offload_caps(struct sfc_adapter *sa) return caps; } -static void -sfc_rx_log_offloads(struct sfc_adapter *sa, const char *offload_group, - const char *verdict, uint64_t offloads) -{ - unsigned long long bit; - - while ((bit = __builtin_ffsll(offloads)) != 0) { - uint64_t flag = (1ULL << --bit); - - sfc_err(sa, "Rx %s offload %s %s", offload_group, - rte_eth_dev_rx_offload_name(flag), verdict); - - offloads &= ~flag; - } -} - -static boolean_t -sfc_rx_queue_offloads_mismatch(struct sfc_adapter *sa, uint64_t requested) -{ - uint64_t mandatory = sa->eth_dev->data->dev_conf.rxmode.offloads; - uint64_t supported = sfc_rx_get_dev_offload_caps(sa) | - sfc_rx_get_queue_offload_caps(sa); - uint64_t rejected = requested & ~supported; - uint64_t missing = (requested & mandatory) ^ mandatory; - boolean_t mismatch = B_FALSE; - - if (rejected) { - sfc_rx_log_offloads(sa, "queue", "is unsupported", rejected); - mismatch = B_TRUE; - } - - if (missing) { - sfc_rx_log_offloads(sa, "queue", "must be set", missing); - mismatch = B_TRUE; - } - - return mismatch; -} - static int sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level, - const struct rte_eth_rxconf *rx_conf) + const struct rte_eth_rxconf *rx_conf, + __rte_unused uint64_t offloads) { - uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) | - sfc_rx_get_queue_offload_caps(sa); int rc = 0; if (rx_conf->rx_thresh.pthresh != 0 || @@ -850,17 +844,6 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level, rc = EINVAL; } - if ((rx_conf->offloads & DEV_RX_OFFLOAD_CHECKSUM) != - DEV_RX_OFFLOAD_CHECKSUM) - sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)"); - - if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) && - (~rx_conf->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)) - sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on"); - - if (sfc_rx_queue_offloads_mismatch(sa, rx_conf->offloads)) - rc = EINVAL; - return rc; } @@ -976,22 +959,24 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, unsigned int rxq_entries; unsigned int evq_entries; unsigned int rxq_max_fill_level; + uint64_t offloads; uint16_t buf_size; struct sfc_rxq_info *rxq_info; struct sfc_evq *evq; struct sfc_rxq *rxq; struct sfc_dp_rx_qcreate_info info; - rc = sa->dp_rx->qsize_up_rings(nb_rx_desc, &rxq_entries, &evq_entries, - &rxq_max_fill_level); + rc = sa->dp_rx->qsize_up_rings(nb_rx_desc, mb_pool, &rxq_entries, + &evq_entries, &rxq_max_fill_level); if (rc != 0) goto fail_size_up_rings; SFC_ASSERT(rxq_entries >= EFX_RXQ_MINNDESCS); SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS); - SFC_ASSERT(rxq_entries >= nb_rx_desc); SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc); - rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf); + offloads = rx_conf->offloads | + sa->eth_dev->data->dev_conf.rxmode.offloads; + rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf, offloads); if (rc != 0) goto fail_bad_conf; @@ -1004,7 +989,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, } if ((buf_size < sa->port.pdu + encp->enc_rx_prefix_size) && - (~rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER)) { + (~offloads & DEV_RX_OFFLOAD_SCATTER)) { sfc_err(sa, "Rx scatter is disabled and RxQ %u mbuf pool " "object size is too small", sw_index); sfc_err(sa, "RxQ %u calculated Rx buffer size is %u vs " @@ -1020,9 +1005,14 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, SFC_ASSERT(rxq_entries <= rxq_info->max_entries); rxq_info->entries = rxq_entries; - rxq_info->type = EFX_RXQ_TYPE_DEFAULT; + + if (sa->dp_rx->dp.hw_fw_caps & SFC_DP_HW_FW_CAP_RX_ES_SUPER_BUFFER) + rxq_info->type = EFX_RXQ_TYPE_ES_SUPER_BUFFER; + else + rxq_info->type = EFX_RXQ_TYPE_DEFAULT; + rxq_info->type_flags = - (rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) ? + (offloads & DEV_RX_OFFLOAD_SCATTER) ? EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE; if ((encp->enc_tunnel_encapsulations_supported != 0) && @@ -1047,6 +1037,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, rxq->refill_threshold = RTE_MAX(rx_conf->rx_free_thresh, SFC_RX_REFILL_BULK); rxq->refill_mb_pool = mb_pool; + rxq->buf_size = buf_size; rc = sfc_dma_alloc(sa, "rxq", sw_index, EFX_RXQ_SIZE(rxq_info->entries), socket_id, &rxq->mem); @@ -1372,7 +1363,8 @@ sfc_rx_start(struct sfc_adapter *sa) goto fail_rss_config; for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) { - if ((!sa->rxq_info[sw_index].deferred_start || + if (sa->rxq_info[sw_index].rxq != NULL && + (!sa->rxq_info[sw_index].deferred_start || sa->rxq_info[sw_index].deferred_started)) { rc = sfc_rx_qstart(sa, sw_index); if (rc != 0) @@ -1427,10 +1419,9 @@ sfc_rx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) { - struct sfc_rss *rss = &sa->rss; uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) | sfc_rx_get_queue_offload_caps(sa); - uint64_t offloads_rejected = rxmode->offloads & ~offloads_supported; + struct sfc_rss *rss = &sa->rss; int rc = 0; switch (rxmode->mq_mode) { @@ -1449,16 +1440,21 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) rc = EINVAL; } - if (offloads_rejected) { - sfc_rx_log_offloads(sa, "device", "is unsupported", - offloads_rejected); - rc = EINVAL; + /* + * Requested offloads are validated against supported by ethdev, + * so unsupported offloads cannot be added as the result of + * below check. + */ + if ((rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) != + (offloads_supported & DEV_RX_OFFLOAD_CHECKSUM)) { + sfc_warn(sa, "Rx checksum offloads cannot be disabled - always on (IPv4/TCP/UDP)"); + rxmode->offloads |= DEV_RX_OFFLOAD_CHECKSUM; } - if (~rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) { - sfc_warn(sa, "FCS stripping cannot be disabled - always on"); - rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP; - rxmode->hw_strip_crc = 1; + if ((offloads_supported & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM) && + (~rxmode->offloads & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)) { + sfc_warn(sa, "Rx outer IPv4 checksum offload cannot be disabled - always on"); + rxmode->offloads |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; } return rc;