net/thunderx: fix build with gcc optimization on
[dpdk.git] / drivers / net / thunderx / nicvf_ethdev.c
index 067f224..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"
 
@@ -162,7 +164,7 @@ static int
 nicvf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 {
        struct nicvf *nic = nicvf_pmd_priv(dev);
-       uint32_t buffsz, frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+       uint32_t buffsz, frame_size = mtu + NIC_HW_L2_OVERHEAD;
        size_t i;
        struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 
@@ -180,7 +182,7 @@ nicvf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
         * Refuse mtu that requires the support of scattered packets
         * when this feature has not been enabled before.
         */
-       if (!dev->data->scattered_rx &&
+       if (dev->data->dev_started && !dev->data->scattered_rx &&
                (frame_size + 2 * VLAN_TAG_SIZE > buffsz))
                return -EINVAL;
 
@@ -194,11 +196,11 @@ nicvf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        else
                rxmode->offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
 
-       if (nicvf_mbox_update_hw_max_frs(nic, frame_size))
+       if (nicvf_mbox_update_hw_max_frs(nic, mtu))
                return -EINVAL;
 
-       /* Update max frame size */
-       rxmode->max_rx_pkt_len = (uint32_t)frame_size;
+       /* Update max_rx_pkt_len */
+       rxmode->max_rx_pkt_len = mtu + ETHER_HDR_LEN;
        nic->mtu = mtu;
 
        for (i = 0; i < nic->sqs_count; i++)
@@ -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");
@@ -1308,7 +1296,7 @@ nicvf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,
        }
 
        /* Mempool memory must be physically contiguous */
-       if (mp->flags & MEMPOOL_F_NO_PHYS_CONTIG) {
+       if (mp->flags & MEMPOOL_F_NO_IOVA_CONTIG) {
                PMD_INIT_LOG(ERR, "Mempool memory must be physically contiguous");
                return -EINVAL;
        }
@@ -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)] =
@@ -1400,8 +1390,6 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
        PMD_INIT_FUNC_TRACE();
 
-       dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
-
        /* Autonegotiation may be disabled */
        dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
        dev_info->speed_capa |= ETH_LINK_SPEED_10M | ETH_LINK_SPEED_100M |
@@ -1410,7 +1398,7 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                dev_info->speed_capa |= ETH_LINK_SPEED_40G;
 
        dev_info->min_rx_bufsize = ETHER_MIN_MTU;
-       dev_info->max_rx_pktlen = NIC_HW_MAX_FRS;
+       dev_info->max_rx_pktlen = NIC_HW_MAX_MTU + ETHER_HDR_LEN;
        dev_info->max_rx_queues =
                        (uint16_t)MAX_RCV_QUEUES_PER_QS * (MAX_SQS_PER_VF + 1);
        dev_info->max_tx_queues =
@@ -1437,12 +1425,6 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
        dev_info->default_txconf = (struct rte_eth_txconf) {
                .tx_free_thresh = NICVF_DEFAULT_TX_FREE_THRESH,
-               .txq_flags =
-                       ETH_TXQ_FLAGS_NOMULTSEGS  |
-                       ETH_TXQ_FLAGS_NOREFCOUNT  |
-                       ETH_TXQ_FLAGS_NOMULTMEMP  |
-                       ETH_TXQ_FLAGS_NOVLANOFFL  |
-                       ETH_TXQ_FLAGS_NOXSUMSCTP,
                .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE |
                        DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM   |
                        DEV_TX_OFFLOAD_UDP_CKSUM          |
@@ -1533,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;
@@ -1743,8 +1726,7 @@ nicvf_dev_start(struct rte_eth_dev *dev)
        /* Setup MTU based on max_rx_pkt_len or default */
        mtu = dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME ?
                dev->data->dev_conf.rxmode.max_rx_pkt_len
-                       -  ETHER_HDR_LEN - ETHER_CRC_LEN
-               : ETHER_MTU;
+                       -  ETHER_HDR_LEN : ETHER_MTU;
 
        if (nicvf_dev_set_mtu(dev, mtu)) {
                PMD_INIT_LOG(ERR, "Failed to set default mtu size");
@@ -1915,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();
 
@@ -1925,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;
        }
@@ -2041,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)
 {
@@ -2150,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],
@@ -2222,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>");