net/i40e: convert to new Tx offloads API
[dpdk.git] / drivers / net / i40e / i40e_rxtx.c
index a35a9d3..bc66059 100644 (file)
@@ -17,7 +17,7 @@
 #include <rte_mbuf.h>
 #include <rte_malloc.h>
 #include <rte_ether.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_tcp.h>
 #include <rte_sctp.h>
 #include <rte_udp.h>
@@ -1685,11 +1685,27 @@ i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 #endif
            dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
            dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
-           dev->rx_pkt_burst == i40e_recv_pkts_vec)
+           dev->rx_pkt_burst == i40e_recv_pkts_vec ||
+           dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec_avx2 ||
+           dev->rx_pkt_burst == i40e_recv_pkts_vec_avx2)
                return ptypes;
        return NULL;
 }
 
+static int
+i40e_check_rx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
+{
+       struct rte_eth_dev_info dev_info;
+       uint64_t mandatory = dev->data->dev_conf.rxmode.offloads;
+       uint64_t supported; /* All per port offloads */
+
+       dev->dev_ops->dev_infos_get(dev, &dev_info);
+       supported = dev_info.rx_offload_capa ^ dev_info.rx_queue_offload_capa;
+       if ((requested & dev_info.rx_offload_capa) != requested)
+               return 0; /* requested range check */
+       return !((mandatory ^ requested) & supported);
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
                        uint16_t queue_idx,
@@ -1710,6 +1726,18 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
        uint16_t len, i;
        uint16_t reg_idx, base, bsf, tc_mapping;
        int q_offset, use_def_burst_func = 1;
+       struct rte_eth_dev_info dev_info;
+
+       if (!i40e_check_rx_queue_offloads(dev, rx_conf->offloads)) {
+               dev->dev_ops->dev_infos_get(dev, &dev_info);
+               PMD_INIT_LOG(ERR, "%p: Rx queue offloads 0x%" PRIx64
+                       " don't match port  offloads 0x%" PRIx64
+                       " or supported offloads 0x%" PRIx64,
+                       (void *)dev, rx_conf->offloads,
+                       dev->data->dev_conf.rxmode.offloads,
+                       dev_info.rx_offload_capa);
+               return -ENOTSUP;
+       }
 
        if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
                vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -1758,8 +1786,8 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
        rxq->queue_id = queue_idx;
        rxq->reg_idx = reg_idx;
        rxq->port_id = dev->data->port_id;
-       rxq->crc_len = (uint8_t) ((dev->data->dev_conf.rxmode.hw_strip_crc) ?
-                                                       0 : ETHER_CRC_LEN);
+       rxq->crc_len = (uint8_t)((dev->data->dev_conf.rxmode.offloads &
+                       DEV_RX_OFFLOAD_CRC_STRIP) ? 0 : ETHER_CRC_LEN);
        rxq->drop_en = rx_conf->rx_drop_en;
        rxq->vsi = vsi;
        rxq->rx_deferred_start = rx_conf->rx_deferred_start;
@@ -1970,6 +1998,20 @@ i40e_dev_tx_descriptor_status(void *tx_queue, uint16_t offset)
        return RTE_ETH_TX_DESC_FULL;
 }
 
+static int
+i40e_check_tx_queue_offloads(struct rte_eth_dev *dev, uint64_t requested)
+{
+       struct rte_eth_dev_info dev_info;
+       uint64_t mandatory = dev->data->dev_conf.txmode.offloads;
+       uint64_t supported; /* All per port offloads */
+
+       dev->dev_ops->dev_infos_get(dev, &dev_info);
+       supported = dev_info.tx_offload_capa ^ dev_info.tx_queue_offload_capa;
+       if ((requested & dev_info.tx_offload_capa) != requested)
+               return 0; /* requested range check */
+       return !((mandatory ^ requested) & supported);
+}
+
 int
 i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
                        uint16_t queue_idx,
@@ -1987,6 +2029,16 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
        uint16_t tx_rs_thresh, tx_free_thresh;
        uint16_t reg_idx, i, base, bsf, tc_mapping;
        int q_offset;
+       struct rte_eth_dev_info dev_info;
+
+       if (!i40e_check_tx_queue_offloads(dev, tx_conf->offloads)) {
+               dev->dev_ops->dev_infos_get(dev, &dev_info);
+               PMD_INIT_LOG(ERR, "%p: Tx queue offloads 0x%" PRIx64
+                       " don't match port  offloads 0x%" PRIx64
+                       " or supported offloads 0x%" PRIx64,
+                       (void *)dev, tx_conf->offloads,
+                       dev->data->dev_conf.txmode.offloads,
+                       dev_info.tx_offload_capa); }
 
        if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
                vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2187,8 +2239,8 @@ i40e_memzone_reserve(const char *name, uint32_t len, int socket_id)
        if (mz)
                return mz;
 
-       mz = rte_memzone_reserve_aligned(name, len,
-                                        socket_id, 0, I40E_RING_BASE_ALIGN);
+       mz = rte_memzone_reserve_aligned(name, len, socket_id,
+                       RTE_MEMZONE_IOVA_CONTIG, I40E_RING_BASE_ALIGN);
        return mz;
 }
 
@@ -2283,7 +2335,8 @@ i40e_tx_queue_release_mbufs(struct i40e_tx_queue *txq)
         *  vPMD tx will not set sw_ring's mbuf to NULL after free,
         *  so need to free remains more carefully.
         */
-       if (dev->tx_pkt_burst == i40e_xmit_pkts_vec) {
+       if (dev->tx_pkt_burst == i40e_xmit_pkts_vec_avx2 ||
+                       dev->tx_pkt_burst == i40e_xmit_pkts_vec) {
                i = txq->tx_next_dd - txq->tx_rs_thresh + 1;
                if (txq->tx_tail < i) {
                        for (; i < txq->nb_tx_desc; i++) {
@@ -2466,7 +2519,7 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq)
 
        len = hw->func_caps.rx_buf_chain_len * rxq->rx_buf_len;
        rxq->max_pkt_len = RTE_MIN(len, data->dev_conf.rxmode.max_rx_pkt_len);
-       if (data->dev_conf.rxmode.jumbo_frame == 1) {
+       if (data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
                if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
                        rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
                        PMD_DRV_LOG(ERR, "maximum packet length must "
@@ -2716,6 +2769,7 @@ i40e_fdir_setup_rx_resources(struct i40e_pf *pf)
        rxq->vsi = pf->fdir.fdir_vsi;
 
        rxq->rx_ring_phys_addr = rz->iova;
+       memset(rz->addr, 0, I40E_FDIR_NUM_RX_DESC * sizeof(union i40e_rx_desc));
        rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
 
        /*
@@ -2743,6 +2797,7 @@ i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
        qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
        qinfo->conf.rx_drop_en = rxq->drop_en;
        qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
+       qinfo->conf.offloads = rxq->offloads;
 }
 
 void
@@ -2806,6 +2861,17 @@ i40e_set_rx_function(struct rte_eth_dev *dev)
                                     dev->data->port_id);
 
                        dev->rx_pkt_burst = i40e_recv_scattered_pkts_vec;
+#ifdef RTE_ARCH_X86
+                       /*
+                        * since AVX frequency can be different to base
+                        * frequency, limit use of AVX2 version to later
+                        * plaforms, not all those that could theoretically
+                        * run it.
+                        */
+                       if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F))
+                               dev->rx_pkt_burst =
+                                       i40e_recv_scattered_pkts_vec_avx2;
+#endif
                } else {
                        PMD_INIT_LOG(DEBUG, "Using a Scattered with bulk "
                                           "allocation callback (port=%d).",
@@ -2825,6 +2891,16 @@ i40e_set_rx_function(struct rte_eth_dev *dev)
                             dev->data->port_id);
 
                dev->rx_pkt_burst = i40e_recv_pkts_vec;
+#ifdef RTE_ARCH_X86
+               /*
+                * since AVX frequency can be different to base
+                * frequency, limit use of AVX2 version to later
+                * plaforms, not all those that could theoretically
+                * run it.
+                */
+               if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F))
+                       dev->rx_pkt_burst = i40e_recv_pkts_vec_avx2;
+#endif
        } else if (ad->rx_bulk_alloc_allowed) {
                PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions are "
                                    "satisfied. Rx Burst Bulk Alloc function "
@@ -2845,7 +2921,9 @@ i40e_set_rx_function(struct rte_eth_dev *dev)
        if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
                rx_using_sse =
                        (dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
-                        dev->rx_pkt_burst == i40e_recv_pkts_vec);
+                        dev->rx_pkt_burst == i40e_recv_pkts_vec ||
+                        dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec_avx2 ||
+                        dev->rx_pkt_burst == i40e_recv_pkts_vec_avx2);
 
                for (i = 0; i < dev->data->nb_rx_queues; i++) {
                        struct i40e_rx_queue *rxq = dev->data->rx_queues[i];
@@ -2902,6 +2980,16 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
                if (ad->tx_vec_allowed) {
                        PMD_INIT_LOG(DEBUG, "Vector tx finally be used.");
                        dev->tx_pkt_burst = i40e_xmit_pkts_vec;
+#ifdef RTE_ARCH_X86
+                       /*
+                        * since AVX frequency can be different to base
+                        * frequency, limit use of AVX2 version to later
+                        * plaforms, not all those that could theoretically
+                        * run it.
+                        */
+                       if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F))
+                               dev->tx_pkt_burst = i40e_xmit_pkts_vec_avx2;
+#endif
                } else {
                        PMD_INIT_LOG(DEBUG, "Simple tx finally be used.");
                        dev->tx_pkt_burst = i40e_xmit_pkts_simple;
@@ -3008,6 +3096,22 @@ i40e_recv_scattered_pkts_vec(
        return 0;
 }
 
+uint16_t __attribute__((weak))
+i40e_recv_pkts_vec_avx2(void __rte_unused *rx_queue,
+                       struct rte_mbuf __rte_unused **rx_pkts,
+                       uint16_t __rte_unused nb_pkts)
+{
+       return 0;
+}
+
+uint16_t __attribute__((weak))
+i40e_recv_scattered_pkts_vec_avx2(void __rte_unused *rx_queue,
+                       struct rte_mbuf __rte_unused **rx_pkts,
+                       uint16_t __rte_unused nb_pkts)
+{
+       return 0;
+}
+
 int __attribute__((weak))
 i40e_rxq_vec_setup(struct i40e_rx_queue __rte_unused *rxq)
 {
@@ -3033,3 +3137,11 @@ i40e_xmit_fixed_burst_vec(void __rte_unused * tx_queue,
 {
        return 0;
 }
+
+uint16_t __attribute__((weak))
+i40e_xmit_pkts_vec_avx2(void __rte_unused * tx_queue,
+                         struct rte_mbuf __rte_unused **tx_pkts,
+                         uint16_t __rte_unused nb_pkts)
+{
+       return 0;
+}