fm10k: select best Rx function
[dpdk.git] / drivers / net / fm10k / fm10k_ethdev.c
index caa1272..c99f577 100644 (file)
@@ -67,6 +67,7 @@ static void fm10k_MAC_filter_set(struct rte_eth_dev *dev,
        const u8 *mac, bool add, uint32_t pool);
 static void fm10k_tx_queue_release(void *queue);
 static void fm10k_rx_queue_release(void *queue);
+static void fm10k_set_rx_function(struct rte_eth_dev *dev);
 
 static void
 fm10k_mbx_initlock(struct fm10k_hw *hw)
@@ -121,6 +122,9 @@ rx_queue_reset(struct fm10k_rx_queue *q)
        q->next_alloc = 0;
        q->next_trigger = q->alloc_thresh - 1;
        FM10K_PCI_REG_WRITE(q->tail_ptr, q->nb_desc - 1);
+       q->rxrearm_start = 0;
+       q->rxrearm_nb = 0;
+
        return 0;
 }
 
@@ -608,7 +612,6 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
                        dev->data->dev_conf.rxmode.enable_scatter) {
                        uint32_t reg;
                        dev->data->scattered_rx = 1;
-                       dev->rx_pkt_burst = fm10k_recv_scattered_pkts;
                        reg = FM10K_READ_REG(hw, FM10K_SRRCTL(i));
                        reg |= FM10K_SRRCTL_BUFFER_CHAINING_EN;
                        FM10K_WRITE_REG(hw, FM10K_SRRCTL(i), reg);
@@ -624,6 +627,10 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 
        /* Configure VMDQ/RSS if applicable */
        fm10k_dev_mq_rx_configure(dev);
+
+       /* Decide the best RX function */
+       fm10k_set_rx_function(dev);
+
        return 0;
 }
 
@@ -1466,6 +1473,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
        const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct fm10k_dev_info *dev_info = FM10K_DEV_PRIVATE_TO_INFO(dev);
        struct fm10k_rx_queue *q;
        const struct rte_memzone *mz;
 
@@ -1548,6 +1556,16 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
        q->hw_ring_phys_addr = mz->phys_addr;
 #endif
 
+       /* Check if number of descs satisfied Vector requirement */
+       if (!rte_is_power_of_2(nb_desc)) {
+               PMD_INIT_LOG(DEBUG, "queue[%d] doesn't meet Vector Rx "
+                                   "preconditions - canceling the feature for "
+                                   "the whole port[%d]",
+                            q->queue_id, q->port_id);
+               dev_info->rx_vec_allowed = false;
+       } else
+               fm10k_rxq_vec_setup(q);
+
        dev->data->rx_queues[queue_id] = q;
        return 0;
 }
@@ -2270,6 +2288,55 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
        .rss_hash_conf_get      = fm10k_rss_hash_conf_get,
 };
 
+static void __attribute__((cold))
+fm10k_set_rx_function(struct rte_eth_dev *dev)
+{
+       struct fm10k_dev_info *dev_info = FM10K_DEV_PRIVATE_TO_INFO(dev);
+       uint16_t i, rx_using_sse;
+
+       /* In order to allow Vector Rx there are a few configuration
+        * conditions to be met.
+        */
+       if (!fm10k_rx_vec_condition_check(dev) && dev_info->rx_vec_allowed) {
+               if (dev->data->scattered_rx)
+                       dev->rx_pkt_burst = fm10k_recv_scattered_pkts_vec;
+               else
+                       dev->rx_pkt_burst = fm10k_recv_pkts_vec;
+       } else if (dev->data->scattered_rx)
+               dev->rx_pkt_burst = fm10k_recv_scattered_pkts;
+
+       rx_using_sse =
+               (dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec ||
+               dev->rx_pkt_burst == fm10k_recv_pkts_vec);
+
+       for (i = 0; i < dev->data->nb_rx_queues; i++) {
+               struct fm10k_rx_queue *rxq = dev->data->rx_queues[i];
+
+               rxq->rx_using_sse = rx_using_sse;
+       }
+}
+
+static void
+fm10k_params_init(struct rte_eth_dev *dev)
+{
+       struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct fm10k_dev_info *info = FM10K_DEV_PRIVATE_TO_INFO(dev);
+
+       /* Inialize bus info. Normally we would call fm10k_get_bus_info(), but
+        * there is no way to get link status without reading BAR4.  Until this
+        * works, assume we have maximum bandwidth.
+        * @todo - fix bus info
+        */
+       hw->bus_caps.speed = fm10k_bus_speed_8000;
+       hw->bus_caps.width = fm10k_bus_width_pcie_x8;
+       hw->bus_caps.payload = fm10k_bus_payload_512;
+       hw->bus.speed = fm10k_bus_speed_8000;
+       hw->bus.width = fm10k_bus_width_pcie_x8;
+       hw->bus.payload = fm10k_bus_payload_256;
+
+       info->rx_vec_allowed = true;
+}
+
 static int
 eth_fm10k_dev_init(struct rte_eth_dev *dev)
 {
@@ -2283,9 +2350,6 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
        dev->rx_pkt_burst = &fm10k_recv_pkts;
        dev->tx_pkt_burst = &fm10k_xmit_pkts;
 
-       if (dev->data->scattered_rx)
-               dev->rx_pkt_burst = &fm10k_recv_scattered_pkts;
-
        /* only initialize in the primary process */
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
@@ -2316,18 +2380,8 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
                return -EIO;
        }
 
-       /*
-        * Inialize bus info. Normally we would call fm10k_get_bus_info(), but
-        * there is no way to get link status without reading BAR4.  Until this
-        * works, assume we have maximum bandwidth.
-        * @todo - fix bus info
-        */
-       hw->bus_caps.speed = fm10k_bus_speed_8000;
-       hw->bus_caps.width = fm10k_bus_width_pcie_x8;
-       hw->bus_caps.payload = fm10k_bus_payload_512;
-       hw->bus.speed = fm10k_bus_speed_8000;
-       hw->bus.width = fm10k_bus_width_pcie_x8;
-       hw->bus.payload = fm10k_bus_payload_256;
+       /* Initialize parameters */
+       fm10k_params_init(dev);
 
        /* Initialize the hw */
        diag = fm10k_init_hw(hw);