New upstream version 17.11.4 17/14617/1 upstream/17.11.4
authorLuca Boccassi <luca.boccassi@gmail.com>
Mon, 3 Sep 2018 09:46:47 +0000 (10:46 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 3 Sep 2018 09:47:29 +0000 (10:47 +0100)
Change-Id: Icb6b9664e7c4adb85c087844abe6e54d6ec32db6
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
129 files changed:
MAINTAINERS
app/test-crypto-perf/cperf_ops.c
app/test-pmd/cmdline_tm.c
app/test-pmd/testpmd.c
buildtools/pmdinfogen/Makefile
doc/guides/nics/enic.rst
doc/guides/nics/qede.rst
doc/guides/rel_notes/release_17_11.rst
doc/guides/testpmd_app_ug/testpmd_funcs.rst
drivers/bus/dpaa/base/fman/fman_hw.c
drivers/bus/dpaa/base/fman/of.c
drivers/bus/dpaa/include/compat.h
drivers/bus/pci/linux/pci.c
drivers/bus/pci/linux/pci_vfio.c
drivers/crypto/qat/qat_crypto.c
drivers/event/octeontx/ssovf_evdev.c
drivers/net/bnx2x/bnx2x.c
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_ethdev.c
drivers/net/bnx2x/bnx2x_ethdev.h
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_filter.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_stats.c
drivers/net/bnxt/bnxt_txr.c
drivers/net/bnxt/bnxt_txr.h
drivers/net/bnxt/bnxt_vnic.c
drivers/net/bnxt/bnxt_vnic.h
drivers/net/bonding/rte_eth_bond_api.c
drivers/net/bonding/rte_eth_bond_pmd.c
drivers/net/cxgbe/base/t4_hw.c
drivers/net/cxgbe/base/t4fw_interface.h
drivers/net/cxgbe/cxgbe_compat.h
drivers/net/cxgbe/sge.c
drivers/net/dpaa2/mc/dpni.c
drivers/net/ena/base/ena_plat_dpdk.h
drivers/net/ena/ena_ethdev.c
drivers/net/enic/enic.h
drivers/net/enic/enic_ethdev.c
drivers/net/enic/enic_main.c
drivers/net/i40e/i40e_ethdev.c
drivers/net/i40e/rte_pmd_i40e.c
drivers/net/ixgbe/ixgbe_ethdev.h
drivers/net/ixgbe/ixgbe_fdir.c
drivers/net/ixgbe/ixgbe_flow.c
drivers/net/mlx4/mlx4.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/mlx4_rxq.c
drivers/net/mlx5/Makefile
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5_defs.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_rxmode.c
drivers/net/mlx5/mlx5_rxtx.c
drivers/net/mlx5/mlx5_rxtx.h
drivers/net/mlx5/mlx5_rxtx_vec.h
drivers/net/mlx5/mlx5_rxtx_vec_neon.h
drivers/net/mlx5/mlx5_rxtx_vec_sse.h
drivers/net/mlx5/mlx5_socket.c
drivers/net/mlx5/mlx5_trigger.c
drivers/net/mlx5/mlx5_txq.c
drivers/net/mrvl/mrvl_ethdev.c
drivers/net/nfp/nfp_net.c
drivers/net/octeontx/octeontx_ethdev.c
drivers/net/pcap/rte_eth_pcap.c
drivers/net/qede/base/ecore_dev.c
drivers/net/qede/base/ecore_int.c
drivers/net/qede/base/ecore_sriov.c
drivers/net/qede/base/ecore_vf.c
drivers/net/qede/base/ecore_vf.h
drivers/net/qede/base/ecore_vfpf_if.h
drivers/net/qede/qede_ethdev.c
drivers/net/qede/qede_ethdev.h
drivers/net/qede/qede_fdir.c
drivers/net/qede/qede_main.c
drivers/net/sfc/sfc_ef10_rx.c
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_flow.c
drivers/net/tap/tap_flow.c
drivers/net/thunderx/nicvf_ethdev.c
drivers/net/thunderx/nicvf_rxtx.c
examples/exception_path/main.c
examples/flow_filtering/main.c
examples/ip_pipeline/config_parse_tm.c
examples/ipsec-secgw/ipsec-secgw.c
examples/ipsec-secgw/parser.c
examples/l2fwd-crypto/main.c
examples/l3fwd/l3fwd_em.c
examples/l3fwd/l3fwd_lpm.c
examples/vhost_scsi/scsi.c
lib/librte_bitratestats/rte_bitrate.c
lib/librte_eal/common/eal_common_memory.c
lib/librte_eal/common/include/rte_bitmap.h
lib/librte_eal/common/include/rte_memory.h
lib/librte_eal/common/include/rte_version.h
lib/librte_eal/linuxapp/eal/eal_interrupts.c
lib/librte_eal/linuxapp/eal/eal_memory.c
lib/librte_eal/linuxapp/eal/eal_thread.c
lib/librte_eal/linuxapp/kni/ethtool/igb/igb_ethtool.c
lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h
lib/librte_eal/rte_eal_version.map
lib/librte_ether/rte_ethdev.h
lib/librte_eventdev/rte_event_eth_rx_adapter.c
lib/librte_eventdev/rte_event_ring.c
lib/librte_hash/rte_cuckoo_hash.c
lib/librte_hash/rte_cuckoo_hash_x86.h
lib/librte_hash/rte_hash.h
lib/librte_kni/rte_kni.c
lib/librte_metrics/rte_metrics.c
lib/librte_ring/rte_ring.h
lib/librte_security/rte_security.c
lib/librte_vhost/iotlb.c
lib/librte_vhost/iotlb.h
lib/librte_vhost/vhost.h
lib/librte_vhost/vhost_user.c
lib/librte_vhost/virtio_net.c
mk/rte.sdkinstall.mk
mk/rte.sdkroot.mk
mk/rte.sdktest.mk
mk/toolchain/gcc/rte.toolchain-compat.mk
mk/toolchain/gcc/rte.vars.mk
pkg/dpdk.spec
test/test/autotest_runner.py
test/test/test_cryptodev.c
test/test/test_eal_flags.c
test/test/test_flow_classify.c
test/test/test_hash_multiwriter.c
test/test/test_pmd_ring.c

index f0baeb4..449409a 100644 (file)
@@ -155,13 +155,13 @@ F: test/test/test_bitmap.c
 
 ARM v7
 M: Jan Viktorin <viktorin@rehivetech.com>
 
 ARM v7
 M: Jan Viktorin <viktorin@rehivetech.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
+M: Gavin Hu <gavin.hu@arm.com>
 F: lib/librte_eal/common/arch/arm/
 F: lib/librte_eal/common/include/arch/arm/
 
 ARM v8
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
 F: lib/librte_eal/common/arch/arm/
 F: lib/librte_eal/common/include/arch/arm/
 
 ARM v8
 M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
+M: Gavin Hu <gavin.hu@arm.com>
 F: lib/librte_eal/common/include/arch/arm/*_64.h
 F: lib/librte_net/net_crc_neon.h
 F: lib/librte_acl/acl_run_neon.*
 F: lib/librte_eal/common/include/arch/arm/*_64.h
 F: lib/librte_net/net_crc_neon.h
 F: lib/librte_acl/acl_run_neon.*
@@ -428,14 +428,14 @@ F: drivers/net/fm10k/
 F: doc/guides/nics/features/fm10k*.ini
 
 Mellanox mlx4
 F: doc/guides/nics/features/fm10k*.ini
 
 Mellanox mlx4
-M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
+M: Matan Azrad <matan@mellanox.com>
+M: Shahaf Shuler <shahafs@mellanox.com>
 F: drivers/net/mlx4/
 F: doc/guides/nics/mlx4.rst
 F: doc/guides/nics/features/mlx4.ini
 
 Mellanox mlx5
 F: drivers/net/mlx4/
 F: doc/guides/nics/mlx4.rst
 F: doc/guides/nics/features/mlx4.ini
 
 Mellanox mlx5
-M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
-M: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
+M: Shahaf Shuler <shahafs@mellanox.com>
 M: Yongseok Koh <yskoh@mellanox.com>
 F: drivers/net/mlx5/
 F: doc/guides/nics/mlx5.rst
 M: Yongseok Koh <yskoh@mellanox.com>
 F: drivers/net/mlx5/
 F: doc/guides/nics/mlx5.rst
@@ -446,7 +446,6 @@ M: Jacek Siuda <jck@semihalf.com>
 M: Tomasz Duszynski <tdu@semihalf.com>
 M: Dmitri Epshtein <dima@marvell.com>
 M: Natalie Samsonov <nsamsono@marvell.com>
 M: Tomasz Duszynski <tdu@semihalf.com>
 M: Dmitri Epshtein <dima@marvell.com>
 M: Natalie Samsonov <nsamsono@marvell.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
 F: drivers/net/mrvl/
 F: doc/guides/nics/mrvl.rst
 F: doc/guides/nics/features/mrvl.ini
 F: drivers/net/mrvl/
 F: doc/guides/nics/mrvl.rst
 F: doc/guides/nics/features/mrvl.ini
@@ -630,7 +629,6 @@ M: Jacek Siuda <jck@semihalf.com>
 M: Tomasz Duszynski <tdu@semihalf.com>
 M: Dmitri Epshtein <dima@marvell.com>
 M: Natalie Samsonov <nsamsono@marvell.com>
 M: Tomasz Duszynski <tdu@semihalf.com>
 M: Dmitri Epshtein <dima@marvell.com>
 M: Natalie Samsonov <nsamsono@marvell.com>
-M: Jianbo Liu <jianbo.liu@arm.org>
 F: drivers/crypto/mrvl/
 F: doc/guides/cryptodevs/mrvl.rst
 F: doc/guides/cryptodevs/features/mrvl.ini
 F: drivers/crypto/mrvl/
 F: doc/guides/cryptodevs/mrvl.rst
 F: doc/guides/cryptodevs/features/mrvl.ini
index 23d30ca..0fa1c41 100644 (file)
@@ -507,6 +507,7 @@ cperf_create_session(struct rte_mempool *sess_mp,
                auth_xform.next = NULL;
                auth_xform.auth.algo = options->auth_algo;
                auth_xform.auth.op = options->auth_op;
                auth_xform.next = NULL;
                auth_xform.auth.algo = options->auth_algo;
                auth_xform.auth.op = options->auth_op;
+               auth_xform.auth.iv.offset = iv_offset;
 
                /* auth different than null */
                if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
 
                /* auth different than null */
                if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
@@ -561,6 +562,8 @@ cperf_create_session(struct rte_mempool *sess_mp,
                auth_xform.next = NULL;
                auth_xform.auth.algo = options->auth_algo;
                auth_xform.auth.op = options->auth_op;
                auth_xform.next = NULL;
                auth_xform.auth.algo = options->auth_algo;
                auth_xform.auth.op = options->auth_op;
+               auth_xform.auth.iv.offset = iv_offset +
+                       cipher_xform.cipher.iv.length;
 
                /* auth different than null */
                if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
 
                /* auth different than null */
                if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
index 803fae4..d40a427 100644 (file)
@@ -1624,10 +1624,12 @@ static void cmd_add_port_tm_nonleaf_node_parsed(void *parsed_result,
 
        np.shaper_profile_id = res->shaper_profile_id;
        np.n_shared_shapers = n_shared_shapers;
 
        np.shaper_profile_id = res->shaper_profile_id;
        np.n_shared_shapers = n_shared_shapers;
-       if (np.n_shared_shapers)
+       if (np.n_shared_shapers) {
                np.shared_shaper_id = &shared_shaper_id[0];
                np.shared_shaper_id = &shared_shaper_id[0];
-       else
-               np.shared_shaper_id = NULL;
+       } else {
+               free(shared_shaper_id);
+               shared_shaper_id = NULL;
+       }
 
        np.nonleaf.n_sp_priorities = res->n_sp_priorities;
        np.stats_mask = res->stats_mask;
 
        np.nonleaf.n_sp_priorities = res->n_sp_priorities;
        np.stats_mask = res->stats_mask;
@@ -1779,10 +1781,12 @@ static void cmd_add_port_tm_leaf_node_parsed(void *parsed_result,
        np.shaper_profile_id = res->shaper_profile_id;
        np.n_shared_shapers = n_shared_shapers;
 
        np.shaper_profile_id = res->shaper_profile_id;
        np.n_shared_shapers = n_shared_shapers;
 
-       if (np.n_shared_shapers)
+       if (np.n_shared_shapers) {
                np.shared_shaper_id = &shared_shaper_id[0];
                np.shared_shaper_id = &shared_shaper_id[0];
-       else
-               np.shared_shaper_id = NULL;
+       } else {
+               free(shared_shaper_id);
+               shared_shaper_id = NULL;
+       }
 
        np.leaf.cman = res->cman_mode;
        np.leaf.wred.wred_profile_id = res->wred_profile_id;
 
        np.leaf.cman = res->cman_mode;
        np.leaf.wred.wred_profile_id = res->wred_profile_id;
index a4b28e9..32d6871 100644 (file)
@@ -354,7 +354,7 @@ struct rte_fdir_conf fdir_conf = {
        .pballoc = RTE_FDIR_PBALLOC_64K,
        .status = RTE_FDIR_REPORT_STATUS,
        .mask = {
        .pballoc = RTE_FDIR_PBALLOC_64K,
        .status = RTE_FDIR_REPORT_STATUS,
        .mask = {
-               .vlan_tci_mask = 0x0,
+               .vlan_tci_mask = 0xFFEF,
                .ipv4_mask     = {
                        .src_ip = 0xFFFFFFFF,
                        .dst_ip = 0xFFFFFFFF,
                .ipv4_mask     = {
                        .src_ip = 0xFFFFFFFF,
                        .dst_ip = 0xFFFFFFFF,
@@ -2297,12 +2297,14 @@ const uint16_t vlan_tags[] = {
 };
 
 static  int
 };
 
 static  int
-get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
+get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
                 enum dcb_mode_enable dcb_mode,
                 enum rte_eth_nb_tcs num_tcs,
                 uint8_t pfc_en)
 {
        uint8_t i;
                 enum dcb_mode_enable dcb_mode,
                 enum rte_eth_nb_tcs num_tcs,
                 uint8_t pfc_en)
 {
        uint8_t i;
+       int32_t rc;
+       struct rte_eth_rss_conf rss_conf;
 
        /*
         * Builds up the correct configuration for dcb+vt based on the vlan tags array
 
        /*
         * Builds up the correct configuration for dcb+vt based on the vlan tags array
@@ -2342,6 +2344,10 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
                struct rte_eth_dcb_tx_conf *tx_conf =
                                &eth_conf->tx_adv_conf.dcb_tx_conf;
 
                struct rte_eth_dcb_tx_conf *tx_conf =
                                &eth_conf->tx_adv_conf.dcb_tx_conf;
 
+               rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
+               if (rc != 0)
+                       return rc;
+
                rx_conf->nb_tcs = num_tcs;
                tx_conf->nb_tcs = num_tcs;
 
                rx_conf->nb_tcs = num_tcs;
                tx_conf->nb_tcs = num_tcs;
 
@@ -2349,8 +2355,9 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
                        rx_conf->dcb_tc[i] = i % num_tcs;
                        tx_conf->dcb_tc[i] = i % num_tcs;
                }
                        rx_conf->dcb_tc[i] = i % num_tcs;
                        tx_conf->dcb_tc[i] = i % num_tcs;
                }
+
                eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
                eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
-               eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
+               eth_conf->rx_adv_conf.rss_conf = rss_conf;
                eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
        }
 
                eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
        }
 
@@ -2381,7 +2388,7 @@ init_port_dcb_config(portid_t pid,
        dcb_config = 1;
 
        /*set configuration of DCB in vt mode and DCB in non-vt mode*/
        dcb_config = 1;
 
        /*set configuration of DCB in vt mode and DCB in non-vt mode*/
-       retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
+       retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
        if (retval < 0)
                return retval;
        port_conf.rxmode.hw_vlan_filter = 1;
        if (retval < 0)
                return retval;
        port_conf.rxmode.hw_vlan_filter = 1;
index bf07b6f..ff7a5fa 100644 (file)
@@ -41,7 +41,7 @@ HOSTAPP = dpdk-pmdinfogen
 #
 SRCS-y += pmdinfogen.c
 
 #
 SRCS-y += pmdinfogen.c
 
-HOST_CFLAGS += $(WERROR_FLAGS) -g
+HOST_CFLAGS += $(HOST_WERROR_FLAGS) -g
 HOST_CFLAGS += -I$(RTE_OUTPUT)/include
 
 include $(RTE_SDK)/mk/rte.hostapp.mk
 HOST_CFLAGS += -I$(RTE_OUTPUT)/include
 
 include $(RTE_SDK)/mk/rte.hostapp.mk
index cb5ae12..a11627a 100644 (file)
@@ -252,6 +252,35 @@ Generic Flow API is supported. The baseline support is:
 More features may be added in future firmware and new versions of the VIC.
 Please refer to the release notes.
 
 More features may be added in future firmware and new versions of the VIC.
 Please refer to the release notes.
 
+Ingress VLAN Rewrite
+--------------------
+
+VIC adapters can tag, untag, or modify the VLAN headers of ingress
+packets. The ingress VLAN rewrite mode controls this behavior. By
+default, it is set to pass-through, where the NIC does not modify the
+VLAN header in any way so that the application can see the original
+header. This mode is sufficient for many applications, but may not be
+suitable for others. Such applications may change the mode by setting
+``devargs`` parameter ``ig-vlan-rewrite`` to one of the following.
+
+- ``pass``: Pass-through mode. The NIC does not modify the VLAN
+  header. This is the default mode.
+
+- ``priority``: Priority-tag default VLAN mode. If the ingress packet
+  is tagged with the default VLAN, the NIC replaces its VLAN header
+  with the priority tag (VLAN ID 0).
+
+- ``trunk``: Default trunk mode. The NIC tags untagged ingress packets
+  with the default VLAN. Tagged ingress packets are not modified. To
+  the application, every packet appears as tagged.
+
+- ``untag``: Untag default VLAN mode. If the ingress packet is tagged
+  with the default VLAN, the NIC removes or untags its VLAN header so
+  that the application sees an untagged packet. As a result, the
+  default VLAN becomes `untagged`. This mode can be useful for
+  applications such as OVS-DPDK performance benchmarks that utilize
+  only the default VLAN and want to see only untagged packets.
+
 .. _enic_limitations:
 
 Limitations
 .. _enic_limitations:
 
 Limitations
@@ -267,9 +296,10 @@ Limitations
   In test setups where an Ethernet port of a Cisco adapter in TRUNK mode is
   connected point-to-point to another adapter port or connected though a router
   instead of a switch, all ingress packets will be VLAN tagged. Programs such
   In test setups where an Ethernet port of a Cisco adapter in TRUNK mode is
   connected point-to-point to another adapter port or connected though a router
   instead of a switch, all ingress packets will be VLAN tagged. Programs such
-  as l3fwd which do not account for VLAN tags in packets will misbehave. The
-  solution is to enable VLAN stripping on ingress. The follow code fragment is
-  example of how to accomplish this:
+  as l3fwd may not account for VLAN tags in packets and may misbehave. One
+  solution is to enable VLAN stripping on ingress so the VLAN tag is removed
+  from the packet and put into the mbuf->vlan_tci field. Here is an example
+  of how to accomplish this:
 
 .. code-block:: console
 
 
 .. code-block:: console
 
@@ -277,6 +307,14 @@ Limitations
      vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
      rte_eth_dev_set_vlan_offload(port, vlan_offload);
 
      vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
      rte_eth_dev_set_vlan_offload(port, vlan_offload);
 
+Another alternative is modify the adapter's ingress VLAN rewrite mode so that
+packets with the default VLAN tag are stripped by the adapter and presented to
+DPDK as untagged packets. In this case mbuf->vlan_tci and the PKT_RX_VLAN and
+PKT_RX_VLAN_STRIPPED mbuf flags would not be set. This mode is enabled with the
+``devargs`` parameter ``ig-vlan-rewrite=untag``. For example::
+
+    -w 12:00.0,ig-vlan-rewrite=untag
+
 - Limited flow director support on 1200 series and 1300 series Cisco VIC
   adapters with old firmware. Please see :ref:`enic-flow-director`.
 
 - Limited flow director support on 1200 series and 1300 series Cisco VIC
   adapters with old firmware. Please see :ref:`enic-flow-director`.
 
index 84becc9..19802f4 100644 (file)
@@ -86,12 +86,13 @@ Prerequisites
   `QLogic Driver Download Center <http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/DefaultNewSearch.aspx>`_.
   For downloading firmware file, select adapter category, model and DPDK Poll Mode Driver.
 
   `QLogic Driver Download Center <http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/DefaultNewSearch.aspx>`_.
   For downloading firmware file, select adapter category, model and DPDK Poll Mode Driver.
 
-- Requires management firmware (MFW) version **8.30.x.x** or higher to be
-  flashed on to the adapter. If the required management firmware is not
-  available then download from
-  `QLogic Driver Download Center <http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/DefaultNewSearch.aspx>`_.
-  For downloading firmware upgrade utility, select adapter category, model and Linux distro.
-  To flash the management firmware refer to the instructions in the QLogic Firmware Upgrade Utility Readme document.
+- Requires the NIC be updated minimally with **8.30.x.x** Management firmware(MFW) version supported for that NIC.
+  It is highly recommended that the NIC be updated with the latest available management firmware version to get latest feature  set.
+  Management Firmware and Firmware Upgrade Utility for Cavium FastLinQ(r) branded adapters can be downloaded from
+  `Driver Download Center <http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/DefaultNewSearch.aspx>`_.
+  For downloading Firmware Upgrade Utility, select NIC category, model and Linux distro.
+  To update the management firmware, refer to the instructions in the Firmware Upgrade Utility Readme document.
+  For OEM branded adapters please follow the instruction provided by the OEM to update the Management Firmware on the NIC.
 
 - SR-IOV requires Linux PF driver version **8.20.x.x** or higher.
   If the required PF driver is not available then download it from
 
 - SR-IOV requires Linux PF driver version **8.20.x.x** or higher.
   If the required PF driver is not available then download it from
index 39a14ff..e17fd2c 100644 (file)
@@ -1305,3 +1305,160 @@ Fixes in 17.11 LTS Release
 * vhost: fix offset while mmaping log base address
 * vhost: fix realloc failure
 * vhost: fix ring index returned to master on stop
 * vhost: fix offset while mmaping log base address
 * vhost: fix realloc failure
 * vhost: fix ring index returned to master on stop
+
+17.11.4
+~~~~~~~
+
+* app/crypto-perf: fix auth IV offset
+* app/testpmd: fix buffer leak in TM command
+* app/testpmd: fix DCB config
+* app/testpmd: fix VLAN TCI mask set error for FDIR
+* bitrate: add sanity check on parameters
+* bus/dpaa: fix buffer offset setting in FMAN
+* bus/dpaa: fix build
+* bus/dpaa: fix phandle support for Linux 4.16
+* bus/pci: use IOVAs check when setting IOVA mode
+* crypto/qat: fix checks for 3GPP algo bit params
+* doc: fix bonding command in testpmd
+* doc: update qede management firmware guide
+* eal: fix bitmap documentation
+* eal: fix return codes on thread naming failure
+* eal/linux: fix invalid syntax in interrupts
+* eal/linux: fix uninitialized value
+* ethdev: fix a doxygen comment for port allocation
+* ethdev: fix queue statistics mapping documentation
+* eventdev: add event buffer flush in Rx adapter
+* eventdev: fix internal port logic in Rx adapter
+* eventdev: fix missing update to Rx adaper WRR position
+* eventdev: fix port in Rx adapter internal function
+* eventdev: fix Rx SW adapter stop
+* event: fix ring init failure handling
+* event/octeontx: remove unnecessary port start and stop
+* examples/exception_path: fix out-of-bounds read
+* examples: fix strncpy error for GCC8
+* examples/flow_filtering: add flow director config for i40e
+* examples/ipsec-secgw: fix bypass rule processing
+* examples/ipsec-secgw: fix IPv4 checksum at Tx
+* examples/l2fwd-crypto: check return value on IV size check
+* examples/l2fwd-crypto: fix digest with AEAD algo
+* examples/l2fwd-crypto: skip device not supporting operation
+* examples/l3fwd: remove useless include
+* hash: fix a multi-writer race condition
+* hash: fix doxygen of return values
+* hash: fix key slot size accuracy
+* hash: fix multiwriter lock memory allocation
+* kni: fix build on RHEL 7.5
+* kni: fix build with gcc 8.1
+* kni: fix crash with null name
+* maintainers: claim maintainership for ARM v7 and v8
+* maintainers: update for Mellanox PMDs
+* mem: add function for checking memsegs IOVAs addresses
+* mem: fix max DMA maskbit size
+* mem: use address hint for mapping hugepages
+* metrics: add check for invalid key
+* metrics: disallow null as metric name
+* metrics: do not fail silently when uninitialised
+* mk: fix cross build
+* mk: fix permissions when using make install
+* mk: remove unnecessary test rules
+* mk: update targets for classified tests
+* net/bnx2x: fix FW command timeout during stop
+* net/bnx2x: fix poll link status
+* net/bnx2x: fix to set device link status
+* net/bnxt: add missing ids in xstats
+* net/bnxt: check access denied for HWRM commands
+* net/bnxt: check for invalid vNIC id
+* net/bnxt: fix filter freeing
+* net/bnxt: fix HW Tx checksum offload check
+* net/bnxt: fix lock release on NVM write failure
+* net/bnxt: fix memory leaks in NVM commands
+* net/bnxt: fix RETA size
+* net/bnxt: fix Rx ring count limitation
+* net/bnxt: fix set MTU
+* net/bnxt: fix to move a flow to a different queue
+* net/bnxt: use correct flags during VLAN configuration
+* net/bonding: always update bonding link status
+* net/bonding: do not clear active slave count
+* net/bonding: fix MAC address reset
+* net/bonding: fix race condition
+* net/cxgbe: fix init failure due to new flash parts
+* net/cxgbe: fix Rx channel map and queue type
+* net/dpaa2: remove loop for unused pool entries
+* net/ena: change memory type
+* net/ena: check pointer before memset
+* net/ena: fix GENMASK_ULL macro
+* net/ena: fix SIGFPE with 0 Rx queue
+* net/ena: set link speed as none
+* net/enic: add devarg to specify ingress VLAN rewrite mode
+* net/enic: do not overwrite admin Tx queue limit
+* net/i40e: fix check of flow director programming status
+* net/i40e: fix link speed
+* net/i40e: fix packet type parsing with DDP
+* net/i40e: fix setting TPID with AQ command
+* net/i40e: fix shifts of 32-bit value
+* net/i40e: revert fix of flow director check
+* net/i40e: workaround performance degradation
+* net/ixgbe: add support for VLAN in IP mode FDIR
+* net/ixgbe: fix mask bits register set error for FDIR
+* net/ixgbe: fix tunnel id format error for FDIR
+* net/ixgbe: fix tunnel type set error for FDIR
+* net/mlx4: check RSS queues number limitation
+* net/mlx4: fix minor resource leak during init
+* net/mlx5: add missing sanity checks for Tx completion queue
+* net/mlx5: fix assert for Tx completion queue count
+* net/mlx5: fix build with old kernels
+* net/mlx5: fix compilation for rdma-core v19
+* net/mlx5: fix crash in device probe
+* net/mlx5: fix error number handling
+* net/mlx5: fix flow search on FDIR deletion
+* net/mlx5: fix queue rollback when starting device
+* net/mlx5: fix return value when deleting fdir filter
+* net/mlx5: fix Rx buffer replenishment threshold
+* net/mlx5: fix secondary process resource leakage
+* net/mlx5: fix TCI mask filter
+* net/mlx5: preserve allmulticast flag for flow isolation mode
+* net/mlx5: preserve promiscuous flag for flow isolation mode
+* net/mvpp2: check pointer before using it
+* net/nfp: check hugepages IOVAs based on DMA mask
+* net/nfp: fix field initialization in Tx descriptor
+* net/nfp: support IOVA VA mode
+* net/octeontx: fix stop clearing Rx/Tx functions
+* net/pcap: fix multiple queues
+* net/qede/base: fix GRC attention callback
+* net/qede/base: fix to clear HW indication
+* net/qede: fix default extended VLAN offload config
+* net/qede: fix for devargs
+* net/qede: fix incorrect link status update
+* net/qede: fix interrupt handler unregister
+* net/qede: fix legacy interrupt mode
+* net/qede: fix link change event notification
+* net/qede: fix MAC address removal failure message
+* net/qede: fix ntuple filter configuration
+* net/qede: fix unicast MAC address handling in VF
+* net/qede: fix VF MTU update
+* net/qede: remove primary MAC removal
+* net/sfc: cut non VLAN ID bits from TCI
+* net/sfc: fix assert in set multicast address list
+* net/sfc: handle unknown L3 packet class in EF10 event parser
+* net/tap: fix zeroed flow mask configurations
+* net/thunderx: avoid sq door bell write on zero packet
+* net/thunderx: fix build with gcc optimization on
+* ring: fix sign conversion warning
+* security: fix crash on destroy null session
+* test/crypto: fix device id when stopping port
+* test: fix code on report
+* test: fix EAL flags autotest on FreeBSD
+* test: fix result printing
+* test: fix uninitialized port configuration
+* test/flow_classify: fix return types
+* test/hash: fix multiwriter with non consecutive cores
+* test/hash: fix potential memory leak
+* test: improve filtering
+* test: make autotest runner python 2/3 compliant
+* test: print autotest categories
+* vfio: fix PCI address comparison
+* vhost: fix missing increment of log cache count
+* vhost: flush IOTLB cache on new mem table handling
+* vhost: improve dirty pages logging performance
+* vhost: release locks on RARP packet failure
+* vhost: retranslate vring addr when memory table changes
index 9789139..c9ce85c 100644 (file)
@@ -1865,7 +1865,7 @@ Create a new bonding device::
 
 For example, to create a bonded device in mode 1 on socket 0::
 
 
 For example, to create a bonded device in mode 1 on socket 0::
 
-   testpmd> create bonded 1 0
+   testpmd> create bonded device 1 0
    created new bonded device (port X)
 
 add bonding slave
    created new bonded device (port X)
 
 add bonding slave
index 077c17c..d66efa1 100644 (file)
@@ -39,6 +39,8 @@
 #include <fsl_fman_crc64.h>
 #include <fsl_bman.h>
 
 #include <fsl_fman_crc64.h>
 #include <fsl_bman.h>
 
+#define FMAN_SP_EXT_BUF_MARG_START_SHIFT            16
+
 /* Instantiate the global variable that the inline CRC64 implementation (in
  * <fsl_fman.h>) depends on.
  */
 /* Instantiate the global variable that the inline CRC64 implementation (in
  * <fsl_fman.h>) depends on.
  */
@@ -445,20 +447,16 @@ fman_if_set_fc_quanta(struct fman_if *fm_if, u16 pause_quanta)
 int
 fman_if_get_fdoff(struct fman_if *fm_if)
 {
 int
 fman_if_get_fdoff(struct fman_if *fm_if)
 {
-       u32 fmbm_ricp;
+       u32 fmbm_rebm;
        int fdoff;
        int fdoff;
-       int iceof_mask = 0x001f0000;
-       int icsz_mask = 0x0000001f;
 
        struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if);
 
        assert(fman_ccsr_map_fd != -1);
 
 
        struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if);
 
        assert(fman_ccsr_map_fd != -1);
 
-       fmbm_ricp =
-                  in_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_ricp);
-       /*iceof + icsz*/
-       fdoff = ((fmbm_ricp & iceof_mask) >> 16) * 16 +
-               (fmbm_ricp & icsz_mask) * 16;
+       fmbm_rebm = in_be32(&((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm);
+
+       fdoff = (fmbm_rebm >> FMAN_SP_EXT_BUF_MARG_START_SHIFT) & 0x1ff;
 
        return fdoff;
 }
 
        return fdoff;
 }
@@ -525,12 +523,16 @@ fman_if_set_fdoff(struct fman_if *fm_if, uint32_t fd_offset)
 {
        struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if);
        unsigned int *fmbm_rebm;
 {
        struct __fman_if *__if = container_of(fm_if, struct __fman_if, __if);
        unsigned int *fmbm_rebm;
+       int val = 0;
+       int fmbm_mask = 0x01ff0000;
+
+       val = fd_offset << FMAN_SP_EXT_BUF_MARG_START_SHIFT;
 
        assert(fman_ccsr_map_fd != -1);
 
        fmbm_rebm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm;
 
 
        assert(fman_ccsr_map_fd != -1);
 
        fmbm_rebm = &((struct rx_bmi_regs *)__if->bmi_map)->fmbm_rebm;
 
-       out_be32(fmbm_rebm, in_be32(fmbm_rebm) | (fd_offset << 16));
+       out_be32(fmbm_rebm, (in_be32(fmbm_rebm) & ~fmbm_mask) | val);
 }
 
 void
 }
 
 void
index b2d7c02..cada412 100644 (file)
@@ -215,6 +215,11 @@ linear_dir(struct dt_dir *d)
                                DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s",
                                             d->node.node.full_name);
                        d->lphandle = f;
                                DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s",
                                             d->node.node.full_name);
                        d->lphandle = f;
+               } else if (!strcmp(f->node.node.name, "phandle")) {
+                       if (d->lphandle)
+                               DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s",
+                                            d->node.node.full_name);
+                       d->lphandle = f;
                } else if (!strcmp(f->node.node.name, "#address-cells")) {
                        if (d->a_cells)
                                DPAA_BUS_LOG(DEBUG, "Duplicate a_cells in %s",
                } else if (!strcmp(f->node.node.name, "#address-cells")) {
                        if (d->a_cells)
                                DPAA_BUS_LOG(DEBUG, "Duplicate a_cells in %s",
index 42733ae..1f56a4b 100644 (file)
  */
 
 /* Required compiler attributes */
  */
 
 /* Required compiler attributes */
+#ifndef __maybe_unused
 #define __maybe_unused __rte_unused
 #define __maybe_unused __rte_unused
+#endif
+#ifndef __always_unused
 #define __always_unused        __rte_unused
 #define __always_unused        __rte_unused
+#endif
+#ifndef __packed
 #define __packed       __rte_packed
 #define __packed       __rte_packed
+#endif
 #define noinline       __attribute__((noinline))
 
 #define L1_CACHE_BYTES 64
 #define noinline       __attribute__((noinline))
 
 #define L1_CACHE_BYTES 64
index 74deef3..44440f2 100644 (file)
@@ -43,6 +43,7 @@
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
 #include <rte_vfio.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
 #include <rte_vfio.h>
+#include <rte_memory.h>
 
 #include "eal_private.h"
 #include "eal_filesystem.h"
 
 #include "eal_private.h"
 #include "eal_filesystem.h"
@@ -582,7 +583,6 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev)
 {
 #define VTD_CAP_MGAW_SHIFT     16
 #define VTD_CAP_MGAW_MASK      (0x3fULL << VTD_CAP_MGAW_SHIFT)
 {
 #define VTD_CAP_MGAW_SHIFT     16
 #define VTD_CAP_MGAW_MASK      (0x3fULL << VTD_CAP_MGAW_SHIFT)
-#define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */
        struct rte_pci_addr *addr = &dev->addr;
        char filename[PATH_MAX];
        FILE *fp;
        struct rte_pci_addr *addr = &dev->addr;
        char filename[PATH_MAX];
        FILE *fp;
@@ -613,10 +613,12 @@ pci_one_device_iommu_support_va(struct rte_pci_device *dev)
        fclose(fp);
 
        mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1;
        fclose(fp);
 
        mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1;
-       if (mgaw < X86_VA_WIDTH)
+
+       if (!rte_eal_check_dma_mask(mgaw))
+               return true;
+       else
                return false;
 
                return false;
 
-       return true;
 }
 #elif defined(RTE_ARCH_PPC_64)
 static bool
 }
 #elif defined(RTE_ARCH_PPC_64)
 static bool
@@ -640,13 +642,17 @@ pci_devices_iommu_support_va(void)
 {
        struct rte_pci_device *dev = NULL;
        struct rte_pci_driver *drv = NULL;
 {
        struct rte_pci_device *dev = NULL;
        struct rte_pci_driver *drv = NULL;
+       int iommu_dma_mask_check_done = 0;
 
        FOREACH_DRIVER_ON_PCIBUS(drv) {
                FOREACH_DEVICE_ON_PCIBUS(dev) {
                        if (!rte_pci_match(drv, dev))
                                continue;
 
        FOREACH_DRIVER_ON_PCIBUS(drv) {
                FOREACH_DEVICE_ON_PCIBUS(dev) {
                        if (!rte_pci_match(drv, dev))
                                continue;
-                       if (!pci_one_device_iommu_support_va(dev))
-                               return false;
+                       if (!iommu_dma_mask_check_done) {
+                               if (!pci_one_device_iommu_support_va(dev))
+                                       return false;
+                               iommu_dma_mask_check_done  = 1;
+                       }
                }
        }
        return true;
                }
        }
        return true;
index e7d7f5d..745db26 100644 (file)
@@ -671,7 +671,7 @@ pci_vfio_unmap_resource(struct rte_pci_device *dev)
        vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
        /* Get vfio_res */
        TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
        vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
        /* Get vfio_res */
        TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-               if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+               if (rte_pci_addr_cmp(&vfio_res->pci_addr, &dev->addr))
                        continue;
                break;
        }
                        continue;
                break;
        }
index acd979d..85a9ba0 100644 (file)
@@ -1292,9 +1292,8 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
                                ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) {
 
                        if (unlikely(
                                ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) {
 
                        if (unlikely(
-                               (cipher_param->cipher_length % BYTE_LENGTH != 0)
-                                || (cipher_param->cipher_offset
-                                                       % BYTE_LENGTH != 0))) {
+                           (op->sym->cipher.data.length % BYTE_LENGTH != 0) ||
+                           (op->sym->cipher.data.offset % BYTE_LENGTH != 0))) {
                                PMD_DRV_LOG(ERR,
                  "SNOW3G/KASUMI/ZUC in QAT PMD only supports byte aligned values");
                                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
                                PMD_DRV_LOG(ERR,
                  "SNOW3G/KASUMI/ZUC in QAT PMD only supports byte aligned values");
                                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
@@ -1327,8 +1326,9 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
                        ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 ||
                        ctx->qat_hash_alg ==
                                ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3) {
                        ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 ||
                        ctx->qat_hash_alg ==
                                ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3) {
-                       if (unlikely((auth_param->auth_off % BYTE_LENGTH != 0)
-                               || (auth_param->auth_len % BYTE_LENGTH != 0))) {
+                       if (unlikely(
+                           (op->sym->auth.data.offset % BYTE_LENGTH != 0) ||
+                           (op->sym->auth.data.length % BYTE_LENGTH != 0))) {
                                PMD_DRV_LOG(ERR,
                "For SNOW3G/KASUMI/ZUC, QAT PMD only supports byte aligned values");
                                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
                                PMD_DRV_LOG(ERR,
                "For SNOW3G/KASUMI/ZUC, QAT PMD only supports byte aligned values");
                                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
index 117b145..9a46894 100644 (file)
@@ -485,14 +485,9 @@ static int
 ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev,
                                        const struct rte_eth_dev *eth_dev)
 {
 ssovf_eth_rx_adapter_start(const struct rte_eventdev *dev,
                                        const struct rte_eth_dev *eth_dev)
 {
-       int ret;
-       const struct octeontx_nic *nic = eth_dev->data->dev_private;
        RTE_SET_USED(dev);
        RTE_SET_USED(dev);
+       RTE_SET_USED(eth_dev);
 
 
-       ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
-       if (ret)
-               return 0;
-       octeontx_pki_port_start(nic->port_id);
        return 0;
 }
 
        return 0;
 }
 
@@ -501,14 +496,9 @@ static int
 ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev,
                const struct rte_eth_dev *eth_dev)
 {
 ssovf_eth_rx_adapter_stop(const struct rte_eventdev *dev,
                const struct rte_eth_dev *eth_dev)
 {
-       int ret;
-       const struct octeontx_nic *nic = eth_dev->data->dev_private;
        RTE_SET_USED(dev);
        RTE_SET_USED(dev);
+       RTE_SET_USED(eth_dev);
 
 
-       ret = strncmp(eth_dev->data->name, "eth_octeontx", 12);
-       if (ret)
-               return 0;
-       octeontx_pki_port_stop(nic->port_id);
        return 0;
 }
 
        return 0;
 }
 
index 98b08d1..e58684d 100644 (file)
@@ -125,7 +125,6 @@ int bnx2x_nic_load(struct bnx2x_softc *sc);
 
 static int bnx2x_handle_sp_tq(struct bnx2x_softc *sc);
 static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp);
 
 static int bnx2x_handle_sp_tq(struct bnx2x_softc *sc);
 static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp);
-static void bnx2x_periodic_stop(struct bnx2x_softc *sc);
 static void bnx2x_ack_sb(struct bnx2x_softc *sc, uint8_t igu_sb_id,
                         uint8_t storm, uint16_t index, uint8_t op,
                         uint8_t update);
 static void bnx2x_ack_sb(struct bnx2x_softc *sc, uint8_t igu_sb_id,
                         uint8_t storm, uint16_t index, uint8_t op,
                         uint8_t update);
@@ -1971,9 +1970,6 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link
 
        PMD_DRV_LOG(DEBUG, "Starting NIC unload...");
 
 
        PMD_DRV_LOG(DEBUG, "Starting NIC unload...");
 
-       /* stop the periodic callout */
-       bnx2x_periodic_stop(sc);
-
        /* mark driver as unloaded in shmem2 */
        if (IS_PF(sc) && SHMEM2_HAS(sc, drv_capabilities_flag)) {
                val = SHMEM2_RD(sc, drv_capabilities_flag[SC_FW_MB_IDX(sc)]);
        /* mark driver as unloaded in shmem2 */
        if (IS_PF(sc) && SHMEM2_HAS(sc, drv_capabilities_flag)) {
                val = SHMEM2_RD(sc, drv_capabilities_flag[SC_FW_MB_IDX(sc)]);
@@ -4492,6 +4488,8 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp)
        struct bnx2x_softc *sc = fp->sc;
        uint8_t more_rx = FALSE;
 
        struct bnx2x_softc *sc = fp->sc;
        uint8_t more_rx = FALSE;
 
+       PMD_DRV_LOG(DEBUG, "---> FP TASK QUEUE (%d) <--", fp->index);
+
        /* update the fastpath index */
        bnx2x_update_fp_sb_idx(fp);
 
        /* update the fastpath index */
        bnx2x_update_fp_sb_idx(fp);
 
@@ -4508,7 +4506,7 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp)
        }
 
        bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID,
        }
 
        bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID,
-                  le16toh(fp->fp_hc_idx), IGU_INT_DISABLE, 1);
+                  le16toh(fp->fp_hc_idx), IGU_INT_ENABLE, 1);
 }
 
 /*
 }
 
 /*
@@ -6999,16 +6997,6 @@ void bnx2x_link_status_update(struct bnx2x_softc *sc)
        }
 }
 
        }
 }
 
-static void bnx2x_periodic_start(struct bnx2x_softc *sc)
-{
-       atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO);
-}
-
-static void bnx2x_periodic_stop(struct bnx2x_softc *sc)
-{
-       atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP);
-}
-
 static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
 {
        int rc, cfg_idx = bnx2x_get_link_cfg_idx(sc);
 static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
 {
        int rc, cfg_idx = bnx2x_get_link_cfg_idx(sc);
@@ -7043,10 +7031,6 @@ static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
                bnx2x_link_report(sc);
        }
 
                bnx2x_link_report(sc);
        }
 
-       if (!CHIP_REV_IS_SLOW(sc)) {
-               bnx2x_periodic_start(sc);
-       }
-
        sc->link_params.req_line_speed[cfg_idx] = req_line_speed;
        return rc;
 }
        sc->link_params.req_line_speed[cfg_idx] = req_line_speed;
        return rc;
 }
@@ -7078,7 +7062,7 @@ void bnx2x_periodic_callout(struct bnx2x_softc *sc)
 {
        if ((sc->state != BNX2X_STATE_OPEN) ||
            (atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_STOP)) {
 {
        if ((sc->state != BNX2X_STATE_OPEN) ||
            (atomic_load_acq_long(&sc->periodic_flags) == PERIODIC_STOP)) {
-               PMD_DRV_LOG(WARNING, "periodic callout exit (state=0x%x)",
+               PMD_DRV_LOG(INFO, "periodic callout exit (state=0x%x)",
                            sc->state);
                return;
        }
                            sc->state);
                return;
        }
index 17075d3..c93f148 100644 (file)
@@ -1930,6 +1930,7 @@ void bnx2x_link_status_update(struct bnx2x_softc *sc);
 int bnx2x_complete_sp(struct bnx2x_softc *sc);
 int bnx2x_set_storm_rx_mode(struct bnx2x_softc *sc);
 void bnx2x_periodic_callout(struct bnx2x_softc *sc);
 int bnx2x_complete_sp(struct bnx2x_softc *sc);
 int bnx2x_set_storm_rx_mode(struct bnx2x_softc *sc);
 void bnx2x_periodic_callout(struct bnx2x_softc *sc);
+void bnx2x_periodic_stop(void *param);
 
 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count);
 void bnx2x_vf_close(struct bnx2x_softc *sc);
 
 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count);
 void bnx2x_vf_close(struct bnx2x_softc *sc);
index 95861a0..650d6ce 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <rte_dev.h>
 #include <rte_ethdev_pci.h>
 
 #include <rte_dev.h>
 #include <rte_ethdev_pci.h>
+#include <rte_alarm.h>
+#include <rte_atomic.h>
 
 /*
  * The set of PCI devices this driver supports
 
 /*
  * The set of PCI devices this driver supports
@@ -78,26 +80,87 @@ static const struct rte_bnx2x_xstats_name_off bnx2x_xstats_strings[] = {
                offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
 };
 
                offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
 };
 
-static void
+/**
+ * Atomically reads the link status information from global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+                                 struct rte_eth_link *link)
+{
+       struct rte_eth_link *dst = link;
+       struct rte_eth_link *src = &dev->data->dev_link;
+
+       if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+                                       *(uint64_t *)src) == 0)
+               return -1;
+
+       return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ *   - Pointer to the structure rte_eth_dev to read from.
+ *   - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ *   - On success, zero.
+ *   - On failure, negative value.
+ */
+static inline int
+bnx2x_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+                                  struct rte_eth_link *link)
+{
+       struct rte_eth_link *dst = &dev->data->dev_link;
+       struct rte_eth_link *src = link;
+
+       if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+                                       *(uint64_t *)src) == 0)
+               return -1;
+
+       return 0;
+}
+
+static int
 bnx2x_link_update(struct rte_eth_dev *dev)
 {
        struct bnx2x_softc *sc = dev->data->dev_private;
 bnx2x_link_update(struct rte_eth_dev *dev)
 {
        struct bnx2x_softc *sc = dev->data->dev_private;
+       struct rte_eth_link orig;
+       struct rte_eth_link link;
 
        PMD_INIT_FUNC_TRACE();
 
        PMD_INIT_FUNC_TRACE();
+
        bnx2x_link_status_update(sc);
        bnx2x_link_status_update(sc);
+       memset(&orig, 0, sizeof(orig));
+       memset(&link, 0, sizeof(link));
+       bnx2x_dev_atomic_read_link_status(dev, &orig);
        mb();
        mb();
-       dev->data->dev_link.link_speed = sc->link_vars.line_speed;
+       link.link_speed = sc->link_vars.line_speed;
        switch (sc->link_vars.duplex) {
                case DUPLEX_FULL:
        switch (sc->link_vars.duplex) {
                case DUPLEX_FULL:
-                       dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+                       link.link_duplex = ETH_LINK_FULL_DUPLEX;
                        break;
                case DUPLEX_HALF:
                        break;
                case DUPLEX_HALF:
-                       dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
+                       link.link_duplex = ETH_LINK_HALF_DUPLEX;
                        break;
        }
                        break;
        }
-       dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+       link.link_autoneg = !(dev->data->dev_conf.link_speeds &
                        ETH_LINK_SPEED_FIXED);
                        ETH_LINK_SPEED_FIXED);
-       dev->data->dev_link.link_status = sc->link_vars.link_up;
+       link.link_status = sc->link_vars.link_up;
+       bnx2x_dev_atomic_write_link_status(dev, &link);
+
+       return (link.link_status == orig.link_status) ? -1 : 0;
 }
 
 static void
 }
 
 static void
@@ -106,8 +169,6 @@ bnx2x_interrupt_action(struct rte_eth_dev *dev)
        struct bnx2x_softc *sc = dev->data->dev_private;
        uint32_t link_status;
 
        struct bnx2x_softc *sc = dev->data->dev_private;
        uint32_t link_status;
 
-       PMD_DEBUG_PERIODIC_LOG(INFO, "Interrupt handled");
-
        bnx2x_intr_legacy(sc, 0);
 
        if (sc->periodic_flags & PERIODIC_GO)
        bnx2x_intr_legacy(sc, 0);
 
        if (sc->periodic_flags & PERIODIC_GO)
@@ -125,14 +186,73 @@ bnx2x_interrupt_handler(void *param)
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
        struct bnx2x_softc *sc = dev->data->dev_private;
 
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
        struct bnx2x_softc *sc = dev->data->dev_private;
 
+       PMD_DEBUG_PERIODIC_LOG(INFO, "Interrupt handled");
+
        bnx2x_interrupt_action(dev);
        rte_intr_enable(&sc->pci_dev->intr_handle);
 }
 
        bnx2x_interrupt_action(dev);
        rte_intr_enable(&sc->pci_dev->intr_handle);
 }
 
+static void bnx2x_periodic_start(void *param)
+{
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+       struct bnx2x_softc *sc = dev->data->dev_private;
+       int ret = 0;
+
+       atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO);
+       bnx2x_interrupt_action(dev);
+       if (IS_PF(sc)) {
+               ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
+                                       bnx2x_periodic_start, (void *)dev);
+               if (ret) {
+                       PMD_DRV_LOG(ERR, "Unable to start periodic"
+                                        " timer rc %d", ret);
+                       assert(false && "Unable to start periodic timer");
+               }
+       }
+}
+
+void bnx2x_periodic_stop(void *param)
+{
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+       struct bnx2x_softc *sc = dev->data->dev_private;
+
+       atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP);
+
+       rte_eal_alarm_cancel(bnx2x_periodic_start, (void *)dev);
+}
+
 /*
  * Devops - helper functions can be called from user application
  */
 
 /*
  * Devops - helper functions can be called from user application
  */
 
+static int
+bnx2x_dev_link_update(struct rte_eth_dev *dev,
+                     __rte_unused int wait_to_complete)
+{
+       PMD_INIT_FUNC_TRACE();
+
+       return bnx2x_link_update(dev);
+}
+
+static int
+bnx2xvf_dev_link_update(struct rte_eth_dev *dev,
+                       __rte_unused int wait_to_complete)
+{
+       struct bnx2x_softc *sc = dev->data->dev_private;
+       int ret = 0;
+
+       ret = bnx2x_link_update(dev);
+
+       bnx2x_check_bull(sc);
+       if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
+               PMD_DRV_LOG(ERR, "PF indicated channel is down."
+                               "VF device is no longer operational");
+               dev->data->dev_link.link_status = ETH_LINK_DOWN;
+       }
+
+       return ret;
+}
+
 static int
 bnx2x_dev_configure(struct rte_eth_dev *dev)
 {
 static int
 bnx2x_dev_configure(struct rte_eth_dev *dev)
 {
@@ -182,6 +302,10 @@ bnx2x_dev_start(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
 
        PMD_INIT_FUNC_TRACE();
 
+       /* start the periodic callout */
+       if (sc->periodic_flags & PERIODIC_STOP)
+               bnx2x_periodic_start(dev);
+
        ret = bnx2x_init(sc);
        if (ret) {
                PMD_DRV_LOG(DEBUG, "bnx2x_init failed (%d)", ret);
        ret = bnx2x_init(sc);
        if (ret) {
                PMD_DRV_LOG(DEBUG, "bnx2x_init failed (%d)", ret);
@@ -222,12 +346,21 @@ bnx2x_dev_stop(struct rte_eth_dev *dev)
                                bnx2x_interrupt_handler, (void *)dev);
        }
 
                                bnx2x_interrupt_handler, (void *)dev);
        }
 
+       /* stop the periodic callout */
+       bnx2x_periodic_stop(dev);
+
        ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
        if (ret) {
                PMD_DRV_LOG(DEBUG, "bnx2x_nic_unload failed (%d)", ret);
                return;
        }
 
        ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
        if (ret) {
                PMD_DRV_LOG(DEBUG, "bnx2x_nic_unload failed (%d)", ret);
                return;
        }
 
+       /* Update device link status */
+       if (IS_PF(sc))
+               bnx2x_dev_link_update(dev, 0);
+       else
+               bnx2xvf_dev_link_update(dev, 0);
+
        return;
 }
 
        return;
 }
 
@@ -299,36 +432,6 @@ bnx2x_dev_allmulticast_disable(struct rte_eth_dev *dev)
        bnx2x_set_rx_mode(sc);
 }
 
        bnx2x_set_rx_mode(sc);
 }
 
-static int
-bnx2x_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
-       PMD_INIT_FUNC_TRACE();
-
-       int old_link_status = dev->data->dev_link.link_status;
-
-       bnx2x_link_update(dev);
-
-       return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
-}
-
-static int
-bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
-{
-       int old_link_status = dev->data->dev_link.link_status;
-       struct bnx2x_softc *sc = dev->data->dev_private;
-
-       bnx2x_link_update(dev);
-
-       bnx2x_check_bull(sc);
-       if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
-               PMD_DRV_LOG(ERR, "PF indicated channel is down."
-                               "VF device is no longer operational");
-               dev->data->dev_link.link_status = ETH_LINK_DOWN;
-       }
-
-       return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
-}
-
 static int
 bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 static int
 bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -580,6 +683,17 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
                return ret;
        }
 
                return ret;
        }
 
+       /* schedule periodic poll for slowpath link events */
+       if (IS_PF(sc)) {
+               ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
+                                       bnx2x_periodic_start, (void *)eth_dev);
+               if (ret) {
+                       PMD_DRV_LOG(ERR, "Unable to start periodic"
+                                         " timer rc %d", ret);
+                       return -EINVAL;
+               }
+       }
+
        eth_dev->data->mac_addrs = (struct ether_addr *)sc->link_params.mac_addr;
 
        PMD_DRV_LOG(INFO, "pcie_bus=%d, pcie_device=%d",
        eth_dev->data->mac_addrs = (struct ether_addr *)sc->link_params.mac_addr;
 
        PMD_DRV_LOG(INFO, "pcie_bus=%d, pcie_device=%d",
@@ -594,18 +708,20 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
        if (IS_VF(sc)) {
                rte_spinlock_init(&sc->vf2pf_lock);
 
        if (IS_VF(sc)) {
                rte_spinlock_init(&sc->vf2pf_lock);
 
-               if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
-                                   &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
-                                   RTE_CACHE_LINE_SIZE) != 0)
-                       return -ENOMEM;
+               ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
+                                     &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
+                                     RTE_CACHE_LINE_SIZE);
+               if (ret)
+                       goto out;
 
                sc->vf2pf_mbox = (struct bnx2x_vf_mbx_msg *)
                                         sc->vf2pf_mbox_mapping.vaddr;
 
 
                sc->vf2pf_mbox = (struct bnx2x_vf_mbx_msg *)
                                         sc->vf2pf_mbox_mapping.vaddr;
 
-               if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
-                                   &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
-                                   RTE_CACHE_LINE_SIZE) != 0)
-                       return -ENOMEM;
+               ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
+                                     &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
+                                     RTE_CACHE_LINE_SIZE);
+               if (ret)
+                       goto out;
 
                sc->pf2vf_bulletin = (struct bnx2x_vf_bulletin *)
                                             sc->pf2vf_bulletin_mapping.vaddr;
 
                sc->pf2vf_bulletin = (struct bnx2x_vf_bulletin *)
                                             sc->pf2vf_bulletin_mapping.vaddr;
@@ -613,10 +729,14 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
                ret = bnx2x_vf_get_resources(sc, sc->max_tx_queues,
                                             sc->max_rx_queues);
                if (ret)
                ret = bnx2x_vf_get_resources(sc, sc->max_tx_queues,
                                             sc->max_rx_queues);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
        return 0;
        }
 
        return 0;
+
+out:
+       bnx2x_periodic_stop(eth_dev);
+       return ret;
 }
 
 static int
 }
 
 static int
index 967d6dc..a53d437 100644 (file)
@@ -58,7 +58,6 @@
 #define wmb()   rte_wmb()
 #define rmb()   rte_rmb()
 
 #define wmb()   rte_wmb()
 #define rmb()   rte_rmb()
 
-
 #define MAX_QUEUES sysconf(_SC_NPROCESSORS_CONF)
 
 #define BNX2X_MIN_RX_BUF_SIZE 1024
 #define MAX_QUEUES sysconf(_SC_NPROCESSORS_CONF)
 
 #define BNX2X_MIN_RX_BUF_SIZE 1024
@@ -72,6 +71,8 @@
 /* Maximum number of Rx packets to process at a time */
 #define BNX2X_RX_BUDGET 0xffffffff
 
 /* Maximum number of Rx packets to process at a time */
 #define BNX2X_RX_BUDGET 0xffffffff
 
+#define BNX2X_SP_TIMER_PERIOD US_PER_S /* 1 second */
+
 #endif
 
 /* MAC address operations */
 #endif
 
 /* MAC address operations */
index 52c511e..7466a64 100644 (file)
@@ -248,6 +248,17 @@ static int bnxt_init_chip(struct bnxt *bp)
        /* VNIC configuration */
        for (i = 0; i < bp->nr_vnics; i++) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
        /* VNIC configuration */
        for (i = 0; i < bp->nr_vnics; i++) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+               uint32_t size = sizeof(*vnic->fw_grp_ids) * bp->max_ring_grps;
+
+               vnic->fw_grp_ids = rte_zmalloc("vnic_fw_grp_ids", size, 0);
+               if (!vnic->fw_grp_ids) {
+                       RTE_LOG(ERR, PMD,
+                               "Failed to alloc %d bytes for group ids\n",
+                               size);
+                       rc = -ENOMEM;
+                       goto err_out;
+               }
+               memset(vnic->fw_grp_ids, -1, size);
 
                rc = bnxt_hwrm_vnic_alloc(bp, vnic);
                if (rc) {
 
                rc = bnxt_hwrm_vnic_alloc(bp, vnic);
                if (rc) {
@@ -429,7 +440,7 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
        /* For the sake of symmetry, max_rx_queues = max_tx_queues */
        dev_info->max_rx_queues = max_rx_rings;
        dev_info->max_tx_queues = max_rx_rings;
        /* For the sake of symmetry, max_rx_queues = max_tx_queues */
        dev_info->max_rx_queues = max_rx_rings;
        dev_info->max_tx_queues = max_rx_rings;
-       dev_info->reta_size = bp->max_rsscos_ctx;
+       dev_info->reta_size = HW_HASH_INDEX_SIZE;
        dev_info->hash_key_size = 40;
        max_vnics = bp->max_vnics;
 
        dev_info->hash_key_size = 40;
        max_vnics = bp->max_vnics;
 
@@ -1268,9 +1279,9 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
        struct bnxt_vnic_info *vnic;
        unsigned int i;
        int rc = 0;
        struct bnxt_vnic_info *vnic;
        unsigned int i;
        int rc = 0;
-       uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
-               HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
-       uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+       uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
+               HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK;
+       uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN;
 
        /* Cycle through all VNICs */
        for (i = 0; i < bp->nr_vnics; i++) {
 
        /* Cycle through all VNICs */
        for (i = 0; i < bp->nr_vnics; i++) {
@@ -1317,8 +1328,8 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
                                memcpy(new_filter->l2_addr, filter->l2_addr,
                                       ETHER_ADDR_LEN);
                                /* MAC + VLAN ID filter */
                                memcpy(new_filter->l2_addr, filter->l2_addr,
                                       ETHER_ADDR_LEN);
                                /* MAC + VLAN ID filter */
-                               new_filter->l2_ovlan = vlan_id;
-                               new_filter->l2_ovlan_mask = 0xF000;
+                               new_filter->l2_ivlan = vlan_id;
+                               new_filter->l2_ivlan_mask = 0xF000;
                                new_filter->enables |= en;
                                rc = bnxt_hwrm_set_l2_filter(bp,
                                                             vnic->fw_vnic_id,
                                new_filter->enables |= en;
                                rc = bnxt_hwrm_set_l2_filter(bp,
                                                             vnic->fw_vnic_id,
@@ -1541,6 +1552,7 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 
        for (i = 0; i < bp->nr_vnics; i++) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
 
        for (i = 0; i < bp->nr_vnics; i++) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+               uint16_t size = 0;
 
                vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
                                        ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
 
                vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
                                        ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
@@ -1548,9 +1560,14 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
                if (rc)
                        break;
 
                if (rc)
                        break;
 
-               rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
-               if (rc)
-                       return rc;
+               size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+               size -= RTE_PKTMBUF_HEADROOM;
+
+               if (size < new_mtu) {
+                       rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+                       if (rc)
+                               return rc;
+               }
        }
 
        return rc;
        }
 
        return rc;
index 8d3ddf1..67daec4 100644 (file)
@@ -1053,9 +1053,13 @@ bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
                                    sizeof(nf->dst_ipaddr_mask))) {
                                if (mf->dst_id == nf->dst_id)
                                        return -EEXIST;
                                    sizeof(nf->dst_ipaddr_mask))) {
                                if (mf->dst_id == nf->dst_id)
                                        return -EEXIST;
-                               /* Same Flow, Different queue
+                               /*
+                                * Same Flow, Different queue
                                 * Clear the old ntuple filter
                                 * Clear the old ntuple filter
+                                * Reuse the matching L2 filter
+                                * ID for the new filter
                                 */
                                 */
+                               nf->fw_l2_filter_id = mf->fw_l2_filter_id;
                                if (nf->filter_type == HWRM_CFA_EM_FILTER)
                                        bnxt_hwrm_clear_em_filter(bp, mf);
                                if (nf->filter_type == HWRM_CFA_NTUPLE_FILTER)
                                if (nf->filter_type == HWRM_CFA_EM_FILTER)
                                        bnxt_hwrm_clear_em_filter(bp, mf);
                                if (nf->filter_type == HWRM_CFA_NTUPLE_FILTER)
index 22f092f..db3222f 100644 (file)
@@ -197,6 +197,10 @@ err_ret:
                RTE_LOG(ERR, PMD, "%s failed rc:%d\n", \
                        __func__, rc); \
                rte_spinlock_unlock(&bp->hwrm_lock); \
                RTE_LOG(ERR, PMD, "%s failed rc:%d\n", \
                        __func__, rc); \
                rte_spinlock_unlock(&bp->hwrm_lock); \
+               if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) \
+                       rc = -EACCES; \
+               else if (rc > 0) \
+                       rc = -EINVAL; \
                return rc; \
        } \
        if (resp->error_code) { \
                return rc; \
        } \
        if (resp->error_code) { \
@@ -218,6 +222,10 @@ err_ret:
                                "%s error %d\n", __func__, rc); \
                } \
                rte_spinlock_unlock(&bp->hwrm_lock); \
                                "%s error %d\n", __func__, rc); \
                } \
                rte_spinlock_unlock(&bp->hwrm_lock); \
+               if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) \
+                       rc = -EACCES; \
+               else if (rc > 0) \
+                       rc = -EINVAL; \
                return rc; \
        } \
 } while (0)
                return rc; \
        } \
 } while (0)
@@ -406,13 +414,13 @@ int bnxt_hwrm_set_l2_filter(struct bnxt *bp,
                req.l2_ovlan = filter->l2_ovlan;
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN)
                req.l2_ovlan = filter->l2_ovlan;
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN)
-               req.l2_ovlan = filter->l2_ivlan;
+               req.l2_ivlan = filter->l2_ivlan;
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
                req.l2_ovlan_mask = filter->l2_ovlan_mask;
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK)
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
                req.l2_ovlan_mask = filter->l2_ovlan_mask;
        if (enables &
            HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK)
-               req.l2_ovlan_mask = filter->l2_ivlan_mask;
+               req.l2_ivlan_mask = filter->l2_ivlan_mask;
        if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
                req.src_id = rte_cpu_to_le_32(filter->src_id);
        if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
        if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
                req.src_id = rte_cpu_to_le_32(filter->src_id);
        if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
@@ -1092,8 +1100,9 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
        /* map ring groups to this vnic */
        RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
                vnic->start_grp_id, vnic->end_grp_id);
        /* map ring groups to this vnic */
        RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
                vnic->start_grp_id, vnic->end_grp_id);
-       for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++)
+       for (i = vnic->start_grp_id, j = 0; i < vnic->end_grp_id; i++, j++)
                vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
                vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
+
        vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
        vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
        vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
        vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
        vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
        vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
@@ -1385,6 +1394,11 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
        struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
        uint16_t size;
 
        struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
        uint16_t size;
 
+       if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+               RTE_LOG(DEBUG, PMD, "VNIC ID %x\n", vnic->fw_vnic_id);
+               return rc;
+       }
+
        HWRM_PREP(req, VNIC_PLCMODES_CFG);
 
        req.flags = rte_cpu_to_le_32(
        HWRM_PREP(req, VNIC_PLCMODES_CFG);
 
        req.flags = rte_cpu_to_le_32(
@@ -1798,6 +1812,7 @@ int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
                        rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
                else
                        rc = bnxt_hwrm_clear_l2_filter(bp, filter);
                        rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
                else
                        rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+               STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next);
                //if (rc)
                        //break;
        }
                //if (rc)
                        //break;
        }
@@ -1885,6 +1900,8 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
                bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
 
                bnxt_hwrm_vnic_free(bp, vnic);
                bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
 
                bnxt_hwrm_vnic_free(bp, vnic);
+
+               rte_free(vnic->fw_grp_ids);
        }
        /* Ring resources */
        bnxt_free_all_hwrm_rings(bp);
        }
        /* Ring resources */
        bnxt_free_all_hwrm_rings(bp);
@@ -3097,13 +3114,12 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data)
        req.host_dest_addr = rte_cpu_to_le_64(dma_handle);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
        req.host_dest_addr = rte_cpu_to_le_64(dma_handle);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
-       HWRM_CHECK_RESULT();
-       HWRM_UNLOCK();
-
        if (rc == 0)
                memcpy(data, buf, len > buflen ? buflen : len);
 
        rte_free(buf);
        if (rc == 0)
                memcpy(data, buf, len > buflen ? buflen : len);
 
        rte_free(buf);
+       HWRM_CHECK_RESULT();
+       HWRM_UNLOCK();
 
        return rc;
 }
 
        return rc;
 }
@@ -3135,12 +3151,13 @@ int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index,
        req.offset = rte_cpu_to_le_32(offset);
        req.len = rte_cpu_to_le_32(length);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
        req.offset = rte_cpu_to_le_32(offset);
        req.len = rte_cpu_to_le_32(length);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
-       HWRM_CHECK_RESULT();
-       HWRM_UNLOCK();
        if (rc == 0)
                memcpy(data, buf, length);
 
        rte_free(buf);
        if (rc == 0)
                memcpy(data, buf, length);
 
        rte_free(buf);
+       HWRM_CHECK_RESULT();
+       HWRM_UNLOCK();
+
        return rc;
 }
 
        return rc;
 }
 
@@ -3171,14 +3188,6 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
        rte_iova_t dma_handle;
        uint8_t *buf;
 
        rte_iova_t dma_handle;
        uint8_t *buf;
 
-       HWRM_PREP(req, NVM_WRITE);
-
-       req.dir_type = rte_cpu_to_le_16(dir_type);
-       req.dir_ordinal = rte_cpu_to_le_16(dir_ordinal);
-       req.dir_ext = rte_cpu_to_le_16(dir_ext);
-       req.dir_attr = rte_cpu_to_le_16(dir_attr);
-       req.dir_data_length = rte_cpu_to_le_32(data_len);
-
        buf = rte_malloc("nvm_write", data_len, 0);
        rte_mem_lock_page(buf);
        if (!buf)
        buf = rte_malloc("nvm_write", data_len, 0);
        rte_mem_lock_page(buf);
        if (!buf)
@@ -3191,14 +3200,22 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
                return -ENOMEM;
        }
        memcpy(buf, data, data_len);
                return -ENOMEM;
        }
        memcpy(buf, data, data_len);
+
+       HWRM_PREP(req, NVM_WRITE);
+
+       req.dir_type = rte_cpu_to_le_16(dir_type);
+       req.dir_ordinal = rte_cpu_to_le_16(dir_ordinal);
+       req.dir_ext = rte_cpu_to_le_16(dir_ext);
+       req.dir_attr = rte_cpu_to_le_16(dir_attr);
+       req.dir_data_length = rte_cpu_to_le_32(data_len);
        req.host_src_addr = rte_cpu_to_le_64(dma_handle);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
        req.host_src_addr = rte_cpu_to_le_64(dma_handle);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
+       rte_free(buf);
        HWRM_CHECK_RESULT();
        HWRM_UNLOCK();
 
        HWRM_CHECK_RESULT();
        HWRM_UNLOCK();
 
-       rte_free(buf);
        return rc;
 }
 
        return rc;
 }
 
index fe83d37..f8bb4ed 100644 (file)
@@ -296,6 +296,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
        count = 0;
        for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
                uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
        count = 0;
        for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
                uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+               xstats[count].id = count;
                xstats[count].value = rte_le_to_cpu_64(
                                *(uint64_t *)((char *)rx_stats +
                                bnxt_rx_stats_strings[i].offset));
                xstats[count].value = rte_le_to_cpu_64(
                                *(uint64_t *)((char *)rx_stats +
                                bnxt_rx_stats_strings[i].offset));
@@ -304,6 +305,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 
        for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
                uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
 
        for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
                uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+               xstats[count].id = count;
                xstats[count].value = rte_le_to_cpu_64(
                                 *(uint64_t *)((char *)tx_stats +
                                bnxt_tx_stats_strings[i].offset));
                xstats[count].value = rte_le_to_cpu_64(
                                 *(uint64_t *)((char *)tx_stats +
                                bnxt_tx_stats_strings[i].offset));
@@ -311,6 +313,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
        }
 
        /* The Tx drop pkts aka the Anti spoof coounter */
        }
 
        /* The Tx drop pkts aka the Anti spoof coounter */
+       xstats[count].id = count;
        xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
        count++;
 
        xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
        count++;
 
index 03d2652..f5ed03f 100644 (file)
@@ -161,7 +161,9 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 
        if (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM |
                                PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |
 
        if (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM |
                                PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |
-                               PKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM))
+                               PKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM |
+                               PKT_TX_TUNNEL_GRE | PKT_TX_TUNNEL_VXLAN |
+                               PKT_TX_TUNNEL_GENEVE))
                long_bd = true;
 
        tx_buf = &txr->tx_buf_ring[txr->tx_prod];
                long_bd = true;
 
        tx_buf = &txr->tx_buf_ring[txr->tx_prod];
@@ -222,16 +224,46 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
                        /* Outer IP, Inner IP, Inner TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
                        /* Outer IP, Inner IP, Inner TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_TCP_CKSUM) ==
+                          PKT_TX_OIP_IIP_TCP_CKSUM) {
+                       /* Outer IP, Inner IP, Inner TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_UDP_CKSUM) ==
+                          PKT_TX_OIP_IIP_UDP_CKSUM) {
+                       /* Outer IP, Inner IP, Inner TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_TIP_IP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
                } else if ((tx_pkt->ol_flags & PKT_TX_IIP_TCP_UDP_CKSUM) ==
                           PKT_TX_IIP_TCP_UDP_CKSUM) {
                        /* (Inner) IP, (Inner) TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
                } else if ((tx_pkt->ol_flags & PKT_TX_IIP_TCP_UDP_CKSUM) ==
                           PKT_TX_IIP_TCP_UDP_CKSUM) {
                        /* (Inner) IP, (Inner) TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_IIP_UDP_CKSUM) ==
+                          PKT_TX_IIP_UDP_CKSUM) {
+                       /* (Inner) IP, (Inner) TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_IIP_TCP_CKSUM) ==
+                          PKT_TX_IIP_TCP_CKSUM) {
+                       /* (Inner) IP, (Inner) TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_IP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
                } else if ((tx_pkt->ol_flags & PKT_TX_OIP_TCP_UDP_CKSUM) ==
                           PKT_TX_OIP_TCP_UDP_CKSUM) {
                        /* Outer IP, (Inner) TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
                } else if ((tx_pkt->ol_flags & PKT_TX_OIP_TCP_UDP_CKSUM) ==
                           PKT_TX_OIP_TCP_UDP_CKSUM) {
                        /* Outer IP, (Inner) TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_UDP_CKSUM) ==
+                          PKT_TX_OIP_UDP_CKSUM) {
+                       /* Outer IP, (Inner) TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_TCP_CKSUM) ==
+                          PKT_TX_OIP_TCP_CKSUM) {
+                       /* Outer IP, (Inner) TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_FLG_TIP_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
                } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_CKSUM) ==
                           PKT_TX_OIP_IIP_CKSUM) {
                        /* Outer IP, Inner IP CSO */
                } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_CKSUM) ==
                           PKT_TX_OIP_IIP_CKSUM) {
                        /* Outer IP, Inner IP CSO */
@@ -242,11 +274,23 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
                        /* TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
                        /* TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
-               } else if (tx_pkt->ol_flags & PKT_TX_IP_CKSUM) {
+               } else if ((tx_pkt->ol_flags & PKT_TX_TCP_CKSUM) ==
+                          PKT_TX_TCP_CKSUM) {
+                       /* TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_UDP_CKSUM) ==
+                          PKT_TX_UDP_CKSUM) {
+                       /* TCP/UDP CSO */
+                       txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+                       txbd1->mss = 0;
+               } else if ((tx_pkt->ol_flags & PKT_TX_IP_CKSUM) ==
+                          PKT_TX_IP_CKSUM) {
                        /* IP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM;
                        txbd1->mss = 0;
                        /* IP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_IP_CHKSUM;
                        txbd1->mss = 0;
-               } else if (tx_pkt->ol_flags & PKT_TX_OUTER_IP_CKSUM) {
+               } else if ((tx_pkt->ol_flags & PKT_TX_OUTER_IP_CKSUM) ==
+                          PKT_TX_OUTER_IP_CKSUM) {
                        /* IP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_T_IP_CHKSUM;
                        txbd1->mss = 0;
                        /* IP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_T_IP_CHKSUM;
                        txbd1->mss = 0;
@@ -270,6 +314,7 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
        }
 
        txbd->flags_type |= TX_BD_LONG_FLAGS_PACKET_END;
        }
 
        txbd->flags_type |= TX_BD_LONG_FLAGS_PACKET_END;
+       txbd1->lflags = rte_cpu_to_le_32(txbd1->lflags);
 
        txr->tx_prod = RING_NEXT(txr->tx_ring_struct, txr->tx_prod);
 
 
        txr->tx_prod = RING_NEXT(txr->tx_ring_struct, txr->tx_prod);
 
index 2feac51..0bc217f 100644 (file)
@@ -71,10 +71,20 @@ uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 #define PKT_TX_OIP_IIP_TCP_UDP_CKSUM   (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
 
 #define PKT_TX_OIP_IIP_TCP_UDP_CKSUM   (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_IIP_UDP_CKSUM       (PKT_TX_UDP_CKSUM | \
+                                       PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_IIP_TCP_CKSUM       (PKT_TX_TCP_CKSUM | \
+                                       PKT_TX_IP_CKSUM | PKT_TX_OUTER_IP_CKSUM)
 #define PKT_TX_IIP_TCP_UDP_CKSUM       (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_IP_CKSUM)
 #define PKT_TX_IIP_TCP_UDP_CKSUM       (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_IP_CKSUM)
+#define PKT_TX_IIP_TCP_CKSUM           (PKT_TX_TCP_CKSUM | PKT_TX_IP_CKSUM)
+#define PKT_TX_IIP_UDP_CKSUM           (PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM)
 #define PKT_TX_OIP_TCP_UDP_CKSUM       (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_OUTER_IP_CKSUM)
 #define PKT_TX_OIP_TCP_UDP_CKSUM       (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | \
                                        PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_UDP_CKSUM           (PKT_TX_UDP_CKSUM | \
+                                       PKT_TX_OUTER_IP_CKSUM)
+#define PKT_TX_OIP_TCP_CKSUM           (PKT_TX_TCP_CKSUM | \
+                                       PKT_TX_OUTER_IP_CKSUM)
 #define PKT_TX_OIP_IIP_CKSUM           (PKT_TX_IP_CKSUM |      \
                                         PKT_TX_OUTER_IP_CKSUM)
 #define PKT_TX_TCP_UDP_CKSUM           (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)
 #define PKT_TX_OIP_IIP_CKSUM           (PKT_TX_IP_CKSUM |      \
                                         PKT_TX_OUTER_IP_CKSUM)
 #define PKT_TX_TCP_UDP_CKSUM           (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)
index 5bac260..293f960 100644 (file)
@@ -67,7 +67,7 @@ void bnxt_init_vnics(struct bnxt *bp)
 {
        struct bnxt_vnic_info *vnic;
        uint16_t max_vnics;
 {
        struct bnxt_vnic_info *vnic;
        uint16_t max_vnics;
-       int i, j;
+       int i;
 
        max_vnics = bp->max_vnics;
        STAILQ_INIT(&bp->free_vnic_list);
 
        max_vnics = bp->max_vnics;
        STAILQ_INIT(&bp->free_vnic_list);
@@ -78,9 +78,6 @@ void bnxt_init_vnics(struct bnxt *bp)
                vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
                vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
                vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
                vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
-               for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
-                       vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
-
                prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
                STAILQ_INIT(&vnic->filter);
                STAILQ_INIT(&vnic->flow_list);
                prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
                STAILQ_INIT(&vnic->filter);
                STAILQ_INIT(&vnic->flow_list);
index 875dc3c..f18fb0a 100644 (file)
@@ -43,13 +43,9 @@ struct bnxt_vnic_info {
 
        uint16_t        fw_vnic_id; /* returned by Chimp during alloc */
        uint16_t        rss_rule;
 
        uint16_t        fw_vnic_id; /* returned by Chimp during alloc */
        uint16_t        rss_rule;
-#define MAX_NUM_TRAFFIC_CLASSES                8
-#define MAX_NUM_RSS_QUEUES_PER_VNIC    16
-#define MAX_QUEUES_PER_VNIC    (MAX_NUM_RSS_QUEUES_PER_VNIC + \
-                                MAX_NUM_TRAFFIC_CLASSES)
        uint16_t        start_grp_id;
        uint16_t        end_grp_id;
        uint16_t        start_grp_id;
        uint16_t        end_grp_id;
-       uint16_t        fw_grp_ids[MAX_QUEUES_PER_VNIC];
+       uint16_t        *fw_grp_ids;
        uint16_t        dflt_ring_grp;
        uint16_t        mru;
        uint16_t        hash_type;
        uint16_t        dflt_ring_grp;
        uint16_t        mru;
        uint16_t        hash_type;
index 8fd90ae..e80338a 100644 (file)
@@ -675,9 +675,21 @@ rte_eth_bond_mac_address_reset(uint16_t bonded_port_id)
        internals->user_defined_mac = 0;
 
        if (internals->slave_count > 0) {
        internals->user_defined_mac = 0;
 
        if (internals->slave_count > 0) {
+               int slave_port;
+               /* Get the primary slave location based on the primary port
+                * number as, while slave_add(), we will keep the primary
+                * slave based on slave_count,but not based on the primary port.
+                */
+               for (slave_port = 0; slave_port < internals->slave_count;
+                    slave_port++) {
+                       if (internals->slaves[slave_port].port_id ==
+                           internals->primary_port)
+                               break;
+               }
+
                /* Set MAC Address of Bonded Device */
                if (mac_address_set(bonded_eth_dev,
                /* Set MAC Address of Bonded Device */
                if (mac_address_set(bonded_eth_dev,
-                               &internals->slaves[internals->primary_port].persisted_mac_addr)
+                       &internals->slaves[slave_port].persisted_mac_addr)
                                != 0) {
                        RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
                        return -1;
                                != 0) {
                        RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
                        return -1;
index e19a4a3..8880231 100644 (file)
@@ -1932,10 +1932,6 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
                }
        }
 
                }
        }
 
-       /* Update all slave devices MACs*/
-       if (mac_address_slaves_update(eth_dev) != 0)
-               goto out_err;
-
        /* If bonded device is configure in promiscuous mode then re-apply config */
        if (internals->promiscuous_en)
                bond_ethdev_promiscuous_enable(eth_dev);
        /* If bonded device is configure in promiscuous mode then re-apply config */
        if (internals->promiscuous_en)
                bond_ethdev_promiscuous_enable(eth_dev);
@@ -1976,6 +1972,10 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
                        (void *)&rte_eth_devices[internals->port_id]);
        }
 
                        (void *)&rte_eth_devices[internals->port_id]);
        }
 
+       /* Update all slave devices MACs*/
+       if (mac_address_slaves_update(eth_dev) != 0)
+               goto out_err;
+
        if (internals->user_defined_primary_port)
                bond_ethdev_primary_set(internals, internals->primary_port);
 
        if (internals->user_defined_primary_port)
                bond_ethdev_primary_set(internals, internals->primary_port);
 
@@ -2048,7 +2048,6 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
                        tlb_last_obytets[internals->active_slaves[i]] = 0;
        }
 
                        tlb_last_obytets[internals->active_slaves[i]] = 0;
        }
 
-       internals->active_slave_count = 0;
        internals->link_status_polling_enabled = 0;
        for (i = 0; i < internals->slave_count; i++)
                internals->slaves[i].last_link_status = 0;
        internals->link_status_polling_enabled = 0;
        for (i = 0; i < internals->slave_count; i++)
                internals->slaves[i].last_link_status = 0;
@@ -2535,10 +2534,8 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 
        rte_eth_link_get_nowait(port_id, &link);
        if (link.link_status) {
 
        rte_eth_link_get_nowait(port_id, &link);
        if (link.link_status) {
-               if (active_pos < internals->active_slave_count) {
-                       rte_spinlock_unlock(&internals->lsc_lock);
-                       return rc;
-               }
+               if (active_pos < internals->active_slave_count)
+                       goto link_update;
 
                /* if no active slave ports then set this port to be primary port */
                if (internals->active_slave_count < 1) {
 
                /* if no active slave ports then set this port to be primary port */
                if (internals->active_slave_count < 1) {
@@ -2557,10 +2554,8 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
                                internals->primary_port == port_id)
                        bond_ethdev_primary_set(internals, port_id);
        } else {
                                internals->primary_port == port_id)
                        bond_ethdev_primary_set(internals, port_id);
        } else {
-               if (active_pos == internals->active_slave_count) {
-                       rte_spinlock_unlock(&internals->lsc_lock);
-                       return rc;
-               }
+               if (active_pos == internals->active_slave_count)
+                       goto link_update;
 
                /* Remove from active slave list */
                deactivate_slave(bonded_eth_dev, port_id);
 
                /* Remove from active slave list */
                deactivate_slave(bonded_eth_dev, port_id);
@@ -2579,6 +2574,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
                }
        }
 
                }
        }
 
+link_update:
        /**
         * Update bonded device link properties after any change to active
         * slaves
        /**
         * Update bonded device link properties after any change to active
         * slaves
@@ -2616,7 +2612,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 
        rte_spinlock_unlock(&internals->lsc_lock);
 
 
        rte_spinlock_unlock(&internals->lsc_lock);
 
-       return 0;
+       return rc;
 }
 
 static int
 }
 
 static int
index 282e2e6..c3d46e0 100644 (file)
@@ -4242,9 +4242,8 @@ struct flash_desc {
 int t4_get_flash_params(struct adapter *adapter)
 {
        /*
 int t4_get_flash_params(struct adapter *adapter)
 {
        /*
-        * Table for non-Numonix supported flash parts.  Numonix parts are left
-        * to the preexisting well-tested code.  All flash parts have 64KB
-        * sectors.
+        * Table for non-standard supported Flash parts.  Note, all Flash
+        * parts must have 64KB sectors.
         */
        static struct flash_desc supported_flash[] = {
                { 0x00150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
         */
        static struct flash_desc supported_flash[] = {
                { 0x00150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
@@ -4253,7 +4252,7 @@ int t4_get_flash_params(struct adapter *adapter)
        int ret;
        u32 flashid = 0;
        unsigned int part, manufacturer;
        int ret;
        u32 flashid = 0;
        unsigned int part, manufacturer;
-       unsigned int density, size;
+       unsigned int density, size = 0;
 
        /**
         * Issue a Read ID Command to the Flash part.  We decode supported
 
        /**
         * Issue a Read ID Command to the Flash part.  We decode supported
@@ -4268,6 +4267,9 @@ int t4_get_flash_params(struct adapter *adapter)
        if (ret < 0)
                return ret;
 
        if (ret < 0)
                return ret;
 
+       /**
+        * Check to see if it's one of our non-standard supported Flash parts.
+        */
        for (part = 0; part < ARRAY_SIZE(supported_flash); part++) {
                if (supported_flash[part].vendor_and_model_id == flashid) {
                        adapter->params.sf_size =
        for (part = 0; part < ARRAY_SIZE(supported_flash); part++) {
                if (supported_flash[part].vendor_and_model_id == flashid) {
                        adapter->params.sf_size =
@@ -4278,6 +4280,15 @@ int t4_get_flash_params(struct adapter *adapter)
                }
        }
 
                }
        }
 
+       /**
+        * Decode Flash part size.  The code below looks repetative with
+        * common encodings, but that's not guaranteed in the JEDEC
+        * specification for the Read JADEC ID command.  The only thing that
+        * we're guaranteed by the JADEC specification is where the
+        * Manufacturer ID is in the returned result.  After that each
+        * Manufacturer ~could~ encode things completely differently.
+        * Note, all Flash parts must have 64KB sectors.
+        */
        manufacturer = flashid & 0xff;
        switch (manufacturer) {
        case 0x20: { /* Micron/Numonix */
        manufacturer = flashid & 0xff;
        switch (manufacturer) {
        case 0x20: { /* Micron/Numonix */
@@ -4314,20 +4325,80 @@ int t4_get_flash_params(struct adapter *adapter)
                case 0x22:
                        size = 1 << 28; /* 256MB */
                        break;
                case 0x22:
                        size = 1 << 28; /* 256MB */
                        break;
-               default:
-                       dev_err(adapter, "Micron Flash Part has bad size, ID = %#x, Density code = %#x\n",
-                               flashid, density);
-                       return -EINVAL;
                }
                }
+               break;
+       }
 
 
-               adapter->params.sf_size = size;
-               adapter->params.sf_nsec = size / SF_SEC_SIZE;
+       case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */
+               /**
+                * This Density -> Size decoding table is taken from ISSI
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x16:
+                       size = 1 << 25; /* 32MB */
+                       break;
+               case 0x17:
+                       size = 1 << 26; /* 64MB */
+                       break;
+               }
                break;
        }
                break;
        }
-       default:
-               dev_err(adapter, "Unsupported Flash Part, ID = %#x\n", flashid);
-               return -EINVAL;
+
+       case 0xc2: { /* Macronix */
+               /**
+                * This Density -> Size decoding table is taken from Macronix
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x17:
+                       size = 1 << 23; /* 8MB */
+                       break;
+               case 0x18:
+                       size = 1 << 24; /* 16MB */
+                       break;
+               }
+               break;
+       }
+
+       case 0xef: { /* Winbond */
+               /**
+                * This Density -> Size decoding table is taken from Winbond
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x17:
+                       size = 1 << 23; /* 8MB */
+                       break;
+               case 0x18:
+                       size = 1 << 24; /* 16MB */
+                       break;
+               }
+               break;
        }
        }
+       }
+
+       /* If we didn't recognize the FLASH part, that's no real issue: the
+        * Hardware/Software contract says that Hardware will _*ALWAYS*_
+        * use a FLASH part which is at least 4MB in size and has 64KB
+        * sectors.  The unrecognized FLASH part is likely to be much larger
+        * than 4MB, but that's all we really need.
+        */
+       if (size == 0) {
+               dev_warn(adapter,
+                        "Unknown Flash Part, ID = %#x, assuming 4MB\n",
+                        flashid);
+               size = 1 << 22;
+       }
+
+       /**
+        * Store decoded Flash size and fall through into vetting code.
+        */
+       adapter->params.sf_size = size;
+       adapter->params.sf_nsec = size / SF_SEC_SIZE;
 
 found:
        /*
 
 found:
        /*
index 6ca4f31..f0566e9 100644 (file)
@@ -473,6 +473,11 @@ enum fw_iq_type {
        FW_IQ_TYPE_FL_INT_CAP,
 };
 
        FW_IQ_TYPE_FL_INT_CAP,
 };
 
+enum fw_iq_iqtype {
+       FW_IQ_IQTYPE_NIC = 1,
+       FW_IQ_IQTYPE_OFLD,
+};
+
 struct fw_iq_cmd {
        __be32 op_to_vfn;
        __be32 alloc_to_len16;
 struct fw_iq_cmd {
        __be32 op_to_vfn;
        __be32 alloc_to_len16;
@@ -606,6 +611,9 @@ struct fw_iq_cmd {
        (((x) >> S_FW_IQ_CMD_IQFLINTCONGEN) & M_FW_IQ_CMD_IQFLINTCONGEN)
 #define F_FW_IQ_CMD_IQFLINTCONGEN      V_FW_IQ_CMD_IQFLINTCONGEN(1U)
 
        (((x) >> S_FW_IQ_CMD_IQFLINTCONGEN) & M_FW_IQ_CMD_IQFLINTCONGEN)
 #define F_FW_IQ_CMD_IQFLINTCONGEN      V_FW_IQ_CMD_IQFLINTCONGEN(1U)
 
+#define S_FW_IQ_CMD_IQTYPE     24
+#define V_FW_IQ_CMD_IQTYPE(x)  ((x) << S_FW_IQ_CMD_IQTYPE)
+
 #define S_FW_IQ_CMD_FL0CNGCHMAP                20
 #define M_FW_IQ_CMD_FL0CNGCHMAP                0xf
 #define V_FW_IQ_CMD_FL0CNGCHMAP(x)     ((x) << S_FW_IQ_CMD_FL0CNGCHMAP)
 #define S_FW_IQ_CMD_FL0CNGCHMAP                20
 #define M_FW_IQ_CMD_FL0CNGCHMAP                0xf
 #define V_FW_IQ_CMD_FL0CNGCHMAP(x)     ((x) << S_FW_IQ_CMD_FL0CNGCHMAP)
index 03bba9f..c1cc936 100644 (file)
@@ -226,15 +226,6 @@ static inline int cxgbe_fls(int x)
        return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
 }
 
        return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
 }
 
-/**
- * cxgbe_ffs - find first bit set
- * @x: the word to search
- */
-static inline int cxgbe_ffs(int x)
-{
-       return x ? __builtin_ffs(x) : 0;
-}
-
 static inline unsigned long ilog2(unsigned long n)
 {
        unsigned int e = 0;
 static inline unsigned long ilog2(unsigned long n)
 {
        unsigned int e = 0;
index fc10d95..5180084 100644 (file)
@@ -1689,6 +1689,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
        char z_name[RTE_MEMZONE_NAMESIZE];
        char z_name_sw[RTE_MEMZONE_NAMESIZE];
        unsigned int nb_refill;
        char z_name[RTE_MEMZONE_NAMESIZE];
        char z_name_sw[RTE_MEMZONE_NAMESIZE];
        unsigned int nb_refill;
+       u8 pciechan;
 
        /* Size needs to be multiple of 16, including status entry. */
        iq->size = cxgbe_roundup(iq->size, 16);
 
        /* Size needs to be multiple of 16, including status entry. */
        iq->size = cxgbe_roundup(iq->size, 16);
@@ -1708,6 +1709,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
        c.op_to_vfn = htonl(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |
                            F_FW_CMD_WRITE | F_FW_CMD_EXEC |
                            V_FW_IQ_CMD_PFN(adap->pf) | V_FW_IQ_CMD_VFN(0));
        c.op_to_vfn = htonl(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |
                            F_FW_CMD_WRITE | F_FW_CMD_EXEC |
                            V_FW_IQ_CMD_PFN(adap->pf) | V_FW_IQ_CMD_VFN(0));
+
+       pciechan = pi->tx_chan;
+
        c.alloc_to_len16 = htonl(F_FW_IQ_CMD_ALLOC | F_FW_IQ_CMD_IQSTART |
                                 (sizeof(c) / 16));
        c.type_to_iqandstindex =
        c.alloc_to_len16 = htonl(F_FW_IQ_CMD_ALLOC | F_FW_IQ_CMD_IQSTART |
                                 (sizeof(c) / 16));
        c.type_to_iqandstindex =
@@ -1719,16 +1723,19 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
                      V_FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
                                                               -intr_idx - 1));
        c.iqdroprss_to_iqesize =
                      V_FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
                                                               -intr_idx - 1));
        c.iqdroprss_to_iqesize =
-               htons(V_FW_IQ_CMD_IQPCIECH(cong > 0 ? cxgbe_ffs(cong) - 1 :
-                                                     pi->tx_chan) |
+               htons(V_FW_IQ_CMD_IQPCIECH(pciechan) |
                      F_FW_IQ_CMD_IQGTSMODE |
                      V_FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
                      V_FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
        c.iqsize = htons(iq->size);
        c.iqaddr = cpu_to_be64(iq->phys_addr);
        if (cong >= 0)
                      F_FW_IQ_CMD_IQGTSMODE |
                      V_FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
                      V_FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
        c.iqsize = htons(iq->size);
        c.iqaddr = cpu_to_be64(iq->phys_addr);
        if (cong >= 0)
-               c.iqns_to_fl0congen = htonl(F_FW_IQ_CMD_IQFLINTCONGEN |
-                                           F_FW_IQ_CMD_IQRO);
+               c.iqns_to_fl0congen =
+                       htonl(F_FW_IQ_CMD_IQFLINTCONGEN |
+                             V_FW_IQ_CMD_IQTYPE(cong ?
+                                                FW_IQ_IQTYPE_NIC :
+                                                FW_IQ_IQTYPE_OFLD) |
+                             F_FW_IQ_CMD_IQRO);
 
        if (fl) {
                struct sge_eth_rxq *rxq = container_of(fl, struct sge_eth_rxq,
 
        if (fl) {
                struct sge_eth_rxq *rxq = container_of(fl, struct sge_eth_rxq,
index 6f671fe..fe2cb52 100644 (file)
@@ -231,7 +231,7 @@ int dpni_set_pools(struct fsl_mc_io *mc_io,
                                          token);
        cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
        cmd_params->num_dpbp = cfg->num_dpbp;
                                          token);
        cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
        cmd_params->num_dpbp = cfg->num_dpbp;
-       for (i = 0; i < DPNI_MAX_DPBP; i++) {
+       for (i = 0; i < cmd_params->num_dpbp; i++) {
                cmd_params->pool[i].dpbp_id =
                        cpu_to_le16(cfg->pools[i].dpbp_id);
                cmd_params->pool[i].priority_mask =
                cmd_params->pool[i].dpbp_id =
                        cpu_to_le16(cfg->pools[i].dpbp_id);
                cmd_params->pool[i].priority_mask =
index accecf5..ea78e8d 100644 (file)
@@ -116,11 +116,13 @@ typedef uint64_t dma_addr_t;
 #define ENA_MIN16(x, y) RTE_MIN((x), (y))
 #define ENA_MIN8(x, y) RTE_MIN((x), (y))
 
 #define ENA_MIN16(x, y) RTE_MIN((x), (y))
 #define ENA_MIN8(x, y) RTE_MIN((x), (y))
 
+#define BITS_PER_LONG_LONG (__SIZEOF_LONG_LONG__ * 8)
 #define U64_C(x) x ## ULL
 #define BIT(nr)         (1UL << (nr))
 #define BITS_PER_LONG  (__SIZEOF_LONG__ * 8)
 #define GENMASK(h, l)  (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #define U64_C(x) x ## ULL
 #define BIT(nr)         (1UL << (nr))
 #define BITS_PER_LONG  (__SIZEOF_LONG__ * 8)
 #define GENMASK(h, l)  (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) (((~0ULL) - (1ULL << (l)) + 1) & \
+                         (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
 #ifdef RTE_LIBRTE_ENA_COM_DEBUG
 #define ena_trc_dbg(format, arg...)                                    \
 
 #ifdef RTE_LIBRTE_ENA_COM_DEBUG
 #define ena_trc_dbg(format, arg...)                                    \
@@ -189,10 +191,15 @@ typedef uint64_t dma_addr_t;
                snprintf(z_name, sizeof(z_name),                        \
                                "ena_alloc_%d", ena_alloc_cnt++);       \
                mz = rte_memzone_reserve(z_name, size, SOCKET_ID_ANY, 0); \
                snprintf(z_name, sizeof(z_name),                        \
                                "ena_alloc_%d", ena_alloc_cnt++);       \
                mz = rte_memzone_reserve(z_name, size, SOCKET_ID_ANY, 0); \
-               memset(mz->addr, 0, size);                              \
-               virt = mz->addr;                                        \
-               phys = mz->iova;                                        \
                handle = mz;                                            \
                handle = mz;                                            \
+               if (mz == NULL) {                                       \
+                       virt = NULL;                                    \
+                       phys = 0;                                       \
+               } else {                                                \
+                       memset(mz->addr, 0, size);                      \
+                       virt = mz->addr;                                \
+                       phys = mz->iova;                                \
+               }                                                       \
        } while (0)
 #define ENA_MEM_FREE_COHERENT(dmadev, size, virt, phys, handle)        \
                ({ ENA_TOUCH(size); ENA_TOUCH(phys);                    \
        } while (0)
 #define ENA_MEM_FREE_COHERENT(dmadev, size, virt, phys, handle)        \
                ({ ENA_TOUCH(size); ENA_TOUCH(phys);                    \
@@ -207,21 +214,20 @@ typedef uint64_t dma_addr_t;
                snprintf(z_name, sizeof(z_name),                        \
                                "ena_alloc_%d", ena_alloc_cnt++);       \
                mz = rte_memzone_reserve(z_name, size, node, 0); \
                snprintf(z_name, sizeof(z_name),                        \
                                "ena_alloc_%d", ena_alloc_cnt++);       \
                mz = rte_memzone_reserve(z_name, size, node, 0); \
-               memset(mz->addr, 0, size);                              \
-               virt = mz->addr;                                        \
-               phys = mz->iova;                                        \
+               if (mz == NULL) {                                       \
+                       virt = NULL;                                    \
+                       phys = 0;                                       \
+               } else {                                                \
+                       memset(mz->addr, 0, size);                      \
+                       virt = mz->addr;                                \
+                       phys = mz->iova;                                \
+               }                                                       \
        } while (0)
 
 #define ENA_MEM_ALLOC_NODE(dmadev, size, virt, node, dev_node) \
        do {                                                            \
        } while (0)
 
 #define ENA_MEM_ALLOC_NODE(dmadev, size, virt, node, dev_node) \
        do {                                                            \
-               const struct rte_memzone *mz;                           \
-               char z_name[RTE_MEMZONE_NAMESIZE];                      \
                ENA_TOUCH(dmadev); ENA_TOUCH(dev_node);                 \
                ENA_TOUCH(dmadev); ENA_TOUCH(dev_node);                 \
-               snprintf(z_name, sizeof(z_name),                        \
-                               "ena_alloc_%d", ena_alloc_cnt++);       \
-               mz = rte_memzone_reserve(z_name, size, node, 0); \
-               memset(mz->addr, 0, size);                              \
-               virt = mz->addr;                                        \
+               virt = rte_zmalloc_socket(NULL, size, 0, node);         \
        } while (0)
 
 #define ENA_MEM_ALLOC(dmadev, size) rte_zmalloc(NULL, size, 1)
        } while (0)
 
 #define ENA_MEM_ALLOC(dmadev, size) rte_zmalloc(NULL, size, 1)
index aa24ef3..4e52656 100644 (file)
@@ -709,7 +709,7 @@ static int ena_link_update(struct rte_eth_dev *dev,
        struct rte_eth_link *link = &dev->data->dev_link;
 
        link->link_status = 1;
        struct rte_eth_link *link = &dev->data->dev_link;
 
        link->link_status = 1;
-       link->link_speed = ETH_SPEED_NUM_10G;
+       link->link_speed = ETH_SPEED_NUM_NONE;
        link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
        return 0;
        link->link_duplex = ETH_LINK_FULL_DUPLEX;
 
        return 0;
@@ -907,7 +907,7 @@ static int ena_start(struct rte_eth_dev *dev)
                return rc;
 
        if (adapter->rte_dev->data->dev_conf.rxmode.mq_mode &
                return rc;
 
        if (adapter->rte_dev->data->dev_conf.rxmode.mq_mode &
-           ETH_MQ_RX_RSS_FLAG) {
+           ETH_MQ_RX_RSS_FLAG && adapter->rte_dev->data->nb_rx_queues > 0) {
                rc = ena_rss_init_default(adapter);
                if (rc)
                        return rc;
                rc = ena_rss_init_default(adapter);
                if (rc)
                        return rc;
index a43fddc..8bbff18 100644 (file)
@@ -139,6 +139,7 @@ struct enic {
        u8 adv_filters;
        u32 flow_filter_mode;
        u8 filter_tags;
        u8 adv_filters;
        u32 flow_filter_mode;
        u8 filter_tags;
+       uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */
 
        unsigned int flags;
        unsigned int priv_flags;
 
        unsigned int flags;
        unsigned int priv_flags;
index 98391b0..46ea2cf 100644 (file)
@@ -40,6 +40,7 @@
 #include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
+#include <rte_kvargs.h>
 #include <rte_string_fns.h>
 
 #include "vnic_intr.h"
 #include <rte_string_fns.h>
 
 #include "vnic_intr.h"
@@ -66,6 +67,8 @@ static const struct rte_pci_id pci_id_enic_map[] = {
        {.vendor_id = 0, /* sentinel */},
 };
 
        {.vendor_id = 0, /* sentinel */},
 };
 
+#define ENIC_DEVARG_IG_VLAN_REWRITE "ig-vlan-rewrite"
+
 static int
 enicpmd_fdir_ctrl_func(struct rte_eth_dev *eth_dev,
                        enum rte_filter_op filter_op, void *arg)
 static int
 enicpmd_fdir_ctrl_func(struct rte_eth_dev *eth_dev,
                        enum rte_filter_op filter_op, void *arg)
@@ -644,6 +647,64 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
        .filter_ctrl          = enicpmd_dev_filter_ctrl,
 };
 
        .filter_ctrl          = enicpmd_dev_filter_ctrl,
 };
 
+static int enic_parse_ig_vlan_rewrite(__rte_unused const char *key,
+                                     const char *value,
+                                     void *opaque)
+{
+       struct enic *enic;
+
+       enic = (struct enic *)opaque;
+       if (strcmp(value, "trunk") == 0) {
+               /* Trunk mode: always tag */
+               enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK;
+       } else if (strcmp(value, "untag") == 0) {
+               /* Untag default VLAN mode: untag if VLAN = default VLAN */
+               enic->ig_vlan_rewrite_mode =
+                       IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN;
+       } else if (strcmp(value, "priority") == 0) {
+               /*
+                * Priority-tag default VLAN mode: priority tag (VLAN header
+                * with ID=0) if VLAN = default
+                */
+               enic->ig_vlan_rewrite_mode =
+                       IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN;
+       } else if (strcmp(value, "pass") == 0) {
+               /* Pass through mode: do not touch tags */
+               enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_PASS_THRU;
+       } else {
+               dev_err(enic, "Invalid value for " ENIC_DEVARG_IG_VLAN_REWRITE
+                       ": expected=trunk|untag|priority|pass given=%s\n",
+                       value);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int enic_check_devargs(struct rte_eth_dev *dev)
+{
+       static const char *const valid_keys[] = {
+               ENIC_DEVARG_IG_VLAN_REWRITE,
+               NULL};
+       struct enic *enic = pmd_priv(dev);
+       struct rte_kvargs *kvlist;
+
+       ENICPMD_FUNC_TRACE();
+
+       enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_PASS_THRU;
+       if (!dev->device->devargs)
+               return 0;
+       kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+       if (!kvlist)
+               return -EINVAL;
+       if (rte_kvargs_process(kvlist, ENIC_DEVARG_IG_VLAN_REWRITE,
+                              enic_parse_ig_vlan_rewrite, enic) < 0) {
+               rte_kvargs_free(kvlist);
+               return -EINVAL;
+       }
+       rte_kvargs_free(kvlist);
+       return 0;
+}
+
 struct enic *enicpmd_list_head = NULL;
 /* Initialize the driver
  * It returns 0 on success.
 struct enic *enicpmd_list_head = NULL;
 /* Initialize the driver
  * It returns 0 on success.
@@ -653,6 +714,7 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
        struct rte_pci_device *pdev;
        struct rte_pci_addr *addr;
        struct enic *enic = pmd_priv(eth_dev);
        struct rte_pci_device *pdev;
        struct rte_pci_addr *addr;
        struct enic *enic = pmd_priv(eth_dev);
+       int err;
 
        ENICPMD_FUNC_TRACE();
 
 
        ENICPMD_FUNC_TRACE();
 
@@ -670,6 +732,9 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
        snprintf(enic->bdf_name, ENICPMD_BDF_LENGTH, "%04x:%02x:%02x.%x",
                addr->domain, addr->bus, addr->devid, addr->function);
 
        snprintf(enic->bdf_name, ENICPMD_BDF_LENGTH, "%04x:%02x:%02x.%x",
                addr->domain, addr->bus, addr->devid, addr->function);
 
+       err = enic_check_devargs(eth_dev);
+       if (err)
+               return err;
        return enic_probe(enic);
 }
 
        return enic_probe(enic);
 }
 
@@ -695,3 +760,5 @@ static struct rte_pci_driver rte_enic_pmd = {
 RTE_PMD_REGISTER_PCI(net_enic, rte_enic_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_enic, pci_id_enic_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_enic, "* igb_uio | uio_pci_generic | vfio-pci");
 RTE_PMD_REGISTER_PCI(net_enic, rte_enic_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_enic, pci_id_enic_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_enic, "* igb_uio | uio_pci_generic | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_enic,
+       ENIC_DEVARG_IG_VLAN_REWRITE "=trunk|untag|priority|pass");
index 6356c10..f946abf 100644 (file)
@@ -782,25 +782,23 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
        static int instance;
 
        wq->socket_id = socket_id;
        static int instance;
 
        wq->socket_id = socket_id;
-       if (nb_desc) {
-               if (nb_desc > enic->config.wq_desc_count) {
-                       dev_warning(enic,
-                               "WQ %d - number of tx desc in cmd line (%d)"\
-                               "is greater than that in the UCSM/CIMC adapter"\
-                               "policy.  Applying the value in the adapter "\
-                               "policy (%d)\n",
-                               queue_idx, nb_desc, enic->config.wq_desc_count);
-               } else if (nb_desc != enic->config.wq_desc_count) {
-                       enic->config.wq_desc_count = nb_desc;
-                       dev_info(enic,
-                               "TX Queues - effective number of descs:%d\n",
-                               nb_desc);
-               }
+       if (nb_desc > enic->config.wq_desc_count) {
+               dev_warning(enic,
+                           "WQ %d - number of tx desc in cmd line (%d) "
+                           "is greater than that in the UCSM/CIMC adapter "
+                           "policy.  Applying the value in the adapter "
+                           "policy (%d)\n",
+                           queue_idx, nb_desc, enic->config.wq_desc_count);
+               nb_desc = enic->config.wq_desc_count;
+       } else if (nb_desc != enic->config.wq_desc_count) {
+               dev_info(enic,
+                        "TX Queues - effective number of descs:%d\n",
+                        nb_desc);
        }
 
        /* Allocate queue resources */
        err = vnic_wq_alloc(enic->vdev, &enic->wq[queue_idx], queue_idx,
        }
 
        /* Allocate queue resources */
        err = vnic_wq_alloc(enic->vdev, &enic->wq[queue_idx], queue_idx,
-               enic->config.wq_desc_count,
+               nb_desc,
                sizeof(struct wq_enet_desc));
        if (err) {
                dev_err(enic, "error in allocation of wq\n");
                sizeof(struct wq_enet_desc));
        if (err) {
                dev_err(enic, "error in allocation of wq\n");
@@ -808,7 +806,7 @@ int enic_alloc_wq(struct enic *enic, uint16_t queue_idx,
        }
 
        err = vnic_cq_alloc(enic->vdev, &enic->cq[cq_index], cq_index,
        }
 
        err = vnic_cq_alloc(enic->vdev, &enic->cq[cq_index], cq_index,
-               socket_id, enic->config.wq_desc_count,
+               socket_id, nb_desc,
                sizeof(struct cq_enet_wq_desc));
        if (err) {
                vnic_wq_free(wq);
                sizeof(struct cq_enet_wq_desc));
        if (err) {
                vnic_wq_free(wq);
@@ -1402,8 +1400,10 @@ int enic_probe(struct enic *enic)
        }
 
        /* Set ingress vlan rewrite mode before vnic initialization */
        }
 
        /* Set ingress vlan rewrite mode before vnic initialization */
+       dev_debug(enic, "Set ig_vlan_rewrite_mode=%u\n",
+                 enic->ig_vlan_rewrite_mode);
        err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
        err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
-               IG_VLAN_REWRITE_MODE_PASS_THRU);
+               enic->ig_vlan_rewrite_mode);
        if (err) {
                dev_err(enic,
                        "Failed to set ingress vlan rewrite mode, aborting.\n");
        if (err) {
                dev_err(enic,
                        "Failed to set ingress vlan rewrite mode, aborting.\n");
index 85baff9..711c6e7 100644 (file)
@@ -1211,6 +1211,13 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        hw->bus.func = pci_dev->addr.function;
        hw->adapter_stopped = 0;
 
        hw->bus.func = pci_dev->addr.function;
        hw->adapter_stopped = 0;
 
+       /*
+        * Switch Tag value should not be identical to either the First Tag
+        * or Second Tag values. So set something other than common Ethertype
+        * for internal switching.
+        */
+       hw->switch_tag = 0xffff;
+
        /* Check if need to support multi-driver */
        i40e_support_multi_driver(dev);
 
        /* Check if need to support multi-driver */
        i40e_support_multi_driver(dev);
 
@@ -1976,27 +1983,40 @@ i40e_phy_conf_link(struct i40e_hw *hw,
        struct i40e_aq_get_phy_abilities_resp phy_ab;
        struct i40e_aq_set_phy_config phy_conf;
        enum i40e_aq_phy_type cnt;
        struct i40e_aq_get_phy_abilities_resp phy_ab;
        struct i40e_aq_set_phy_config phy_conf;
        enum i40e_aq_phy_type cnt;
+       uint8_t avail_speed;
        uint32_t phy_type_mask = 0;
 
        const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX |
                        I40E_AQ_PHY_FLAG_PAUSE_RX |
                        I40E_AQ_PHY_FLAG_PAUSE_RX |
                        I40E_AQ_PHY_FLAG_LOW_POWER;
        uint32_t phy_type_mask = 0;
 
        const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX |
                        I40E_AQ_PHY_FLAG_PAUSE_RX |
                        I40E_AQ_PHY_FLAG_PAUSE_RX |
                        I40E_AQ_PHY_FLAG_LOW_POWER;
-       const uint8_t advt = I40E_LINK_SPEED_40GB |
-                       I40E_LINK_SPEED_25GB |
-                       I40E_LINK_SPEED_10GB |
-                       I40E_LINK_SPEED_1GB |
-                       I40E_LINK_SPEED_100MB;
        int ret = -ENOTSUP;
 
        int ret = -ENOTSUP;
 
+       /* To get phy capabilities of available speeds. */
+       status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab,
+                                             NULL);
+       if (status) {
+               PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n",
+                               status);
+               return ret;
+       }
+       avail_speed = phy_ab.link_speed;
 
 
+       /* To get the current phy config. */
        status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab,
                                              NULL);
        status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab,
                                              NULL);
-       if (status)
+       if (status) {
+               PMD_DRV_LOG(ERR, "Failed to get the current PHY config: %d\n",
+                               status);
                return ret;
                return ret;
+       }
 
 
-       /* If link already up, no need to set up again */
-       if (is_up && phy_ab.phy_type != 0)
+       /* If link needs to go up and it is in autoneg mode the speed is OK,
+        * no need to set up again.
+        */
+       if (is_up && phy_ab.phy_type != 0 &&
+                    abilities & I40E_AQ_PHY_AN_ENABLED &&
+                    phy_ab.link_speed != 0)
                return I40E_SUCCESS;
 
        memset(&phy_conf, 0, sizeof(phy_conf));
                return I40E_SUCCESS;
 
        memset(&phy_conf, 0, sizeof(phy_conf));
@@ -2005,18 +2025,20 @@ i40e_phy_conf_link(struct i40e_hw *hw,
        abilities &= ~mask;
        abilities |= phy_ab.abilities & mask;
 
        abilities &= ~mask;
        abilities |= phy_ab.abilities & mask;
 
-       /* update ablities and speed */
-       if (abilities & I40E_AQ_PHY_AN_ENABLED)
-               phy_conf.link_speed = advt;
-       else
-               phy_conf.link_speed = is_up ? force_speed : phy_ab.link_speed;
-
        phy_conf.abilities = abilities;
 
        phy_conf.abilities = abilities;
 
+       /* If link needs to go up, but the force speed is not supported,
+        * Warn users and config the default available speeds.
+        */
+       if (is_up && !(force_speed & avail_speed)) {
+               PMD_DRV_LOG(WARNING, "Invalid speed setting, set to default!\n");
+               phy_conf.link_speed = avail_speed;
+       } else {
+               phy_conf.link_speed = is_up ? force_speed : avail_speed;
+       }
 
 
-
-       /* To enable link, phy_type mask needs to include each type */
-       for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_MAX; cnt++)
+       /* PHY type mask needs to include each type except PHY type extension */
+       for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_25GBASE_KR; cnt++)
                phy_type_mask |= 1 << cnt;
 
        /* use get_phy_abilities_resp value for the rest */
                phy_type_mask |= 1 << cnt;
 
        /* use get_phy_abilities_resp value for the rest */
@@ -2049,11 +2071,18 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_eth_conf *conf = &dev->data->dev_conf;
 
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_eth_conf *conf = &dev->data->dev_conf;
 
+       if (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) {
+               conf->link_speeds = ETH_LINK_SPEED_40G |
+                                   ETH_LINK_SPEED_25G |
+                                   ETH_LINK_SPEED_20G |
+                                   ETH_LINK_SPEED_10G |
+                                   ETH_LINK_SPEED_1G |
+                                   ETH_LINK_SPEED_100M;
+       }
        speed = i40e_parse_link_speeds(conf->link_speeds);
        speed = i40e_parse_link_speeds(conf->link_speeds);
-       abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
-       if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
-               abilities |= I40E_AQ_PHY_AN_ENABLED;
-       abilities |= I40E_AQ_PHY_LINK_ENABLED;
+       abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK |
+                    I40E_AQ_PHY_AN_ENABLED |
+                    I40E_AQ_PHY_LINK_ENABLED;
 
        return i40e_phy_conf_link(hw, abilities, speed, true);
 }
 
        return i40e_phy_conf_link(hw, abilities, speed, true);
 }
@@ -2160,13 +2189,6 @@ i40e_dev_start(struct rte_eth_dev *dev)
        }
 
        /* Apply link configure */
        }
 
        /* Apply link configure */
-       if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
-                               ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
-                               ETH_LINK_SPEED_20G | ETH_LINK_SPEED_25G |
-                               ETH_LINK_SPEED_40G)) {
-               PMD_DRV_LOG(ERR, "Invalid link setting");
-               goto err_up;
-       }
        ret = i40e_apply_link_speed(dev);
        if (I40E_SUCCESS != ret) {
                PMD_DRV_LOG(ERR, "Fail to apply link setting");
        ret = i40e_apply_link_speed(dev);
        if (I40E_SUCCESS != ret) {
                PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -9768,6 +9790,60 @@ i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE   0x06060606
 #define I40E_GL_SWR_PM_UP_THR            0x269FBC
 
 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE   0x06060606
 #define I40E_GL_SWR_PM_UP_THR            0x269FBC
 
+/*
+ * GL_SWR_PM_UP_THR:
+ * The value is not impacted from the link speed, its value is set according
+ * to the total number of ports for a better pipe-monitor configuration.
+ */
+static bool
+i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value)
+{
+#define I40E_GL_SWR_PM_EF_DEVICE(dev) \
+               .device_id = (dev),   \
+               .val = I40E_GL_SWR_PM_UP_THR_EF_VALUE
+
+#define I40E_GL_SWR_PM_SF_DEVICE(dev) \
+               .device_id = (dev),   \
+               .val = I40E_GL_SWR_PM_UP_THR_SF_VALUE
+
+       static const struct {
+               uint16_t device_id;
+               uint32_t val;
+       } swr_pm_table[] = {
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_XL710) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) },
+               { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) },
+
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2_A) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_B) },
+               { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_SFP28) },
+       };
+       uint32_t i;
+
+       if (value == NULL) {
+               PMD_DRV_LOG(ERR, "value is NULL");
+               return false;
+       }
+
+       for (i = 0; i < RTE_DIM(swr_pm_table); i++) {
+               if (hw->device_id == swr_pm_table[i].device_id) {
+                       *value = swr_pm_table[i].val;
+
+                       PMD_DRV_LOG(DEBUG, "Device 0x%x with GL_SWR_PM_UP_THR "
+                                   "value - 0x%08x",
+                                   hw->device_id, *value);
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static int
 i40e_dev_sync_phy_type(struct i40e_hw *hw)
 {
 static int
 i40e_dev_sync_phy_type(struct i40e_hw *hw)
 {
@@ -9832,13 +9908,16 @@ i40e_configure_registers(struct i40e_hw *hw)
                }
 
                if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) {
                }
 
                if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) {
-                       if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types) || /* For XL710 */
-                           I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types)) /* For XXV710 */
-                               reg_table[i].val =
-                                       I40E_GL_SWR_PM_UP_THR_SF_VALUE;
-                       else /* For X710 */
-                               reg_table[i].val =
-                                       I40E_GL_SWR_PM_UP_THR_EF_VALUE;
+                       uint32_t cfg_val;
+
+                       if (!i40e_get_swr_pm_cfg(hw, &cfg_val)) {
+                               PMD_DRV_LOG(DEBUG, "Device 0x%x skips "
+                                           "GL_SWR_PM_UP_THR value fixup",
+                                           hw->device_id);
+                               continue;
+                       }
+
+                       reg_table[i].val = cfg_val;
                }
 
                ret = i40e_aq_debug_read_register(hw, reg_table[i].addr,
                }
 
                ret = i40e_aq_debug_read_register(hw, reg_table[i].addr,
index ab1163c..2d25873 100644 (file)
@@ -1688,6 +1688,7 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff,
                                PMD_DRV_LOG(ERR, "Profile of group 0 already exists.");
                        else if (is_exist == 3)
                                PMD_DRV_LOG(ERR, "Profile of different group already exists");
                                PMD_DRV_LOG(ERR, "Profile of group 0 already exists.");
                        else if (is_exist == 3)
                                PMD_DRV_LOG(ERR, "Profile of different group already exists");
+                       i40e_update_customized_info(dev, buff, size, op);
                        rte_free(profile_info_sec);
                        return -EEXIST;
                }
                        rte_free(profile_info_sec);
                        return -EEXIST;
                }
index 51ddcfd..762f1ad 100644 (file)
 #define IXGBE_5TUPLE_MAX_PRI            7
 #define IXGBE_5TUPLE_MIN_PRI            1
 
 #define IXGBE_5TUPLE_MAX_PRI            7
 #define IXGBE_5TUPLE_MIN_PRI            1
 
+/* bit of VXLAN tunnel type | 7 bits of zeros  | 8 bits of zeros*/
+#define IXGBE_FDIR_VXLAN_TUNNEL_TYPE    0x8000
+/* bit of NVGRE tunnel type | 7 bits of zeros  | 8 bits of zeros*/
+#define IXGBE_FDIR_NVGRE_TUNNEL_TYPE    0x0
+
 #define IXGBE_RSS_OFFLOAD_ALL ( \
        ETH_RSS_IPV4 | \
        ETH_RSS_NONFRAG_IPV4_TCP | \
 #define IXGBE_RSS_OFFLOAD_ALL ( \
        ETH_RSS_IPV4 | \
        ETH_RSS_NONFRAG_IPV4_TCP | \
index c117647..02adfa4 100644 (file)
@@ -423,9 +423,12 @@ fdir_set_input_mask_x550(struct rte_eth_dev *dev)
                                IXGBE_FDIRIP6M_TNI_VNI;
 
        if (mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
                                IXGBE_FDIRIP6M_TNI_VNI;
 
        if (mode == RTE_FDIR_MODE_PERFECT_TUNNEL) {
-               mac_mask = info->mask.mac_addr_byte_mask;
-               fdiripv6m |= (mac_mask << IXGBE_FDIRIP6M_INNER_MAC_SHIFT)
-                               & IXGBE_FDIRIP6M_INNER_MAC;
+               fdiripv6m |= IXGBE_FDIRIP6M_INNER_MAC;
+               mac_mask = info->mask.mac_addr_byte_mask &
+                       (IXGBE_FDIRIP6M_INNER_MAC >>
+                       IXGBE_FDIRIP6M_INNER_MAC_SHIFT);
+               fdiripv6m &= ~((mac_mask << IXGBE_FDIRIP6M_INNER_MAC_SHIFT) &
+                               IXGBE_FDIRIP6M_INNER_MAC);
 
                switch (info->mask.tunnel_type_mask) {
                case 0:
 
                switch (info->mask.tunnel_type_mask) {
                case 0:
@@ -800,10 +803,19 @@ ixgbe_fdir_filter_to_atr_input(const struct rte_eth_fdir_filter *fdir_filter,
                        input->formatted.inner_mac,
                        fdir_filter->input.flow.tunnel_flow.mac_addr.addr_bytes,
                        sizeof(input->formatted.inner_mac));
                        input->formatted.inner_mac,
                        fdir_filter->input.flow.tunnel_flow.mac_addr.addr_bytes,
                        sizeof(input->formatted.inner_mac));
-               input->formatted.tunnel_type =
-                       fdir_filter->input.flow.tunnel_flow.tunnel_type;
+               if (fdir_filter->input.flow.tunnel_flow.tunnel_type ==
+                               RTE_FDIR_TUNNEL_TYPE_VXLAN)
+                       input->formatted.tunnel_type =
+                                       IXGBE_FDIR_VXLAN_TUNNEL_TYPE;
+               else if (fdir_filter->input.flow.tunnel_flow.tunnel_type ==
+                               RTE_FDIR_TUNNEL_TYPE_NVGRE)
+                       input->formatted.tunnel_type =
+                                       IXGBE_FDIR_NVGRE_TUNNEL_TYPE;
+               else
+                       PMD_DRV_LOG(ERR, " invalid tunnel type arguments.");
+
                input->formatted.tni_vni =
                input->formatted.tni_vni =
-                       fdir_filter->input.flow.tunnel_flow.tunnel_id;
+                       fdir_filter->input.flow.tunnel_flow.tunnel_id >> 8;
        }
 
        return 0;
        }
 
        return 0;
@@ -1030,8 +1042,7 @@ fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), 0);
                } else {
                        /* tunnel mode */
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), 0);
                } else {
                        /* tunnel mode */
-                       if (input->formatted.tunnel_type !=
-                               RTE_FDIR_TUNNEL_TYPE_NVGRE)
+                       if (input->formatted.tunnel_type)
                                tunnel_type = 0x80000000;
                        tunnel_type |= addr_high;
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), addr_low);
                                tunnel_type = 0x80000000;
                        tunnel_type |= addr_high;
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), addr_low);
@@ -1039,6 +1050,9 @@ fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2),
                                        input->formatted.tni_vni);
                }
                        IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2),
                                        input->formatted.tni_vni);
                }
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, 0);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, 0);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, 0);
        }
 
        /* record vlan (little-endian) and flex_bytes(big-endian) */
        }
 
        /* record vlan (little-endian) and flex_bytes(big-endian) */
index 07abb34..e60ecce 100644 (file)
@@ -1665,7 +1665,8 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev,
                                return -rte_errno;
                        }
                } else {
                                return -rte_errno;
                        }
                } else {
-                       if (item->type != RTE_FLOW_ITEM_TYPE_IPV4) {
+                       if (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
+                                       item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
                                memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
                                rte_flow_error_set(error, EINVAL,
                                        RTE_FLOW_ERROR_TYPE_ITEM,
                                memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
                                rte_flow_error_set(error, EINVAL,
                                        RTE_FLOW_ERROR_TYPE_ITEM,
@@ -2370,7 +2371,7 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
        /* Get the VxLAN info */
        if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
                rule->ixgbe_fdir.formatted.tunnel_type =
        /* Get the VxLAN info */
        if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
                rule->ixgbe_fdir.formatted.tunnel_type =
-                       RTE_FDIR_TUNNEL_TYPE_VXLAN;
+                               IXGBE_FDIR_VXLAN_TUNNEL_TYPE;
 
                /* Only care about VNI, others should be masked. */
                if (!item->mask) {
 
                /* Only care about VNI, others should be masked. */
                if (!item->mask) {
@@ -2422,17 +2423,15 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
                        vxlan_spec = (const struct rte_flow_item_vxlan *)
                                        item->spec;
                        rte_memcpy(((uint8_t *)
                        vxlan_spec = (const struct rte_flow_item_vxlan *)
                                        item->spec;
                        rte_memcpy(((uint8_t *)
-                               &rule->ixgbe_fdir.formatted.tni_vni + 1),
+                               &rule->ixgbe_fdir.formatted.tni_vni),
                                vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
                                vxlan_spec->vni, RTE_DIM(vxlan_spec->vni));
-                       rule->ixgbe_fdir.formatted.tni_vni = rte_be_to_cpu_32(
-                               rule->ixgbe_fdir.formatted.tni_vni);
                }
        }
 
        /* Get the NVGRE info */
        if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) {
                rule->ixgbe_fdir.formatted.tunnel_type =
                }
        }
 
        /* Get the NVGRE info */
        if (item->type == RTE_FLOW_ITEM_TYPE_NVGRE) {
                rule->ixgbe_fdir.formatted.tunnel_type =
-                       RTE_FDIR_TUNNEL_TYPE_NVGRE;
+                               IXGBE_FDIR_NVGRE_TUNNEL_TYPE;
 
                /**
                 * Only care about flags0, flags1, protocol and TNI,
 
                /**
                 * Only care about flags0, flags1, protocol and TNI,
@@ -2524,7 +2523,6 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
                        /* tni is a 24-bits bit field */
                        rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
                        nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
                        /* tni is a 24-bits bit field */
                        rte_memcpy(&rule->ixgbe_fdir.formatted.tni_vni,
                        nvgre_spec->tni, RTE_DIM(nvgre_spec->tni));
-                       rule->ixgbe_fdir.formatted.tni_vni <<= 8;
                }
        }
 
                }
        }
 
index 4d7bd5f..d39ad3e 100644 (file)
@@ -434,6 +434,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        int err = 0;
        struct ibv_context *attr_ctx = NULL;
        struct ibv_device_attr device_attr;
        int err = 0;
        struct ibv_context *attr_ctx = NULL;
        struct ibv_device_attr device_attr;
+       struct ibv_device_attr_ex device_attr_ex;
        struct mlx4_conf conf = {
                .ports.present = 0,
        };
        struct mlx4_conf conf = {
                .ports.present = 0,
        };
@@ -494,19 +495,24 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        ibv_dev = list[i];
        DEBUG("device opened");
        if (ibv_query_device(attr_ctx, &device_attr)) {
        ibv_dev = list[i];
        DEBUG("device opened");
        if (ibv_query_device(attr_ctx, &device_attr)) {
-               rte_errno = ENODEV;
+               err = ENODEV;
                goto error;
        }
        INFO("%u port(s) detected", device_attr.phys_port_cnt);
        conf.ports.present |= (UINT64_C(1) << device_attr.phys_port_cnt) - 1;
        if (mlx4_args(pci_dev->device.devargs, &conf)) {
                ERROR("failed to process device arguments");
                goto error;
        }
        INFO("%u port(s) detected", device_attr.phys_port_cnt);
        conf.ports.present |= (UINT64_C(1) << device_attr.phys_port_cnt) - 1;
        if (mlx4_args(pci_dev->device.devargs, &conf)) {
                ERROR("failed to process device arguments");
-               rte_errno = EINVAL;
+               err = EINVAL;
                goto error;
        }
        /* Use all ports when none are defined */
        if (!conf.ports.enabled)
                conf.ports.enabled = conf.ports.present;
                goto error;
        }
        /* Use all ports when none are defined */
        if (!conf.ports.enabled)
                conf.ports.enabled = conf.ports.present;
+       /* Retrieve extended device attributes. */
+       if (ibv_query_device_ex(attr_ctx, NULL, &device_attr_ex)) {
+               err = ENODEV;
+               goto error;
+       }
        for (i = 0; i < device_attr.phys_port_cnt; i++) {
                uint32_t port = i + 1; /* ports are indexed from one */
                struct ibv_context *ctx = NULL;
        for (i = 0; i < device_attr.phys_port_cnt; i++) {
                uint32_t port = i + 1; /* ports are indexed from one */
                struct ibv_context *ctx = NULL;
@@ -522,18 +528,18 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                DEBUG("using port %u", port);
                ctx = ibv_open_device(ibv_dev);
                if (ctx == NULL) {
                DEBUG("using port %u", port);
                ctx = ibv_open_device(ibv_dev);
                if (ctx == NULL) {
-                       rte_errno = ENODEV;
+                       err = ENODEV;
                        goto port_error;
                }
                /* Check port status. */
                err = ibv_query_port(ctx, port, &port_attr);
                if (err) {
                        goto port_error;
                }
                /* Check port status. */
                err = ibv_query_port(ctx, port, &port_attr);
                if (err) {
-                       rte_errno = err;
-                       ERROR("port query failed: %s", strerror(rte_errno));
+                       err = ENODEV;
+                       ERROR("port query failed: %s", strerror(err));
                        goto port_error;
                }
                if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
                        goto port_error;
                }
                if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
-                       rte_errno = ENOTSUP;
+                       err = ENOTSUP;
                        ERROR("port %d is not configured in Ethernet mode",
                              port);
                        goto port_error;
                        ERROR("port %d is not configured in Ethernet mode",
                              port);
                        goto port_error;
@@ -543,15 +549,16 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                              port, ibv_port_state_str(port_attr.state),
                              port_attr.state);
                /* Make asynchronous FD non-blocking to handle interrupts. */
                              port, ibv_port_state_str(port_attr.state),
                              port_attr.state);
                /* Make asynchronous FD non-blocking to handle interrupts. */
-               if (mlx4_fd_set_non_blocking(ctx->async_fd) < 0) {
+               err = mlx4_fd_set_non_blocking(ctx->async_fd);
+               if (err) {
                        ERROR("cannot make asynchronous FD non-blocking: %s",
                        ERROR("cannot make asynchronous FD non-blocking: %s",
-                             strerror(rte_errno));
+                             strerror(err));
                        goto port_error;
                }
                /* Allocate protection domain. */
                pd = ibv_alloc_pd(ctx);
                if (pd == NULL) {
                        goto port_error;
                }
                /* Allocate protection domain. */
                pd = ibv_alloc_pd(ctx);
                if (pd == NULL) {
-                       rte_errno = ENOMEM;
+                       err = ENOMEM;
                        ERROR("PD allocation failure");
                        goto port_error;
                }
                        ERROR("PD allocation failure");
                        goto port_error;
                }
@@ -560,7 +567,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                                   sizeof(*priv),
                                   RTE_CACHE_LINE_SIZE);
                if (priv == NULL) {
                                   sizeof(*priv),
                                   RTE_CACHE_LINE_SIZE);
                if (priv == NULL) {
-                       rte_errno = ENOMEM;
+                       err = ENOMEM;
                        ERROR("priv allocation failure");
                        goto port_error;
                }
                        ERROR("priv allocation failure");
                        goto port_error;
                }
@@ -581,10 +588,14 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                         PCI_DEVICE_ID_MELLANOX_CONNECTX3PRO);
                DEBUG("L2 tunnel checksum offloads are %ssupported",
                      (priv->hw_csum_l2tun ? "" : "not "));
                         PCI_DEVICE_ID_MELLANOX_CONNECTX3PRO);
                DEBUG("L2 tunnel checksum offloads are %ssupported",
                      (priv->hw_csum_l2tun ? "" : "not "));
+               priv->hw_rss_max_qps =
+                       device_attr_ex.rss_caps.max_rwq_indirection_table_size;
+               DEBUG("MAX RSS queues %d", priv->hw_rss_max_qps);
                /* Configure the first MAC address by default. */
                /* Configure the first MAC address by default. */
-               if (mlx4_get_mac(priv, &mac.addr_bytes)) {
+               err = mlx4_get_mac(priv, &mac.addr_bytes);
+               if (err) {
                        ERROR("cannot get MAC address, is mlx4_en loaded?"
                        ERROR("cannot get MAC address, is mlx4_en loaded?"
-                             " (rte_errno: %s)", strerror(rte_errno));
+                             " (error: %s)", strerror(err));
                        goto port_error;
                }
                INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
                        goto port_error;
                }
                INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
@@ -617,8 +628,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                        eth_dev = rte_eth_dev_allocate(name);
                }
                if (eth_dev == NULL) {
                        eth_dev = rte_eth_dev_allocate(name);
                }
                if (eth_dev == NULL) {
+                       err = ENOMEM;
                        ERROR("can not allocate rte ethdev");
                        ERROR("can not allocate rte ethdev");
-                       rte_errno = ENOMEM;
                        goto port_error;
                }
                eth_dev->data->dev_private = priv;
                        goto port_error;
                }
                eth_dev->data->dev_private = priv;
@@ -663,8 +674,6 @@ port_error:
                        rte_eth_dev_release_port(eth_dev);
                break;
        }
                        rte_eth_dev_release_port(eth_dev);
                break;
        }
-       if (i == device_attr.phys_port_cnt)
-               return 0;
        /*
         * XXX if something went wrong in the loop above, there is a resource
         * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
        /*
         * XXX if something went wrong in the loop above, there is a resource
         * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
@@ -676,8 +685,9 @@ error:
                claim_zero(ibv_close_device(attr_ctx));
        if (list)
                ibv_free_device_list(list);
                claim_zero(ibv_close_device(attr_ctx));
        if (list)
                ibv_free_device_list(list);
-       assert(rte_errno >= 0);
-       return -rte_errno;
+       if (err)
+               rte_errno = err;
+       return -err;
 }
 
 static const struct rte_pci_id mlx4_pci_id_map[] = {
 }
 
 static const struct rte_pci_id mlx4_pci_id_map[] = {
index 41d652b..30f12eb 100644 (file)
@@ -129,6 +129,7 @@ struct priv {
        uint32_t rss_init:1; /**< Common RSS context is initialized. */
        uint32_t hw_csum:1; /* Checksum offload is supported. */
        uint32_t hw_csum_l2tun:1; /* Checksum support for L2 tunnels. */
        uint32_t rss_init:1; /**< Common RSS context is initialized. */
        uint32_t hw_csum:1; /* Checksum offload is supported. */
        uint32_t hw_csum_l2tun:1; /* Checksum support for L2 tunnels. */
+       uint32_t hw_rss_max_qps; /**< Max Rx Queues supported by RSS. */
        struct rte_intr_handle intr_handle; /**< Port interrupt handle. */
        struct mlx4_drop *drop; /**< Shared resources for drop flow rules. */
        LIST_HEAD(, mlx4_rss) rss; /**< Shared targets for Rx flow rules. */
        struct rte_intr_handle intr_handle; /**< Port interrupt handle. */
        struct mlx4_drop *drop; /**< Shared resources for drop flow rules. */
        LIST_HEAD(, mlx4_rss) rss; /**< Shared targets for Rx flow rules. */
index 06030c2..b3f70d6 100644 (file)
@@ -365,6 +365,12 @@ mlx4_rss_init(struct priv *priv)
 
        if (priv->rss_init)
                return 0;
 
        if (priv->rss_init)
                return 0;
+       if (priv->dev->data->nb_rx_queues > priv->hw_rss_max_qps) {
+               ERROR("RSS does not support more than %d queues",
+                     priv->hw_rss_max_qps);
+               rte_errno = EINVAL;
+               return -rte_errno;
+       }
        /* Prepare range for RSS contexts before creating the first WQ. */
        ret = mlx4dv_set_context_attr(priv->ctx,
                                      MLX4DV_SET_CTX_ATTR_LOG_WQS_RANGE_SZ,
        /* Prepare range for RSS contexts before creating the first WQ. */
        ret = mlx4dv_set_context_attr(priv->ctx,
                                      MLX4DV_SET_CTX_ATTR_LOG_WQS_RANGE_SZ,
index a3984eb..c62ad11 100644 (file)
@@ -145,7 +145,52 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
        $Q sh -- '$<' '$@' \
                HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT \
                infiniband/verbs.h \
        $Q sh -- '$<' '$@' \
                HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT \
                infiniband/verbs.h \
-               enum IBV_FLOW_SPEC_ACTION_COUNT \
+               type 'struct ibv_counter_set_init_attr' \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_40000baseKR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_40000baseKR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_40000baseCR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_40000baseCR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_40000baseSR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_40000baseSR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_40000baseLR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_40000baseLR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_56000baseKR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_56000baseKR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_56000baseCR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_56000baseCR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_56000baseSR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_56000baseSR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_SUPPORTED_56000baseLR4_Full \
+               /usr/include/linux/ethtool.h \
+               define SUPPORTED_56000baseLR4_Full \
+               $(AUTOCONF_OUTPUT)
+       $Q sh -- '$<' '$@' \
+               HAVE_STATIC_ASSERT \
+               /usr/include/assert.h \
+               define static_assert \
                $(AUTOCONF_OUTPUT)
 
 # Create mlx5_autoconf.h or update it in case it differs from the new one.
                $(AUTOCONF_OUTPUT)
 
 # Create mlx5_autoconf.h or update it in case it differs from the new one.
index 10ce335..36f3a05 100644 (file)
@@ -345,6 +345,10 @@ const struct eth_dev_ops mlx5_dev_ops_isolate = {
        .dev_set_link_down = mlx5_set_link_down,
        .dev_set_link_up = mlx5_set_link_up,
        .dev_close = mlx5_dev_close,
        .dev_set_link_down = mlx5_set_link_down,
        .dev_set_link_up = mlx5_set_link_up,
        .dev_close = mlx5_dev_close,
+       .promiscuous_enable = mlx5_promiscuous_enable,
+       .promiscuous_disable = mlx5_promiscuous_disable,
+       .allmulticast_enable = mlx5_allmulticast_enable,
+       .allmulticast_disable = mlx5_allmulticast_disable,
        .link_update = mlx5_link_update,
        .stats_get = mlx5_stats_get,
        .stats_reset = mlx5_stats_reset,
        .link_update = mlx5_link_update,
        .stats_get = mlx5_stats_get,
        .stats_reset = mlx5_stats_reset,
@@ -680,7 +684,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        int i;
        struct mlx5dv_context attrs_out;
 #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
        int i;
        struct mlx5dv_context attrs_out;
 #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
-       struct ibv_counter_set_description cs_desc;
+       struct ibv_counter_set_description cs_desc = { .counter_type = 0 };
 #endif
 
        assert(pci_drv == &mlx5_driver);
 #endif
 
        assert(pci_drv == &mlx5_driver);
index d706357..9c64bb3 100644 (file)
 #define MLX5_VPMD_MIN_TXQS 4
 
 /* Threshold of buffer replenishment for vectorized Rx. */
 #define MLX5_VPMD_MIN_TXQS 4
 
 /* Threshold of buffer replenishment for vectorized Rx. */
-#define MLX5_VPMD_RXQ_RPLNSH_THRESH   64U
+#define MLX5_VPMD_RXQ_RPLNSH_THRESH(n) \
+       (RTE_MIN(MLX5_VPMD_RX_MAX_BURST, (unsigned int)(n) >> 2))
 
 /* Maximum size of burst for vectorized Rx. */
 
 /* Maximum size of burst for vectorized Rx. */
-#define MLX5_VPMD_RX_MAX_BURST        MLX5_VPMD_RXQ_RPLNSH_THRESH
+#define MLX5_VPMD_RX_MAX_BURST 64U
 
 /*
  * Maximum size of burst for vectorized Tx. This is related to the maximum size
 
 /*
  * Maximum size of burst for vectorized Tx. This is related to the maximum size
  */
 #define MLX5_UAR_OFFSET (1ULL << 32)
 
  */
 #define MLX5_UAR_OFFSET (1ULL << 32)
 
+/* Definition of static_assert found in /usr/include/assert.h */
+#ifndef HAVE_STATIC_ASSERT
+#define static_assert _Static_assert
+#endif
+
 #endif /* RTE_PMD_MLX5_DEFS_H_ */
 #endif /* RTE_PMD_MLX5_DEFS_H_ */
index 5edc751..e441483 100644 (file)
 #include "mlx5_rxtx.h"
 #include "mlx5_utils.h"
 
 #include "mlx5_rxtx.h"
 #include "mlx5_utils.h"
 
+/* Supported speed values found in /usr/include/linux/ethtool.h */
+#ifndef HAVE_SUPPORTED_40000baseKR4_Full
+#define SUPPORTED_40000baseKR4_Full (1 << 23)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseCR4_Full
+#define SUPPORTED_40000baseCR4_Full (1 << 24)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseSR4_Full
+#define SUPPORTED_40000baseSR4_Full (1 << 25)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseLR4_Full
+#define SUPPORTED_40000baseLR4_Full (1 << 26)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseKR4_Full
+#define SUPPORTED_56000baseKR4_Full (1 << 27)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseCR4_Full
+#define SUPPORTED_56000baseCR4_Full (1 << 28)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseSR4_Full
+#define SUPPORTED_56000baseSR4_Full (1 << 29)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseLR4_Full
+#define SUPPORTED_56000baseLR4_Full (1 << 30)
+#endif
+
 /* Add defines in case the running kernel is not the same as user headers. */
 #ifndef ETHTOOL_GLINKSETTINGS
 struct ethtool_link_settings {
 /* Add defines in case the running kernel is not the same as user headers. */
 #ifndef ETHTOOL_GLINKSETTINGS
 struct ethtool_link_settings {
index 57b654c..1822c2b 100644 (file)
 #define MLX5_IPV6 6
 
 #ifndef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
 #define MLX5_IPV6 6
 
 #ifndef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
-struct ibv_counter_set_init_attr {
-       int dummy;
-};
-struct ibv_flow_spec_counter_action {
-       int dummy;
-};
 struct ibv_counter_set {
        int dummy;
 };
 struct ibv_counter_set {
        int dummy;
 };
@@ -885,10 +879,17 @@ mlx5_flow_convert_items_validate(const struct rte_flow_item items[],
                                sizeof(struct ibv_flow_spec_action_tag);
        }
        if (parser->count) {
                                sizeof(struct ibv_flow_spec_action_tag);
        }
        if (parser->count) {
+#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
                unsigned int size = sizeof(struct ibv_flow_spec_counter_action);
 
                for (i = 0; i != hash_rxq_init_n; ++i)
                        parser->queue[i].offset += size;
                unsigned int size = sizeof(struct ibv_flow_spec_counter_action);
 
                for (i = 0; i != hash_rxq_init_n; ++i)
                        parser->queue[i].offset += size;
+#else
+               rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
+                                  items,
+                                  "Count action supported only on "
+                                  "MLNX_OFED_4.2 and above");
+#endif
        }
        return 0;
 exit_item_not_supported:
        }
        return 0;
 exit_item_not_supported:
@@ -2959,10 +2960,21 @@ mlx5_fdir_filter_delete(struct rte_eth_dev *dev,
                struct ibv_spec_header *flow_h;
                void *flow_spec;
                unsigned int specs_n;
                struct ibv_spec_header *flow_h;
                void *flow_spec;
                unsigned int specs_n;
-               unsigned int queue_id = parser.drop ? HASH_RXQ_ETH :
-                                                     parser.layer;
+               unsigned int queue_id;
 
 
-               attr = parser.queue[queue_id].ibv_attr;
+               /*
+                * Search for a non-empty ibv_attr. There should be only one
+                * because no RSS action is allowed for FDIR. This should have
+                * been referenced directly by parser.layer but due to a bug in
+                * mlx5_flow_convert() as of v17.11.4, parser.layer isn't
+                * correct. This bug will have to be addressed later.
+                */
+               for (queue_id = 0; queue_id != hash_rxq_init_n; ++queue_id) {
+                       attr = parser.queue[queue_id].ibv_attr;
+                       if (attr)
+                               break;
+               }
+               assert(!parser.drop || queue_id == HASH_RXQ_ETH);
                flow_attr = flow->frxq[queue_id].ibv_attr;
                /* Compare first the attributes. */
                if (!flow_attr ||
                flow_attr = flow->frxq[queue_id].ibv_attr;
                /* Compare first the attributes. */
                if (!flow_attr ||
@@ -2991,16 +3003,20 @@ wrong_flow:
                /* The flow does not match. */
                continue;
        }
                /* The flow does not match. */
                continue;
        }
-       ret = rte_errno; /* Save rte_errno before cleanup. */
        if (flow)
                mlx5_flow_list_destroy(dev, &priv->flows, flow);
 exit:
        if (flow)
                mlx5_flow_list_destroy(dev, &priv->flows, flow);
 exit:
+       if (ret)
+               ret = rte_errno; /* Save rte_errno before cleanup. */
        for (i = 0; i != hash_rxq_init_n; ++i) {
                if (parser.queue[i].ibv_attr)
                        rte_free(parser.queue[i].ibv_attr);
        }
        for (i = 0; i != hash_rxq_init_n; ++i) {
                if (parser.queue[i].ibv_attr)
                        rte_free(parser.queue[i].ibv_attr);
        }
-       rte_errno = ret; /* Restore rte_errno. */
-       return -rte_errno;
+       if (ret) {
+               rte_errno = ret; /* Restore rte_errno. */
+               return -rte_errno;
+       }
+       return 0;
 }
 
 /**
 }
 
 /**
index 23eae7c..617138c 100644 (file)
 void
 mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 {
 void
 mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 {
+       struct priv *priv = dev->data->dev_private;
        int ret;
 
        dev->data->promiscuous = 1;
        int ret;
 
        dev->data->promiscuous = 1;
+       if (priv->isolated) {
+               DRV_LOG(WARNING,
+                       "port %u cannot enable promiscuous mode"
+                       " in flow isolation mode",
+                       dev->data->port_id);
+               return;
+       }
        ret = mlx5_traffic_restart(dev);
        if (ret)
                DRV_LOG(ERR, "port %u cannot enable promiscuous mode: %s",
        ret = mlx5_traffic_restart(dev);
        if (ret)
                DRV_LOG(ERR, "port %u cannot enable promiscuous mode: %s",
@@ -96,9 +104,17 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 void
 mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 {
 void
 mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 {
+       struct priv *priv = dev->data->dev_private;
        int ret;
 
        dev->data->all_multicast = 1;
        int ret;
 
        dev->data->all_multicast = 1;
+       if (priv->isolated) {
+               DRV_LOG(WARNING,
+                       "port %u cannot enable allmulticast mode"
+                       " in flow isolation mode",
+                       dev->data->port_id);
+               return;
+       }
        ret = mlx5_traffic_restart(dev);
        if (ret)
                DRV_LOG(ERR, "port %u cannot enable allmulicast mode: %s",
        ret = mlx5_traffic_restart(dev);
        if (ret)
                DRV_LOG(ERR, "port %u cannot enable allmulicast mode: %s",
index 2e003ae..1bbce3b 100644 (file)
@@ -740,6 +740,8 @@ next_wqe:
        /* Check whether completion threshold has been reached. */
        comp = txq->elts_comp + i + j + k;
        if (comp >= MLX5_TX_COMP_THRESH) {
        /* Check whether completion threshold has been reached. */
        comp = txq->elts_comp + i + j + k;
        if (comp >= MLX5_TX_COMP_THRESH) {
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request completion on last WQE. */
                last_wqe->ctrl2 = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
                /* Request completion on last WQE. */
                last_wqe->ctrl2 = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
@@ -951,6 +953,8 @@ mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
        if (comp >= MLX5_TX_COMP_THRESH) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
        if (comp >= MLX5_TX_COMP_THRESH) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
@@ -1243,6 +1247,8 @@ mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
        if (comp >= MLX5_TX_COMP_THRESH) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
        if (comp >= MLX5_TX_COMP_THRESH) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
@@ -1370,8 +1376,6 @@ mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
        /* Start processing. */
        mlx5_tx_complete(txq);
        max_elts = (elts_n - (elts_head - txq->elts_tail));
        /* Start processing. */
        mlx5_tx_complete(txq);
        max_elts = (elts_n - (elts_head - txq->elts_tail));
-       /* A CQE slot must always be available. */
-       assert((1u << txq->cqe_n) - (txq->cq_pi - txq->cq_ci));
        max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
        if (unlikely(!max_wqe))
                return 0;
        max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
        if (unlikely(!max_wqe))
                return 0;
@@ -1584,13 +1588,14 @@ mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                         (1 << txq->wqe_n) / MLX5_TX_COMP_THRESH_INLINE_DIV) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
                         (1 << txq->wqe_n) / MLX5_TX_COMP_THRESH_INLINE_DIV) {
                volatile struct mlx5_wqe *wqe = mpw.wqe;
 
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
                wqe->ctrl[3] = elts_head;
                txq->elts_comp = 0;
                txq->mpw_comp = txq->wqe_ci;
                /* Request completion on last WQE. */
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                /* Save elts_head in unused "immediate" field of WQE. */
                wqe->ctrl[3] = elts_head;
                txq->elts_comp = 0;
                txq->mpw_comp = txq->wqe_ci;
-               txq->cq_pi++;
        } else {
                txq->elts_comp += j;
        }
        } else {
                txq->elts_comp += j;
        }
index 29019f7..dac3b39 100644 (file)
@@ -185,7 +185,9 @@ struct mlx5_txq_data {
        uint16_t elts_comp; /* Counter since last completion request. */
        uint16_t mpw_comp; /* WQ index since last completion request. */
        uint16_t cq_ci; /* Consumer index for completion queue. */
        uint16_t elts_comp; /* Counter since last completion request. */
        uint16_t mpw_comp; /* WQ index since last completion request. */
        uint16_t cq_ci; /* Consumer index for completion queue. */
+#ifndef NDEBUG
        uint16_t cq_pi; /* Producer index for completion queue. */
        uint16_t cq_pi; /* Producer index for completion queue. */
+#endif
        uint16_t wqe_ci; /* Consumer index for work queue. */
        uint16_t wqe_pi; /* Producer index for work queue. */
        uint16_t elts_n:4; /* (*elts)[] length (in log2). */
        uint16_t wqe_ci; /* Consumer index for work queue. */
        uint16_t wqe_pi; /* Producer index for work queue. */
        uint16_t elts_n:4; /* (*elts)[] length (in log2). */
index 1f08ed0..d504e2a 100644 (file)
@@ -106,9 +106,9 @@ mlx5_rx_replenish_bulk_mbuf(struct mlx5_rxq_data *rxq, uint16_t n)
        volatile struct mlx5_wqe_data_seg *wq = &(*rxq->wqes)[elts_idx];
        unsigned int i;
 
        volatile struct mlx5_wqe_data_seg *wq = &(*rxq->wqes)[elts_idx];
        unsigned int i;
 
-       assert(n >= MLX5_VPMD_RXQ_RPLNSH_THRESH);
+       assert(n >= MLX5_VPMD_RXQ_RPLNSH_THRESH(q_n));
        assert(n <= (uint16_t)(q_n - (rxq->rq_ci - rxq->rq_pi)));
        assert(n <= (uint16_t)(q_n - (rxq->rq_ci - rxq->rq_pi)));
-       assert(MLX5_VPMD_RXQ_RPLNSH_THRESH > MLX5_VPMD_DESCS_PER_LOOP);
+       assert(MLX5_VPMD_RXQ_RPLNSH_THRESH(q_n) > MLX5_VPMD_DESCS_PER_LOOP);
        /* Not to cross queue end. */
        n = RTE_MIN(n - MLX5_VPMD_DESCS_PER_LOOP, q_n - elts_idx);
        if (rte_mempool_get_bulk(rxq->mp, (void *)elts, n) < 0) {
        /* Not to cross queue end. */
        n = RTE_MIN(n - MLX5_VPMD_DESCS_PER_LOOP, q_n - elts_idx);
        if (rte_mempool_get_bulk(rxq->mp, (void *)elts, n) < 0) {
index cf42477..e748615 100644 (file)
@@ -202,10 +202,11 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
        txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
        txq->elts_head = elts_head;
        if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
        txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
        txq->elts_head = elts_head;
        if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                wqe->ctrl[3] = txq->elts_head;
                txq->elts_comp = 0;
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                wqe->ctrl[3] = txq->elts_head;
                txq->elts_comp = 0;
-               ++txq->cq_pi;
        }
 #ifdef MLX5_PMD_SOFT_COUNTERS
        txq->stats.opackets += n;
        }
 #ifdef MLX5_PMD_SOFT_COUNTERS
        txq->stats.opackets += n;
@@ -304,9 +305,10 @@ txq_burst_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts, uint16_t pkts_n,
        if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
                txq->elts_comp += pkts_n;
        } else {
        if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
                txq->elts_comp += pkts_n;
        } else {
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request a completion. */
                txq->elts_comp = 0;
                /* Request a completion. */
                txq->elts_comp = 0;
-               ++txq->cq_pi;
                comp_req = 8;
        }
        /* Fill CTRL in the header. */
                comp_req = 8;
        }
        /* Fill CTRL in the header. */
@@ -754,7 +756,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
         *   N - (rq_ci - rq_pi) := # of buffers consumed (to be replenished).
         */
        repl_n = q_n - (rxq->rq_ci - rxq->rq_pi);
         *   N - (rq_ci - rq_pi) := # of buffers consumed (to be replenished).
         */
        repl_n = q_n - (rxq->rq_ci - rxq->rq_pi);
-       if (repl_n >= MLX5_VPMD_RXQ_RPLNSH_THRESH)
+       if (repl_n >= MLX5_VPMD_RXQ_RPLNSH_THRESH(q_n))
                mlx5_rx_replenish_bulk_mbuf(rxq, repl_n);
        /* See if there're unreturned mbufs from compressed CQE. */
        rcvd_pkt = rxq->cq_ci - rxq->rq_pi;
                mlx5_rx_replenish_bulk_mbuf(rxq, repl_n);
        /* See if there're unreturned mbufs from compressed CQE. */
        rcvd_pkt = rxq->cq_ci - rxq->rq_pi;
index 7931429..7e8c9b8 100644 (file)
@@ -203,10 +203,11 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
        txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
        txq->elts_head = elts_head;
        if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
        txq->elts_comp += (uint16_t)(elts_head - txq->elts_head);
        txq->elts_head = elts_head;
        if (txq->elts_comp >= MLX5_TX_COMP_THRESH) {
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                wqe->ctrl[3] = txq->elts_head;
                txq->elts_comp = 0;
                wqe->ctrl[2] = rte_cpu_to_be_32(8);
                wqe->ctrl[3] = txq->elts_head;
                txq->elts_comp = 0;
-               ++txq->cq_pi;
        }
 #ifdef MLX5_PMD_SOFT_COUNTERS
        txq->stats.opackets += n;
        }
 #ifdef MLX5_PMD_SOFT_COUNTERS
        txq->stats.opackets += n;
@@ -305,9 +306,10 @@ txq_burst_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts, uint16_t pkts_n,
        if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
                txq->elts_comp += pkts_n;
        } else {
        if (txq->elts_comp + pkts_n < MLX5_TX_COMP_THRESH) {
                txq->elts_comp += pkts_n;
        } else {
+               /* A CQE slot must always be available. */
+               assert((1u << txq->cqe_n) - (txq->cq_pi++ - txq->cq_ci));
                /* Request a completion. */
                txq->elts_comp = 0;
                /* Request a completion. */
                txq->elts_comp = 0;
-               ++txq->cq_pi;
                comp_req = 8;
        }
        /* Fill CTRL in the header. */
                comp_req = 8;
        }
        /* Fill CTRL in the header. */
@@ -735,7 +737,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
         *   N - (rq_ci - rq_pi) := # of buffers consumed (to be replenished).
         */
        repl_n = q_n - (rxq->rq_ci - rxq->rq_pi);
         *   N - (rq_ci - rq_pi) := # of buffers consumed (to be replenished).
         */
        repl_n = q_n - (rxq->rq_ci - rxq->rq_pi);
-       if (repl_n >= MLX5_VPMD_RXQ_RPLNSH_THRESH)
+       if (repl_n >= MLX5_VPMD_RXQ_RPLNSH_THRESH(q_n))
                mlx5_rx_replenish_bulk_mbuf(rxq, repl_n);
        /* See if there're unreturned mbufs from compressed CQE. */
        rcvd_pkt = rxq->cq_ci - rxq->rq_pi;
                mlx5_rx_replenish_bulk_mbuf(rxq, repl_n);
        /* See if there're unreturned mbufs from compressed CQE. */
        rcvd_pkt = rxq->cq_ci - rxq->rq_pi;
index 7ab3100..97f90c0 100644 (file)
@@ -61,6 +61,12 @@ mlx5_socket_init(struct rte_eth_dev *dev)
        int ret;
        int flags;
 
        int ret;
        int flags;
 
+       /*
+        * Close the last socket that was used to communicate
+        * with the secondary process
+        */
+       if (priv->primary_socket)
+               mlx5_socket_uninit(dev);
        /*
         * Initialise the socket to communicate with the secondary
         * process.
        /*
         * Initialise the socket to communicate with the secondary
         * process.
index 214543f..9a1d6f9 100644 (file)
@@ -73,7 +73,6 @@ mlx5_txq_start(struct rte_eth_dev *dev)
        unsigned int i;
        int ret;
 
        unsigned int i;
        int ret;
 
-       /* Add memory regions to Tx queues. */
        for (i = 0; i != priv->txqs_n; ++i) {
                unsigned int idx = 0;
                struct mlx5_mr *mr;
        for (i = 0; i != priv->txqs_n; ++i) {
                unsigned int idx = 0;
                struct mlx5_mr *mr;
@@ -94,12 +93,17 @@ mlx5_txq_start(struct rte_eth_dev *dev)
                }
        }
        ret = mlx5_tx_uar_remap(dev, priv->ctx->cmd_fd);
                }
        }
        ret = mlx5_tx_uar_remap(dev, priv->ctx->cmd_fd);
-       if (ret)
+       if (ret) {
+               /* Adjust index for rollback. */
+               i = priv->txqs_n - 1;
                goto error;
                goto error;
+       }
        return 0;
 error:
        ret = rte_errno; /* Save rte_errno before cleanup. */
        return 0;
 error:
        ret = rte_errno; /* Save rte_errno before cleanup. */
-       mlx5_txq_stop(dev);
+       do {
+               mlx5_txq_release(dev, i);
+       } while (i-- != 0);
        rte_errno = ret; /* Restore rte_errno. */
        return -rte_errno;
 }
        rte_errno = ret; /* Restore rte_errno. */
        return -rte_errno;
 }
@@ -151,7 +155,9 @@ mlx5_rxq_start(struct rte_eth_dev *dev)
        return 0;
 error:
        ret = rte_errno; /* Save rte_errno before cleanup. */
        return 0;
 error:
        ret = rte_errno; /* Save rte_errno before cleanup. */
-       mlx5_rxq_stop(dev);
+       do {
+               mlx5_rxq_release(dev, i);
+       } while (i-- != 0);
        rte_errno = ret; /* Restore rte_errno. */
        return -rte_errno;
 }
        rte_errno = ret; /* Restore rte_errno. */
        return -rte_errno;
 }
@@ -174,28 +180,28 @@ mlx5_dev_start(struct rte_eth_dev *dev)
        struct mlx5_mr *mr = NULL;
        int ret;
 
        struct mlx5_mr *mr = NULL;
        int ret;
 
-       dev->data->dev_started = 1;
+       DRV_LOG(DEBUG, "port %u starting device", dev->data->port_id);
        ret = mlx5_flow_create_drop_queue(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u drop queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
                goto error;
        }
        ret = mlx5_flow_create_drop_queue(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u drop queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
                goto error;
        }
-       DRV_LOG(DEBUG, "port %u allocating and configuring hash Rx queues",
-               dev->data->port_id);
        rte_mempool_walk(mlx5_mp2mr_iter, priv);
        ret = mlx5_txq_start(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Tx queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
        rte_mempool_walk(mlx5_mp2mr_iter, priv);
        ret = mlx5_txq_start(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Tx queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
-               goto error;
+               return -rte_errno;
        }
        ret = mlx5_rxq_start(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Rx queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
        }
        ret = mlx5_rxq_start(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Rx queue allocation failed: %s",
                        dev->data->port_id, strerror(rte_errno));
-               goto error;
+               mlx5_txq_stop(dev);
+               return -rte_errno;
        }
        }
+       dev->data->dev_started = 1;
        ret = mlx5_rx_intr_vec_enable(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Rx interrupt vector creation failed",
        ret = mlx5_rx_intr_vec_enable(dev);
        if (ret) {
                DRV_LOG(ERR, "port %u Rx interrupt vector creation failed",
@@ -254,8 +260,7 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
        dev->tx_pkt_burst = removed_tx_burst;
        rte_wmb();
        usleep(1000 * priv->rxqs_n);
        dev->tx_pkt_burst = removed_tx_burst;
        rte_wmb();
        usleep(1000 * priv->rxqs_n);
-       DRV_LOG(DEBUG, "port %u cleaning up and destroying hash Rx queues",
-               dev->data->port_id);
+       DRV_LOG(DEBUG, "port %u stopping device", dev->data->port_id);
        mlx5_flow_stop(dev, &priv->flows);
        mlx5_traffic_disable(dev);
        mlx5_rx_intr_vec_disable(dev);
        mlx5_flow_stop(dev, &priv->flows);
        mlx5_traffic_disable(dev);
        mlx5_rx_intr_vec_disable(dev);
@@ -336,9 +341,8 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
                        struct rte_flow_item_vlan vlan_spec = {
                                .tci = rte_cpu_to_be_16(vlan),
                        };
                        struct rte_flow_item_vlan vlan_spec = {
                                .tci = rte_cpu_to_be_16(vlan),
                        };
-                       struct rte_flow_item_vlan vlan_mask = {
-                               .tci = 0xffff,
-                       };
+                       struct rte_flow_item_vlan vlan_mask =
+                               rte_flow_item_vlan_mask;
 
                        ret = mlx5_ctrl_flow_vlan(dev, &bcast, &bcast,
                                                  &vlan_spec, &vlan_mask);
 
                        ret = mlx5_ctrl_flow_vlan(dev, &bcast, &bcast,
                                                  &vlan_spec, &vlan_mask);
@@ -375,9 +379,8 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
                        struct rte_flow_item_vlan vlan_spec = {
                                .tci = rte_cpu_to_be_16(vlan),
                        };
                        struct rte_flow_item_vlan vlan_spec = {
                                .tci = rte_cpu_to_be_16(vlan),
                        };
-                       struct rte_flow_item_vlan vlan_mask = {
-                               .tci = 0xffff,
-                       };
+                       struct rte_flow_item_vlan vlan_mask =
+                               rte_flow_item_vlan_mask;
 
                        ret = mlx5_ctrl_flow_vlan(dev, &unicast,
                                                  &unicast_mask,
 
                        ret = mlx5_ctrl_flow_vlan(dev, &unicast,
                                                  &unicast_mask,
index a5c6b58..760ac92 100644 (file)
@@ -467,7 +467,9 @@ mlx5_txq_ibv_new(struct rte_eth_dev *dev, uint16_t idx)
                (volatile struct mlx5_cqe (*)[])
                (uintptr_t)cq_info.buf;
        txq_data->cq_ci = 0;
                (volatile struct mlx5_cqe (*)[])
                (uintptr_t)cq_info.buf;
        txq_data->cq_ci = 0;
+#ifndef NDEBUG
        txq_data->cq_pi = 0;
        txq_data->cq_pi = 0;
+#endif
        txq_data->wqe_ci = 0;
        txq_data->wqe_pi = 0;
        txq_ibv->qp = tmpl.qp;
        txq_data->wqe_ci = 0;
        txq_data->wqe_pi = 0;
        txq_ibv->qp = tmpl.qp;
index d7e9cef..2fc2478 100644 (file)
@@ -1375,9 +1375,12 @@ mrvl_rx_queue_release(void *rxq)
        if (core_id == LCORE_ID_ANY)
                core_id = 0;
 
        if (core_id == LCORE_ID_ANY)
                core_id = 0;
 
+       if (!q)
+               return;
+
        hif = mrvl_get_hif(q->priv, core_id);
 
        hif = mrvl_get_hif(q->priv, core_id);
 
-       if (!q || !hif)
+       if (!hif)
                return;
 
        tc = q->priv->rxq_map[q->queue_id].tc;
                return;
 
        tc = q->priv->rxq_map[q->queue_id].tc;
index d9cd047..8ab28dd 100644 (file)
@@ -2292,11 +2292,15 @@ nfp_net_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                                txq->wr_p = 0;
 
                        pkt_size -= dma_size;
                                txq->wr_p = 0;
 
                        pkt_size -= dma_size;
-                       if (!pkt_size)
-                               /* End of packet */
-                               txds->offset_eop |= PCIE_DESC_TX_EOP;
+
+                       /*
+                        * Making the EOP, packets with just one segment
+                        * the priority
+                        */
+                       if (likely(!pkt_size))
+                               txds->offset_eop = PCIE_DESC_TX_EOP;
                        else
                        else
-                               txds->offset_eop &= PCIE_DESC_TX_OFFSET_MASK;
+                               txds->offset_eop = 0;
 
                        pkt = pkt->next;
                        /* Referencing next free TX descriptor */
 
                        pkt = pkt->next;
                        /* Referencing next free TX descriptor */
@@ -2649,6 +2653,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
 
        pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 
 
        pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 
+       /* NFP can not handle DMA addresses requiring more than 40 bits */
+       if (rte_eal_check_dma_mask(40) < 0) {
+               RTE_LOG(INFO, PMD, "device %s can not be used:",
+                                  pci_dev->device.name);
+               RTE_LOG(INFO, PMD, "\trestricted dma mask to 40 bits!\n");
+               return -ENODEV;
+       };
+
        if ((pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC) ||
            (pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC)) {
                port = get_pf_port_number(eth_dev->data->name);
        if ((pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC) ||
            (pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC)) {
                port = get_pf_port_number(eth_dev->data->name);
@@ -3045,14 +3057,16 @@ static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)
 
 static struct rte_pci_driver rte_nfp_net_pf_pmd = {
        .id_table = pci_id_nfp_pf_net_map,
 
 static struct rte_pci_driver rte_nfp_net_pf_pmd = {
        .id_table = pci_id_nfp_pf_net_map,
-       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+                    RTE_PCI_DRV_IOVA_AS_VA,
        .probe = nfp_pf_pci_probe,
        .remove = eth_nfp_pci_remove,
 };
 
 static struct rte_pci_driver rte_nfp_net_vf_pmd = {
        .id_table = pci_id_nfp_vf_net_map,
        .probe = nfp_pf_pci_probe,
        .remove = eth_nfp_pci_remove,
 };
 
 static struct rte_pci_driver rte_nfp_net_vf_pmd = {
        .id_table = pci_id_nfp_vf_net_map,
-       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+                    RTE_PCI_DRV_IOVA_AS_VA,
        .probe = eth_nfp_pci_probe,
        .remove = eth_nfp_pci_remove,
 };
        .probe = eth_nfp_pci_probe,
        .remove = eth_nfp_pci_remove,
 };
index 33c6e78..13dfbbc 100644 (file)
@@ -377,6 +377,9 @@ octeontx_dev_close(struct rte_eth_dev *dev)
 
                rte_free(txq);
        }
 
                rte_free(txq);
        }
+
+       dev->tx_pkt_burst = NULL;
+       dev->rx_pkt_burst = NULL;
 }
 
 static int
 }
 
 static int
@@ -470,9 +473,6 @@ octeontx_dev_stop(struct rte_eth_dev *dev)
                             ret);
                return;
        }
                             ret);
                return;
        }
-
-       dev->tx_pkt_burst = NULL;
-       dev->rx_pkt_burst = NULL;
 }
 
 static void
 }
 
 static void
index 3994710..f71ba00 100644 (file)
@@ -687,19 +687,19 @@ static const struct eth_dev_ops ops = {
 static int
 open_rx_pcap(const char *key, const char *value, void *extra_args)
 {
 static int
 open_rx_pcap(const char *key, const char *value, void *extra_args)
 {
-       unsigned int i;
        const char *pcap_filename = value;
        struct pmd_devargs *rx = extra_args;
        pcap_t *pcap = NULL;
 
        const char *pcap_filename = value;
        struct pmd_devargs *rx = extra_args;
        pcap_t *pcap = NULL;
 
-       for (i = 0; i < rx->num_of_queue; i++) {
-               if (open_single_rx_pcap(pcap_filename, &pcap) < 0)
-                       return -1;
+       if (rx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
+               return -1;
+       if (open_single_rx_pcap(pcap_filename, &pcap) < 0)
+               return -1;
 
 
-               rx->queue[i].pcap = pcap;
-               rx->queue[i].name = pcap_filename;
-               rx->queue[i].type = key;
-       }
+       rx->queue[rx->num_of_queue].pcap = pcap;
+       rx->queue[rx->num_of_queue].name = pcap_filename;
+       rx->queue[rx->num_of_queue].type = key;
+       rx->num_of_queue++;
 
        return 0;
 }
 
        return 0;
 }
@@ -711,19 +711,19 @@ open_rx_pcap(const char *key, const char *value, void *extra_args)
 static int
 open_tx_pcap(const char *key, const char *value, void *extra_args)
 {
 static int
 open_tx_pcap(const char *key, const char *value, void *extra_args)
 {
-       unsigned int i;
        const char *pcap_filename = value;
        struct pmd_devargs *dumpers = extra_args;
        pcap_dumper_t *dumper;
 
        const char *pcap_filename = value;
        struct pmd_devargs *dumpers = extra_args;
        pcap_dumper_t *dumper;
 
-       for (i = 0; i < dumpers->num_of_queue; i++) {
-               if (open_single_tx_pcap(pcap_filename, &dumper) < 0)
-                       return -1;
+       if (dumpers->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
+               return -1;
+       if (open_single_tx_pcap(pcap_filename, &dumper) < 0)
+               return -1;
 
 
-               dumpers->queue[i].dumper = dumper;
-               dumpers->queue[i].name = pcap_filename;
-               dumpers->queue[i].type = key;
-       }
+       dumpers->queue[dumpers->num_of_queue].dumper = dumper;
+       dumpers->queue[dumpers->num_of_queue].name = pcap_filename;
+       dumpers->queue[dumpers->num_of_queue].type = key;
+       dumpers->num_of_queue++;
 
        return 0;
 }
 
        return 0;
 }
@@ -754,18 +754,18 @@ open_rx_tx_iface(const char *key, const char *value, void *extra_args)
 static inline int
 open_rx_iface(const char *key, const char *value, void *extra_args)
 {
 static inline int
 open_rx_iface(const char *key, const char *value, void *extra_args)
 {
-       unsigned int i;
        const char *iface = value;
        struct pmd_devargs *rx = extra_args;
        pcap_t *pcap = NULL;
 
        const char *iface = value;
        struct pmd_devargs *rx = extra_args;
        pcap_t *pcap = NULL;
 
-       for (i = 0; i < rx->num_of_queue; i++) {
-               if (open_single_iface(iface, &pcap) < 0)
-                       return -1;
-               rx->queue[i].pcap = pcap;
-               rx->queue[i].name = iface;
-               rx->queue[i].type = key;
-       }
+       if (rx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
+               return -1;
+       if (open_single_iface(iface, &pcap) < 0)
+               return -1;
+       rx->queue[rx->num_of_queue].pcap = pcap;
+       rx->queue[rx->num_of_queue].name = iface;
+       rx->queue[rx->num_of_queue].type = key;
+       rx->num_of_queue++;
 
        return 0;
 }
 
        return 0;
 }
@@ -776,18 +776,18 @@ open_rx_iface(const char *key, const char *value, void *extra_args)
 static int
 open_tx_iface(const char *key, const char *value, void *extra_args)
 {
 static int
 open_tx_iface(const char *key, const char *value, void *extra_args)
 {
-       unsigned int i;
        const char *iface = value;
        struct pmd_devargs *tx = extra_args;
        pcap_t *pcap;
 
        const char *iface = value;
        struct pmd_devargs *tx = extra_args;
        pcap_t *pcap;
 
-       for (i = 0; i < tx->num_of_queue; i++) {
-               if (open_single_iface(iface, &pcap) < 0)
-                       return -1;
-               tx->queue[i].pcap = pcap;
-               tx->queue[i].name = iface;
-               tx->queue[i].type = key;
-       }
+       if (tx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
+               return -1;
+       if (open_single_iface(iface, &pcap) < 0)
+               return -1;
+       tx->queue[tx->num_of_queue].pcap = pcap;
+       tx->queue[tx->num_of_queue].name = iface;
+       tx->queue[tx->num_of_queue].type = key;
+       tx->num_of_queue++;
 
        return 0;
 }
 
        return 0;
 }
@@ -977,15 +977,8 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
         * We check whether we want to open a RX stream from a real NIC or a
         * pcap file
         */
         * We check whether we want to open a RX stream from a real NIC or a
         * pcap file
         */
-       pcaps.num_of_queue = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG);
-       if (pcaps.num_of_queue)
-               is_rx_pcap = 1;
-       else
-               pcaps.num_of_queue = rte_kvargs_count(kvlist,
-                               ETH_PCAP_RX_IFACE_ARG);
-
-       if (pcaps.num_of_queue > RTE_PMD_PCAP_MAX_QUEUES)
-               pcaps.num_of_queue = RTE_PMD_PCAP_MAX_QUEUES;
+       is_rx_pcap = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0;
+       pcaps.num_of_queue = 0;
 
        if (is_rx_pcap)
                ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
 
        if (is_rx_pcap)
                ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
@@ -1001,15 +994,8 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
         * We check whether we want to open a TX stream to a real NIC or a
         * pcap file
         */
         * We check whether we want to open a TX stream to a real NIC or a
         * pcap file
         */
-       dumpers.num_of_queue = rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG);
-       if (dumpers.num_of_queue)
-               is_tx_pcap = 1;
-       else
-               dumpers.num_of_queue = rte_kvargs_count(kvlist,
-                               ETH_PCAP_TX_IFACE_ARG);
-
-       if (dumpers.num_of_queue > RTE_PMD_PCAP_MAX_QUEUES)
-               dumpers.num_of_queue = RTE_PMD_PCAP_MAX_QUEUES;
+       is_tx_pcap = rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) ? 1 : 0;
+       dumpers.num_of_queue = 0;
 
        if (is_tx_pcap)
                ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG,
 
        if (is_tx_pcap)
                ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG,
index 9affcbc..092606b 100644 (file)
@@ -2423,9 +2423,8 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
                        }
                }
 
                        }
                }
 
-               /* Log and clean previous pglue_b errors if such exist */
+               /* Log and clear previous pglue_b errors if such exist */
                ecore_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt);
                ecore_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt);
-               ecore_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt);
 
                /* Enable the PF's internal FID_enable in the PXP */
                rc = ecore_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt,
 
                /* Enable the PF's internal FID_enable in the PXP */
                rc = ecore_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt,
@@ -2433,6 +2432,13 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
                if (rc != ECORE_SUCCESS)
                        goto load_err;
 
                if (rc != ECORE_SUCCESS)
                        goto load_err;
 
+               /* Clear the pglue_b was_error indication.
+                * In E4 it must be done after the BME and the internal
+                * FID_enable for the PF are set, since VDMs may cause the
+                * indication to be set again.
+                */
+               ecore_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt);
+
                switch (load_code) {
                case FW_MSG_CODE_DRV_LOAD_ENGINE:
                        rc = ecore_hw_init_common(p_hwfn, p_hwfn->p_main_ptt,
                switch (load_code) {
                case FW_MSG_CODE_DRV_LOAD_ENGINE:
                        rc = ecore_hw_init_common(p_hwfn, p_hwfn->p_main_ptt,
index e6cef85..61e36a4 100644 (file)
@@ -231,15 +231,19 @@ static const char *grc_timeout_attn_master_to_str(u8 master)
 
 static enum _ecore_status_t ecore_grc_attn_cb(struct ecore_hwfn *p_hwfn)
 {
 
 static enum _ecore_status_t ecore_grc_attn_cb(struct ecore_hwfn *p_hwfn)
 {
+       enum _ecore_status_t rc = ECORE_SUCCESS;
        u32 tmp, tmp2;
 
        /* We've already cleared the timeout interrupt register, so we learn
        u32 tmp, tmp2;
 
        /* We've already cleared the timeout interrupt register, so we learn
-        * of interrupts via the validity register
+        * of interrupts via the validity register.
+        * Any attention which is not for a timeout event is treated as fatal.
         */
        tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
                       GRC_REG_TIMEOUT_ATTN_ACCESS_VALID);
         */
        tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
                       GRC_REG_TIMEOUT_ATTN_ACCESS_VALID);
-       if (!(tmp & ECORE_GRC_ATTENTION_VALID_BIT))
+       if (!(tmp & ECORE_GRC_ATTENTION_VALID_BIT)) {
+               rc = ECORE_INVAL;
                goto out;
                goto out;
+       }
 
        /* Read the GRC timeout information */
        tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
 
        /* Read the GRC timeout information */
        tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
@@ -263,11 +267,11 @@ static enum _ecore_status_t ecore_grc_attn_cb(struct ecore_hwfn *p_hwfn)
                  (tmp2 & ECORE_GRC_ATTENTION_VF_MASK) >>
                  ECORE_GRC_ATTENTION_VF_SHIFT);
 
                  (tmp2 & ECORE_GRC_ATTENTION_VF_MASK) >>
                  ECORE_GRC_ATTENTION_VF_SHIFT);
 
-out:
-       /* Regardles of anything else, clean the validity bit */
+       /* Clean the validity bit */
        ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt,
                 GRC_REG_TIMEOUT_ATTN_ACCESS_VALID, 0);
        ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt,
                 GRC_REG_TIMEOUT_ATTN_ACCESS_VALID, 0);
-       return ECORE_SUCCESS;
+out:
+       return rc;
 }
 
 #define ECORE_PGLUE_ATTENTION_VALID (1 << 29)
 }
 
 #define ECORE_PGLUE_ATTENTION_VALID (1 << 29)
index 68f40f8..1c885e1 100644 (file)
@@ -61,6 +61,8 @@ const char *ecore_channel_tlvs_string[] = {
        "CHANNEL_TLV_COALESCE_UPDATE",
        "CHANNEL_TLV_QID",
        "CHANNEL_TLV_COALESCE_READ",
        "CHANNEL_TLV_COALESCE_UPDATE",
        "CHANNEL_TLV_QID",
        "CHANNEL_TLV_COALESCE_READ",
+       "CHANNEL_TLV_BULLETIN_UPDATE_MAC",
+       "CHANNEL_TLV_UPDATE_MTU",
        "CHANNEL_TLV_MAX"
 };
 
        "CHANNEL_TLV_MAX"
 };
 
@@ -2854,6 +2856,45 @@ out:
                               length, status);
 }
 
                               length, status);
 }
 
+static enum _ecore_status_t
+ecore_iov_vf_pf_update_mtu(struct ecore_hwfn *p_hwfn,
+                                   struct ecore_ptt *p_ptt,
+                                   struct ecore_vf_info *p_vf)
+{
+       struct ecore_iov_vf_mbx *mbx = &p_vf->vf_mbx;
+       struct ecore_sp_vport_update_params params;
+       enum _ecore_status_t rc = ECORE_SUCCESS;
+       struct vfpf_update_mtu_tlv *p_req;
+       u8 status = PFVF_STATUS_SUCCESS;
+
+       /* Valiate PF can send such a request */
+       if (!p_vf->vport_instance) {
+               DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+                          "No VPORT instance available for VF[%d], failing MTU update\n",
+                          p_vf->abs_vf_id);
+               status = PFVF_STATUS_FAILURE;
+               goto send_status;
+       }
+
+       p_req = &mbx->req_virt->update_mtu;
+
+       OSAL_MEMSET(&params, 0, sizeof(params));
+       params.opaque_fid =  p_vf->opaque_fid;
+       params.vport_id = p_vf->vport_id;
+       params.mtu = p_req->mtu;
+       rc = ecore_sp_vport_update(p_hwfn, &params, ECORE_SPQ_MODE_EBLOCK,
+                                  OSAL_NULL);
+
+       if (rc)
+               status = PFVF_STATUS_FAILURE;
+send_status:
+       ecore_iov_prepare_resp(p_hwfn, p_ptt, p_vf,
+                              CHANNEL_TLV_UPDATE_MTU,
+                              sizeof(struct pfvf_def_resp_tlv),
+                              status);
+       return rc;
+}
+
 void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn,
                                 void *p_tlvs_list, u16 req_type)
 {
 void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn,
                                 void *p_tlvs_list, u16 req_type)
 {
@@ -4136,6 +4177,9 @@ void ecore_iov_process_mbx_req(struct ecore_hwfn *p_hwfn,
                case CHANNEL_TLV_COALESCE_READ:
                        ecore_iov_vf_pf_get_coalesce(p_hwfn, p_ptt, p_vf);
                        break;
                case CHANNEL_TLV_COALESCE_READ:
                        ecore_iov_vf_pf_get_coalesce(p_hwfn, p_ptt, p_vf);
                        break;
+               case CHANNEL_TLV_UPDATE_MTU:
+                       ecore_iov_vf_pf_update_mtu(p_hwfn, p_ptt, p_vf);
+                       break;
                }
        } else if (ecore_iov_tlv_supported(mbx->first_tlv.tl.type)) {
                /* If we've received a message from a VF we consider malicious
                }
        } else if (ecore_iov_tlv_supported(mbx->first_tlv.tl.type)) {
                /* If we've received a message from a VF we consider malicious
index 8a08911..334db6b 100644 (file)
@@ -1628,6 +1628,39 @@ exit:
        return rc;
 }
 
        return rc;
 }
 
+enum _ecore_status_t
+ecore_vf_pf_update_mtu(struct ecore_hwfn *p_hwfn, u16 mtu)
+{
+       struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
+       struct vfpf_update_mtu_tlv *p_req;
+       struct pfvf_def_resp_tlv *p_resp;
+       enum _ecore_status_t rc;
+
+       if (!mtu)
+               return ECORE_INVAL;
+
+       /* clear mailbox and prep header tlv */
+       p_req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_UPDATE_MTU,
+                                sizeof(*p_req));
+       p_req->mtu = mtu;
+       DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
+                  "Requesting MTU update to %d\n", mtu);
+
+       /* add list termination tlv */
+       ecore_add_tlv(&p_iov->offset,
+                     CHANNEL_TLV_LIST_END,
+                     sizeof(struct channel_list_end_tlv));
+
+       p_resp = &p_iov->pf2vf_reply->default_resp;
+       rc = ecore_send_msg2pf(p_hwfn, &p_resp->hdr.status, sizeof(*p_resp));
+       if (p_resp->hdr.status == PFVF_STATUS_NOT_SUPPORTED)
+               rc = ECORE_INVAL;
+
+       ecore_vf_pf_req_end(p_hwfn, rc);
+
+       return rc;
+}
+
 u16 ecore_vf_get_igu_sb_id(struct ecore_hwfn *p_hwfn,
                           u16               sb_id)
 {
 u16 ecore_vf_get_igu_sb_id(struct ecore_hwfn *p_hwfn,
                           u16               sb_id)
 {
index de2758c..e5555bb 100644 (file)
@@ -319,5 +319,14 @@ void ecore_vf_set_vf_start_tunn_update_param(struct ecore_tunnel_info *p_tun);
 
 u32 ecore_vf_hw_bar_size(struct ecore_hwfn *p_hwfn,
                     enum BAR_ID bar_id);
 
 u32 ecore_vf_hw_bar_size(struct ecore_hwfn *p_hwfn,
                     enum BAR_ID bar_id);
+
+/**
+ * @brief - ecore_vf_pf_update_mtu Update MTU for VF.
+ *
+ * @param p_hwfn
+ * @param - mtu
+ */
+enum _ecore_status_t
+ecore_vf_pf_update_mtu(struct ecore_hwfn *p_hwfn, u16 mtu);
 #endif
 #endif /* __ECORE_VF_H__ */
 #endif
 #endif /* __ECORE_VF_H__ */
index c6af9ca..08b1f24 100644 (file)
@@ -531,6 +531,18 @@ struct pfvf_read_coal_resp_tlv {
        u8 padding[6];
 };
 
        u8 padding[6];
 };
 
+struct vfpf_bulletin_update_mac_tlv {
+       struct vfpf_first_tlv first_tlv;
+       u8 mac[ETH_ALEN];
+       u8 padding[2];
+};
+
+struct vfpf_update_mtu_tlv {
+       struct vfpf_first_tlv first_tlv;
+       u16 mtu;
+       u8 padding[6];
+};
+
 union vfpf_tlvs {
        struct vfpf_first_tlv                   first_tlv;
        struct vfpf_acquire_tlv                 acquire;
 union vfpf_tlvs {
        struct vfpf_first_tlv                   first_tlv;
        struct vfpf_acquire_tlv                 acquire;
@@ -545,6 +557,8 @@ union vfpf_tlvs {
        struct vfpf_update_tunn_param_tlv       tunn_param_update;
        struct vfpf_update_coalesce             update_coalesce;
        struct vfpf_read_coal_req_tlv           read_coal_req;
        struct vfpf_update_tunn_param_tlv       tunn_param_update;
        struct vfpf_update_coalesce             update_coalesce;
        struct vfpf_read_coal_req_tlv           read_coal_req;
+       struct vfpf_bulletin_update_mac_tlv     bulletin_update_mac;
+       struct vfpf_update_mtu_tlv              update_mtu;
        struct tlv_buffer_size                  tlv_buf_size;
 };
 
        struct tlv_buffer_size                  tlv_buf_size;
 };
 
@@ -675,6 +689,8 @@ enum {
        CHANNEL_TLV_COALESCE_UPDATE,
        CHANNEL_TLV_QID,
        CHANNEL_TLV_COALESCE_READ,
        CHANNEL_TLV_COALESCE_UPDATE,
        CHANNEL_TLV_QID,
        CHANNEL_TLV_COALESCE_READ,
+       CHANNEL_TLV_BULLETIN_UPDATE_MAC,
+       CHANNEL_TLV_UPDATE_MTU,
        CHANNEL_TLV_MAX,
 
        /* Required for iterating over vport-update tlvs.
        CHANNEL_TLV_MAX,
 
        /* Required for iterating over vport-update tlvs.
index 7462f1a..4a5e485 100644 (file)
@@ -335,6 +335,24 @@ static void qede_interrupt_action(struct ecore_hwfn *p_hwfn)
        ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn));
 }
 
        ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn));
 }
 
+static void
+qede_interrupt_handler_intx(void *param)
+{
+       struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+       struct qede_dev *qdev = eth_dev->data->dev_private;
+       struct ecore_dev *edev = &qdev->edev;
+       u64 status;
+
+       /* Check if our device actually raised an interrupt */
+       status = ecore_int_igu_read_sisr_reg(ECORE_LEADING_HWFN(edev));
+       if (status & 0x1) {
+               qede_interrupt_action(ECORE_LEADING_HWFN(edev));
+
+               if (rte_intr_enable(eth_dev->intr_handle))
+                       DP_ERR(edev, "rte_intr_enable failed\n");
+       }
+}
+
 static void
 qede_interrupt_handler(void *param)
 {
 static void
 qede_interrupt_handler(void *param)
 {
@@ -516,12 +534,9 @@ int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg)
        params.update_vport_active_tx_flg = 1;
        params.vport_active_rx_flg = flg;
        params.vport_active_tx_flg = flg;
        params.update_vport_active_tx_flg = 1;
        params.vport_active_rx_flg = flg;
        params.vport_active_tx_flg = flg;
-       if (!qdev->enable_tx_switching) {
-               if (IS_VF(edev)) {
-                       params.update_tx_switching_flg = 1;
-                       params.tx_switching_flg = !flg;
-                       DP_INFO(edev, "VF tx-switching is disabled\n");
-               }
+       if (~qdev->enable_tx_switching & flg) {
+               params.update_tx_switching_flg = 1;
+               params.tx_switching_flg = !flg;
        }
        for_each_hwfn(edev, i) {
                p_hwfn = &edev->hwfns[i];
        }
        for_each_hwfn(edev, i) {
                p_hwfn = &edev->hwfns[i];
@@ -597,37 +612,6 @@ int qede_enable_tpa(struct rte_eth_dev *eth_dev, bool flg)
        return 0;
 }
 
        return 0;
 }
 
-/* Update MTU via vport-update without doing port restart.
- * The vport must be deactivated before calling this API.
- */
-int qede_update_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu)
-{
-       struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
-       struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
-       struct ecore_sp_vport_update_params params;
-       struct ecore_hwfn *p_hwfn;
-       int rc;
-       int i;
-
-       memset(&params, 0, sizeof(struct ecore_sp_vport_update_params));
-       params.vport_id = 0;
-       params.mtu = mtu;
-       params.vport_id = 0;
-       for_each_hwfn(edev, i) {
-               p_hwfn = &edev->hwfns[i];
-               params.opaque_fid = p_hwfn->hw_info.opaque_fid;
-               rc = ecore_sp_vport_update(p_hwfn, &params,
-                               ECORE_SPQ_MODE_EBLOCK, NULL);
-               if (rc != ECORE_SUCCESS) {
-                       DP_ERR(edev, "Failed to update MTU\n");
-                       return -1;
-               }
-       }
-       DP_INFO(edev, "MTU updated to %u\n", mtu);
-
-       return 0;
-}
-
 static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
 {
        memset(ucast, 0, sizeof(struct ecore_filter_ucast));
 static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
 {
        memset(ucast, 0, sizeof(struct ecore_filter_ucast));
@@ -861,7 +845,10 @@ qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
        if (rc == 0)
                rc = ecore_filter_ucast_cmd(edev, ucast,
                                            ECORE_SPQ_MODE_CB, NULL);
        if (rc == 0)
                rc = ecore_filter_ucast_cmd(edev, ucast,
                                            ECORE_SPQ_MODE_CB, NULL);
-       if (rc != ECORE_SUCCESS)
+       /* Indicate error only for add filter operation.
+        * Delete filter operations are not severe.
+        */
+       if ((rc != ECORE_SUCCESS) && add)
                DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n",
                       rc, add);
 
                DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n",
                       rc, add);
 
@@ -875,7 +862,11 @@ qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
        struct ecore_filter_ucast ucast;
        int re;
 
        struct ecore_filter_ucast ucast;
        int re;
 
+       if (!is_valid_assigned_ether_addr(mac_addr))
+               return -EINVAL;
+
        qede_set_ucast_cmn_params(&ucast);
        qede_set_ucast_cmn_params(&ucast);
+       ucast.opcode = ECORE_FILTER_ADD;
        ucast.type = ECORE_FILTER_MAC;
        ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
        re = (int)qede_mac_int_ops(eth_dev, &ucast, 1);
        ucast.type = ECORE_FILTER_MAC;
        ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
        re = (int)qede_mac_int_ops(eth_dev, &ucast, 1);
@@ -897,6 +888,9 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
                return;
        }
 
                return;
        }
 
+       if (!is_valid_assigned_ether_addr(&eth_dev->data->mac_addrs[index]))
+               return;
+
        qede_set_ucast_cmn_params(&ucast);
        ucast.opcode = ECORE_FILTER_REMOVE;
        ucast.type = ECORE_FILTER_MAC;
        qede_set_ucast_cmn_params(&ucast);
        ucast.opcode = ECORE_FILTER_REMOVE;
        ucast.type = ECORE_FILTER_MAC;
@@ -922,6 +916,7 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
                return;
        }
 
                return;
        }
 
+       qede_mac_addr_remove(eth_dev, 0);
        qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
 }
 
        qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
 }
 
@@ -1182,6 +1177,12 @@ static int qede_dev_start(struct rte_eth_dev *eth_dev)
 
        PMD_INIT_FUNC_TRACE(edev);
 
 
        PMD_INIT_FUNC_TRACE(edev);
 
+       /* Update MTU only if it has changed */
+       if (eth_dev->data->mtu != qdev->mtu) {
+               if (qede_update_mtu(eth_dev, qdev->mtu))
+                       goto err;
+       }
+
        /* Configure TPA parameters */
        if (rxmode->enable_lro) {
                if (qede_enable_tpa(eth_dev, true))
        /* Configure TPA parameters */
        if (rxmode->enable_lro) {
                if (qede_enable_tpa(eth_dev, true))
@@ -1245,16 +1246,13 @@ static void qede_dev_stop(struct rte_eth_dev *eth_dev)
        /* Disable traffic */
        ecore_hw_stop_fastpath(edev); /* TBD - loop */
 
        /* Disable traffic */
        ecore_hw_stop_fastpath(edev); /* TBD - loop */
 
-       if (IS_PF(edev))
-               qede_mac_addr_remove(eth_dev, 0);
-
        DP_INFO(edev, "Device is stopped\n");
 }
 
        DP_INFO(edev, "Device is stopped\n");
 }
 
-#define QEDE_TX_SWITCHING              "vf_txswitch"
+#define QEDE_VF_TX_SWITCHING           "vf_tx_switching"
 
 const char *valid_args[] = {
 
 const char *valid_args[] = {
-       QEDE_TX_SWITCHING,
+       QEDE_VF_TX_SWITCHING,
        NULL,
 };
 
        NULL,
 };
 
@@ -1264,9 +1262,7 @@ static int qede_args_check(const char *key, const char *val, void *opaque)
        int ret = 0;
        struct rte_eth_dev *eth_dev = opaque;
        struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
        int ret = 0;
        struct rte_eth_dev *eth_dev = opaque;
        struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
-#ifdef RTE_LIBRTE_QEDE_DEBUG_INFO
        struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
        struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
-#endif
 
        errno = 0;
        tmp = strtoul(val, NULL, 0);
 
        errno = 0;
        tmp = strtoul(val, NULL, 0);
@@ -1275,8 +1271,10 @@ static int qede_args_check(const char *key, const char *val, void *opaque)
                return errno;
        }
 
                return errno;
        }
 
-       if (strcmp(QEDE_TX_SWITCHING, key) == 0)
+       if (strcmp(QEDE_VF_TX_SWITCHING, key) == 0 && IS_VF(edev)) {
                qdev->enable_tx_switching = !!tmp;
                qdev->enable_tx_switching = !!tmp;
+               DP_INFO(edev, "Disabling VF tx-switching\n");
+       }
 
        return ret;
 }
 
        return ret;
 }
@@ -1351,7 +1349,8 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 
        /* Parse devargs and fix up rxmode */
        if (qede_args(eth_dev))
 
        /* Parse devargs and fix up rxmode */
        if (qede_args(eth_dev))
-               return -ENOTSUP;
+               DP_NOTICE(edev, false,
+                         "Invalid devargs supplied, requested change will not take effect\n");
 
        /* Sanity checks and throw warnings */
        if (rxmode->enable_scatter)
 
        /* Sanity checks and throw warnings */
        if (rxmode->enable_scatter)
@@ -1392,8 +1391,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 
        /* Enable VLAN offloads by default */
        ret = qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK  |
 
        /* Enable VLAN offloads by default */
        ret = qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK  |
-                       ETH_VLAN_FILTER_MASK |
-                       ETH_VLAN_EXTEND_MASK);
+                                            ETH_VLAN_FILTER_MASK);
        if (ret)
                return ret;
 
        if (ret)
                return ret;
 
@@ -1491,7 +1489,7 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
 {
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
 {
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
-       uint16_t link_duplex;
+       uint16_t link_duplex, old_link_status;
        struct qed_link_output link;
        struct rte_eth_link *curr = &eth_dev->data->dev_link;
 
        struct qed_link_output link;
        struct rte_eth_link *curr = &eth_dev->data->dev_link;
 
@@ -1516,6 +1514,7 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
        curr->link_duplex = link_duplex;
 
        /* Link Status */
        curr->link_duplex = link_duplex;
 
        /* Link Status */
+       old_link_status = curr->link_status;
        curr->link_status = (link.link_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
        /* AN */
        curr->link_status = (link.link_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
        /* AN */
@@ -1527,7 +1526,7 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
                curr->link_autoneg, curr->link_status);
 
        /* return 0 means link status changed, -1 means not changed */
                curr->link_autoneg, curr->link_status);
 
        /* return 0 means link status changed, -1 means not changed */
-       return ((curr->link_status == link.link_up) ? -1 : 0);
+       return ((curr->link_status == old_link_status) ? -1 : 0);
 }
 
 static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 }
 
 static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
@@ -1613,8 +1612,20 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
        qdev->ops->common->slowpath_stop(edev);
        qdev->ops->common->remove(edev);
        rte_intr_disable(&pci_dev->intr_handle);
        qdev->ops->common->slowpath_stop(edev);
        qdev->ops->common->remove(edev);
        rte_intr_disable(&pci_dev->intr_handle);
-       rte_intr_callback_unregister(&pci_dev->intr_handle,
-                                    qede_interrupt_handler, (void *)eth_dev);
+
+       switch (pci_dev->intr_handle.type) {
+       case RTE_INTR_HANDLE_UIO_INTX:
+       case RTE_INTR_HANDLE_VFIO_LEGACY:
+               rte_intr_callback_unregister(&pci_dev->intr_handle,
+                                            qede_interrupt_handler_intx,
+                                            (void *)eth_dev);
+               break;
+       default:
+               rte_intr_callback_unregister(&pci_dev->intr_handle,
+                                          qede_interrupt_handler,
+                                          (void *)eth_dev);
+       }
+
        if (ECORE_IS_CMT(edev))
                rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev);
 }
        if (ECORE_IS_CMT(edev))
                rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev);
 }
@@ -1932,6 +1943,70 @@ qede_set_mc_addr_list(struct rte_eth_dev *eth_dev, struct ether_addr *mc_addrs,
        return qede_add_mcast_filters(eth_dev, mc_addrs, mc_addrs_num);
 }
 
        return qede_add_mcast_filters(eth_dev, mc_addrs, mc_addrs_num);
 }
 
+/* Update MTU via vport-update without doing port restart.
+ * The vport must be deactivated before calling this API.
+ */
+int qede_update_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu)
+{
+       struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+       struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+       struct ecore_hwfn *p_hwfn;
+       int rc;
+       int i;
+
+       if (IS_PF(edev)) {
+               struct ecore_sp_vport_update_params params;
+
+               memset(&params, 0, sizeof(struct ecore_sp_vport_update_params));
+               params.vport_id = 0;
+               params.mtu = mtu;
+               params.vport_id = 0;
+               for_each_hwfn(edev, i) {
+                       p_hwfn = &edev->hwfns[i];
+                       params.opaque_fid = p_hwfn->hw_info.opaque_fid;
+                       rc = ecore_sp_vport_update(p_hwfn, &params,
+                                       ECORE_SPQ_MODE_EBLOCK, NULL);
+                       if (rc != ECORE_SUCCESS)
+                               goto err;
+               }
+       } else {
+               for_each_hwfn(edev, i) {
+                       p_hwfn = &edev->hwfns[i];
+                       rc = ecore_vf_pf_update_mtu(p_hwfn, mtu);
+                       if (rc == ECORE_INVAL) {
+                               DP_INFO(edev, "VF MTU Update TLV not supported\n");
+                               /* Recreate vport */
+                               rc = qede_start_vport(qdev, mtu);
+                               if (rc != ECORE_SUCCESS)
+                                       goto err;
+
+                               /* Restore config lost due to vport stop */
+                               if (eth_dev->data->promiscuous)
+                                       qede_promiscuous_enable(eth_dev);
+                               else
+                                       qede_promiscuous_disable(eth_dev);
+
+                               if (eth_dev->data->all_multicast)
+                                       qede_allmulticast_enable(eth_dev);
+                               else
+                                       qede_allmulticast_disable(eth_dev);
+
+                               qede_vlan_offload_set(eth_dev,
+                                                     qdev->vlan_offload_mask);
+                       } else if (rc != ECORE_SUCCESS) {
+                               goto err;
+                       }
+               }
+       }
+       DP_INFO(edev, "%s MTU updated to %u\n", IS_PF(edev) ? "PF" : "VF", mtu);
+
+       return 0;
+
+err:
+       DP_ERR(edev, "Failed to update MTU\n");
+       return -1;
+}
+
 static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev,
                              struct rte_eth_fc_conf *fc_conf)
 {
 static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev,
                              struct rte_eth_fc_conf *fc_conf)
 {
@@ -2332,12 +2407,8 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
                dev->data->dev_started = 0;
                qede_dev_stop(dev);
                restart = true;
                dev->data->dev_started = 0;
                qede_dev_stop(dev);
                restart = true;
-       } else {
-               if (IS_PF(edev))
-                       qede_mac_addr_remove(dev, 0);
        }
        rte_delay_ms(1000);
        }
        rte_delay_ms(1000);
-       qede_start_vport(qdev, mtu); /* Recreate vport */
        qdev->mtu = mtu;
 
        /* Fix up RX buf size for all queues of the port */
        qdev->mtu = mtu;
 
        /* Fix up RX buf size for all queues of the port */
@@ -2361,22 +2432,6 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        else
                dev->data->dev_conf.rxmode.jumbo_frame = 0;
 
        else
                dev->data->dev_conf.rxmode.jumbo_frame = 0;
 
-       /* Restore config lost due to vport stop */
-       if (IS_PF(edev))
-               qede_mac_addr_set(dev, &qdev->primary_mac);
-
-       if (dev->data->promiscuous)
-               qede_promiscuous_enable(dev);
-       else
-               qede_promiscuous_disable(dev);
-
-       if (dev->data->all_multicast)
-               qede_allmulticast_enable(dev);
-       else
-               qede_allmulticast_disable(dev);
-
-       qede_vlan_offload_set(dev, qdev->vlan_offload_mask);
-
        if (!dev->data->dev_started && restart) {
                qede_dev_start(dev);
                dev->data->dev_started = 1;
        if (!dev->data->dev_started && restart) {
                qede_dev_start(dev);
                dev->data->dev_started = 1;
@@ -2792,6 +2847,9 @@ static const struct eth_dev_ops qede_eth_vf_dev_ops = {
        .mtu_set = qede_set_mtu,
        .udp_tunnel_port_add = qede_udp_dst_port_add,
        .udp_tunnel_port_del = qede_udp_dst_port_del,
        .mtu_set = qede_set_mtu,
        .udp_tunnel_port_add = qede_udp_dst_port_add,
        .udp_tunnel_port_del = qede_udp_dst_port_del,
+       .mac_addr_add = qede_mac_addr_add,
+       .mac_addr_remove = qede_mac_addr_remove,
+       .mac_addr_set = qede_mac_addr_set,
 };
 
 static void qede_update_pf_params(struct ecore_dev *edev)
 };
 
 static void qede_update_pf_params(struct ecore_dev *edev)
@@ -2820,6 +2878,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
        /* Fix up ecore debug level */
        uint32_t dp_module = ~0 & ~ECORE_MSG_HW;
        uint8_t dp_level = ECORE_LEVEL_VERBOSE;
        /* Fix up ecore debug level */
        uint32_t dp_module = ~0 & ~ECORE_MSG_HW;
        uint8_t dp_level = ECORE_LEVEL_VERBOSE;
+       uint32_t int_mode;
        int rc;
 
        /* Extract key data structures */
        int rc;
 
        /* Extract key data structures */
@@ -2864,8 +2923,22 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
                return -ENODEV;
        }
        qede_update_pf_params(edev);
                return -ENODEV;
        }
        qede_update_pf_params(edev);
-       rte_intr_callback_register(&pci_dev->intr_handle,
-                                  qede_interrupt_handler, (void *)eth_dev);
+
+       switch (pci_dev->intr_handle.type) {
+       case RTE_INTR_HANDLE_UIO_INTX:
+       case RTE_INTR_HANDLE_VFIO_LEGACY:
+               int_mode = ECORE_INT_MODE_INTA;
+               rte_intr_callback_register(&pci_dev->intr_handle,
+                                          qede_interrupt_handler_intx,
+                                          (void *)eth_dev);
+               break;
+       default:
+               int_mode = ECORE_INT_MODE_MSIX;
+               rte_intr_callback_register(&pci_dev->intr_handle,
+                                          qede_interrupt_handler,
+                                          (void *)eth_dev);
+       }
+
        if (rte_intr_enable(&pci_dev->intr_handle)) {
                DP_ERR(edev, "rte_intr_enable() failed\n");
                return -ENODEV;
        if (rte_intr_enable(&pci_dev->intr_handle)) {
                DP_ERR(edev, "rte_intr_enable() failed\n");
                return -ENODEV;
@@ -2873,7 +2946,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 
        /* Start the Slowpath-process */
        memset(&params, 0, sizeof(struct qed_slowpath_params));
 
        /* Start the Slowpath-process */
        memset(&params, 0, sizeof(struct qed_slowpath_params));
-       params.int_mode = ECORE_INT_MODE_MSIX;
+
+       params.int_mode = int_mode;
        params.drv_major = QEDE_PMD_VERSION_MAJOR;
        params.drv_minor = QEDE_PMD_VERSION_MINOR;
        params.drv_rev = QEDE_PMD_VERSION_REVISION;
        params.drv_major = QEDE_PMD_VERSION_MAJOR;
        params.drv_minor = QEDE_PMD_VERSION_MINOR;
        params.drv_rev = QEDE_PMD_VERSION_REVISION;
@@ -2956,7 +3030,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
                                                ECORE_LEADING_HWFN(edev),
                                                vf_mac,
                                                &is_mac_forced);
                                                ECORE_LEADING_HWFN(edev),
                                                vf_mac,
                                                &is_mac_forced);
-                       if (is_mac_exist && is_mac_forced) {
+                       if (is_mac_exist) {
                                DP_INFO(edev, "VF macaddr received from PF\n");
                                ether_addr_copy((struct ether_addr *)&vf_mac,
                                                &eth_dev->data->mac_addrs[0]);
                                DP_INFO(edev, "VF macaddr received from PF\n");
                                ether_addr_copy((struct ether_addr *)&vf_mac,
                                                &eth_dev->data->mac_addrs[0]);
index 2145aa6..cc1a409 100644 (file)
@@ -34,6 +34,7 @@
 #include "base/nvm_cfg.h"
 #include "base/ecore_sp_commands.h"
 #include "base/ecore_l2.h"
 #include "base/nvm_cfg.h"
 #include "base/ecore_sp_commands.h"
 #include "base/ecore_l2.h"
+#include "base/ecore_vf.h"
 
 #include "qede_logs.h"
 #include "qede_if.h"
 
 #include "qede_logs.h"
 #include "qede_if.h"
index 153ef96..0515256 100644 (file)
@@ -465,5 +465,8 @@ int qede_ntuple_filter_conf(struct rte_eth_dev *eth_dev,
                udpv4_flow->src_port = ntuple->src_port;
                udpv4_flow->dst_port = ntuple->dst_port;
        }
                udpv4_flow->src_port = ntuple->src_port;
                udpv4_flow->dst_port = ntuple->dst_port;
        }
+
+       fdir_entry.action.rx_queue = ntuple->queue;
+
        return qede_config_cmn_fdir_filter(eth_dev, &fdir_entry, add);
 }
        return qede_config_cmn_fdir_filter(eth_dev, &fdir_entry, add);
 }
index ae18732..95b4cd9 100644 (file)
@@ -279,7 +279,7 @@ static int qed_slowpath_start(struct ecore_dev *edev,
        /* Start the slowpath */
        memset(&hw_init_params, 0, sizeof(hw_init_params));
        hw_init_params.b_hw_start = true;
        /* Start the slowpath */
        memset(&hw_init_params, 0, sizeof(hw_init_params));
        hw_init_params.b_hw_start = true;
-       hw_init_params.int_mode = ECORE_INT_MODE_MSIX;
+       hw_init_params.int_mode = params->int_mode;
        hw_init_params.allow_npar_tx_switch = true;
        hw_init_params.bin_fw_data = data;
 
        hw_init_params.allow_npar_tx_switch = true;
        hw_init_params.bin_fw_data = data;
 
@@ -633,8 +633,11 @@ void qed_link_update(struct ecore_hwfn *hwfn)
 {
        struct ecore_dev *edev = hwfn->p_dev;
        struct qede_dev *qdev = (struct qede_dev *)edev;
 {
        struct ecore_dev *edev = hwfn->p_dev;
        struct qede_dev *qdev = (struct qede_dev *)edev;
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev;
 
 
-       qede_link_update((struct rte_eth_dev *)qdev->ethdev, 0);
+       if (!qede_link_update(dev, 0))
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+                                             NULL, NULL);
 }
 
 static int qed_drain(struct ecore_dev *edev)
 }
 
 static int qed_drain(struct ecore_dev *edev)
index 4c76f74..bd2cbd0 100644 (file)
@@ -296,6 +296,8 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
                /* Override Layer 2 packet type */
                l2_ptype = RTE_PTYPE_L2_ETHER_ARP;
                break;
                /* Override Layer 2 packet type */
                l2_ptype = RTE_PTYPE_L2_ETHER_ARP;
                break;
+       case ESE_DZ_L3_CLASS_UNKNOWN:
+               break;
        default:
                /* Unexpected Layer 3 class */
                SFC_ASSERT(false);
        default:
                /* Unexpected Layer 3 class */
                SFC_ASSERT(false);
index fabcc32..1b160b5 100644 (file)
@@ -1030,7 +1030,7 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
        if (rc != 0)
                sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
 
        if (rc != 0)
                sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
 
-       SFC_ASSERT(rc > 0);
+       SFC_ASSERT(rc >= 0);
        return -rc;
 }
 
        return -rc;
 }
 
index fddc670..90ef5bf 100644 (file)
@@ -330,7 +330,8 @@ sfc_flow_parse_vlan(const struct rte_flow_item *item,
         * the outer tag and the next matches the inner tag.
         */
        if (mask->tci == supp_mask.tci) {
         * the outer tag and the next matches the inner tag.
         */
        if (mask->tci == supp_mask.tci) {
-               vid = rte_bswap16(spec->tci);
+               /* Apply mask to keep VID only */
+               vid = rte_bswap16(spec->tci & mask->tci);
 
                if (!(efx_spec->efs_match_flags &
                      EFX_FILTER_MATCH_OUTER_VID)) {
 
                if (!(efx_spec->efs_match_flags &
                      EFX_FILTER_MATCH_OUTER_VID)) {
index ffc0b85..f10bbf6 100644 (file)
@@ -464,7 +464,7 @@ tap_flow_create_eth(const struct rte_flow_item *item, void *data)
        if (!flow)
                return 0;
        msg = &flow->msg;
        if (!flow)
                return 0;
        msg = &flow->msg;
-       if (!is_zero_ether_addr(&spec->dst)) {
+       if (!is_zero_ether_addr(&mask->dst)) {
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_DST, ETHER_ADDR_LEN,
                           &spec->dst.addr_bytes);
                nlattr_add(&msg->nh,
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_ETH_DST, ETHER_ADDR_LEN,
                           &spec->dst.addr_bytes);
                nlattr_add(&msg->nh,
@@ -570,13 +570,13 @@ tap_flow_create_ipv4(const struct rte_flow_item *item, void *data)
                info->eth_type = htons(ETH_P_IP);
        if (!spec)
                return 0;
                info->eth_type = htons(ETH_P_IP);
        if (!spec)
                return 0;
-       if (spec->hdr.dst_addr) {
+       if (mask->hdr.dst_addr) {
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST,
                             spec->hdr.dst_addr);
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST_MASK,
                             mask->hdr.dst_addr);
        }
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST,
                             spec->hdr.dst_addr);
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_DST_MASK,
                             mask->hdr.dst_addr);
        }
-       if (spec->hdr.src_addr) {
+       if (mask->hdr.src_addr) {
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC,
                             spec->hdr.src_addr);
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC_MASK,
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC,
                             spec->hdr.src_addr);
                nlattr_add32(&msg->nh, TCA_FLOWER_KEY_IPV4_SRC_MASK,
@@ -626,13 +626,13 @@ tap_flow_create_ipv6(const struct rte_flow_item *item, void *data)
                info->eth_type = htons(ETH_P_IPV6);
        if (!spec)
                return 0;
                info->eth_type = htons(ETH_P_IPV6);
        if (!spec)
                return 0;
-       if (memcmp(spec->hdr.dst_addr, empty_addr, 16)) {
+       if (memcmp(mask->hdr.dst_addr, empty_addr, 16)) {
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST,
                           sizeof(spec->hdr.dst_addr), &spec->hdr.dst_addr);
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST_MASK,
                           sizeof(mask->hdr.dst_addr), &mask->hdr.dst_addr);
        }
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST,
                           sizeof(spec->hdr.dst_addr), &spec->hdr.dst_addr);
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_DST_MASK,
                           sizeof(mask->hdr.dst_addr), &mask->hdr.dst_addr);
        }
-       if (memcmp(spec->hdr.src_addr, empty_addr, 16)) {
+       if (memcmp(mask->hdr.src_addr, empty_addr, 16)) {
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC,
                           sizeof(spec->hdr.src_addr), &spec->hdr.src_addr);
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC_MASK,
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC,
                           sizeof(spec->hdr.src_addr), &spec->hdr.src_addr);
                nlattr_add(&msg->nh, TCA_FLOWER_KEY_IPV6_SRC_MASK,
@@ -680,10 +680,10 @@ tap_flow_create_udp(const struct rte_flow_item *item, void *data)
        nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_UDP);
        if (!spec)
                return 0;
        nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_UDP);
        if (!spec)
                return 0;
-       if (spec->hdr.dst_port & mask->hdr.dst_port)
+       if (mask->hdr.dst_port)
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_DST,
                             spec->hdr.dst_port);
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_DST,
                             spec->hdr.dst_port);
-       if (spec->hdr.src_port & mask->hdr.src_port)
+       if (mask->hdr.src_port)
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_SRC,
                             spec->hdr.src_port);
        return 0;
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_UDP_SRC,
                             spec->hdr.src_port);
        return 0;
@@ -726,10 +726,10 @@ tap_flow_create_tcp(const struct rte_flow_item *item, void *data)
        nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_TCP);
        if (!spec)
                return 0;
        nlattr_add8(&msg->nh, TCA_FLOWER_KEY_IP_PROTO, IPPROTO_TCP);
        if (!spec)
                return 0;
-       if (spec->hdr.dst_port & mask->hdr.dst_port)
+       if (mask->hdr.dst_port)
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_DST,
                             spec->hdr.dst_port);
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_DST,
                             spec->hdr.dst_port);
-       if (spec->hdr.src_port & mask->hdr.src_port)
+       if (mask->hdr.src_port)
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_SRC,
                             spec->hdr.src_port);
        return 0;
                nlattr_add16(&msg->nh, TCA_FLOWER_KEY_TCP_SRC,
                             spec->hdr.src_port);
        return 0;
index c62371c..3843084 100644 (file)
@@ -897,7 +897,7 @@ nicvf_dev_tx_queue_release(void *sq)
 static void
 nicvf_set_tx_function(struct rte_eth_dev *dev)
 {
 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;
 
        size_t i;
        bool multiseg = false;
 
@@ -918,6 +918,9 @@ nicvf_set_tx_function(struct rte_eth_dev *dev)
                dev->tx_pkt_burst = nicvf_xmit_pkts;
        }
 
                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
        if (txq->pool_free == nicvf_single_pool_free_xmited_buffers)
                PMD_DRV_LOG(DEBUG, "Using single-mempool tx free method");
        else
index 9d69cf4..06cbc46 100644 (file)
@@ -190,12 +190,14 @@ nicvf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                free_desc -= TX_DESC_PER_PKT;
        }
 
                free_desc -= TX_DESC_PER_PKT;
        }
 
-       sq->tail = tail;
-       sq->xmit_bufs += i;
-       rte_wmb();
+       if (likely(i)) {
+               sq->tail = tail;
+               sq->xmit_bufs += i;
+               rte_wmb();
 
 
-       /* Inform HW to xmit the packets */
-       nicvf_addr_write(sq->sq_door, i * TX_DESC_PER_PKT);
+               /* Inform HW to xmit the packets */
+               nicvf_addr_write(sq->sq_door, i * TX_DESC_PER_PKT);
+       }
        return i;
 }
 
        return i;
 }
 
@@ -246,12 +248,14 @@ nicvf_xmit_pkts_multiseg(void *tx_queue, struct rte_mbuf **tx_pkts,
                }
        }
 
                }
        }
 
-       sq->tail = tail;
-       sq->xmit_bufs += used_bufs;
-       rte_wmb();
+       if (likely(used_desc)) {
+               sq->tail = tail;
+               sq->xmit_bufs += used_bufs;
+               rte_wmb();
 
 
-       /* Inform HW to xmit the packets */
-       nicvf_addr_write(sq->sq_door, used_desc);
+               /* Inform HW to xmit the packets */
+               nicvf_addr_write(sq->sq_door, used_desc);
+       }
        return i;
 }
 
        return i;
 }
 
index dc1d964..ba081e3 100644 (file)
@@ -164,6 +164,9 @@ print_stats(void)
               " Lcore    Port            RX            TX    Dropped on TX\n"
               "-------  ------  ------------  ------------  ---------------\n");
        RTE_LCORE_FOREACH(i) {
               " Lcore    Port            RX            TX    Dropped on TX\n"
               "-------  ------  ------------  ------------  ---------------\n");
        RTE_LCORE_FOREACH(i) {
+               /* limit ourselves to application supported cores only */
+               if (i >= APP_MAX_LCORE)
+                       break;
                printf("%6u %7u %13"PRIu64" %13"PRIu64" %16"PRIu64"\n",
                       i, (unsigned)port_ids[i],
                       lcore_stats[i].rx, lcore_stats[i].tx,
                printf("%6u %7u %13"PRIu64" %13"PRIu64" %16"PRIu64"\n",
                       i, (unsigned)port_ids[i],
                       lcore_stats[i].rx, lcore_stats[i].tx,
index 7d739b4..fe512da 100644 (file)
@@ -149,6 +149,22 @@ init_port(void)
                        /**< CRC stripped by hardware */
                        .hw_strip_crc   = 1,
                },
                        /**< CRC stripped by hardware */
                        .hw_strip_crc   = 1,
                },
+               /*
+                * Initialize fdir_conf of rte_eth_conf.
+                * Fdir is used in flow filtering for I40e,
+                * so rte_flow rules involve some fdir
+                * configurations. In long term it's better
+                * that drivers don't require any fdir
+                * configuration for rte_flow, but we need to
+                * get this workaround so that sample app can
+                * run on I40e.
+                */
+               .fdir_conf = {
+                       .mode = RTE_FDIR_MODE_PERFECT,
+                       .pballoc = RTE_FDIR_PBALLOC_64K,
+                       .status = RTE_FDIR_REPORT_STATUS,
+                       .drop_queue = 127,
+               },
        };
 
        printf(":: initializing port: %d\n", port_id);
        };
 
        printf(":: initializing port: %d\n", port_id);
index e75eed7..1c945c9 100644 (file)
@@ -352,7 +352,7 @@ tm_cfgfile_load_sched_subport(
                                        char name[CFG_NAME_LEN + 1];
 
                                        profile = atoi(entries[j].value);
                                        char name[CFG_NAME_LEN + 1];
 
                                        profile = atoi(entries[j].value);
-                                       strncpy(name,
+                                       memcpy(name,
                                                entries[j].name,
                                                sizeof(name));
                                        n_tokens = rte_strsplit(
                                                entries[j].name,
                                                sizeof(name));
                                        n_tokens = rte_strsplit(
index b5ec70a..46af3f0 100644 (file)
@@ -302,6 +302,7 @@ prepare_tx_pkt(struct rte_mbuf *pkt, uint16_t port)
                pkt->l3_len = sizeof(struct ip);
                pkt->l2_len = ETHER_HDR_LEN;
 
                pkt->l3_len = sizeof(struct ip);
                pkt->l2_len = ETHER_HDR_LEN;
 
+               ip->ip_sum = 0;
                ethhdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
        } else {
                pkt->ol_flags |= PKT_TX_IPV6;
                ethhdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
        } else {
                pkt->ol_flags |= PKT_TX_IPV6;
@@ -475,11 +476,13 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip,
                sa_idx = ip->res[i] & PROTECT_MASK;
                if (ip->res[i] & DISCARD)
                        rte_pktmbuf_free(m);
                sa_idx = ip->res[i] & PROTECT_MASK;
                if (ip->res[i] & DISCARD)
                        rte_pktmbuf_free(m);
+               else if (ip->res[i] & BYPASS)
+                       ip->pkts[j++] = m;
                else if (sa_idx < IPSEC_SA_MAX_ENTRIES) {
                        ipsec->res[ipsec->num] = sa_idx;
                        ipsec->pkts[ipsec->num++] = m;
                else if (sa_idx < IPSEC_SA_MAX_ENTRIES) {
                        ipsec->res[ipsec->num] = sa_idx;
                        ipsec->pkts[ipsec->num++] = m;
-               } else /* BYPASS */
-                       ip->pkts[j++] = m;
+               } else /* invalid SA idx */
+                       rte_pktmbuf_free(m);
        }
        ip->num = j;
 }
        }
        ip->num = j;
 }
index 9d0ea46..e0881b7 100644 (file)
@@ -544,7 +544,7 @@ parse_cfg_file(const char *cfg_filename)
                                goto error_exit;
                        }
 
                                goto error_exit;
                        }
 
-                       strncpy(str + strlen(str), oneline,
+                       memcpy(str + strlen(str), oneline,
                                strlen(oneline));
 
                        continue;
                                strlen(oneline));
 
                        continue;
index ff57522..77af7e6 100644 (file)
@@ -439,7 +439,7 @@ l2fwd_simple_crypto_enqueue(struct rte_mbuf *m,
        /* Zero pad data to be crypto'd so it is block aligned */
        data_len  = rte_pktmbuf_data_len(m) - ipdata_offset;
 
        /* Zero pad data to be crypto'd so it is block aligned */
        data_len  = rte_pktmbuf_data_len(m) - ipdata_offset;
 
-       if (cparams->do_hash && cparams->hash_verify)
+       if ((cparams->do_hash || cparams->do_aead) && cparams->hash_verify)
                data_len -= cparams->digest_length;
 
        if (cparams->do_cipher) {
                data_len -= cparams->digest_length;
 
        if (cparams->do_cipher) {
@@ -2081,10 +2081,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
 
                        options->block_size = cap->sym.aead.block_size;
 
 
                        options->block_size = cap->sym.aead.block_size;
 
-                       check_iv_param(&cap->sym.aead.iv_size,
+                       if (check_iv_param(&cap->sym.aead.iv_size,
                                        options->aead_iv_param,
                                        options->aead_iv_random_size,
                                        options->aead_iv_param,
                                        options->aead_iv_random_size,
-                                       &options->aead_iv.length);
+                                       &options->aead_iv.length) < 0)
+                               continue;
 
                        /*
                         * Check if length of provided AEAD key is supported
 
                        /*
                         * Check if length of provided AEAD key is supported
@@ -2098,7 +2099,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.aead.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported aead key length\n");
                                                cap->sym.aead.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported aead key length\n");
-                                       return -1;
+                                       continue;
                                }
                        /*
                         * Check if length of the aead key to be randomly generated
                                }
                        /*
                         * Check if length of the aead key to be randomly generated
@@ -2111,7 +2112,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.aead.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported aead key length\n");
                                                cap->sym.aead.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported aead key length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->aead_xform.aead.key.length =
                                                        options->aead_key_random_size;
                                }
                                options->aead_xform.aead.key.length =
                                                        options->aead_key_random_size;
@@ -2136,7 +2137,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.aead.aad_size.increment)
                                                        != 0) {
                                        printf("Unsupported AAD length\n");
                                                cap->sym.aead.aad_size.increment)
                                                        != 0) {
                                        printf("Unsupported AAD length\n");
-                                       return -1;
+                                       continue;
                                }
                        /*
                         * Check if length of AAD to be randomly generated
                                }
                        /*
                         * Check if length of AAD to be randomly generated
@@ -2149,7 +2150,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.aead.aad_size.increment)
                                                        != 0) {
                                        printf("Unsupported AAD length\n");
                                                cap->sym.aead.aad_size.increment)
                                                        != 0) {
                                        printf("Unsupported AAD length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->aad.length = options->aad_random_size;
                        /* No size provided, use minimum size. */
                                }
                                options->aad.length = options->aad_random_size;
                        /* No size provided, use minimum size. */
@@ -2167,7 +2168,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.aead.digest_size.increment)
                                                        != 0) {
                                        printf("Unsupported digest length\n");
                                                cap->sym.aead.digest_size.increment)
                                                        != 0) {
                                        printf("Unsupported digest length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->aead_xform.aead.digest_length =
                                                        options->digest_size;
                                }
                                options->aead_xform.aead.digest_length =
                                                        options->digest_size;
@@ -2189,10 +2190,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
 
                        options->block_size = cap->sym.cipher.block_size;
 
 
                        options->block_size = cap->sym.cipher.block_size;
 
-                       check_iv_param(&cap->sym.cipher.iv_size,
+                       if (check_iv_param(&cap->sym.cipher.iv_size,
                                        options->cipher_iv_param,
                                        options->cipher_iv_random_size,
                                        options->cipher_iv_param,
                                        options->cipher_iv_random_size,
-                                       &options->cipher_iv.length);
+                                       &options->cipher_iv.length) < 0)
+                               continue;
 
                        /*
                         * Check if length of provided cipher key is supported
 
                        /*
                         * Check if length of provided cipher key is supported
@@ -2206,7 +2208,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.cipher.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported cipher key length\n");
                                                cap->sym.cipher.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported cipher key length\n");
-                                       return -1;
+                                       continue;
                                }
                        /*
                         * Check if length of the cipher key to be randomly generated
                                }
                        /*
                         * Check if length of the cipher key to be randomly generated
@@ -2219,7 +2221,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.cipher.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported cipher key length\n");
                                                cap->sym.cipher.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported cipher key length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->cipher_xform.cipher.key.length =
                                                        options->ckey_random_size;
                                }
                                options->cipher_xform.cipher.key.length =
                                                        options->ckey_random_size;
@@ -2245,10 +2247,11 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                        if (cap == NULL)
                                continue;
 
                        if (cap == NULL)
                                continue;
 
-                       check_iv_param(&cap->sym.auth.iv_size,
+                       if (check_iv_param(&cap->sym.auth.iv_size,
                                        options->auth_iv_param,
                                        options->auth_iv_random_size,
                                        options->auth_iv_param,
                                        options->auth_iv_random_size,
-                                       &options->auth_iv.length);
+                                       &options->auth_iv.length) < 0)
+                               continue;
                        /*
                         * Check if length of provided auth key is supported
                         * by the algorithm chosen.
                        /*
                         * Check if length of provided auth key is supported
                         * by the algorithm chosen.
@@ -2261,7 +2264,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.auth.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported auth key length\n");
                                                cap->sym.auth.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported auth key length\n");
-                                       return -1;
+                                       continue;
                                }
                        /*
                         * Check if length of the auth key to be randomly generated
                                }
                        /*
                         * Check if length of the auth key to be randomly generated
@@ -2274,7 +2277,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.auth.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported auth key length\n");
                                                cap->sym.auth.key_size.increment)
                                                        != 0) {
                                        printf("Unsupported auth key length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->auth_xform.auth.key.length =
                                                        options->akey_random_size;
                                }
                                options->auth_xform.auth.key.length =
                                                        options->akey_random_size;
@@ -2296,7 +2299,7 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
                                                cap->sym.auth.digest_size.increment)
                                                        != 0) {
                                        printf("Unsupported digest length\n");
                                                cap->sym.auth.digest_size.increment)
                                                        != 0) {
                                        printf("Unsupported digest length\n");
-                                       return -1;
+                                       continue;
                                }
                                options->auth_xform.auth.digest_length =
                                                        options->digest_size;
                                }
                                options->auth_xform.auth.digest_length =
                                                        options->digest_size;
index 2b7c173..cc7a835 100644 (file)
@@ -47,7 +47,6 @@
 #include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
-#include <rte_mempool.h>
 #include <rte_cycles.h>
 #include <rte_mbuf.h>
 #include <rte_ip.h>
 #include <rte_cycles.h>
 #include <rte_mbuf.h>
 #include <rte_ip.h>
index 2d0e172..c185e5e 100644 (file)
@@ -46,7 +46,6 @@
 #include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
-#include <rte_mempool.h>
 #include <rte_cycles.h>
 #include <rte_mbuf.h>
 #include <rte_ip.h>
 #include <rte_cycles.h>
 #include <rte_mbuf.h>
 #include <rte_ip.h>
index fd430ec..47c5c83 100644 (file)
@@ -210,7 +210,7 @@ vhost_bdev_scsi_inquiry_command(struct vhost_block_dev *bdev,
                        break;
                case SPC_VPD_UNIT_SERIAL_NUMBER:
                        hlen = 4;
                        break;
                case SPC_VPD_UNIT_SERIAL_NUMBER:
                        hlen = 4;
-                       strncpy((char *)vpage->params, bdev->name, 32);
+                       memcpy((char *)vpage->params, bdev->name, 32);
                        vpage->alloc_len = rte_cpu_to_be_16(32);
                        break;
                case SPC_VPD_DEVICE_IDENTIFICATION:
                        vpage->alloc_len = rte_cpu_to_be_16(32);
                        break;
                case SPC_VPD_DEVICE_IDENTIFICATION:
@@ -247,7 +247,7 @@ vhost_bdev_scsi_inquiry_command(struct vhost_block_dev *bdev,
                        strncpy((char *)desig->desig, "INTEL", 8);
                        vhost_strcpy_pad((char *)&desig->desig[8],
                                         bdev->product_name, 16, ' ');
                        strncpy((char *)desig->desig, "INTEL", 8);
                        vhost_strcpy_pad((char *)&desig->desig[8],
                                         bdev->product_name, 16, ' ');
-                       strncpy((char *)&desig->desig[24], bdev->name, 32);
+                       memcpy((char *)&desig->desig[24], bdev->name, 32);
                        len += sizeof(struct scsi_desig_desc) + 8 + 16 + 32;
 
                        buf += sizeof(struct scsi_desig_desc) + desig->len;
                        len += sizeof(struct scsi_desig_desc) + 8 + 16 + 32;
 
                        buf += sizeof(struct scsi_desig_desc) + desig->len;
@@ -312,7 +312,7 @@ vhost_bdev_scsi_inquiry_command(struct vhost_block_dev *bdev,
                                bdev->product_name);
 
                /* PRODUCT REVISION LEVEL */
                                bdev->product_name);
 
                /* PRODUCT REVISION LEVEL */
-               strncpy((char *)inqdata->product_rev, "0001", 4);
+               memcpy((char *)inqdata->product_rev, "0001", 4);
 
                /* Standard inquiry data ends here. Only populate
                 * remaining fields if alloc_len indicates enough
 
                /* Standard inquiry data ends here. Only populate
                 * remaining fields if alloc_len indicates enough
index f373697..d39edbf 100644 (file)
@@ -76,6 +76,9 @@ rte_stats_bitrate_reg(struct rte_stats_bitrates *bitrate_data)
        };
        int return_value;
 
        };
        int return_value;
 
+       if (bitrate_data == NULL)
+               return -EINVAL;
+
        return_value = rte_metrics_reg_names(&names[0], ARRAY_SIZE(names));
        if (return_value >= 0)
                bitrate_data->id_stats_set = return_value;
        return_value = rte_metrics_reg_names(&names[0], ARRAY_SIZE(names));
        if (return_value >= 0)
                bitrate_data->id_stats_set = return_value;
@@ -94,6 +97,9 @@ rte_stats_bitrate_calc(struct rte_stats_bitrates *bitrate_data,
        const int64_t alpha_percent = 20;
        uint64_t values[6];
 
        const int64_t alpha_percent = 20;
        uint64_t values[6];
 
+       if (bitrate_data == NULL)
+               return -EINVAL;
+
        ret_code = rte_eth_stats_get(port_id, &eth_stats);
        if (ret_code != 0)
                return ret_code;
        ret_code = rte_eth_stats_get(port_id, &eth_stats);
        if (ret_code != 0)
                return ret_code;
index fc6c44d..a0922f1 100644 (file)
@@ -109,6 +109,49 @@ rte_dump_physmem_layout(FILE *f)
        }
 }
 
        }
 }
 
+/* 63 bits is good enough for a sanity check */
+#define MAX_DMA_MASK_BITS 63
+
+/* check memseg iovas are within the required range based on dma mask */
+int
+rte_eal_check_dma_mask(uint8_t maskbits)
+{
+
+       const struct rte_mem_config *mcfg;
+       uint64_t mask;
+       int i;
+
+       /* sanity check */
+       if (maskbits > MAX_DMA_MASK_BITS) {
+               RTE_LOG(INFO, EAL, "wrong dma mask size %u (Max: %u)\n",
+                                  maskbits, MAX_DMA_MASK_BITS);
+               return -1;
+       }
+
+       /* create dma mask */
+       mask = ~((1ULL << maskbits) - 1);
+
+       /* get pointer to global configuration */
+       mcfg = rte_eal_get_configuration()->mem_config;
+
+       for (i = 0; i < RTE_MAX_MEMSEG; i++) {
+               if (mcfg->memseg[i].addr == NULL)
+                       break;
+
+               if (mcfg->memseg[i].iova & mask) {
+                       RTE_LOG(INFO, EAL,
+                               "memseg[%d] iova %"PRIx64" out of range:\n",
+                               i, mcfg->memseg[i].iova);
+
+                       RTE_LOG(INFO, EAL, "\tusing dma mask %"PRIx64"\n",
+                               mask);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 /* return the number of memory channels */
 unsigned rte_memory_get_nchannel(void)
 {
 /* return the number of memory channels */
 unsigned rte_memory_get_nchannel(void)
 {
index b9067e6..13bfd9c 100644 (file)
@@ -227,12 +227,12 @@ rte_bitmap_get_memory_footprint(uint32_t n_bits) {
 /**
  * Bitmap initialization
  *
 /**
  * Bitmap initialization
  *
- * @param mem_size
- *   Minimum expected size of bitmap.
+ * @param n_bits
+ *   Number of pre-allocated bits in array2.
  * @param mem
  *   Base address of array1 and array2.
  * @param mem
  *   Base address of array1 and array2.
- * @param n_bits
- *   Number of pre-allocated bits in array2. Must be non-zero and multiple of 512.
+ * @param mem_size
+ *   Minimum expected size of bitmap.
  * @return
  *   Handle to bitmap instance.
  */
  * @return
  *   Handle to bitmap instance.
  */
index 80a8fc0..b2a0168 100644 (file)
@@ -209,6 +209,9 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
  */
 unsigned rte_memory_get_nrank(void);
 
+/* check memsegs iovas are within a range based on dma mask */
+int rte_eal_check_dma_mask(uint8_t maskbits);
+
 /**
  * Drivers based on uio will not load unless physical
  * addresses are obtainable. It is only possible to get
 /**
  * Drivers based on uio will not load unless physical
  * addresses are obtainable. It is only possible to get
index 99ae35e..4d0a9f7 100644 (file)
@@ -66,7 +66,7 @@ extern "C" {
 /**
  * Patch level number i.e. the z in yy.mm.z
  */
 /**
  * Patch level number i.e. the z in yy.mm.z
  */
-#define RTE_VER_MINOR 3
+#define RTE_VER_MINOR 4
 
 /**
  * Extra string to be appended to version number
 
 /**
  * Extra string to be appended to version number
index 1c20693..e1179b8 100644 (file)
@@ -449,7 +449,7 @@ rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
        TAILQ_FOREACH(src, &intr_sources, next) {
                if (src->intr_handle.fd == intr_handle->fd) {
                        /* we had no interrupts for this */
        TAILQ_FOREACH(src, &intr_sources, next) {
                if (src->intr_handle.fd == intr_handle->fd) {
                        /* we had no interrupts for this */
-                       if TAILQ_EMPTY(&src->callbacks)
+                       if (TAILQ_EMPTY(&src->callbacks))
                                wake_thread = 1;
 
                        TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
                                wake_thread = 1;
 
                        TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
index 17c20d4..bac969a 100644 (file)
 
 static uint64_t baseaddr_offset;
 
 
 static uint64_t baseaddr_offset;
 
+#ifdef RTE_ARCH_64
+/*
+ * Linux kernel uses a really high address as starting address for serving
+ * mmaps calls. If there exists addressing limitations and IOVA mode is VA,
+ * this starting address is likely too high for those devices. However, it
+ * is possible to use a lower address in the process virtual address space
+ * as with 64 bits there is a lot of available space.
+ *
+ * Current known limitations are 39 or 40 bits. Setting the starting address
+ * at 4GB implies there are 508GB or 1020GB for mapping the available
+ * hugepages. This is likely enough for most systems, although a device with
+ * addressing limitations should call rte_dev_check_dma_mask for ensuring all
+ * memory is within supported range.
+ */
+static uint64_t baseaddr = 0x100000000;
+#endif
+
 static bool phys_addrs_available = true;
 
 #define RANDOMIZE_VA_SPACE_FILE "/proc/sys/kernel/randomize_va_space"
 static bool phys_addrs_available = true;
 
 #define RANDOMIZE_VA_SPACE_FILE "/proc/sys/kernel/randomize_va_space"
@@ -95,7 +112,7 @@ static bool phys_addrs_available = true;
 static void
 test_phys_addrs_available(void)
 {
 static void
 test_phys_addrs_available(void)
 {
-       uint64_t tmp;
+       uint64_t tmp = 0;
        phys_addr_t physaddr;
 
        if (!rte_eal_has_hugepages()) {
        phys_addr_t physaddr;
 
        if (!rte_eal_has_hugepages()) {
@@ -250,6 +267,23 @@ aslr_enabled(void)
        }
 }
 
        }
 }
 
+static void *
+get_addr_hint(void)
+{
+       if (internal_config.base_virtaddr != 0) {
+               return (void *) (uintptr_t)
+                           (internal_config.base_virtaddr +
+                            baseaddr_offset);
+       } else {
+#ifdef RTE_ARCH_64
+               return (void *) (uintptr_t) (baseaddr +
+                               baseaddr_offset);
+#else
+               return NULL;
+#endif
+       }
+}
+
 /*
  * Try to mmap *size bytes in /dev/zero. If it is successful, return the
  * pointer to the mmap'd area and keep *size unmodified. Else, retry
 /*
  * Try to mmap *size bytes in /dev/zero. If it is successful, return the
  * pointer to the mmap'd area and keep *size unmodified. Else, retry
@@ -260,16 +294,10 @@ aslr_enabled(void)
 static void *
 get_virtual_area(size_t *size, size_t hugepage_sz)
 {
 static void *
 get_virtual_area(size_t *size, size_t hugepage_sz)
 {
-       void *addr;
+       void *addr, *addr_hint;
        int fd;
        long aligned_addr;
 
        int fd;
        long aligned_addr;
 
-       if (internal_config.base_virtaddr != 0) {
-               addr = (void*) (uintptr_t) (internal_config.base_virtaddr +
-                               baseaddr_offset);
-       }
-       else addr = NULL;
-
        RTE_LOG(DEBUG, EAL, "Ask a virtual area of 0x%zx bytes\n", *size);
 
        fd = open("/dev/zero", O_RDONLY);
        RTE_LOG(DEBUG, EAL, "Ask a virtual area of 0x%zx bytes\n", *size);
 
        fd = open("/dev/zero", O_RDONLY);
@@ -278,7 +306,9 @@ get_virtual_area(size_t *size, size_t hugepage_sz)
                return NULL;
        }
        do {
                return NULL;
        }
        do {
-               addr = mmap(addr,
+               addr_hint = get_addr_hint();
+
+               addr = mmap(addr_hint,
                                (*size) + hugepage_sz, PROT_READ,
 #ifdef RTE_ARCH_PPC_64
                                MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
                                (*size) + hugepage_sz, PROT_READ,
 #ifdef RTE_ARCH_PPC_64
                                MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
@@ -286,8 +316,15 @@ get_virtual_area(size_t *size, size_t hugepage_sz)
                                MAP_PRIVATE,
 #endif
                                fd, 0);
                                MAP_PRIVATE,
 #endif
                                fd, 0);
-               if (addr == MAP_FAILED)
+               if (addr == MAP_FAILED) {
+                       /* map failed. Let's try with less memory */
                        *size -= hugepage_sz;
                        *size -= hugepage_sz;
+               } else if (addr_hint && addr != addr_hint) {
+                       /* hint was not used. Try with another offset */
+                       munmap(addr, (*size) + hugepage_sz);
+                       addr = MAP_FAILED;
+                       baseaddr_offset += 0x100000000;
+               }
        } while (addr == MAP_FAILED && *size > 0);
 
        if (addr == MAP_FAILED) {
        } while (addr == MAP_FAILED && *size > 0);
 
        if (addr == MAP_FAILED) {
index e9a579e..c3947d7 100644 (file)
@@ -205,7 +205,7 @@ int rte_sys_gettid(void)
 
 int rte_thread_setname(pthread_t id, const char *name)
 {
 
 int rte_thread_setname(pthread_t id, const char *name)
 {
-       int ret = -1;
+       int ret = ENOSYS;
 #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
 #if __GLIBC_PREREQ(2, 12)
        ret = pthread_setname_np(id, name);
 #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
 #if __GLIBC_PREREQ(2, 12)
        ret = pthread_setname_np(id, name);
@@ -213,5 +213,5 @@ int rte_thread_setname(pthread_t id, const char *name)
 #endif
        RTE_SET_USED(id);
        RTE_SET_USED(name);
 #endif
        RTE_SET_USED(id);
        RTE_SET_USED(name);
-       return ret;
+       return -ret;
 }
 }
index 95e262b..aed14bc 100644 (file)
@@ -826,9 +826,10 @@ static void igb_get_drvinfo(struct net_device *netdev,
        strncpy(drvinfo->driver,  igb_driver_name, sizeof(drvinfo->driver) - 1);
        strncpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version) - 1);
 
        strncpy(drvinfo->driver,  igb_driver_name, sizeof(drvinfo->driver) - 1);
        strncpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version) - 1);
 
-       strncpy(drvinfo->fw_version, adapter->fw_version,
-               sizeof(drvinfo->fw_version) - 1);
-       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), sizeof(drvinfo->bus_info) -1);
+       strlcpy(drvinfo->fw_version, adapter->fw_version,
+               sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+               sizeof(drvinfo->bus_info));
        drvinfo->n_stats = IGB_STATS_LEN;
        drvinfo->testinfo_len = IGB_TEST_LEN;
        drvinfo->regdump_len = igb_get_regs_len(netdev);
        drvinfo->n_stats = IGB_STATS_LEN;
        drvinfo->testinfo_len = IGB_TEST_LEN;
        drvinfo->regdump_len = igb_get_regs_len(netdev);
index 6691edf..6b73891 100644 (file)
@@ -3944,6 +3944,11 @@ skb_set_hash(struct sk_buff *skb, __u32 hash, __always_unused int type)
 #endif
 #endif
 
 #endif
 #endif
 
+#if (defined(RHEL_RELEASE_CODE) && \
+       (RHEL_RELEASE_VERSION(7, 5) <= RHEL_RELEASE_CODE))
+#define ndo_change_mtu ndo_change_mtu_rh74
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
 #define HAVE_PCI_ENABLE_MSIX
 #endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
 #define HAVE_PCI_ENABLE_MSIX
 #endif
index f4f46c1..aa6cf87 100644 (file)
@@ -184,6 +184,7 @@ DPDK_17.11 {
 
        rte_eal_create_uio_dev;
        rte_bus_get_iommu_class;
 
        rte_eal_create_uio_dev;
        rte_bus_get_iommu_class;
+       rte_eal_check_dma_mask;
        rte_eal_has_pci;
        rte_eal_iova_mode;
        rte_eal_mbuf_default_mempool_ops;
        rte_eal_has_pci;
        rte_eal_iova_mode;
        rte_eal_mbuf_default_mempool_ops;
index eba11ca..47e37a6 100644 (file)
@@ -1877,7 +1877,6 @@ struct rte_eth_dev *rte_eth_dev_allocated(const char *name);
  * to that slot for the driver to use.
  *
  * @param      name    Unique identifier name for each Ethernet device
  * to that slot for the driver to use.
  *
  * @param      name    Unique identifier name for each Ethernet device
- * @param      type    Device type of this Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
@@ -2543,7 +2542,7 @@ void rte_eth_xstats_reset(uint16_t port_id);
  * @param stat_idx
  *   The per-queue packet statistics functionality number that the transmit
  *   queue is to be assigned.
  * @param stat_idx
  *   The per-queue packet statistics functionality number that the transmit
  *   queue is to be assigned.
- *   The value must be in the range [0, RTE_MAX_ETHPORT_QUEUE_STATS_MAPS - 1].
+ *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
  * @return
  *   Zero if successful. Non-zero otherwise.
  */
  * @return
  *   Zero if successful. Non-zero otherwise.
  */
@@ -2563,7 +2562,7 @@ int rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id,
  * @param stat_idx
  *   The per-queue packet statistics functionality number that the receive
  *   queue is to be assigned.
  * @param stat_idx
  *   The per-queue packet statistics functionality number that the receive
  *   queue is to be assigned.
- *   The value must be in the range [0, RTE_MAX_ETHPORT_QUEUE_STATS_MAPS - 1].
+ *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
  * @return
  *   Zero if successful. Non-zero otherwise.
  */
  * @return
  *   Zero if successful. Non-zero otherwise.
  */
index 90106e6..d5c3fd5 100644 (file)
@@ -87,6 +87,8 @@ struct rte_event_eth_rx_adapter {
        int socket_id;
        /* Per adapter EAL service */
        uint32_t service_id;
        int socket_id;
        /* Per adapter EAL service */
        uint32_t service_id;
+       /* Adapter started flag */
+       uint8_t rxa_started;
 } __rte_cache_aligned;
 
 /* Per eth device */
 } __rte_cache_aligned;
 
 /* Per eth device */
@@ -220,6 +222,8 @@ eth_poll_wrr_calc(struct rte_event_eth_rx_adapter *rx_adapter)
                        nb_rx_queues = dev_info->dev->data->nb_rx_queues;
                        if (dev_info->rx_queue == NULL)
                                continue;
                        nb_rx_queues = dev_info->dev->data->nb_rx_queues;
                        if (dev_info->rx_queue == NULL)
                                continue;
+                       if (dev_info->internal_event_port)
+                               continue;
                        for (q = 0; q < nb_rx_queues; q++) {
                                struct eth_rx_queue_info *queue_info =
                                        &dev_info->rx_queue[q];
                        for (q = 0; q < nb_rx_queues; q++) {
                                struct eth_rx_queue_info *queue_info =
                                        &dev_info->rx_queue[q];
@@ -414,14 +418,14 @@ flush_event_buffer(struct rte_event_eth_rx_adapter *rx_adapter)
 
 static inline void
 fill_event_buffer(struct rte_event_eth_rx_adapter *rx_adapter,
 
 static inline void
 fill_event_buffer(struct rte_event_eth_rx_adapter *rx_adapter,
-       uint8_t dev_id,
+       uint16_t eth_dev_id,
        uint16_t rx_queue_id,
        struct rte_mbuf **mbufs,
        uint16_t num)
 {
        uint32_t i;
        struct eth_device_info *eth_device_info =
        uint16_t rx_queue_id,
        struct rte_mbuf **mbufs,
        uint16_t num)
 {
        uint32_t i;
        struct eth_device_info *eth_device_info =
-                                       &rx_adapter->eth_devices[dev_id];
+                                       &rx_adapter->eth_devices[eth_dev_id];
        struct eth_rx_queue_info *eth_rx_queue_info =
                                        &eth_device_info->rx_queue[rx_queue_id];
 
        struct eth_rx_queue_info *eth_rx_queue_info =
                                        &eth_device_info->rx_queue[rx_queue_id];
 
@@ -476,7 +480,7 @@ fill_event_buffer(struct rte_event_eth_rx_adapter *rx_adapter,
  * the hypervisor's switching layer where adjustments can be made to deal with
  * it.
  */
  * the hypervisor's switching layer where adjustments can be made to deal with
  * it.
  */
-static inline uint32_t
+static inline void
 eth_rx_poll(struct rte_event_eth_rx_adapter *rx_adapter)
 {
        uint32_t num_queue;
 eth_rx_poll(struct rte_event_eth_rx_adapter *rx_adapter)
 {
        uint32_t num_queue;
@@ -503,8 +507,10 @@ eth_rx_poll(struct rte_event_eth_rx_adapter *rx_adapter)
                 */
                if (buf->count >= BATCH_SIZE)
                        flush_event_buffer(rx_adapter);
                 */
                if (buf->count >= BATCH_SIZE)
                        flush_event_buffer(rx_adapter);
-               if (BATCH_SIZE > (ETH_EVENT_BUFFER_SIZE - buf->count))
-                       break;
+               if (BATCH_SIZE > (ETH_EVENT_BUFFER_SIZE - buf->count)) {
+                       rx_adapter->wrr_pos = wrr_pos;
+                       return;
+               }
 
                stats->rx_poll_count++;
                n = rte_eth_rx_burst(d, qid, mbufs, BATCH_SIZE);
 
                stats->rx_poll_count++;
                n = rte_eth_rx_burst(d, qid, mbufs, BATCH_SIZE);
@@ -519,7 +525,7 @@ eth_rx_poll(struct rte_event_eth_rx_adapter *rx_adapter)
                        if (nb_rx > max_nb_rx) {
                                rx_adapter->wrr_pos =
                                    (wrr_pos + 1) % rx_adapter->wrr_len;
                        if (nb_rx > max_nb_rx) {
                                rx_adapter->wrr_pos =
                                    (wrr_pos + 1) % rx_adapter->wrr_len;
-                               return nb_rx;
+                               break;
                        }
                }
 
                        }
                }
 
@@ -527,20 +533,22 @@ eth_rx_poll(struct rte_event_eth_rx_adapter *rx_adapter)
                        wrr_pos = 0;
        }
 
                        wrr_pos = 0;
        }
 
-       return nb_rx;
+       if (buf->count >= BATCH_SIZE)
+               flush_event_buffer(rx_adapter);
 }
 
 static int
 event_eth_rx_adapter_service_func(void *args)
 {
        struct rte_event_eth_rx_adapter *rx_adapter = args;
 }
 
 static int
 event_eth_rx_adapter_service_func(void *args)
 {
        struct rte_event_eth_rx_adapter *rx_adapter = args;
-       struct rte_eth_event_enqueue_buffer *buf;
 
 
-       buf = &rx_adapter->event_enqueue_buffer;
        if (rte_spinlock_trylock(&rx_adapter->rx_lock) == 0)
                return 0;
        if (rte_spinlock_trylock(&rx_adapter->rx_lock) == 0)
                return 0;
-       if (eth_rx_poll(rx_adapter) == 0 && buf->count)
-               flush_event_buffer(rx_adapter);
+       if (!rx_adapter->rxa_started) {
+               return 0;
+               rte_spinlock_unlock(&rx_adapter->rx_lock);
+       }
+       eth_rx_poll(rx_adapter);
        rte_spinlock_unlock(&rx_adapter->rx_lock);
        return 0;
 }
        rte_spinlock_unlock(&rx_adapter->rx_lock);
        return 0;
 }
@@ -829,8 +837,12 @@ rx_adapter_ctrl(uint8_t id, int start)
                                                &rte_eth_devices[i]);
        }
 
                                                &rte_eth_devices[i]);
        }
 
-       if (use_service)
+       if (use_service) {
+               rte_spinlock_lock(&rx_adapter->rx_lock);
+               rx_adapter->rxa_started = start;
                rte_service_runstate_set(rx_adapter->service_id, start);
                rte_service_runstate_set(rx_adapter->service_id, start);
+               rte_spinlock_unlock(&rx_adapter->rx_lock);
+       }
 
        return 0;
 }
 
        return 0;
 }
@@ -1032,6 +1044,7 @@ rte_event_eth_rx_adapter_queue_add(uint8_t id,
                                &rte_eth_devices[eth_dev_id],
                                rx_queue_id, queue_conf);
                if (ret == 0) {
                                &rte_eth_devices[eth_dev_id],
                                rx_queue_id, queue_conf);
                if (ret == 0) {
+                       dev_info->internal_event_port = 1;
                        update_queue_info(rx_adapter,
                                        &rx_adapter->eth_devices[eth_dev_id],
                                        rx_queue_id,
                        update_queue_info(rx_adapter,
                                        &rx_adapter->eth_devices[eth_dev_id],
                                        rx_queue_id,
@@ -1039,6 +1052,7 @@ rte_event_eth_rx_adapter_queue_add(uint8_t id,
                }
        } else {
                rte_spinlock_lock(&rx_adapter->rx_lock);
                }
        } else {
                rte_spinlock_lock(&rx_adapter->rx_lock);
+               dev_info->internal_event_port = 0;
                ret = init_service(rx_adapter, id);
                if (ret == 0)
                        ret = add_rx_queue(rx_adapter, eth_dev_id, rx_queue_id,
                ret = init_service(rx_adapter, id);
                if (ret == 0)
                        ret = add_rx_queue(rx_adapter, eth_dev_id, rx_queue_id,
index b14c212..c0603cb 100644 (file)
@@ -110,11 +110,16 @@ rte_event_ring_create(const char *name, unsigned int count, int socket_id,
        mz = rte_memzone_reserve(mz_name, ring_size, socket_id, mz_flags);
        if (mz != NULL) {
                r = mz->addr;
        mz = rte_memzone_reserve(mz_name, ring_size, socket_id, mz_flags);
        if (mz != NULL) {
                r = mz->addr;
-               /*
-                * no need to check return value here, we already checked the
-                * arguments above
-                */
-               rte_event_ring_init(r, name, requested_count, flags);
+               /* Check return value in case rte_ring_init() fails on size */
+               int err = rte_event_ring_init(r, name, requested_count, flags);
+               if (err) {
+                       RTE_LOG(ERR, RING, "Ring init failed\n");
+                       if (rte_memzone_free(mz) != 0)
+                               RTE_LOG(ERR, RING, "Cannot free memzone\n");
+                       rte_free(te);
+                       rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+                       return NULL;
+               }
 
                te->data = (void *) r;
                r->r.memzone = mz;
 
                te->data = (void *) r;
                r->r.memzone = mz;
index cbf78fa..9be514d 100644 (file)
@@ -154,13 +154,13 @@ rte_hash_create(const struct rte_hash_parameters *params)
                 * except for the first cache
                 */
                num_key_slots = params->entries + (RTE_MAX_LCORE - 1) *
                 * except for the first cache
                 */
                num_key_slots = params->entries + (RTE_MAX_LCORE - 1) *
-                                       LCORE_CACHE_SIZE + 1;
+                                       (LCORE_CACHE_SIZE - 1) + 1;
        else
                num_key_slots = params->entries + 1;
 
        snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
        /* Create ring (Dummy slot index is not enqueued) */
        else
                num_key_slots = params->entries + 1;
 
        snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
        /* Create ring (Dummy slot index is not enqueued) */
-       r = rte_ring_create(ring_name, rte_align32pow2(num_key_slots - 1),
+       r = rte_ring_create(ring_name, rte_align32pow2(num_key_slots),
                        params->socket_id, 0);
        if (r == NULL) {
                RTE_LOG(ERR, HASH, "memory allocation failed\n");
                        params->socket_id, 0);
        if (r == NULL) {
                RTE_LOG(ERR, HASH, "memory allocation failed\n");
@@ -302,14 +302,17 @@ rte_hash_create(const struct rte_hash_parameters *params)
                        h->add_key = ADD_KEY_MULTIWRITER;
                        h->multiwriter_lock = rte_malloc(NULL,
                                                        sizeof(rte_spinlock_t),
                        h->add_key = ADD_KEY_MULTIWRITER;
                        h->multiwriter_lock = rte_malloc(NULL,
                                                        sizeof(rte_spinlock_t),
-                                                       LCORE_CACHE_SIZE);
+                                                       RTE_CACHE_LINE_SIZE);
+                       if (h->multiwriter_lock == NULL)
+                               goto err_unlock;
+
                        rte_spinlock_init(h->multiwriter_lock);
                }
        } else
                h->add_key = ADD_KEY_SINGLEWRITER;
 
        /* Populate free slots ring. Entry zero is reserved for key misses. */
                        rte_spinlock_init(h->multiwriter_lock);
                }
        } else
                h->add_key = ADD_KEY_SINGLEWRITER;
 
        /* Populate free slots ring. Entry zero is reserved for key misses. */
-       for (i = 1; i < params->entries + 1; i++)
+       for (i = 1; i < num_key_slots; i++)
                rte_ring_sp_enqueue(r, (void *)((uintptr_t) i));
 
        te->data = (void *) h;
                rte_ring_sp_enqueue(r, (void *)((uintptr_t) i));
 
        te->data = (void *) h;
@@ -391,7 +394,7 @@ void
 rte_hash_reset(struct rte_hash *h)
 {
        void *ptr;
 rte_hash_reset(struct rte_hash *h)
 {
        void *ptr;
-       unsigned i;
+       uint32_t tot_ring_cnt, i;
 
        if (h == NULL)
                return;
 
        if (h == NULL)
                return;
@@ -404,7 +407,13 @@ rte_hash_reset(struct rte_hash *h)
                rte_pause();
 
        /* Repopulate the free slots ring. Entry zero is reserved for key misses */
                rte_pause();
 
        /* Repopulate the free slots ring. Entry zero is reserved for key misses */
-       for (i = 1; i < h->entries + 1; i++)
+       if (h->hw_trans_mem_support)
+               tot_ring_cnt = h->entries + (RTE_MAX_LCORE - 1) *
+                                       (LCORE_CACHE_SIZE - 1);
+       else
+               tot_ring_cnt = h->entries;
+
+       for (i = 1; i < tot_ring_cnt + 1; i++)
                rte_ring_sp_enqueue(h->free_slots, (void *)((uintptr_t) i));
 
        if (h->hw_trans_mem_support) {
                rte_ring_sp_enqueue(h->free_slots, (void *)((uintptr_t) i));
 
        if (h->hw_trans_mem_support) {
index 0c94244..a2f1663 100644 (file)
@@ -95,6 +95,9 @@ rte_hash_cuckoo_move_insert_mw_tm(const struct rte_hash *h,
        while (try < RTE_HASH_TSX_MAX_RETRY) {
                status = rte_xbegin();
                if (likely(status == RTE_XBEGIN_STARTED)) {
        while (try < RTE_HASH_TSX_MAX_RETRY) {
                status = rte_xbegin();
                if (likely(status == RTE_XBEGIN_STARTED)) {
+                       /* In case empty slot was gone before entering TSX */
+                       if (curr_bkt->key_idx[curr_slot] != EMPTY_SLOT)
+                               rte_xabort(RTE_XABORT_CUCKOO_PATH_INVALIDED);
                        while (likely(curr_node->prev != NULL)) {
                                prev_node = curr_node->prev;
                                prev_bkt = prev_node->bkt;
                        while (likely(curr_node->prev != NULL)) {
                                prev_node = curr_node->prev;
                                prev_bkt = prev_node->bkt;
index 622c180..5539e33 100644 (file)
@@ -283,8 +283,8 @@ rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key, hash_sig_t
  *   Output containing a pointer to the key
  * @return
  *   - 0 if retrieved successfully
  *   Output containing a pointer to the key
  * @return
  *   - 0 if retrieved successfully
- *   - EINVAL if the parameters are invalid.
- *   - ENOENT if no valid key is found in the given position.
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if no valid key is found in the given position.
  */
 int
 rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
  */
 int
 rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
@@ -301,9 +301,11 @@ rte_hash_get_key_with_position(const struct rte_hash *h, const int32_t position,
  * @param data
  *   Output with pointer to data returned from the hash table.
  * @return
  * @param data
  *   Output with pointer to data returned from the hash table.
  * @return
- *   0 if successful lookup
- *   - EINVAL if the parameters are invalid.
- *   - ENOENT if the key is not found.
+ *   - A positive value that can be used by the caller as an offset into an
+ *     array of user data. This value is unique for this key, and is the same
+ *     value that was returned when the key was added.
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if the key is not found.
  */
 int
 rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data);
  */
 int
 rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data);
@@ -322,9 +324,11 @@ rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data);
  * @param data
  *   Output with pointer to data returned from the hash table.
  * @return
  * @param data
  *   Output with pointer to data returned from the hash table.
  * @return
- *   0 if successful lookup
- *   - EINVAL if the parameters are invalid.
- *   - ENOENT if the key is not found.
+ *   - A positive value that can be used by the caller as an offset into an
+ *     array of user data. This value is unique for this key, and is the same
+ *     value that was returned when the key was added.
+ *   - -EINVAL if the parameters are invalid.
+ *   - -ENOENT if the key is not found.
  */
 int
 rte_hash_lookup_with_hash_data(const struct rte_hash *h, const void *key,
  */
 int
 rte_hash_lookup_with_hash_data(const struct rte_hash *h, const void *key,
index 8eca8c0..4b45d1a 100644 (file)
@@ -681,6 +681,9 @@ rte_kni_get(const char *name)
        struct rte_kni_memzone_slot *it;
        struct rte_kni *kni;
 
        struct rte_kni_memzone_slot *it;
        struct rte_kni *kni;
 
+       if (name == NULL || name[0] == '\0')
+               return NULL;
+
        /* Note: could be improved perf-wise if necessary */
        for (i = 0; i < kni_memzone_pool.max_ifaces; i++) {
                it = &kni_memzone_pool.slots[i];
        /* Note: could be improved perf-wise if necessary */
        for (i = 0; i < kni_memzone_pool.max_ifaces; i++) {
                it = &kni_memzone_pool.slots[i];
index d940400..dc63446 100644 (file)
@@ -124,6 +124,9 @@ rte_metrics_reg_names(const char * const *names, uint16_t cnt_names)
        /* Some sanity checks */
        if (cnt_names < 1 || names == NULL)
                return -EINVAL;
        /* Some sanity checks */
        if (cnt_names < 1 || names == NULL)
                return -EINVAL;
+       for (idx_name = 0; idx_name < cnt_names; idx_name++)
+               if (names[idx_name] == NULL)
+                       return -EINVAL;
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
        if (memzone == NULL)
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
        if (memzone == NULL)
@@ -190,6 +193,11 @@ rte_metrics_update_values(int port_id,
        stats = memzone->addr;
 
        rte_spinlock_lock(&stats->lock);
        stats = memzone->addr;
 
        rte_spinlock_lock(&stats->lock);
+
+       if (key >= stats->cnt_stats) {
+               rte_spinlock_unlock(&stats->lock);
+               return -EINVAL;
+       }
        idx_metric = key;
        cnt_setsize = 1;
        while (idx_metric < stats->cnt_stats) {
        idx_metric = key;
        cnt_setsize = 1;
        while (idx_metric < stats->cnt_stats) {
@@ -231,9 +239,8 @@ rte_metrics_get_names(struct rte_metric_name *names,
        int return_value;
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
        int return_value;
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
-       /* If not allocated, fail silently */
        if (memzone == NULL)
        if (memzone == NULL)
-               return 0;
+               return -EIO;
 
        stats = memzone->addr;
        rte_spinlock_lock(&stats->lock);
 
        stats = memzone->addr;
        rte_spinlock_lock(&stats->lock);
@@ -269,9 +276,9 @@ rte_metrics_get_values(int port_id,
                return -EINVAL;
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
                return -EINVAL;
 
        memzone = rte_memzone_lookup(RTE_METRICS_MEMZONE_NAME);
-       /* If not allocated, fail silently */
        if (memzone == NULL)
        if (memzone == NULL)
-               return 0;
+               return -EIO;
+
        stats = memzone->addr;
        rte_spinlock_lock(&stats->lock);
 
        stats = memzone->addr;
        rte_spinlock_lock(&stats->lock);
 
index 7069d52..fc433b0 100644 (file)
@@ -582,7 +582,7 @@ __rte_ring_do_dequeue(struct rte_ring *r, void **obj_table,
        uint32_t cons_head, cons_next;
        uint32_t entries;
 
        uint32_t cons_head, cons_next;
        uint32_t entries;
 
-       n = __rte_ring_move_cons_head(r, is_sc, n, behavior,
+       n = __rte_ring_move_cons_head(r, (int)is_sc, n, behavior,
                        &cons_head, &cons_next, &entries);
        if (n == 0)
                goto end;
                        &cons_head, &cons_next, &entries);
        if (n == 0)
                goto end;
index 685729f..503f5b5 100644 (file)
@@ -84,7 +84,6 @@ rte_security_session_destroy(struct rte_security_ctx *instance,
                             struct rte_security_session *sess)
 {
        int ret;
                             struct rte_security_session *sess)
 {
        int ret;
-       struct rte_mempool *mp = rte_mempool_from_obj(sess);
 
        RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->session_destroy, -ENOTSUP);
 
 
        RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->session_destroy, -ENOTSUP);
 
@@ -93,7 +92,7 @@ rte_security_session_destroy(struct rte_security_ctx *instance,
 
        ret = instance->ops->session_destroy(instance->device, sess);
        if (!ret)
 
        ret = instance->ops->session_destroy(instance->device, sess);
        if (!ret)
-               rte_mempool_put(mp, (void *)sess);
+               rte_mempool_put(rte_mempool_from_obj(sess), (void *)sess);
 
        return ret;
 }
 
        return ret;
 }
index c11ebca..c6354fe 100644 (file)
@@ -303,6 +303,13 @@ out:
        return vva;
 }
 
        return vva;
 }
 
+void
+vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq)
+{
+       vhost_user_iotlb_cache_remove_all(vq);
+       vhost_user_iotlb_pending_remove_all(vq);
+}
+
 int
 vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
 {
 int
 vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
 {
@@ -315,8 +322,7 @@ vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
                 * The cache has already been initialized,
                 * just drop all cached and pending entries.
                 */
                 * The cache has already been initialized,
                 * just drop all cached and pending entries.
                 */
-               vhost_user_iotlb_cache_remove_all(vq);
-               vhost_user_iotlb_pending_remove_all(vq);
+               vhost_user_iotlb_flush_all(vq);
        }
 
 #ifdef RTE_LIBRTE_VHOST_NUMA
        }
 
 #ifdef RTE_LIBRTE_VHOST_NUMA
index e7083e3..60b9e4c 100644 (file)
@@ -73,7 +73,7 @@ void vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint8_t perm);
 void vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint64_t size, uint8_t perm);
                                                uint8_t perm);
 void vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint64_t size, uint8_t perm);
-
+void vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq);
 int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index);
 
 #endif /* _VHOST_IOTLB_H_ */
 int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index);
 
 #endif /* _VHOST_IOTLB_H_ */
index 16d6b89..11ce271 100644 (file)
@@ -59,6 +59,8 @@
 
 #define BUF_VECTOR_MAX 256
 
 
 #define BUF_VECTOR_MAX 256
 
+#define VHOST_LOG_CACHE_NR 32
+
 /**
  * Structure contains buffer address, length and descriptor index
  * from vring to do scatter RX.
 /**
  * Structure contains buffer address, length and descriptor index
  * from vring to do scatter RX.
@@ -92,6 +94,14 @@ struct batch_copy_elem {
        uint64_t log_addr;
 };
 
        uint64_t log_addr;
 };
 
+/*
+ * Structure that contains the info for batched dirty logging.
+ */
+struct log_cache_entry {
+       uint32_t offset;
+       unsigned long val;
+};
+
 /**
  * Structure contains variables relevant to RX/TX virtqueues.
  */
 /**
  * Structure contains variables relevant to RX/TX virtqueues.
  */
@@ -133,6 +143,9 @@ struct vhost_virtqueue {
        struct batch_copy_elem  *batch_copy_elems;
        uint16_t                batch_copy_nb_elems;
 
        struct batch_copy_elem  *batch_copy_elems;
        uint16_t                batch_copy_nb_elems;
 
+       struct log_cache_entry log_cache[VHOST_LOG_CACHE_NR];
+       uint16_t log_cache_nb_elem;
+
        rte_rwlock_t    iotlb_lock;
        rte_rwlock_t    iotlb_pending_lock;
        struct rte_mempool *iotlb_pool;
        rte_rwlock_t    iotlb_lock;
        rte_rwlock_t    iotlb_pending_lock;
        struct rte_mempool *iotlb_pool;
@@ -266,7 +279,15 @@ struct virtio_net {
 static __rte_always_inline void
 vhost_set_bit(unsigned int nr, volatile uint8_t *addr)
 {
 static __rte_always_inline void
 vhost_set_bit(unsigned int nr, volatile uint8_t *addr)
 {
-       __sync_fetch_and_or_8(addr, (1U << nr));
+#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION < 70100)
+       /*
+        * __sync_ built-ins are deprecated, but __atomic_ ones
+        * are sub-optimized in older GCC versions.
+        */
+       __sync_fetch_and_or_1(addr, (1U << nr));
+#else
+       __atomic_fetch_or(addr, (1U << nr), __ATOMIC_RELAXED);
+#endif
 }
 
 static __rte_always_inline void
 }
 
 static __rte_always_inline void
@@ -297,6 +318,103 @@ vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len)
        }
 }
 
        }
 }
 
+static __rte_always_inline void
+vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq)
+{
+       unsigned long *log_base;
+       int i;
+
+       if (likely(((dev->features & (1ULL << VHOST_F_LOG_ALL)) == 0) ||
+                  !dev->log_base))
+               return;
+
+       log_base = (unsigned long *)(uintptr_t)dev->log_base;
+
+       /*
+        * It is expected a write memory barrier has been issued
+        * before this function is called.
+        */
+
+       for (i = 0; i < vq->log_cache_nb_elem; i++) {
+               struct log_cache_entry *elem = vq->log_cache + i;
+
+#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION < 70100)
+               /*
+                * '__sync' builtins are deprecated, but '__atomic' ones
+                * are sub-optimized in older GCC versions.
+                */
+               __sync_fetch_and_or(log_base + elem->offset, elem->val);
+#else
+               __atomic_fetch_or(log_base + elem->offset, elem->val,
+                               __ATOMIC_RELAXED);
+#endif
+       }
+
+       rte_smp_wmb();
+
+       vq->log_cache_nb_elem = 0;
+}
+
+static __rte_always_inline void
+vhost_log_cache_page(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                       uint64_t page)
+{
+       uint32_t bit_nr = page % (sizeof(unsigned long) << 3);
+       uint32_t offset = page / (sizeof(unsigned long) << 3);
+       int i;
+
+       for (i = 0; i < vq->log_cache_nb_elem; i++) {
+               struct log_cache_entry *elem = vq->log_cache + i;
+
+               if (elem->offset == offset) {
+                       elem->val |= (1UL << bit_nr);
+                       return;
+               }
+       }
+
+       if (unlikely(i >= VHOST_LOG_CACHE_NR)) {
+               /*
+                * No more room for a new log cache entry,
+                * so write the dirty log map directly.
+                */
+               rte_smp_wmb();
+               vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page);
+
+               return;
+       }
+
+       vq->log_cache[i].offset = offset;
+       vq->log_cache[i].val = (1UL << bit_nr);
+       vq->log_cache_nb_elem++;
+}
+
+static __rte_always_inline void
+vhost_log_cache_write(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                       uint64_t addr, uint64_t len)
+{
+       uint64_t page;
+
+       if (likely(((dev->features & (1ULL << VHOST_F_LOG_ALL)) == 0) ||
+                  !dev->log_base || !len))
+               return;
+
+       if (unlikely(dev->log_size <= ((addr + len - 1) / VHOST_LOG_PAGE / 8)))
+               return;
+
+       page = addr / VHOST_LOG_PAGE;
+       while (page * VHOST_LOG_PAGE < addr + len) {
+               vhost_log_cache_page(dev, vq, page);
+               page += 1;
+       }
+}
+
+static __rte_always_inline void
+vhost_log_cache_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                       uint64_t offset, uint64_t len)
+{
+       vhost_log_cache_write(dev, vq, vq->log_guest_addr + offset, len);
+}
+
 static __rte_always_inline void
 vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
                     uint64_t offset, uint64_t len)
 static __rte_always_inline void
 vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
                     uint64_t offset, uint64_t len)
index c0efb31..0eb5e0d 100644 (file)
@@ -623,8 +623,9 @@ vhost_memory_changed(struct VhostUserMemory *new,
 }
 
 static int
 }
 
 static int
-vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
+vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *pmsg)
 {
 {
+       struct virtio_net *dev = *pdev;
        struct VhostUserMemory memory = pmsg->payload.memory;
        struct rte_vhost_mem_region *reg;
        void *mmap_addr;
        struct VhostUserMemory memory = pmsg->payload.memory;
        struct rte_vhost_mem_region *reg;
        void *mmap_addr;
@@ -650,6 +651,11 @@ vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
                dev->mem = NULL;
        }
 
                dev->mem = NULL;
        }
 
+       /* Flush IOTLB cache as previous HVAs are now invalid */
+       if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
+               for (i = 0; i < dev->nr_vring; i++)
+                       vhost_user_iotlb_flush_all(dev->virtqueue[i]);
+
        dev->nr_guest_pages = 0;
        if (!dev->guest_pages) {
                dev->max_guest_pages = 8;
        dev->nr_guest_pages = 0;
        if (!dev->guest_pages) {
                dev->max_guest_pages = 8;
@@ -743,6 +749,25 @@ vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
                        mmap_offset);
        }
 
                        mmap_offset);
        }
 
+       for (i = 0; i < dev->nr_vring; i++) {
+               struct vhost_virtqueue *vq = dev->virtqueue[i];
+
+               if (vq->desc || vq->avail || vq->used) {
+                       /*
+                        * If the memory table got updated, the ring addresses
+                        * need to be translated again as virtual addresses have
+                        * changed.
+                        */
+                       vring_invalidate(dev, vq);
+
+                       dev = translate_ring_addresses(dev, i);
+                       if (!dev)
+                               return -1;
+
+                       *pdev = dev;
+               }
+       }
+
        dump_guest_pages(dev);
 
        return 0;
        dump_guest_pages(dev);
 
        return 0;
@@ -1404,7 +1429,7 @@ vhost_user_msg_handler(int vid, int fd)
                break;
 
        case VHOST_USER_SET_MEM_TABLE:
                break;
 
        case VHOST_USER_SET_MEM_TABLE:
-               ret = vhost_user_set_mem_table(dev, &msg);
+               ret = vhost_user_set_mem_table(&dev, &msg);
                break;
 
        case VHOST_USER_SET_LOG_BASE:
                break;
 
        case VHOST_USER_SET_LOG_BASE:
index ecfabca..bde360f 100644 (file)
@@ -107,7 +107,7 @@ do_flush_shadow_used_ring(struct virtio_net *dev, struct vhost_virtqueue *vq,
        rte_memcpy(&vq->used->ring[to],
                        &vq->shadow_used_ring[from],
                        size * sizeof(struct vring_used_elem));
        rte_memcpy(&vq->used->ring[to],
                        &vq->shadow_used_ring[from],
                        size * sizeof(struct vring_used_elem));
-       vhost_log_used_vring(dev, vq,
+       vhost_log_cache_used_vring(dev, vq,
                        offsetof(struct vring_used, ring[to]),
                        size * sizeof(struct vring_used_elem));
 }
                        offsetof(struct vring_used, ring[to]),
                        size * sizeof(struct vring_used_elem));
 }
@@ -135,6 +135,8 @@ flush_shadow_used_ring(struct virtio_net *dev, struct vhost_virtqueue *vq)
 
        rte_smp_wmb();
 
 
        rte_smp_wmb();
 
+       vhost_log_cache_sync(dev, vq);
+
        *(volatile uint16_t *)&vq->used->idx += vq->shadow_used_idx;
        vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
                sizeof(vq->used->idx));
        *(volatile uint16_t *)&vq->used->idx += vq->shadow_used_idx;
        vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
                sizeof(vq->used->idx));
@@ -159,7 +161,7 @@ do_data_copy_enqueue(struct virtio_net *dev, struct vhost_virtqueue *vq)
 
        for (i = 0; i < count; i++) {
                rte_memcpy(elem[i].dst, elem[i].src, elem[i].len);
 
        for (i = 0; i < count; i++) {
                rte_memcpy(elem[i].dst, elem[i].src, elem[i].len);
-               vhost_log_write(dev, elem[i].log_addr, elem[i].len);
+               vhost_log_cache_write(dev, vq, elem[i].log_addr, elem[i].len);
                PRINT_PACKET(dev, (uintptr_t)elem[i].dst, elem[i].len, 0);
        }
 }
                PRINT_PACKET(dev, (uintptr_t)elem[i].dst, elem[i].len, 0);
        }
 }
@@ -275,7 +277,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
                virtio_enqueue_offload(m,
                                (struct virtio_net_hdr *)(uintptr_t)desc_addr);
                PRINT_PACKET(dev, (uintptr_t)desc_addr, dev->vhost_hlen, 0);
                virtio_enqueue_offload(m,
                                (struct virtio_net_hdr *)(uintptr_t)desc_addr);
                PRINT_PACKET(dev, (uintptr_t)desc_addr, dev->vhost_hlen, 0);
-               vhost_log_write(dev, desc_gaddr, dev->vhost_hlen);
+               vhost_log_cache_write(dev, vq, desc_gaddr, dev->vhost_hlen);
        } else {
                struct virtio_net_hdr vnet_hdr;
                uint64_t remain = dev->vhost_hlen;
        } else {
                struct virtio_net_hdr vnet_hdr;
                uint64_t remain = dev->vhost_hlen;
@@ -298,7 +300,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
                                        (void *)(uintptr_t)src, len);
 
                        PRINT_PACKET(dev, (uintptr_t)dst, (uint32_t)len, 0);
                                        (void *)(uintptr_t)src, len);
 
                        PRINT_PACKET(dev, (uintptr_t)dst, (uint32_t)len, 0);
-                       vhost_log_write(dev, guest_addr, len);
+                       vhost_log_cache_write(dev, vq, guest_addr, len);
                        remain -= len;
                        guest_addr += len;
                        dst += len;
                        remain -= len;
                        guest_addr += len;
                        dst += len;
@@ -379,7 +381,8 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
                                                        desc_offset)),
                                rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
                                cpy_len);
                                                        desc_offset)),
                                rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
                                cpy_len);
-                       vhost_log_write(dev, desc_gaddr + desc_offset, cpy_len);
+                       vhost_log_cache_write(dev, vq, desc_gaddr + desc_offset,
+                                       cpy_len);
                        PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
                                     cpy_len, 0);
                } else {
                        PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
                                     cpy_len, 0);
                } else {
@@ -468,7 +471,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
                vq->used->ring[used_idx].id = desc_indexes[i];
                vq->used->ring[used_idx].len = pkts[i]->pkt_len +
                                               dev->vhost_hlen;
                vq->used->ring[used_idx].id = desc_indexes[i];
                vq->used->ring[used_idx].len = pkts[i]->pkt_len +
                                               dev->vhost_hlen;
-               vhost_log_used_vring(dev, vq,
+               vhost_log_cache_used_vring(dev, vq,
                        offsetof(struct vring_used, ring[used_idx]),
                        sizeof(vq->used->ring[used_idx]));
        }
                        offsetof(struct vring_used, ring[used_idx]),
                        sizeof(vq->used->ring[used_idx]));
        }
@@ -528,6 +531,8 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 
        rte_smp_wmb();
 
 
        rte_smp_wmb();
 
+       vhost_log_cache_sync(dev, vq);
+
        *(volatile uint16_t *)&vq->used->idx += count;
        vq->last_used_idx += count;
        vhost_log_used_vring(dev, vq,
        *(volatile uint16_t *)&vq->used->idx += count;
        vq->last_used_idx += count;
        vhost_log_used_vring(dev, vq,
@@ -797,7 +802,8 @@ copy_mbuf_to_desc_mergeable(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
                                        PRINT_PACKET(dev, (uintptr_t)dst,
                                                        (uint32_t)len, 0);
 
                                        PRINT_PACKET(dev, (uintptr_t)dst,
                                                        (uint32_t)len, 0);
-                                       vhost_log_write(dev, guest_addr, len);
+                                       vhost_log_cache_write(dev, vq,
+                                                       guest_addr, len);
 
                                        remain -= len;
                                        guest_addr += len;
 
                                        remain -= len;
                                        guest_addr += len;
@@ -806,7 +812,7 @@ copy_mbuf_to_desc_mergeable(struct virtio_net *dev, struct vhost_virtqueue *vq,
                        } else {
                                PRINT_PACKET(dev, (uintptr_t)hdr_addr,
                                                dev->vhost_hlen, 0);
                        } else {
                                PRINT_PACKET(dev, (uintptr_t)hdr_addr,
                                                dev->vhost_hlen, 0);
-                               vhost_log_write(dev, hdr_phys_addr,
+                               vhost_log_cache_write(dev, vq, hdr_phys_addr,
                                                dev->vhost_hlen);
                        }
 
                                                dev->vhost_hlen);
                        }
 
@@ -820,7 +826,8 @@ copy_mbuf_to_desc_mergeable(struct virtio_net *dev, struct vhost_virtqueue *vq,
                                                        desc_offset)),
                                rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
                                cpy_len);
                                                        desc_offset)),
                                rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
                                cpy_len);
-                       vhost_log_write(dev, desc_gaddr + desc_offset, cpy_len);
+                       vhost_log_cache_write(dev, vq, desc_gaddr + desc_offset,
+                                       cpy_len);
                        PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
                                cpy_len, 0);
                } else {
                        PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
                                cpy_len, 0);
                } else {
@@ -1384,7 +1391,7 @@ update_used_ring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 {
        vq->used->ring[used_idx].id  = desc_idx;
        vq->used->ring[used_idx].len = 0;
 {
        vq->used->ring[used_idx].id  = desc_idx;
        vq->used->ring[used_idx].len = 0;
-       vhost_log_used_vring(dev, vq,
+       vhost_log_cache_used_vring(dev, vq,
                        offsetof(struct vring_used, ring[used_idx]),
                        sizeof(vq->used->ring[used_idx]));
 }
                        offsetof(struct vring_used, ring[used_idx]),
                        sizeof(vq->used->ring[used_idx]));
 }
@@ -1399,6 +1406,8 @@ update_used_idx(struct virtio_net *dev, struct vhost_virtqueue *vq,
        rte_smp_wmb();
        rte_smp_rmb();
 
        rte_smp_wmb();
        rte_smp_rmb();
 
+       vhost_log_cache_sync(dev, vq);
+
        vq->used->idx += count;
        vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
                        sizeof(vq->used->idx));
        vq->used->idx += count;
        vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
                        sizeof(vq->used->idx));
@@ -1557,7 +1566,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
                if (rarp_mbuf == NULL) {
                        RTE_LOG(ERR, VHOST_DATA,
                                "Failed to allocate memory for mbuf.\n");
                if (rarp_mbuf == NULL) {
                        RTE_LOG(ERR, VHOST_DATA,
                                "Failed to allocate memory for mbuf.\n");
-                       return 0;
+                       goto out;
                }
 
                if (make_rarp_packet(rarp_mbuf, &dev->mac)) {
                }
 
                if (make_rarp_packet(rarp_mbuf, &dev->mac)) {
index 4e97fef..99c4eac 100644 (file)
@@ -113,18 +113,22 @@ else
        @echo Installation in $(DESTDIR)$(prefix)/ complete
 endif
 
        @echo Installation in $(DESTDIR)$(prefix)/ complete
 endif
 
+# when installing we want recursive copies preserving timestamps only, no
+# preservation of user/group ids or permissions
+CP_FLAGS=-dR --preserve=timestamps
+TAR_X_FLAGS=--strip-components=1 --keep-newer-files --no-same-owner --no-same-permissions
+
 install-runtime:
        $(Q)$(call rte_mkdir, $(DESTDIR)$(libdir))
 install-runtime:
        $(Q)$(call rte_mkdir, $(DESTDIR)$(libdir))
-       $(Q)cp -a    $O/lib/* $(DESTDIR)$(libdir)
+       $(Q)cp $(CP_FLAGS)    $O/lib/* $(DESTDIR)$(libdir)
        $(Q)$(call rte_mkdir, $(DESTDIR)$(bindir))
        $(Q)tar -cf -      -C $O --exclude 'app/*.map' \
                --exclude app/dpdk-pmdinfogen \
                --exclude 'app/cmdline*' --exclude app/test \
                --exclude app/testacl --exclude app/testpipeline app | \
        $(Q)$(call rte_mkdir, $(DESTDIR)$(bindir))
        $(Q)tar -cf -      -C $O --exclude 'app/*.map' \
                --exclude app/dpdk-pmdinfogen \
                --exclude 'app/cmdline*' --exclude app/test \
                --exclude app/testacl --exclude app/testpipeline app | \
-           tar -xf -      -C $(DESTDIR)$(bindir) --strip-components=1 \
-               --keep-newer-files
+           tar -xf -      -C $(DESTDIR)$(bindir) $(TAR_X_FLAGS)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(datadir))
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(datadir))
-       $(Q)cp -a $(RTE_SDK)/usertools $(DESTDIR)$(datadir)
+       $(Q)cp $(CP_FLAGS) $(RTE_SDK)/usertools $(DESTDIR)$(datadir)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(sbindir))
        $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/usertools/dpdk-devbind.py, \
                                   $(DESTDIR)$(sbindir)/dpdk-devbind)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(sbindir))
        $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/usertools/dpdk-devbind.py, \
                                   $(DESTDIR)$(sbindir)/dpdk-devbind)
@@ -132,30 +136,29 @@ install-runtime:
                                   $(DESTDIR)$(bindir)/dpdk-pmdinfo)
 ifneq ($(wildcard $O/doc/man/*/*.1),)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(mandir)/man1)
                                   $(DESTDIR)$(bindir)/dpdk-pmdinfo)
 ifneq ($(wildcard $O/doc/man/*/*.1),)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(mandir)/man1)
-       $(Q)cp -a $O/doc/man/*/*.1 $(DESTDIR)$(mandir)/man1
+       $(Q)cp $(CP_FLAGS) $O/doc/man/*/*.1 $(DESTDIR)$(mandir)/man1
 endif
 ifneq ($(wildcard $O/doc/man/*/*.8),)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(mandir)/man8)
 endif
 ifneq ($(wildcard $O/doc/man/*/*.8),)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(mandir)/man8)
-       $(Q)cp -a $O/doc/man/*/*.8 $(DESTDIR)$(mandir)/man8
+       $(Q)cp $(CP_FLAGS) $O/doc/man/*/*.8 $(DESTDIR)$(mandir)/man8
 endif
 
 install-kmod:
 ifneq ($(wildcard $O/kmod/*),)
        $(Q)$(call rte_mkdir, $(DESTDIR)$(kerneldir))
 endif
 
 install-kmod:
 ifneq ($(wildcard $O/kmod/*),)
        $(Q)$(call rte_mkdir, $(DESTDIR)$(kerneldir))
-       $(Q)cp -a   $O/kmod/* $(DESTDIR)$(kerneldir)
+       $(Q)cp $(CP_FLAGS)   $O/kmod/* $(DESTDIR)$(kerneldir)
 endif
 
 install-sdk:
        $(Q)$(call rte_mkdir, $(DESTDIR)$(includedir))
        $(Q)tar -chf -     -C $O include | \
 endif
 
 install-sdk:
        $(Q)$(call rte_mkdir, $(DESTDIR)$(includedir))
        $(Q)tar -chf -     -C $O include | \
-           tar -xf -      -C $(DESTDIR)$(includedir) --strip-components=1 \
-               --keep-newer-files
+           tar -xf -      -C $(DESTDIR)$(includedir) $(TAR_X_FLAGS)
        $(Q)$(call rte_mkdir,                            $(DESTDIR)$(sdkdir))
        $(Q)$(call rte_mkdir,                            $(DESTDIR)$(sdkdir))
-       $(Q)cp -a               $(RTE_SDK)/mk            $(DESTDIR)$(sdkdir)
-       $(Q)cp -a               $(RTE_SDK)/buildtools    $(DESTDIR)$(sdkdir)
+       $(Q)cp $(CP_FLAGS)      $(RTE_SDK)/mk            $(DESTDIR)$(sdkdir)
+       $(Q)cp $(CP_FLAGS)      $(RTE_SDK)/buildtools    $(DESTDIR)$(sdkdir)
        $(Q)$(call rte_mkdir,                            $(DESTDIR)$(targetdir)/app)
        $(Q)$(call rte_mkdir,                            $(DESTDIR)$(targetdir)/app)
-       $(Q)cp -a               $O/.config               $(DESTDIR)$(targetdir)
-       $(Q)cp -a               $O/app/dpdk-pmdinfogen   $(DESTDIR)$(targetdir)/app
+       $(Q)cp $(CP_FLAGS)      $O/.config               $(DESTDIR)$(targetdir)
+       $(Q)cp $(CP_FLAGS)      $O/app/dpdk-pmdinfogen   $(DESTDIR)$(targetdir)/app
        $(Q)$(call rte_symlink, $(DESTDIR)$(includedir), $(DESTDIR)$(targetdir)/include)
        $(Q)$(call rte_symlink, $(DESTDIR)$(libdir),     $(DESTDIR)$(targetdir)/lib)
 
        $(Q)$(call rte_symlink, $(DESTDIR)$(includedir), $(DESTDIR)$(targetdir)/include)
        $(Q)$(call rte_symlink, $(DESTDIR)$(libdir),     $(DESTDIR)$(targetdir)/lib)
 
@@ -163,12 +166,11 @@ install-doc:
 ifneq ($(wildcard $O/doc/html),)
        $(Q)$(call rte_mkdir, $(DESTDIR)$(docdir))
        $(Q)tar -cf -      -C $O/doc --exclude 'html/guides/.*' html | \
 ifneq ($(wildcard $O/doc/html),)
        $(Q)$(call rte_mkdir, $(DESTDIR)$(docdir))
        $(Q)tar -cf -      -C $O/doc --exclude 'html/guides/.*' html | \
-           tar -xf -      -C $(DESTDIR)$(docdir) --strip-components=1 \
-               --keep-newer-files
+           tar -xf -      -C $(DESTDIR)$(docdir) $(TAR_X_FLAGS)
 endif
 ifneq ($(wildcard $O/doc/*/*/*pdf),)
        $(Q)$(call rte_mkdir,     $(DESTDIR)$(docdir)/guides)
 endif
 ifneq ($(wildcard $O/doc/*/*/*pdf),)
        $(Q)$(call rte_mkdir,     $(DESTDIR)$(docdir)/guides)
-       $(Q)cp -a $O/doc/*/*/*pdf $(DESTDIR)$(docdir)/guides
+       $(Q)cp $(CP_FLAGS) $O/doc/*/*/*pdf $(DESTDIR)$(docdir)/guides
 endif
        $(Q)$(call rte_mkdir,         $(DESTDIR)$(datadir))
 endif
        $(Q)$(call rte_mkdir,         $(DESTDIR)$(datadir))
-       $(Q)cp -a $(RTE_SDK)/examples $(DESTDIR)$(datadir)
+       $(Q)cp $(CP_FLAGS) $(RTE_SDK)/examples $(DESTDIR)$(datadir)
index e2e3eff..2fcf8de 100644 (file)
@@ -96,8 +96,8 @@ config defconfig showconfigs showversion showversionum:
 cscope gtags tags etags:
        $(Q)$(RTE_SDK)/devtools/build-tags.sh $@ $T
 
 cscope gtags tags etags:
        $(Q)$(RTE_SDK)/devtools/build-tags.sh $@ $T
 
-.PHONY: test test-basic test-fast test-ring test-mempool test-perf coverage
-test test-basic test-fast test-ring test-mempool test-perf coverage:
+.PHONY: test test-fast test-perf coverage test-drivers test-dump
+test test-fast test-perf coverage test-drivers test-dump:
        $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdktest.mk $@
 
 test: test-build
        $(Q)$(MAKE) -f $(RTE_SDK)/mk/rte.sdktest.mk $@
 
 test: test-build
index daeea90..18e03d6 100644 (file)
@@ -46,14 +46,34 @@ DIR := $(shell basename $(RTE_OUTPUT))
 #
 # test: launch auto-tests, very simple for now.
 #
 #
 # test: launch auto-tests, very simple for now.
 #
-.PHONY: test test-basic test-fast test-perf coverage
+.PHONY: test test-fast test-perf test-drivers test-dump coverage
 
 
-PERFLIST=ring_perf,mempool_perf,memcpy_perf,hash_perf,timer_perf
-coverage: BLACKLIST=-$(PERFLIST)
-test-fast: BLACKLIST=-$(PERFLIST)
-test-perf: WHITELIST=$(PERFLIST)
+PERFLIST=ring_perf,mempool_perf,memcpy_perf,hash_perf,timer_perf,\
+         reciprocal_division,reciprocal_division_perf,lpm_perf,red_all,\
+         barrier,hash_multiwriter,timer_racecond,efd,hash_functions,\
+         eventdev_selftest_sw,member_perf,efd_perf,lpm6_perf,red_perf,\
+         distributor_perf,ring_pmd_perf,pmd_perf,ring_perf
+DRIVERSLIST=link_bonding,link_bonding_mode4,link_bonding_rssconf,\
+            cryptodev_sw_mrvl,cryptodev_dpaa2_sec,cryptodev_dpaa_sec,\
+            cryptodev_qat,cryptodev_aesni_mb,cryptodev_openssl,\
+            cryptodev_scheduler,cryptodev_aesni_gcm,cryptodev_null,\
+            cryptodev_sw_snow3g,cryptodev_sw_kasumi,cryptodev_sw_zuc
+DUMPLIST=dump_struct_sizes,dump_mempool,dump_malloc_stats,dump_devargs,\
+         dump_log_types,dump_ring,dump_physmem,dump_memzone
 
 
-test test-basic test-fast test-perf:
+SPACESTR:=
+SPACESTR+=
+STRIPPED_PERFLIST=$(subst $(SPACESTR),,$(PERFLIST))
+STRIPPED_DRIVERSLIST=$(subst $(SPACESTR),,$(DRIVERSLIST))
+STRIPPED_DUMPLIST=$(subst $(SPACESTR),,$(DUMPLIST))
+
+coverage: BLACKLIST=-$(STRIPPED_PERFLIST)
+test-fast: BLACKLIST=-$(STRIPPED_PERFLIST),$(STRIPPED_DRIVERSLIST),$(STRIPPED_DUMPLIST)
+test-perf: WHITELIST=$(STRIPPED_PERFLIST)
+test-drivers: WHITELIST=$(STRIPPED_DRIVERSLIST)
+test-dump: WHITELIST=$(STRIPPED_DUMPLIST)
+
+test test-fast test-perf test-drivers test-dump:
        @mkdir -p $(AUTOTEST_DIR) ; \
        cd $(AUTOTEST_DIR) ; \
        if [ -f $(RTE_OUTPUT)/app/test ]; then \
        @mkdir -p $(AUTOTEST_DIR) ; \
        cd $(AUTOTEST_DIR) ; \
        if [ -f $(RTE_OUTPUT)/app/test ]; then \
index 01ac7e2..8dbd441 100644 (file)
@@ -42,6 +42,11 @@ GCC_MAJOR = $(shell echo __GNUC__ | $(CC) -E -x c - | tail -n 1)
 GCC_MINOR = $(shell echo __GNUC_MINOR__ | $(CC) -E -x c - | tail -n 1)
 GCC_VERSION = $(GCC_MAJOR)$(GCC_MINOR)
 
 GCC_MINOR = $(shell echo __GNUC_MINOR__ | $(CC) -E -x c - | tail -n 1)
 GCC_VERSION = $(GCC_MAJOR)$(GCC_MINOR)
 
+HOST_GCC_MAJOR = $(shell echo __GNUC__ | $(HOSTCC) -E -x c - | tail -n 1)
+HOST_GCC_MINOR = $(shell echo __GNUC_MINOR__ | $(HOSTCC) -E -x c - | tail -n 1)
+HOST_GCC_PATCHLEVEL = $(shell echo __GNUC_PATCHLEVEL__ | $(HOSTCC) -E -x c - | tail -n 1)
+HOST_GCC_VERSION = $(HOST_GCC_MAJOR)$(HOST_GCC_MINOR)
+
 # if GCC is older than 4.x
 ifeq ($(shell test $(GCC_VERSION) -lt 40 && echo 1), 1)
        MACHINE_CFLAGS =
 # if GCC is older than 4.x
 ifeq ($(shell test $(GCC_VERSION) -lt 40 && echo 1), 1)
        MACHINE_CFLAGS =
index 3b907e2..e7008c0 100644 (file)
@@ -99,6 +99,15 @@ ifeq ($(shell test $(GCC_VERSION) -lt 47 && echo 1), 1)
 WERROR_FLAGS += -Wno-uninitialized
 endif
 
 WERROR_FLAGS += -Wno-uninitialized
 endif
 
+HOST_WERROR_FLAGS := $(WERROR_FLAGS)
+
+ifeq ($(shell test $(HOST_GCC_VERSION) -gt 70 && echo 1), 1)
+# Tell GCC only to error for switch fallthroughs without a suitable comment
+HOST_WERROR_FLAGS += -Wimplicit-fallthrough=2
+# Ignore errors for snprintf truncation
+HOST_WERROR_FLAGS += -Wno-format-truncation
+endif
+
 ifeq ($(shell test $(GCC_VERSION) -gt 70 && echo 1), 1)
 # Tell GCC only to error for switch fallthroughs without a suitable comment
 WERROR_FLAGS += -Wimplicit-fallthrough=2
 ifeq ($(shell test $(GCC_VERSION) -gt 70 && echo 1), 1)
 # Tell GCC only to error for switch fallthroughs without a suitable comment
 WERROR_FLAGS += -Wimplicit-fallthrough=2
index 1bd171e..f2486b9 100644 (file)
@@ -30,7 +30,7 @@
 # OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Name: dpdk
 # OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Name: dpdk
-Version: 17.11.3
+Version: 17.11.4
 Release: 1
 Packager: packaging@6wind.com
 URL: http://dpdk.org
 Release: 1
 Packager: packaging@6wind.com
 URL: http://dpdk.org
index fc882ec..c6a9105 100644 (file)
@@ -31,6 +31,7 @@
 
 # The main logic behind running autotests in parallel
 
 
 # The main logic behind running autotests in parallel
 
+from __future__ import print_function
 import StringIO
 import csv
 import multiprocessing
 import StringIO
 import csv
 import multiprocessing
@@ -69,7 +70,7 @@ def wait_prompt(child):
 # quite a bit of effort to make it work).
 
 
 # quite a bit of effort to make it work).
 
 
-def run_test_group(cmdline, test_group):
+def run_test_group(cmdline, target, test_group):
     results = []
     child = None
     start_time = time.time()
     results = []
     child = None
     start_time = time.time()
@@ -80,8 +81,8 @@ def run_test_group(cmdline, test_group):
         # prepare logging of init
         startuplog = StringIO.StringIO()
 
         # prepare logging of init
         startuplog = StringIO.StringIO()
 
-        print >>startuplog, "\n%s %s\n" % ("=" * 20, test_group["Prefix"])
-        print >>startuplog, "\ncmdline=%s" % cmdline
+        print("\n%s %s\n" % ("=" * 20, test_group["Prefix"]), file=startuplog)
+        print("\ncmdline=%s" % cmdline, file=startuplog)
 
         child = pexpect.spawn(cmdline, logfile=startuplog)
 
 
         child = pexpect.spawn(cmdline, logfile=startuplog)
 
@@ -122,13 +123,6 @@ def run_test_group(cmdline, test_group):
     results.append((0, "Success", "Start %s" % test_group["Prefix"],
                     time.time() - start_time, startuplog.getvalue(), None))
 
     results.append((0, "Success", "Start %s" % test_group["Prefix"],
                     time.time() - start_time, startuplog.getvalue(), None))
 
-    # parse the binary for available test commands
-    binary = cmdline.split()[0]
-    stripped = 'not stripped' not in subprocess.check_output(['file', binary])
-    if not stripped:
-        symbols = subprocess.check_output(['nm', binary]).decode('utf-8')
-        avail_cmds = re.findall('test_register_(\w+)', symbols)
-
     # run all tests in test group
     for test in test_group["Tests"]:
 
     # run all tests in test group
     for test in test_group["Tests"]:
 
@@ -145,25 +139,23 @@ def run_test_group(cmdline, test_group):
 
         try:
             # print test name to log buffer
 
         try:
             # print test name to log buffer
-            print >>logfile, "\n%s %s\n" % ("-" * 20, test["Name"])
+            print("\n%s %s\n" % ("-" * 20, test["Name"]), file=logfile)
 
             # run test function associated with the test
 
             # run test function associated with the test
-            if stripped or test["Command"] in avail_cmds:
-                result = test["Func"](child, test["Command"])
-            else:
-                result = (0, "Skipped [Not Available]")
+            result = test["Func"](child, test["Command"])
 
             # make a note when the test was finished
             end_time = time.time()
 
 
             # make a note when the test was finished
             end_time = time.time()
 
+            log = logfile.getvalue()
+
             # append test data to the result tuple
             # append test data to the result tuple
-            result += (test["Name"], end_time - start_time,
-                       logfile.getvalue())
+            result += (test["Name"], end_time - start_time, log)
 
             # call report function, if any defined, and supply it with
             # target and complete log for test run
             if test["Report"]:
 
             # call report function, if any defined, and supply it with
             # target and complete log for test run
             if test["Report"]:
-                report = test["Report"](self.target, log)
+                report = test["Report"](target, log)
 
                 # append report to results tuple
                 result += (report,)
 
                 # append report to results tuple
                 result += (report,)
@@ -212,8 +204,10 @@ class AutotestRunner:
     def __init__(self, cmdline, target, blacklist, whitelist):
         self.cmdline = cmdline
         self.target = target
     def __init__(self, cmdline, target, blacklist, whitelist):
         self.cmdline = cmdline
         self.target = target
+        self.binary = cmdline.split()[0]
         self.blacklist = blacklist
         self.whitelist = whitelist
         self.blacklist = blacklist
         self.whitelist = whitelist
+        self.skipped = []
 
         # log file filename
         logfile = "%s.log" % target
 
         # log file filename
         logfile = "%s.log" % target
@@ -275,7 +269,7 @@ class AutotestRunner:
 
             # don't print out total time every line, it's the same anyway
             if i == len(results) - 1:
 
             # don't print out total time every line, it's the same anyway
             if i == len(results) - 1:
-                print(result,
+                print(result +
                       "[%02dm %02ds]" % (total_time / 60, total_time % 60))
             else:
                 print(result)
                       "[%02dm %02ds]" % (total_time / 60, total_time % 60))
             else:
                 print(result)
@@ -302,53 +296,58 @@ class AutotestRunner:
             if i != 0:
                 self.csvwriter.writerow([test_name, test_result, result_str])
 
             if i != 0:
                 self.csvwriter.writerow([test_name, test_result, result_str])
 
-    # this function iterates over test groups and removes each
-    # test that is not in whitelist/blacklist
-    def __filter_groups(self, test_groups):
-        groups_to_remove = []
-
-        # filter out tests from parallel test groups
-        for i, test_group in enumerate(test_groups):
-
-            # iterate over a copy so that we could safely delete individual
-            # tests
-            for test in test_group["Tests"][:]:
-                test_id = test["Command"]
-
-                # dump tests are specified in full e.g. "Dump_mempool"
-                if "_autotest" in test_id:
-                    test_id = test_id[:-len("_autotest")]
-
-                # filter out blacklisted/whitelisted tests
-                if self.blacklist and test_id in self.blacklist:
-                    test_group["Tests"].remove(test)
-                    continue
-                if self.whitelist and test_id not in self.whitelist:
-                    test_group["Tests"].remove(test)
-                    continue
-
-            # modify or remove original group
-            if len(test_group["Tests"]) > 0:
-                test_groups[i] = test_group
-            else:
-                # remember which groups should be deleted
-                # put the numbers backwards so that we start
-                # deleting from the end, not from the beginning
-                groups_to_remove.insert(0, i)
+    # this function checks individual test and decides if this test should be in
+    # the group by comparing it against  whitelist/blacklist. it also checks if
+    # the test is compiled into the binary, and marks it as skipped if necessary
+    def __filter_test(self, test):
+        test_cmd = test["Command"]
+        test_id = test_cmd
+
+        # dump tests are specified in full e.g. "Dump_mempool"
+        if "_autotest" in test_id:
+            test_id = test_id[:-len("_autotest")]
+
+        # filter out blacklisted/whitelisted tests
+        if self.blacklist and test_id in self.blacklist:
+            return False
+        if self.whitelist and test_id not in self.whitelist:
+            return False
+
+        # if test wasn't compiled in, remove it as well
+
+        # parse the binary for available test commands
+        stripped = 'not stripped' not in \
+                   subprocess.check_output(['file', self.binary])
+        if not stripped:
+            symbols = subprocess.check_output(['nm',
+                                               self.binary]).decode('utf-8')
+            avail_cmds = re.findall('test_register_(\w+)', symbols)
+
+            if test_cmd not in avail_cmds:
+                # notify user
+                result = 0, "Skipped [Not compiled]", test_id, 0, "", None
+                self.skipped.append(tuple(result))
+                return False
 
 
-        # remove test groups that need to be removed
-        for i in groups_to_remove:
-            del test_groups[i]
+        return True
 
 
-        return test_groups
+    def __filter_group(self, group):
+        group["Tests"] = list(filter(self.__filter_test, group["Tests"]))
+        return len(group["Tests"]) > 0
 
     # iterate over test groups and run tests associated with them
     def run_all_tests(self):
         # filter groups
 
     # iterate over test groups and run tests associated with them
     def run_all_tests(self):
         # filter groups
-        self.parallel_test_groups = \
-            self.__filter_groups(self.parallel_test_groups)
-        self.non_parallel_test_groups = \
-            self.__filter_groups(self.non_parallel_test_groups)
+        # for each test group, check all tests against the filter, then remove
+        # all groups that don't have any tests
+        self.parallel_test_groups = list(
+            filter(self.__filter_group,
+                   self.parallel_test_groups)
+        )
+        self.non_parallel_test_groups = list(
+            filter(self.__filter_group,
+                   self.non_parallel_test_groups)
+        )
 
         # create a pool of worker threads
         pool = multiprocessing.Pool(processes=1)
 
         # create a pool of worker threads
         pool = multiprocessing.Pool(processes=1)
@@ -360,17 +359,36 @@ class AutotestRunner:
 
             # create table header
             print("")
 
             # create table header
             print("")
-            print("Test name".ljust(30), "Test result".ljust(29),
-                  "Test".center(9), "Total".center(9))
+            print("Test name".ljust(30) + "Test result".ljust(29) +
+                  "Test".center(9) + "Total".center(9))
             print("=" * 80)
 
             print("=" * 80)
 
+            # print out skipped autotests if there were any
+            if len(self.skipped):
+                print("Skipped autotests:")
+
+                # print out any skipped tests
+                for result in self.skipped:
+                    # unpack result tuple
+                    test_result, result_str, test_name, _, _, _ = result
+                    self.csvwriter.writerow([test_name, test_result,
+                                             result_str])
+
+                    t = ("%s:" % test_name).ljust(30)
+                    t += result_str.ljust(29)
+                    t += "[00m 00s]"
+
+                    print(t)
+
             # make a note of tests start time
             self.start = time.time()
 
             # make a note of tests start time
             self.start = time.time()
 
+            print("Parallel autotests:")
             # assign worker threads to run test groups
             for test_group in self.parallel_test_groups:
                 result = pool.apply_async(run_test_group,
                                           [self.__get_cmdline(test_group),
             # assign worker threads to run test groups
             for test_group in self.parallel_test_groups:
                 result = pool.apply_async(run_test_group,
                                           [self.__get_cmdline(test_group),
+                                           self.target,
                                            test_group])
                 results.append(result)
 
                                            test_group])
                 results.append(result)
 
@@ -392,10 +410,11 @@ class AutotestRunner:
                     # remove result from results list once we're done with it
                     results.remove(group_result)
 
                     # remove result from results list once we're done with it
                     results.remove(group_result)
 
+            print("Non-parallel autotests:")
             # run non_parallel tests. they are run one by one, synchronously
             for test_group in self.non_parallel_test_groups:
                 group_result = run_test_group(
             # run non_parallel tests. they are run one by one, synchronously
             for test_group in self.non_parallel_test_groups:
                 group_result = run_test_group(
-                    self.__get_cmdline(test_group), test_group)
+                    self.__get_cmdline(test_group), self.target, test_group)
 
                 self.__process_results(group_result)
 
 
                 self.__process_results(group_result)
 
index 83cf730..28f982f 100644 (file)
@@ -567,7 +567,7 @@ test_device_configure_invalid_dev_id(void)
        dev_id = ts_params->valid_devs[ts_params->valid_dev_count - 1];
 
        /* Stop the device in case it's started so it can be configured */
        dev_id = ts_params->valid_devs[ts_params->valid_dev_count - 1];
 
        /* Stop the device in case it's started so it can be configured */
-       rte_cryptodev_stop(ts_params->valid_devs[dev_id]);
+       rte_cryptodev_stop(dev_id);
 
        TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf),
                        "Failed test for rte_cryptodev_configure: "
 
        TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf),
                        "Failed test for rte_cryptodev_configure: "
index 473ea11..e82bb96 100644 (file)
@@ -404,17 +404,17 @@ test_invalid_vdev_flag(void)
 #endif
 
        /* Test with invalid vdev option */
 #endif
 
        /* Test with invalid vdev option */
-       const char *vdevinval[] = {prgname, prefix, "-n", "1",
+       const char *vdevinval[] = {prgname, prefix, no_huge, "-n", "1",
                                "-c", "1", vdev, "eth_dummy"};
 
        /* Test with valid vdev option */
                                "-c", "1", vdev, "eth_dummy"};
 
        /* Test with valid vdev option */
-       const char *vdevval1[] = {prgname, prefix, "-n", "1",
+       const char *vdevval1[] = {prgname, prefix, no_huge, "-n", "1",
        "-c", "1", vdev, "net_ring0"};
 
        "-c", "1", vdev, "net_ring0"};
 
-       const char *vdevval2[] = {prgname, prefix, "-n", "1",
+       const char *vdevval2[] = {prgname, prefix, no_huge, "-n", "1",
        "-c", "1", vdev, "net_ring0,args=test"};
 
        "-c", "1", vdev, "net_ring0,args=test"};
 
-       const char *vdevval3[] = {prgname, prefix, "-n", "1",
+       const char *vdevval3[] = {prgname, prefix, no_huge, "-n", "1",
        "-c", "1", vdev, "net_ring0,nodeaction=r1:0:CREATE"};
 
        if (launch_proc(vdevinval) == 0) {
        "-c", "1", vdev, "net_ring0,nodeaction=r1:0:CREATE"};
 
        if (launch_proc(vdevinval) == 0) {
@@ -877,13 +877,10 @@ test_misc_flags(void)
        const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
        /* With invalid --syslog */
        const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
        const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
        /* With invalid --syslog */
        const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
-       /* With no-sh-conf */
+       /* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
        const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
        const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
-                       no_shconf, nosh_prefix };
+                       no_shconf, nosh_prefix, no_huge};
 
 
-#ifdef RTE_EXEC_ENV_BSDAPP
-       return 0;
-#endif
        /* With --huge-dir */
        const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
                        "--file-prefix=hugedir", "--huge-dir", hugepath};
        /* With --huge-dir */
        const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
                        "--file-prefix=hugedir", "--huge-dir", hugepath};
@@ -917,6 +914,7 @@ test_misc_flags(void)
        const char *argv15[] = {prgname, "--file-prefix=intr",
                        "-c", "1", "-n", "2", "--vfio-intr=invalid"};
 
        const char *argv15[] = {prgname, "--file-prefix=intr",
                        "-c", "1", "-n", "2", "--vfio-intr=invalid"};
 
+       /* run all tests also applicable to FreeBSD first */
 
        if (launch_proc(argv0) == 0) {
                printf("Error - process ran ok with invalid flag\n");
 
        if (launch_proc(argv0) == 0) {
                printf("Error - process ran ok with invalid flag\n");
@@ -930,6 +928,16 @@ test_misc_flags(void)
                printf("Error - process did not run ok with -v flag\n");
                return -1;
        }
                printf("Error - process did not run ok with -v flag\n");
                return -1;
        }
+       if (launch_proc(argv6) != 0) {
+               printf("Error - process did not run ok with --no-shconf flag\n");
+               return -1;
+       }
+
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* no more tests to be done on FreeBSD */
+       return 0;
+#endif
+
        if (launch_proc(argv3) != 0) {
                printf("Error - process did not run ok with --syslog flag\n");
                return -1;
        if (launch_proc(argv3) != 0) {
                printf("Error - process did not run ok with --syslog flag\n");
                return -1;
@@ -942,13 +950,6 @@ test_misc_flags(void)
                printf("Error - process run ok with invalid --syslog flag\n");
                return -1;
        }
                printf("Error - process run ok with invalid --syslog flag\n");
                return -1;
        }
-       if (launch_proc(argv6) != 0) {
-               printf("Error - process did not run ok with --no-shconf flag\n");
-               return -1;
-       }
-#ifdef RTE_EXEC_ENV_BSDAPP
-       return 0;
-#endif
        if (launch_proc(argv7) != 0) {
                printf("Error - process did not run ok with --huge-dir flag\n");
                return -1;
        if (launch_proc(argv7) != 0) {
                printf("Error - process did not run ok with --huge-dir flag\n");
                return -1;
index 9f331cd..a8a1cad 100644 (file)
@@ -641,32 +641,32 @@ test_flow_classify(void)
                printf("Line %i: f_create has failed!\n", __LINE__);
                rte_flow_classifier_free(cls->cls);
                rte_free(cls);
                printf("Line %i: f_create has failed!\n", __LINE__);
                rte_flow_classifier_free(cls->cls);
                rte_free(cls);
-               return -1;
+               return TEST_FAILED;
        }
        printf("Created table_acl for for IPv4 five tuple packets\n");
 
        ret = init_mbufpool();
        if (ret) {
                printf("Line %i: init_mbufpool has failed!\n", __LINE__);
        }
        printf("Created table_acl for for IPv4 five tuple packets\n");
 
        ret = init_mbufpool();
        if (ret) {
                printf("Line %i: init_mbufpool has failed!\n", __LINE__);
-               return -1;
+               return TEST_FAILED;
        }
 
        if (test_invalid_parameters() < 0)
        }
 
        if (test_invalid_parameters() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_valid_parameters() < 0)
        if (test_valid_parameters() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_invalid_patterns() < 0)
        if (test_invalid_patterns() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_invalid_actions() < 0)
        if (test_invalid_actions() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_query_udp() < 0)
        if (test_query_udp() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_query_tcp() < 0)
        if (test_query_tcp() < 0)
-               return -1;
+               return TEST_FAILED;
        if (test_query_sctp() < 0)
        if (test_query_sctp() < 0)
-               return -1;
+               return TEST_FAILED;
 
 
-       return 0;
+       return TEST_SUCCESS;
 }
 
 REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);
 }
 
 REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);
index 4dcbd9d..0e9ac71 100644 (file)
@@ -76,18 +76,29 @@ static rte_atomic64_t ginsertions;
 static int use_htm;
 
 static int
 static int use_htm;
 
 static int
-test_hash_multiwriter_worker(__attribute__((unused)) void *arg)
+test_hash_multiwriter_worker(void *arg)
 {
        uint64_t i, offset;
 {
        uint64_t i, offset;
+       uint16_t pos_core;
        uint32_t lcore_id = rte_lcore_id();
        uint64_t begin, cycles;
        uint32_t lcore_id = rte_lcore_id();
        uint64_t begin, cycles;
+       uint16_t *enabled_core_ids = (uint16_t *)arg;
 
 
-       offset = (lcore_id - rte_get_master_lcore())
-               * tbl_multiwriter_test_params.nb_tsx_insertion;
+       for (pos_core = 0; pos_core < rte_lcore_count(); pos_core++) {
+               if (enabled_core_ids[pos_core] == lcore_id)
+                       break;
+       }
+
+       /*
+        * Calculate offset for entries based on the position of the
+        * logical core, from the master core (not counting not enabled cores)
+        */
+       offset = pos_core * tbl_multiwriter_test_params.nb_tsx_insertion;
 
        printf("Core #%d inserting %d: %'"PRId64" - %'"PRId64"\n",
               lcore_id, tbl_multiwriter_test_params.nb_tsx_insertion,
 
        printf("Core #%d inserting %d: %'"PRId64" - %'"PRId64"\n",
               lcore_id, tbl_multiwriter_test_params.nb_tsx_insertion,
-              offset, offset + tbl_multiwriter_test_params.nb_tsx_insertion);
+              offset,
+              offset + tbl_multiwriter_test_params.nb_tsx_insertion - 1);
 
        begin = rte_rdtsc_precise();
 
 
        begin = rte_rdtsc_precise();
 
@@ -116,6 +127,8 @@ test_hash_multiwriter(void)
 {
        unsigned int i, rounded_nb_total_tsx_insertion;
        static unsigned calledCount = 1;
 {
        unsigned int i, rounded_nb_total_tsx_insertion;
        static unsigned calledCount = 1;
+       uint16_t enabled_core_ids[RTE_MAX_LCORE];
+       uint16_t core_id;
 
        uint32_t *keys;
        uint32_t *found;
 
        uint32_t *keys;
        uint32_t *found;
@@ -168,16 +181,17 @@ test_hash_multiwriter(void)
                goto err1;
        }
 
                goto err1;
        }
 
+       for (i = 0; i < nb_entries; i++)
+               keys[i] = i;
+
+       tbl_multiwriter_test_params.keys = keys;
+
        found = rte_zmalloc(NULL, sizeof(uint32_t) * nb_entries, 0);
        if (found == NULL) {
                printf("RTE_ZMALLOC failed\n");
                goto err2;
        }
 
        found = rte_zmalloc(NULL, sizeof(uint32_t) * nb_entries, 0);
        if (found == NULL) {
                printf("RTE_ZMALLOC failed\n");
                goto err2;
        }
 
-       for (i = 0; i < nb_entries; i++)
-               keys[i] = i;
-
-       tbl_multiwriter_test_params.keys = keys;
        tbl_multiwriter_test_params.found = found;
 
        rte_atomic64_init(&gcycles);
        tbl_multiwriter_test_params.found = found;
 
        rte_atomic64_init(&gcycles);
@@ -186,9 +200,27 @@ test_hash_multiwriter(void)
        rte_atomic64_init(&ginsertions);
        rte_atomic64_clear(&ginsertions);
 
        rte_atomic64_init(&ginsertions);
        rte_atomic64_clear(&ginsertions);
 
+       /* Get list of enabled cores */
+       i = 0;
+       for (core_id = 0; core_id < RTE_MAX_LCORE; core_id++) {
+               if (i == rte_lcore_count())
+                       break;
+
+               if (rte_lcore_is_enabled(core_id)) {
+                       enabled_core_ids[i] = core_id;
+                       i++;
+               }
+       }
+
+       if (i != rte_lcore_count()) {
+               printf("Number of enabled cores in list is different from "
+                               "number given by rte_lcore_count()\n");
+               goto err3;
+       }
+
        /* Fire all threads. */
        rte_eal_mp_remote_launch(test_hash_multiwriter_worker,
        /* Fire all threads. */
        rte_eal_mp_remote_launch(test_hash_multiwriter_worker,
-                                NULL, CALL_MASTER);
+                                enabled_core_ids, CALL_MASTER);
        rte_eal_mp_wait_lcore();
 
        while (rte_hash_iterate(handle, &next_key, &next_data, &iter) >= 0) {
        rte_eal_mp_wait_lcore();
 
        while (rte_hash_iterate(handle, &next_key, &next_data, &iter) >= 0) {
index 2cdf60d..8d5813c 100644 (file)
@@ -247,6 +247,8 @@ test_pmd_ring_pair_create_attach(int portd, int porte)
        struct rte_mbuf buf, *pbuf = &buf;
        struct rte_eth_conf null_conf;
 
        struct rte_mbuf buf, *pbuf = &buf;
        struct rte_eth_conf null_conf;
 
+       memset(&null_conf, 0, sizeof(struct rte_eth_conf));
+
        if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0)
                || (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) {
                printf("Configure failed for port\n");
        if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0)
                || (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) {
                printf("Configure failed for port\n");