net/thunderx: fix build with gcc optimization on
[dpdk.git] / drivers / net / thunderx / nicvf_ethdev.c
index 2a8bdf3..5968421 100644 (file)
@@ -34,6 +34,8 @@
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
 #include <rte_tailq.h>
+#include <rte_devargs.h>
+#include <rte_kvargs.h>
 
 #include "base/nicvf_plat.h"
 
@@ -883,7 +885,7 @@ nicvf_dev_tx_queue_release(void *sq)
 static void
 nicvf_set_tx_function(struct rte_eth_dev *dev)
 {
-       struct nicvf_txq *txq;
+       struct nicvf_txq *txq = NULL;
        size_t i;
        bool multiseg = false;
 
@@ -904,6 +906,9 @@ nicvf_set_tx_function(struct rte_eth_dev *dev)
                dev->tx_pkt_burst = nicvf_xmit_pkts;
        }
 
+       if (!txq)
+               return;
+
        if (txq->pool_free == nicvf_single_pool_free_xmited_buffers)
                PMD_DRV_LOG(DEBUG, "Using single-mempool tx free method");
        else
@@ -931,7 +936,7 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
        bool is_single_pool;
        struct nicvf_txq *txq;
        struct nicvf *nic = nicvf_pmd_priv(dev);
-       uint64_t conf_offloads, offload_capa, unsupported_offloads;
+       uint64_t offloads;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -945,17 +950,6 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
                PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
                socket_id, nic->node);
 
-       conf_offloads = tx_conf->offloads;
-       offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-       unsupported_offloads = conf_offloads & ~offload_capa;
-       if (unsupported_offloads) {
-               PMD_INIT_LOG(ERR, "Tx offloads 0x%" PRIx64 " are not supported."
-                     "Requested 0x%" PRIx64 " supported 0x%" PRIx64 ".\n",
-                     unsupported_offloads, conf_offloads, offload_capa);
-               return -ENOTSUP;
-       }
-
        /* Tx deferred start is not supported */
        if (tx_conf->tx_deferred_start) {
                PMD_INIT_LOG(ERR, "Tx deferred start not supported");
@@ -1007,9 +1001,10 @@ nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
        txq->tx_free_thresh = tx_free_thresh;
        txq->sq_head = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_HEAD;
        txq->sq_door = nicvf_qset_base(nic, qidx) + NIC_QSET_SQ_0_7_DOOR;
-       txq->offloads = conf_offloads;
+       offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+       txq->offloads = offloads;
 
-       is_single_pool = !!(conf_offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
+       is_single_pool = !!(offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE);
 
        /* Choose optimum free threshold value for multipool case */
        if (!is_single_pool) {
@@ -1240,6 +1235,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq)
 {
        uintptr_t p;
        struct rte_mbuf mb_def;
+       struct nicvf *nic = rxq->nic;
 
        RTE_BUILD_BUG_ON(sizeof(union mbuf_initializer) != 8);
        RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0);
@@ -1250,7 +1246,7 @@ nicvf_rxq_mbuf_setup(struct nicvf_rxq *rxq)
        RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) -
                                offsetof(struct rte_mbuf, data_off) != 6);
        mb_def.nb_segs = 1;
-       mb_def.data_off = RTE_PKTMBUF_HEADROOM;
+       mb_def.data_off = RTE_PKTMBUF_HEADROOM + (nic->skip_bytes);
        mb_def.port = rxq->port_id;
        rte_mbuf_refcnt_set(&mb_def, 1);
 
@@ -1269,10 +1265,20 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
        uint16_t rx_free_thresh;
        struct nicvf_rxq *rxq;
        struct nicvf *nic = nicvf_pmd_priv(dev);
-       uint64_t conf_offloads, offload_capa, unsupported_offloads;
+       uint64_t offloads;
+       uint32_t buffsz;
+       struct rte_pktmbuf_pool_private *mbp_priv;
 
        PMD_INIT_FUNC_TRACE();
 
+       /* First skip check */
+       mbp_priv = rte_mempool_get_priv(mp);
+       buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
+       if (buffsz < (uint32_t)(nic->skip_bytes)) {
+               PMD_INIT_LOG(ERR, "First skip is more than configured buffer size");
+               return -EINVAL;
+       }
+
        if (qidx >= MAX_RCV_QUEUES_PER_QS)
                nic = nic->snicvf[qidx / MAX_RCV_QUEUES_PER_QS - 1];
 
@@ -1283,24 +1289,6 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
                PMD_DRV_LOG(WARNING, "socket_id expected %d, configured %d",
                socket_id, nic->node);
 
-
-       conf_offloads = rx_conf->offloads;
-
-       if (conf_offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-               PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-               conf_offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-       }
-
-       offload_capa = NICVF_RX_OFFLOAD_CAPA;
-       unsupported_offloads = conf_offloads & ~offload_capa;
-
-       if (unsupported_offloads) {
-               PMD_INIT_LOG(ERR, "Rx offloads 0x%" PRIx64 " are not supported. "
-                     "Requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-                     unsupported_offloads, conf_offloads, offload_capa);
-               return -ENOTSUP;
-       }
-
        /* Mempool memory must be contiguous, so must be one memory segment*/
        if (mp->nb_mem_chunks != 1) {
                PMD_INIT_LOG(ERR, "Non-contiguous mempool, add more huge pages");
@@ -1326,6 +1314,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
                return -EINVAL;
        }
 
+
        /* Check rx_free_thresh upper bound */
        rx_free_thresh = (uint16_t)((rx_conf->rx_free_thresh) ?
                                rx_conf->rx_free_thresh :
@@ -1381,10 +1370,11 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
 
        nicvf_rx_queue_reset(rxq);
 
+       offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
        PMD_INIT_LOG(DEBUG, "[%d] rxq=%p pool=%s nb_desc=(%d/%d)"
                        " phy=0x%" PRIx64 " offloads=0x%" PRIx64,
                        nicvf_netdev_qidx(nic, qidx), rxq, mp->name, nb_desc,
-                       rte_mempool_avail_count(mp), rxq->phys, conf_offloads);
+                       rte_mempool_avail_count(mp), rxq->phys, offloads);
 
        dev->data->rx_queues[nicvf_netdev_qidx(nic, qidx)] = rxq;
        dev->data->rx_queue_state[nicvf_netdev_qidx(nic, qidx)] =
@@ -1525,6 +1515,7 @@ nicvf_vf_start(struct rte_eth_dev *dev, struct nicvf *nic, uint32_t rbdrsz)
                        return -EINVAL;
                }
                rxq->mbuf_phys_off -= data_off;
+               rxq->mbuf_phys_off -= nic->skip_bytes;
 
                if (mbuf_phys_off == 0)
                        mbuf_phys_off = rxq->mbuf_phys_off;
@@ -1906,8 +1897,6 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
        struct rte_eth_txmode *txmode = &conf->txmode;
        struct nicvf *nic = nicvf_pmd_priv(dev);
        uint8_t cqcount;
-       uint64_t conf_rx_offloads, rx_offload_capa;
-       uint64_t conf_tx_offloads, tx_offload_capa;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1916,32 +1905,7 @@ nicvf_dev_configure(struct rte_eth_dev *dev)
                return -EINVAL;
        }
 
-       conf_tx_offloads = dev->data->dev_conf.txmode.offloads;
-       tx_offload_capa = NICVF_TX_OFFLOAD_CAPA;
-
-       if ((conf_tx_offloads & tx_offload_capa) != conf_tx_offloads) {
-               PMD_INIT_LOG(ERR, "Some Tx offloads are not supported "
-                     "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-                     conf_tx_offloads, tx_offload_capa);
-               return -ENOTSUP;
-       }
-
-       if (rxmode->offloads & DEV_RX_OFFLOAD_CHECKSUM) {
-               PMD_INIT_LOG(NOTICE, "Rx checksum not supported");
-               rxmode->offloads &= ~DEV_RX_OFFLOAD_CHECKSUM;
-       }
-
-       conf_rx_offloads = rxmode->offloads;
-       rx_offload_capa = NICVF_RX_OFFLOAD_CAPA;
-
-       if ((conf_rx_offloads & rx_offload_capa) != conf_rx_offloads) {
-               PMD_INIT_LOG(ERR, "Some Rx offloads are not supported "
-                     "requested 0x%" PRIx64 " supported 0x%" PRIx64 "\n",
-                     conf_rx_offloads, rx_offload_capa);
-               return -ENOTSUP;
-       }
-
-       if ((conf_rx_offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
+       if ((rxmode->offloads & DEV_RX_OFFLOAD_CRC_STRIP) == 0) {
                PMD_INIT_LOG(NOTICE, "Can't disable hw crc strip");
                rxmode->offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
        }
@@ -2032,6 +1996,59 @@ static const struct eth_dev_ops nicvf_eth_dev_ops = {
        .get_reg                  = nicvf_dev_get_regs,
 };
 
+static inline int
+nicvf_set_first_skip(struct rte_eth_dev *dev)
+{
+       int bytes_to_skip = 0;
+       int ret = 0;
+       unsigned int i;
+       struct rte_kvargs *kvlist;
+       static const char *const skip[] = {
+               SKIP_DATA_BYTES,
+               NULL};
+       struct nicvf *nic = nicvf_pmd_priv(dev);
+
+       if (!dev->device->devargs) {
+               nicvf_first_skip_config(nic, 0);
+               return ret;
+       }
+
+       kvlist = rte_kvargs_parse(dev->device->devargs->args, skip);
+       if (!kvlist)
+               return -EINVAL;
+
+       if (kvlist->count == 0)
+               goto exit;
+
+       for (i = 0; i != kvlist->count; ++i) {
+               const struct rte_kvargs_pair *pair = &kvlist->pairs[i];
+
+               if (!strcmp(pair->key, SKIP_DATA_BYTES))
+                       bytes_to_skip = atoi(pair->value);
+       }
+
+       /*128 bytes amounts to one cache line*/
+       if (bytes_to_skip >= 0 && bytes_to_skip < 128) {
+               if (!(bytes_to_skip % 8)) {
+                       nicvf_first_skip_config(nic, (bytes_to_skip / 8));
+                       nic->skip_bytes = bytes_to_skip;
+                       goto kvlist_free;
+               } else {
+                       PMD_INIT_LOG(ERR, "skip_data_bytes should be multiple of 8");
+                       ret = -EINVAL;
+                       goto exit;
+               }
+       } else {
+               PMD_INIT_LOG(ERR, "skip_data_bytes should be less than 128");
+               ret = -EINVAL;
+               goto exit;
+       }
+exit:
+       nicvf_first_skip_config(nic, 0);
+kvlist_free:
+       rte_kvargs_free(kvlist);
+       return ret;
+}
 static int
 nicvf_eth_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -2141,6 +2158,11 @@ nicvf_eth_dev_init(struct rte_eth_dev *eth_dev)
                goto malloc_fail;
        }
 
+       ret = nicvf_set_first_skip(eth_dev);
+       if (ret) {
+               PMD_INIT_LOG(ERR, "Failed to configure first skip");
+               goto malloc_fail;
+       }
        PMD_INIT_LOG(INFO, "Port %d (%x:%x) mac=%02x:%02x:%02x:%02x:%02x:%02x",
                eth_dev->data->port_id, nic->vendor_id, nic->device_id,
                nic->mac_addr[0], nic->mac_addr[1], nic->mac_addr[2],
@@ -2213,3 +2235,4 @@ static struct rte_pci_driver rte_nicvf_pmd = {
 RTE_PMD_REGISTER_PCI(net_thunderx, rte_nicvf_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_thunderx, pci_id_nicvf_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_thunderx, "* igb_uio | uio_pci_generic | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_thunderx, SKIP_DATA_BYTES "=<int>");