net/sfc: support deferred start of receive queues
authorAndrew Rybchenko <arybchenko@solarflare.com>
Thu, 15 Dec 2016 12:51:11 +0000 (12:51 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:40:50 +0000 (19:40 +0100)
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
doc/guides/nics/features/sfc_efx.ini
doc/guides/nics/sfc_efx.rst
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_rx.c
drivers/net/sfc/sfc_rx.h

index 74cc942..4a887f0 100644 (file)
@@ -7,6 +7,7 @@
 Speed capabilities   = Y
 Link status          = Y
 Link status event    = Y
+Queue start/stop     = P
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
index 2e30dfe..b0beaf1 100644 (file)
@@ -71,6 +71,8 @@ SFC EFX PMD has support for:
 
 - Scattered Rx DMA for packet that are larger that a single Rx descriptor
 
+- Deferred receive queue start
+
 
 Non-supported Features
 ----------------------
index f3ab8bd..d3c2a35 100644 (file)
@@ -839,6 +839,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
        qinfo->mp = rxq->refill_mb_pool;
        qinfo->conf.rx_free_thresh = rxq->refill_threshold;
        qinfo->conf.rx_drop_en = 1;
+       qinfo->conf.rx_deferred_start = rxq_info->deferred_start;
        qinfo->scattered_rx = (rxq_info->type == EFX_RXQ_TYPE_SCATTER);
        qinfo->nb_desc = rxq_info->entries;
 
@@ -863,6 +864,54 @@ sfc_rx_descriptor_done(void *queue, uint16_t offset)
        return sfc_rx_qdesc_done(rxq, offset);
 }
 
+static int
+sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+       int rc;
+
+       sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+       sfc_adapter_lock(sa);
+
+       rc = EINVAL;
+       if (sa->state != SFC_ADAPTER_STARTED)
+               goto fail_not_started;
+
+       rc = sfc_rx_qstart(sa, rx_queue_id);
+       if (rc != 0)
+               goto fail_rx_qstart;
+
+       sa->rxq_info[rx_queue_id].deferred_started = B_TRUE;
+
+       sfc_adapter_unlock(sa);
+
+       return 0;
+
+fail_rx_qstart:
+fail_not_started:
+       sfc_adapter_unlock(sa);
+       SFC_ASSERT(rc > 0);
+       return -rc;
+}
+
+static int
+sfc_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+
+       sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+       sfc_adapter_lock(sa);
+       sfc_rx_qstop(sa, rx_queue_id);
+
+       sa->rxq_info[rx_queue_id].deferred_started = B_FALSE;
+
+       sfc_adapter_unlock(sa);
+
+       return 0;
+}
+
 static const struct eth_dev_ops sfc_eth_dev_ops = {
        .dev_configure                  = sfc_dev_configure,
        .dev_start                      = sfc_dev_start,
@@ -881,6 +930,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
        .dev_infos_get                  = sfc_dev_infos_get,
        .dev_supported_ptypes_get       = sfc_dev_supported_ptypes_get,
        .mtu_set                        = sfc_dev_set_mtu,
+       .rx_queue_start                 = sfc_rx_queue_start,
+       .rx_queue_stop                  = sfc_rx_queue_stop,
        .rx_queue_setup                 = sfc_rx_queue_setup,
        .rx_queue_release               = sfc_rx_queue_release,
        .rx_queue_count                 = sfc_rx_queue_count,
index 2909ec0..3bfce1c 100644 (file)
@@ -444,6 +444,9 @@ 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)
+               return;
        SFC_ASSERT(rxq->state & SFC_RXQ_STARTED);
 
        /* It seems to be used by DPDK for debug purposes only ('rte_ether') */
@@ -491,11 +494,6 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
                rc = EINVAL;
        }
 
-       if (rx_conf->rx_deferred_start != 0) {
-               sfc_err(sa, "RxQ deferred start is not supported");
-               rc = EINVAL;
-       }
-
        return rc;
 }
 
@@ -688,6 +686,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
        rxq->state = SFC_RXQ_INITIALIZED;
 
        rxq_info->rxq = rxq;
+       rxq_info->deferred_start = (rx_conf->rx_deferred_start != 0);
 
        return 0;
 
@@ -742,9 +741,12 @@ sfc_rx_start(struct sfc_adapter *sa)
                goto fail_rx_init;
 
        for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
-               rc = sfc_rx_qstart(sa, sw_index);
-               if (rc != 0)
-                       goto fail_rx_qstart;
+               if ((!sa->rxq_info[sw_index].deferred_start ||
+                    sa->rxq_info[sw_index].deferred_started)) {
+                       rc = sfc_rx_qstart(sa, sw_index);
+                       if (rc != 0)
+                               goto fail_rx_qstart;
+               }
        }
 
        return 0;
index 8d8e709..4aa6aea 100644 (file)
@@ -119,6 +119,8 @@ struct sfc_rxq_info {
        unsigned int            entries;
        efx_rxq_type_t          type;
        struct sfc_rxq          *rxq;
+       boolean_t               deferred_start;
+       boolean_t               deferred_started;
 };
 
 int sfc_rx_init(struct sfc_adapter *sa);