New upstream version 17.11.1 01/11001/1 upstream/17.11.1
authorLuca Boccassi <luca.boccassi@gmail.com>
Wed, 7 Mar 2018 11:22:30 +0000 (11:22 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 7 Mar 2018 11:23:17 +0000 (11:23 +0000)
Change-Id: Ida1700b5dac8649fc563670a37278e636bea051c
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
253 files changed:
app/Makefile
app/test-pmd/Makefile
app/test-pmd/cmdline.c
app/test-pmd/config.c
app/test-pmd/flowgen.c
app/test-pmd/parameters.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h
app/test-pmd/txonly.c
buildtools/pmdinfogen/pmdinfogen.c
config/common_base
config/common_linuxapp
doc/guides/cryptodevs/openssl.rst
doc/guides/cryptodevs/qat.rst
doc/guides/nics/i40e.rst
doc/guides/nics/mlx4.rst
doc/guides/rel_notes/release_17_11.rst
doc/guides/sample_app_ug/ipsec_secgw.rst
doc/guides/sample_app_ug/keep_alive.rst
drivers/bus/dpaa/base/qbman/bman.h
drivers/bus/dpaa/base/qbman/qman.c
drivers/bus/dpaa/base/qbman/qman.h
drivers/bus/dpaa/dpaa_bus.c
drivers/bus/dpaa/include/fsl_qman.h
drivers/bus/dpaa/rte_dpaa_bus.h
drivers/bus/fslmc/fslmc_vfio.c
drivers/bus/fslmc/mc/fsl_mc_sys.h
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
drivers/bus/fslmc/rte_fslmc.h
drivers/bus/pci/linux/pci.c
drivers/bus/pci/linux/pci_vfio.c
drivers/bus/pci/pci_common_uio.c
drivers/bus/vdev/vdev.c
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
drivers/crypto/dpaa_sec/dpaa_sec.c
drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
drivers/crypto/qat/qat_crypto.c
drivers/crypto/qat/qat_qp.c
drivers/crypto/scheduler/rte_cryptodev_scheduler.c
drivers/event/octeontx/Makefile
drivers/event/octeontx/ssovf_worker.h
drivers/event/sw/sw_evdev.c
drivers/event/sw/sw_evdev.h
drivers/mempool/octeontx/octeontx_fpavf.c
drivers/mempool/octeontx/octeontx_fpavf.h
drivers/mempool/octeontx/octeontx_mbox.c
drivers/mempool/octeontx/rte_mempool_octeontx.c
drivers/net/af_packet/rte_eth_af_packet.c
drivers/net/avp/rte_avp_common.h
drivers/net/bnxt/bnxt.h
drivers/net/bnxt/bnxt_cpr.c
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_filter.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_ring.c
drivers/net/bnxt/bnxt_ring.h
drivers/net/bnxt/bnxt_rxq.c
drivers/net/bnxt/bnxt_rxr.c
drivers/net/bnxt/bnxt_txr.c
drivers/net/bonding/rte_eth_bond_8023ad.c
drivers/net/bonding/rte_eth_bond_api.c
drivers/net/bonding/rte_eth_bond_pmd.c
drivers/net/bonding/rte_eth_bond_private.h
drivers/net/dpaa/dpaa_ethdev.c
drivers/net/dpaa/dpaa_ethdev.h
drivers/net/dpaa/dpaa_rxtx.c
drivers/net/e1000/em_ethdev.c
drivers/net/e1000/igb_ethdev.c
drivers/net/e1000/igb_flow.c
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/enic/enic_rxtx.c
drivers/net/failsafe/failsafe.c
drivers/net/failsafe/failsafe_args.c
drivers/net/failsafe/failsafe_rxtx.c
drivers/net/fm10k/fm10k_ethdev.c
drivers/net/i40e/i40e_ethdev.c
drivers/net/i40e/i40e_ethdev.h
drivers/net/i40e/i40e_ethdev_vf.c
drivers/net/i40e/i40e_fdir.c
drivers/net/i40e/i40e_flow.c
drivers/net/i40e/i40e_rxtx.c
drivers/net/i40e/rte_pmd_i40e.c
drivers/net/i40e/rte_pmd_i40e.h
drivers/net/ixgbe/base/ixgbe_common.c
drivers/net/ixgbe/ixgbe_ethdev.c
drivers/net/ixgbe/ixgbe_fdir.c
drivers/net/ixgbe/ixgbe_flow.c
drivers/net/ixgbe/ixgbe_pf.c
drivers/net/kni/rte_eth_kni.c
drivers/net/mlx4/Makefile
drivers/net/mlx4/mlx4.c
drivers/net/mlx4/mlx4_flow.c
drivers/net/mlx4/mlx4_rxtx.c
drivers/net/mlx4/mlx4_txq.c
drivers/net/mlx4/mlx4_utils.h
drivers/net/mlx5/mlx5.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_defs.h
drivers/net/mlx5/mlx5_ethdev.c
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_mac.c
drivers/net/mlx5/mlx5_mr.c
drivers/net/mlx5/mlx5_rss.c
drivers/net/mlx5/mlx5_rxmode.c
drivers/net/mlx5/mlx5_rxq.c
drivers/net/mlx5/mlx5_rxtx.c
drivers/net/mlx5/mlx5_rxtx.h
drivers/net/mlx5/mlx5_rxtx_vec.c
drivers/net/mlx5/mlx5_rxtx_vec_neon.h
drivers/net/mlx5/mlx5_rxtx_vec_sse.h
drivers/net/mlx5/mlx5_stats.c
drivers/net/mlx5/mlx5_trigger.c
drivers/net/mlx5/mlx5_txq.c
drivers/net/mlx5/mlx5_vlan.c
drivers/net/mrvl/mrvl_ethdev.c
drivers/net/mrvl/mrvl_ethdev.h
drivers/net/mrvl/mrvl_qos.c
drivers/net/nfp/nfp_net.c
drivers/net/null/rte_eth_null.c
drivers/net/octeontx/octeontx_ethdev.c
drivers/net/octeontx/octeontx_ethdev.h
drivers/net/octeontx/rte_pmd_octeontx_version.map
drivers/net/pcap/rte_eth_pcap.c
drivers/net/qede/base/ecore_dcbx.c
drivers/net/qede/base/ecore_vf.c
drivers/net/qede/base/ecore_vfpf_if.h
drivers/net/qede/qede_ethdev.c
drivers/net/qede/qede_ethdev.h
drivers/net/qede/qede_rxtx.c
drivers/net/qede/qede_rxtx.h
drivers/net/ring/rte_eth_ring.c
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_ef10_rx.c
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_ev.c
drivers/net/sfc/sfc_flow.c
drivers/net/sfc/sfc_intr.c
drivers/net/sfc/sfc_port.c
drivers/net/softnic/rte_eth_softnic.c
drivers/net/szedata2/rte_eth_szedata2.c
drivers/net/tap/rte_eth_tap.c
drivers/net/thunderx/nicvf_ethdev.c
drivers/net/thunderx/nicvf_rxtx.c
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_user/virtio_user_dev.c
drivers/net/virtio/virtqueue.c
drivers/net/virtio/virtqueue.h
drivers/net/vmxnet3/vmxnet3_ethdev.c
examples/bond/main.c
examples/ip_pipeline/init.c
examples/ipsec-secgw/ipsec-secgw.c
examples/ipsec-secgw/ipsec.c
examples/ipsec-secgw/sa.c
examples/l3fwd-power/main.c
examples/vhost/main.c
lib/Makefile
lib/librte_cmdline/cmdline_cirbuf.h
lib/librte_cmdline/cmdline_parse.c
lib/librte_cryptodev/rte_crypto.h
lib/librte_cryptodev/rte_cryptodev.c
lib/librte_cryptodev/rte_cryptodev.h
lib/librte_cryptodev/rte_cryptodev_pmd.h
lib/librte_eal/common/arch/ppc_64/rte_cycles.c
lib/librte_eal/common/eal_common_log.c
lib/librte_eal/common/eal_common_memzone.c
lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
lib/librte_eal/common/include/arch/ppc_64/rte_atomic.h
lib/librte_eal/common/include/arch/x86/rte_atomic.h
lib/librte_eal/common/include/arch/x86/rte_byteorder.h
lib/librte_eal/common/include/arch/x86/rte_cycles.h
lib/librte_eal/common/include/arch/x86/rte_memcpy.h
lib/librte_eal/common/include/arch/x86/rte_vect.h
lib/librte_eal/common/include/generic/rte_byteorder.h
lib/librte_eal/common/include/rte_bitmap.h
lib/librte_eal/common/include/rte_common.h
lib/librte_eal/common/include/rte_dev.h
lib/librte_eal/common/include/rte_eal.h
lib/librte_eal/common/include/rte_eal_memconfig.h
lib/librte_eal/common/include/rte_keepalive.h
lib/librte_eal/common/include/rte_lcore.h
lib/librte_eal/common/include/rte_log.h
lib/librte_eal/common/include/rte_memory.h
lib/librte_eal/common/include/rte_service.h
lib/librte_eal/common/include/rte_version.h
lib/librte_eal/common/malloc_elem.c
lib/librte_eal/common/malloc_heap.c
lib/librte_eal/common/malloc_heap.h
lib/librte_eal/common/rte_keepalive.c
lib/librte_eal/common/rte_service.c
lib/librte_eal/linuxapp/eal/eal_vfio.c
lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
lib/librte_eal/linuxapp/igb_uio/igb_uio.c
lib/librte_eal/linuxapp/kni/ethtool/igb/igb_main.c
lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h
lib/librte_ether/rte_ethdev.c
lib/librte_ether/rte_ethdev.h
lib/librte_ether/rte_ethdev_pci.h
lib/librte_ether/rte_ethdev_vdev.h
lib/librte_eventdev/rte_eventdev.c
lib/librte_eventdev/rte_eventdev.h
lib/librte_eventdev/rte_eventdev_pmd.h
lib/librte_eventdev/rte_eventdev_pmd_pci.h
lib/librte_eventdev/rte_eventdev_pmd_vdev.h
lib/librte_flow_classify/rte_flow_classify.h
lib/librte_hash/rte_fbk_hash.h
lib/librte_hash/rte_hash_crc.h
lib/librte_hash/rte_jhash.h
lib/librte_hash/rte_thash.h
lib/librte_ip_frag/rte_ip_frag.h
lib/librte_lpm/rte_lpm.c
lib/librte_lpm/rte_lpm.h
lib/librte_mbuf/rte_mbuf.h
lib/librte_member/rte_member.c
lib/librte_member/rte_member.h
lib/librte_mempool/rte_mempool.c
lib/librte_mempool/rte_mempool.h
lib/librte_net/rte_esp.h
lib/librte_pdump/rte_pdump.c
lib/librte_ring/rte_ring.h
lib/librte_security/rte_security.c
lib/librte_security/rte_security.h
lib/librte_table/rte_lru.h
lib/librte_table/rte_lru_x86.h
lib/librte_timer/rte_timer.c
lib/librte_timer/rte_timer.h
lib/librte_vhost/iotlb.c
lib/librte_vhost/iotlb.h
lib/librte_vhost/socket.c
lib/librte_vhost/vhost.c
lib/librte_vhost/vhost.h
lib/librte_vhost/vhost_user.c
lib/librte_vhost/virtio_net.c
mk/internal/rte.extvars.mk
mk/machine/tilegx/rte.vars.mk [deleted file]
pkg/dpdk.spec
test/test/test.c
test/test/test_bitmap.c
test/test/test_cryptodev.c
test/test/test_eventdev.c
test/test/test_eventdev_octeontx.c
test/test/test_memzone.c
test/test/test_reorder.c
test/test/test_ring.c
test/test/test_ring_perf.c
test/test/test_service_cores.c
test/test/test_table.c
test/test/test_table_acl.c
test/test/test_timer_perf.c
usertools/dpdk-devbind.py

index 7ea02b0..6398c18 100644 (file)
@@ -32,7 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd
-DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += proc_info
+DIRS-$(CONFIG_RTE_PROC_INFO) += proc_info
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump
 
 ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
index d21308f..4993c91 100644 (file)
@@ -83,10 +83,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
 LDLIBS += -lrte_pmd_bnxt
 endif
 
-ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
-LDLIBS += -lrte_pmd_xenvirt
-endif
-
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC),y)
 LDLIBS += -lrte_pmd_softnic
 endif
index f71d963..b3c3f24 100644 (file)
@@ -1501,6 +1501,8 @@ cmd_config_rx_tx_parsed(void *parsed_result,
                        printf("Warning: Either rx or tx queues should be non zero\n");
                        return;
                }
+               if (check_nb_rxq(res->value) != 0)
+                       return;
                nb_rxq = res->value;
        }
        else if (!strcmp(res->name, "txq")) {
@@ -1508,6 +1510,8 @@ cmd_config_rx_tx_parsed(void *parsed_result,
                        printf("Warning: Either rx or tx queues should be non zero\n");
                        return;
                }
+               if (check_nb_txq(res->value) != 0)
+                       return;
                nb_txq = res->value;
        }
        else if (!strcmp(res->name, "rxd")) {
@@ -3352,7 +3356,7 @@ cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
                              tp_id, UINT16);
 cmdline_parse_token_num_t cmd_vlan_tpid_portid =
        TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
-                             port_id, UINT8);
+                             port_id, UINT16);
 
 cmdline_parse_inst_t cmd_vlan_tpid = {
        .f = cmd_vlan_tpid_parsed,
@@ -9747,11 +9751,11 @@ struct cmd_flow_director_result {
        uint16_t port_dst;
        cmdline_fixed_string_t verify_tag;
        uint32_t verify_tag_value;
-       cmdline_ipaddr_t tos;
+       cmdline_fixed_string_t tos;
        uint8_t tos_value;
-       cmdline_ipaddr_t proto;
+       cmdline_fixed_string_t proto;
        uint8_t proto_value;
-       cmdline_ipaddr_t ttl;
+       cmdline_fixed_string_t ttl;
        uint8_t ttl_value;
        cmdline_fixed_string_t vlan;
        uint16_t vlan_value;
@@ -10298,7 +10302,7 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
                (void *)&cmd_flow_director_flow_type,
                (void *)&cmd_flow_director_src,
                (void *)&cmd_flow_director_ip_src,
-               (void *)&cmd_flow_director_port_dst,
+               (void *)&cmd_flow_director_port_src,
                (void *)&cmd_flow_director_dst,
                (void *)&cmd_flow_director_ip_dst,
                (void *)&cmd_flow_director_port_dst,
index cd2ac11..a0f3c24 100644 (file)
@@ -724,11 +724,14 @@ port_offload_cap_display(portid_t port_id)
 int
 port_id_is_invalid(portid_t port_id, enum print_warning warning)
 {
+       uint16_t pid;
+
        if (port_id == (portid_t)RTE_PORT_ALL)
                return 0;
 
-       if (rte_eth_dev_is_valid_port(port_id))
-               return 0;
+       RTE_ETH_FOREACH_DEV(pid)
+               if (port_id == pid)
+                       return 0;
 
        if (warning == ENABLED_WARN)
                printf("Invalid port %d\n", port_id);
@@ -1655,33 +1658,45 @@ fwd_lcores_config_display(void)
 void
 rxtx_config_display(void)
 {
-       printf("  %s packet forwarding%s - CRC stripping %s - "
-              "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name,
+       portid_t pid;
+
+       printf("  %s packet forwarding%s packets/burst=%d\n",
+              cur_fwd_eng->fwd_mode_name,
               retry_enabled == 0 ? "" : " with retry",
-              rx_mode.hw_strip_crc ? "enabled" : "disabled",
               nb_pkt_per_burst);
 
        if (cur_fwd_eng == &tx_only_engine || cur_fwd_eng == &flow_gen_engine)
                printf("  packet len=%u - nb packet segments=%d\n",
                                (unsigned)tx_pkt_length, (int) tx_pkt_nb_segs);
 
-       struct rte_eth_rxconf *rx_conf = &ports[0].rx_conf;
-       struct rte_eth_txconf *tx_conf = &ports[0].tx_conf;
-
        printf("  nb forwarding cores=%d - nb forwarding ports=%d\n",
               nb_fwd_lcores, nb_fwd_ports);
-       printf("  RX queues=%d - RX desc=%d - RX free threshold=%d\n",
-              nb_rxq, nb_rxd, rx_conf->rx_free_thresh);
-       printf("  RX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
-              rx_conf->rx_thresh.pthresh, rx_conf->rx_thresh.hthresh,
-              rx_conf->rx_thresh.wthresh);
-       printf("  TX queues=%d - TX desc=%d - TX free threshold=%d\n",
-              nb_txq, nb_txd, tx_conf->tx_free_thresh);
-       printf("  TX threshold registers: pthresh=%d hthresh=%d wthresh=%d\n",
-              tx_conf->tx_thresh.pthresh, tx_conf->tx_thresh.hthresh,
-              tx_conf->tx_thresh.wthresh);
-       printf("  TX RS bit threshold=%d - TXQ flags=0x%"PRIx32"\n",
-              tx_conf->tx_rs_thresh, tx_conf->txq_flags);
+
+       RTE_ETH_FOREACH_DEV(pid) {
+               struct rte_eth_rxconf *rx_conf = &ports[pid].rx_conf;
+               struct rte_eth_txconf *tx_conf = &ports[pid].tx_conf;
+
+               printf("  port %d:\n", (unsigned int)pid);
+               printf("  CRC stripping %s\n",
+                               ports[pid].dev_conf.rxmode.hw_strip_crc ?
+                               "enabled" : "disabled");
+               printf("  RX queues=%d - RX desc=%d - RX free threshold=%d\n",
+                               nb_rxq, nb_rxd, rx_conf->rx_free_thresh);
+               printf("  RX threshold registers: pthresh=%d hthresh=%d "
+                      " wthresh=%d\n",
+                               rx_conf->rx_thresh.pthresh,
+                               rx_conf->rx_thresh.hthresh,
+                               rx_conf->rx_thresh.wthresh);
+               printf("  TX queues=%d - TX desc=%d - TX free threshold=%d\n",
+                               nb_txq, nb_txd, tx_conf->tx_free_thresh);
+               printf("  TX threshold registers: pthresh=%d hthresh=%d "
+                      " wthresh=%d\n",
+                               tx_conf->tx_thresh.pthresh,
+                               tx_conf->tx_thresh.hthresh,
+                               tx_conf->tx_thresh.wthresh);
+               printf("  TX RS bit threshold=%d - TXQ flags=0x%"PRIx32"\n",
+                               tx_conf->tx_rs_thresh, tx_conf->txq_flags);
+       }
 }
 
 void
@@ -1861,6 +1876,36 @@ setup_fwd_config_of_each_lcore(struct fwd_config *cfg)
        }
 }
 
+static portid_t
+fwd_topology_tx_port_get(portid_t rxp)
+{
+       static int warning_once = 1;
+
+       RTE_ASSERT(rxp < cur_fwd_config.nb_fwd_ports);
+
+       switch (port_topology) {
+       default:
+       case PORT_TOPOLOGY_PAIRED:
+               if ((rxp & 0x1) == 0) {
+                       if (rxp + 1 < cur_fwd_config.nb_fwd_ports)
+                               return rxp + 1;
+                       if (warning_once) {
+                               printf("\nWarning! port-topology=paired"
+                                      " and odd forward ports number,"
+                                      " the last port will pair with"
+                                      " itself.\n\n");
+                               warning_once = 0;
+                       }
+                       return rxp;
+               }
+               return rxp - 1;
+       case PORT_TOPOLOGY_CHAINED:
+               return (rxp + 1) % cur_fwd_config.nb_fwd_ports;
+       case PORT_TOPOLOGY_LOOP:
+               return rxp;
+       }
+}
+
 static void
 simple_fwd_config_setup(void)
 {
@@ -1923,11 +1968,6 @@ simple_fwd_config_setup(void)
  * For the RSS forwarding test all streams distributed over lcores. Each stream
  * being composed of a RX queue to poll on a RX port for input messages,
  * associated with a TX queue of a TX port where to send forwarded packets.
- * All packets received on the RX queue of index "RxQj" of the RX port "RxPi"
- * are sent on the TX queue "TxQl" of the TX port "TxPk" according to the two
- * following rules:
- *    - TxPk = (RxPi + 1) if RxPi is even, (RxPi - 1) if RxPi is odd
- *    - TxQl = RxQj
  */
 static void
 rss_fwd_config_setup(void)
@@ -1959,18 +1999,7 @@ rss_fwd_config_setup(void)
                struct fwd_stream *fs;
 
                fs = fwd_streams[sm_id];
-
-               if ((rxp & 0x1) == 0)
-                       txp = (portid_t) (rxp + 1);
-               else
-                       txp = (portid_t) (rxp - 1);
-               /*
-                * if we are in loopback, simply send stuff out through the
-                * ingress port
-                */
-               if (port_topology == PORT_TOPOLOGY_LOOP)
-                       txp = rxp;
-
+               txp = fwd_topology_tx_port_get(rxp);
                fs->rx_port = fwd_ports_ids[rxp];
                fs->rx_queue = rxq;
                fs->tx_port = fwd_ports_ids[txp];
@@ -1985,11 +2014,7 @@ rss_fwd_config_setup(void)
                 * Restart from RX queue 0 on next RX port
                 */
                rxq = 0;
-               if (numa_support && (nb_fwd_ports <= (nb_ports >> 1)))
-                       rxp = (portid_t)
-                               (rxp + ((nb_ports >> 1) / nb_fwd_ports));
-               else
-                       rxp = (portid_t) (rxp + 1);
+               rxp++;
        }
 }
 
index acf9af9..46478fc 100644 (file)
@@ -123,7 +123,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
        struct ipv4_hdr *ip_hdr;
        struct udp_hdr *udp_hdr;
        uint16_t vlan_tci, vlan_tci_outer;
-       uint16_t ol_flags;
+       uint64_t ol_flags;
        uint16_t nb_rx;
        uint16_t nb_tx;
        uint16_t nb_pkt;
@@ -151,7 +151,13 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
        mbp = current_fwd_lcore()->mbp;
        vlan_tci = ports[fs->tx_port].tx_vlan_id;
        vlan_tci_outer = ports[fs->tx_port].tx_vlan_id_outer;
-       ol_flags = ports[fs->tx_port].tx_ol_flags;
+
+       if (ports[fs->tx_port].tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_VLAN)
+               ol_flags = PKT_TX_VLAN_PKT;
+       if (ports[fs->tx_port].tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+               ol_flags |= PKT_TX_QINQ_PKT;
+       if (ports[fs->tx_port].tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+               ol_flags |= PKT_TX_MACSEC;
 
        for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
                pkt = rte_mbuf_raw_alloc(mbp);
index 84e7a63..8fbb515 100644 (file)
@@ -565,6 +565,7 @@ launch_args_parse(int argc, char** argv)
        int n, opt;
        char **argvopt;
        int opt_idx;
+       portid_t pid;
        enum { TX, RX };
 
        static struct option lgopts[] = {
@@ -951,21 +952,21 @@ launch_args_parse(int argc, char** argv)
                                rss_hf = ETH_RSS_UDP;
                        if (!strcmp(lgopts[opt_idx].name, "rxq")) {
                                n = atoi(optarg);
-                               if (n >= 0 && n <= (int) MAX_QUEUE_ID)
+                               if (n >= 0 && check_nb_rxq((queueid_t)n) == 0)
                                        nb_rxq = (queueid_t) n;
                                else
                                        rte_exit(EXIT_FAILURE, "rxq %d invalid - must be"
-                                                 " >= 0 && <= %d\n", n,
-                                                 (int) MAX_QUEUE_ID);
+                                                 " >= 0 && <= %u\n", n,
+                                                 get_allowed_max_nb_rxq(&pid));
                        }
                        if (!strcmp(lgopts[opt_idx].name, "txq")) {
                                n = atoi(optarg);
-                               if (n >= 0 && n <= (int) MAX_QUEUE_ID)
+                               if (n >= 0 && check_nb_txq((queueid_t)n) == 0)
                                        nb_txq = (queueid_t) n;
                                else
                                        rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
-                                                 " >= 0 && <= %d\n", n,
-                                                 (int) MAX_QUEUE_ID);
+                                                 " >= 0 && <= %u\n", n,
+                                                 get_allowed_max_nb_txq(&pid));
                        }
                        if (!nb_rxq && !nb_txq) {
                                rte_exit(EXIT_FAILURE, "Either rx or tx queues should "
index c3ab448..f66f4c6 100644 (file)
@@ -568,6 +568,98 @@ check_socket_id(const unsigned int socket_id)
        return 0;
 }
 
+/*
+ * Get the allowed maximum number of RX queues.
+ * *pid return the port id which has minimal value of
+ * max_rx_queues in all ports.
+ */
+queueid_t
+get_allowed_max_nb_rxq(portid_t *pid)
+{
+       queueid_t allowed_max_rxq = MAX_QUEUE_ID;
+       portid_t pi;
+       struct rte_eth_dev_info dev_info;
+
+       RTE_ETH_FOREACH_DEV(pi) {
+               rte_eth_dev_info_get(pi, &dev_info);
+               if (dev_info.max_rx_queues < allowed_max_rxq) {
+                       allowed_max_rxq = dev_info.max_rx_queues;
+                       *pid = pi;
+               }
+       }
+       return allowed_max_rxq;
+}
+
+/*
+ * Check input rxq is valid or not.
+ * If input rxq is not greater than any of maximum number
+ * of RX queues of all ports, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_rxq(queueid_t rxq)
+{
+       queueid_t allowed_max_rxq;
+       portid_t pid = 0;
+
+       allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
+       if (rxq > allowed_max_rxq) {
+               printf("Fail: input rxq (%u) can't be greater "
+                      "than max_rx_queues (%u) of port %u\n",
+                      rxq,
+                      allowed_max_rxq,
+                      pid);
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Get the allowed maximum number of TX queues.
+ * *pid return the port id which has minimal value of
+ * max_tx_queues in all ports.
+ */
+queueid_t
+get_allowed_max_nb_txq(portid_t *pid)
+{
+       queueid_t allowed_max_txq = MAX_QUEUE_ID;
+       portid_t pi;
+       struct rte_eth_dev_info dev_info;
+
+       RTE_ETH_FOREACH_DEV(pi) {
+               rte_eth_dev_info_get(pi, &dev_info);
+               if (dev_info.max_tx_queues < allowed_max_txq) {
+                       allowed_max_txq = dev_info.max_tx_queues;
+                       *pid = pi;
+               }
+       }
+       return allowed_max_txq;
+}
+
+/*
+ * Check input txq is valid or not.
+ * If input txq is not greater than any of maximum number
+ * of TX queues of all ports, it is valid.
+ * if valid, return 0, else return -1
+ */
+int
+check_nb_txq(queueid_t txq)
+{
+       queueid_t allowed_max_txq;
+       portid_t pid = 0;
+
+       allowed_max_txq = get_allowed_max_nb_txq(&pid);
+       if (txq > allowed_max_txq) {
+               printf("Fail: input txq (%u) can't be greater "
+                      "than max_tx_queues (%u) of port %u\n",
+                      txq,
+                      allowed_max_txq,
+                      pid);
+               return -1;
+       }
+       return 0;
+}
+
 static void
 init_config(void)
 {
index 1639d27..92e1607 100644 (file)
@@ -728,6 +728,11 @@ enum print_warning {
 int port_id_is_invalid(portid_t port_id, enum print_warning warning);
 int new_socket_id(unsigned int socket_id);
 
+queueid_t get_allowed_max_nb_rxq(portid_t *pid);
+int check_nb_rxq(queueid_t rxq);
+queueid_t get_allowed_max_nb_txq(portid_t *pid);
+int check_nb_txq(queueid_t txq);
+
 /*
  * Work-around of a compilation error with ICC on invocations of the
  * rte_be_to_cpu_16() function.
index 309c738..4ce4d61 100644 (file)
@@ -104,6 +104,7 @@ copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
                buf = ((char*) buf + copy_len);
                seg = seg->next;
                seg_buf = rte_pktmbuf_mtod(seg, char *);
+               copy_len = seg->data_len;
        }
        rte_memcpy(seg_buf, buf, (size_t) len);
 }
index 96ccbf3..b07dbcf 100644 (file)
@@ -158,7 +158,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
                 * There are more than 64k sections,
                 * read count from .sh_size.
                 */
-               info->num_sections = TO_NATIVE(endian, 32, sechdrs[0].sh_size);
+               info->num_sections =
+                       TO_NATIVE(endian, ADDR_SIZE, sechdrs[0].sh_size);
        } else {
                info->num_sections = hdr->e_shnum;
        }
@@ -181,7 +182,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
                sechdrs[i].sh_offset    =
                        TO_NATIVE(endian, ADDR_SIZE, sechdrs[i].sh_offset);
                sechdrs[i].sh_size      =
-                       TO_NATIVE(endian, 32, sechdrs[i].sh_size);
+                       TO_NATIVE(endian, ADDR_SIZE, sechdrs[i].sh_size);
                sechdrs[i].sh_link      =
                        TO_NATIVE(endian, 32, sechdrs[i].sh_link);
                sechdrs[i].sh_info      =
index e74febe..214d9a2 100644 (file)
@@ -230,7 +230,6 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
 #
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS=n
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
 
 #
@@ -415,7 +414,6 @@ CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_RX=n
-CONFIG_RTE_LIBRTE_QEDE_VF_TX_SWITCH=y
 #Provides abs path/name of the firmware file.
 #Empty string denotes driver will use default firmware
 CONFIG_RTE_LIBRTE_QEDE_FW=""
@@ -804,6 +802,11 @@ CONFIG_RTE_LIBRTE_PMD_VHOST=n
 CONFIG_RTE_APP_TEST=y
 CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
 
+#
+# Compile the procinfo application
+#
+CONFIG_RTE_PROC_INFO=n
+
 #
 # Compile the PMD test application
 #
index 74c7d64..15c6961 100644 (file)
@@ -50,3 +50,4 @@ CONFIG_RTE_LIBRTE_AVP_PMD=y
 CONFIG_RTE_LIBRTE_NFP_PMD=y
 CONFIG_RTE_LIBRTE_POWER=y
 CONFIG_RTE_VIRTIO_USER=y
+CONFIG_RTE_PROC_INFO=y
index 243ea36..61a4da3 100644 (file)
@@ -44,6 +44,7 @@ Features
 OpenSSL PMD has support for:
 
 Supported cipher algorithms:
+
 * ``RTE_CRYPTO_CIPHER_3DES_CBC``
 * ``RTE_CRYPTO_CIPHER_AES_CBC``
 * ``RTE_CRYPTO_CIPHER_AES_CTR``
@@ -51,6 +52,7 @@ Supported cipher algorithms:
 * ``RTE_CRYPTO_CIPHER_DES_DOCSISBPI``
 
 Supported authentication algorithms:
+
 * ``RTE_CRYPTO_AUTH_AES_GMAC``
 * ``RTE_CRYPTO_AUTH_MD5``
 * ``RTE_CRYPTO_AUTH_SHA1``
@@ -66,6 +68,7 @@ Supported authentication algorithms:
 * ``RTE_CRYPTO_AUTH_SHA512_HMAC``
 
 Supported AEAD algorithms:
+
 * ``RTE_CRYPTO_AEAD_AES_GCM``
 * ``RTE_CRYPTO_AEAD_AES_CCM``
 
@@ -77,17 +80,23 @@ To compile openssl PMD, it has to be enabled in the config/common_base file
 and appropriate openssl packages have to be installed in the build environment.
 
 The newest openssl library version is supported:
+
 * 1.0.2h-fips  3 May 2016.
+
 Older versions that were also verified:
+
 * 1.0.1f 6 Jan 2014
 * 1.0.1 14 Mar 2012
 
 For Ubuntu 14.04 LTS these packages have to be installed in the build system:
-sudo apt-get install openssl
-sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target)
+
+.. code-block:: console
+
+    sudo apt-get install openssl
+    sudo apt-get install libc6-dev-i386 # for i686-native-linuxapp-gcc target
 
 This code was also verified on Fedora 24.
-This code was NOT yet verified on FreeBSD.
+This code has NOT been verified on FreeBSD yet.
 
 Initialization
 --------------
index cb17b6b..581cd2f 100644 (file)
@@ -78,6 +78,7 @@ Hash algorithms:
 * ``RTE_CRYPTO_AUTH_ZUC_EIA3``
 
 Supported AEAD algorithms:
+
 * ``RTE_CRYPTO_AEAD_AES_GCM``
 
 
index cd46874..71d9561 100644 (file)
@@ -134,6 +134,17 @@ Driver compilation and testing
 Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
 for details.
 
+- ``Support multiple driver`` (default ``disable``)
+
+  There was a multiple driver support issue during use of 700 series Ethernet
+  Adapter with both Linux kernel and DPDK PMD. To fix this issue, ``devargs``
+  parameter ``support-multi-driver`` is introduced, for example::
+
+    -w 84:00.0,support-multi-driver=1
+
+  With the above configuration, DPDK PMD will not change global registers, and
+  will switch PF interrupt from IntN to Int0 to avoid interrupt conflict between
+  DPDK and Linux Kernel.
 
 SR-IOV: Prerequisites and sample Application Notes
 --------------------------------------------------
@@ -483,6 +494,18 @@ Vlan strip of VF
 
 The VF vlan strip function is only supported in the i40e kernel driver >= 2.1.26.
 
+Global configuration warning
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I40E PMD will set some global registers to enable some function or set some
+configure. Then when using different ports of the same NIC with Linux kernel
+and DPDK, the port with Linux kernel will be impacted by the port with DPDK.
+For example, register I40E_GL_SWT_L2TAGCTRL is used to control L2 tag, i40e
+PMD uses I40E_GL_SWT_L2TAGCTRL to set vlan TPID. If setting TPID in port A
+with DPDK, then the configuration will also impact port B in the NIC with
+kernel driver, which don't want to use the TPID.
+So PMD reports warning to clarify what is changed by writing global register.
+
 High Performance of Small Packets on 40G NIC
 --------------------------------------------
 
index 22341b9..cab45df 100644 (file)
@@ -92,14 +92,6 @@ These options can be modified in the ``.config`` file.
   adds additional run-time checks and debugging messages at the cost of
   lower performance.
 
-- ``CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS`` (default **n**)
-
-  Mellanox OFED versions earlier than 4.2 may return false errors from
-  Verbs object destruction APIs after the device is plugged out.
-  Enabling this option replaces assertion checks that cause the program
-  to abort with harmless debugging messages as a workaround.
-  Relevant only when CONFIG_RTE_LIBRTE_MLX4_DEBUG is enabled.
-
 - ``CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE`` (default **8**)
 
   Maximum number of cached memory pools (MPs) per TX queue. Each MP from
index 016a08c..77f2ea0 100644 (file)
@@ -820,3 +820,258 @@ Tested Platforms
        * Host interface: PCI Express 3.0 x16
        * Device ID: 15b3:1017
        * Firmware version: 16.21.1000
+
+Fixes in 17.11 LTS Release
+--------------------------
+
+17.11.1
+~~~~~~~
+
+* app/procinfo: add compilation option in config
+* app/testpmd: fix crash of txonly with multiple segments
+* app/testpmd: fix flow director filter
+* app/testpmd: fix flowgen forwarding offload flags
+* app/testpmd: fix invalid Rx queue number setting
+* app/testpmd: fix invalid Tx queue number setting
+* app/testpmd: fix port configuration print
+* app/testpmd: fix port id allocation
+* app/testpmd: fix port index in RSS forward config
+* app/testpmd: fix port topology in RSS forward config
+* app/testpmd: fix port validation
+* app/testpmd: remove xenvirt again
+* bus/dpaa: fix ARM big endian build
+* bus/dpaa: fix build when assert enabled
+* bus/dpaa: fix default IOVA mode
+* bus/fslmc: fix build with latest glibc
+* bus/fslmc: fix the cplusplus macro closure
+* bus/pci: fix interrupt handler type
+* bus/pci: forbid IOVA mode if IOMMU address width too small
+* bus/vdev: continue probing after a device failure
+* cmdline: avoid garbage in unused fields of parsed result
+* cmdline: fix dynamic tokens parsing
+* cryptodev: add missing CPU flag string
+* cryptodev: fix function prototype
+* cryptodev: fix session pointer cast
+* crypto/dpaa2_sec: fix enum conversion for GCM
+* crypto: fix pedantic compilation
+* crypto/qat: fix allocation check and leak
+* crypto/qat: fix null auth algo overwrite
+* crypto/qat: fix out-of-bounds access
+* crypto/qat: fix parameter type
+* crypto/scheduler: fix strncpy
+* doc: fix format in OpenSSL installation guide
+* doc: fix lists of supported crypto algorithms
+* drivers: change the deprecated memseg physaddr to IOVA
+* eal/arm64: remove the braces in memory barrier macros
+* eal/ppc64: revert arch-specific TSC freq query
+* eal/ppc: remove the braces in memory barrier macros
+* ethdev: fix link autonegotiation value
+* ethdev: fix missing imissed counter in xstats
+* ethdev: fix port data reset timing
+* ethdev: fix port id allocation
+* eventdev: fix doxygen comments
+* eventdev: set error code in port link/unlink functions
+* event/octeontx: fix Rx adapter port id mapping
+* event/sw: fix debug logging config option
+* event/sw: fix queue memory leak and multi-link bug
+* examples/bond: check mbuf allocation
+* examples/bond: fix vdev name
+* examples/ip_pipeline: fix timer period unit
+* examples/ipsec-secgw: fix corner case for SPI value
+* examples/ipsec-secgw: fix missing ingress flow attribute
+* examples/ipsec-secgw: fix SPI byte order in flow item
+* examples/ipsec-secgw: fix usage of incorrect port
+* examples/l3fwd-power: fix frequency detection
+* examples/l3fwd-power: fix Rx without interrupt
+* examples/vhost: fix sending ARP packet to self
+* examples/vhost: fix startup check
+* flow_classify: fix ISO C in exported header
+* igb_uio: allow multi-process access
+* keepalive: fix state alignment
+* kni: fix build dependency
+* kni: fix build with kernel 4.15
+* lib: fix missing includes in exported headers
+* log: fix memory leak in regexp level set
+* lpm: fix ARM big endian build
+* malloc: fix end for bounded elements
+* malloc: protect stats with lock
+* mbuf: fix NULL freeing when debug enabled
+* mbuf: fix performance of freeing with non atomic refcnt
+* member: fix ISO C in exported header
+* member: fix memory leak on error
+* mempool: fix first memory area notification
+* mempool: fix physical contiguous check
+* mempool/octeontx: fix improper memory barrier
+* mempool/octeontx: fix memory area registration
+* mempool/octeontx: fix natural alignment being optimized out
+* memzone: fix leak on allocation error
+* mk: fix external build
+* mk: remove TILE-Gx machine type
+* mk: support renamed Makefile in external project
+* net/bnxt: fix check for ether type
+* net/bnxt: fix double increment of idx during Tx ring alloc
+* net/bnxt: fix duplicate filter pattern creation error
+* net/bnxt: fix duplicate pattern for 5tuple filter
+* net/bnxt: fix group info usage
+* net/bnxt: fix link speed setting with autoneg off
+* net/bnxt: fix number of pools for RSS
+* net/bnxt: fix return code in MAC address set
+* net/bnxt: fix Rx checksum flags
+* net/bnxt: fix size of Tx ring in HW
+* net/bnxt: free the aggregation ring
+* net/bnxt: parse checksum offload flags
+* net/bonding: check error of MAC address setting
+* net/bonding: fix activated slave in 8023ad mode
+* net/bonding: fix bonding in 8023ad mode
+* net/bonding: fix setting slave MAC addresses
+* net/dpaa: fix FW version code
+* net/dpaa: fix potential memory leak
+* net/dpaa: fix the mbuf packet type if zero
+* net/dpaa: fix uninitialized and unused variables
+* net/e1000: fix null pointer check
+* net/e1000: fix VF Rx interrupt enabling
+* net/ena: do not set Tx L4 offloads in Rx path
+* net/enic: fix crash due to static max number of queues
+* net/enic: fix L4 Rx ptype comparison
+* net/failsafe: fix invalid free
+* net/failsafe: fix Rx safe check compiler hint
+* net: fix ESP header byte ordering definition
+* net/fm10k: fix logical port delete
+* net/i40e: add debug logs when writing global registers
+* net/i40e: add FDIR NVGRE parameter check
+* net/i40e: check multi-driver option parsing
+* net/i40e: exclude LLDP packet count
+* net/i40e: fix ARM big endian build
+* net/i40e: fix FDIR input set conflict
+* net/i40e: fix FDIR rule confiliction issue
+* net/i40e: fix flag for MAC address write
+* net/i40e: fix flow director Rx resource defect
+* net/i40e: fix interrupt conflict with multi-driver
+* net/i40e: fix ISO C in exported header
+* net/i40e: fix memory leak
+* net/i40e: fix multiple DDP packages conflict
+* net/i40e: fix multiple driver support
+* net/i40e: fix packet type for X722
+* net/i40e: fix port segmentation fault when restart
+* net/i40e: fix Rx interrupt
+* net/i40e: fix setting MAC address of VF
+* net/i40e: fix setting of MAC address on i40evf
+* net/i40e: fix VF reset stats crash
+* net/i40e: fix VF Rx interrupt enabling
+* net/i40e: fix VLAN offload setting
+* net/i40e: fix VLAN offload setting issue
+* net/i40e: fix VSI MAC filter on primary address change
+* net/i40e: warn when writing global registers
+* net/igb: fix Tx queue number assignment
+* net/ixgbe: fix ARM big endian build
+* net/ixgbe: fix max queue number for VF
+* net/ixgbe: fix parsing FDIR NVGRE issue
+* net/ixgbe: fix reset error handling
+* net/ixgbe: fix the failure of number of Tx queue check
+* net/ixgbe: fix tunnel filter fail problem
+* net/ixgbe: fix VF Rx interrupt enabling
+* net/ixgbe: fix wrong PBA setting
+* net/mlx4: fix drop flow resources leak
+* net/mlx4: fix Rx offload non-fragmented indication
+* net/mlx4: fix Tx packet drop application report
+* net/mlx4: fix unnecessary include
+* net/mlx4: revert workaround for broken Verbs
+* net/mlx5: cleanup allocation of ethtool stats
+* net/mlx5: fix calculation of flow ID flag
+* net/mlx5: fix deadlock of link status alarm
+* net/mlx5: fix flow item validation
+* net/mlx5: fix flow priority on queue action
+* net/mlx5: fix flow RSS configuration
+* net/mlx5: fix handling link status event
+* net/mlx5: fix HW checksum offload for outer IP
+* net/mlx5: fix link state on device start
+* net/mlx5: fix memory region boundary checks
+* net/mlx5: fix memory region cache last index
+* net/mlx5: fix memory region cache lookup
+* net/mlx5: fix memory region lookup
+* net/mlx5: fix Memory Region registration
+* net/mlx5: fix missing attribute size for drop action
+* net/mlx5: fix missing RSS capability
+* net/mlx5: fix overflow of Memory Region cache
+* net/mlx5: fix overwriting bit-fields in SW Rx queue
+* net/mlx5: fix port stop by verify flows are still present
+* net/mlx5: fix return value of start operation
+* net/mlx5: fix RSS key configuration
+* net/mlx5: fix secondary process verification
+* net/mlx5: fix Tx checksum offloads
+* net/mlx5: fix UAR remapping on non configured queues
+* net/mlx5: fix un-supported RSS hash fields use
+* net/mlx5: fix VLAN configuration after port stop
+* net/mlx5: remove parser/flow drop queue
+* net/mlx5: use PCI address as port name
+* net/mrvl: fix HIF objects allocation
+* net/mrvl: fix multiple probe
+* net/mrvl: fix oversize bpool handling
+* net/mrvl: fix shadow queue tail and size calculations
+* net/mrvl: keep shadow Txqs inside PMD Txq
+* net/nfp: fix CRC strip check behaviour
+* net/nfp: fix jumbo settings
+* net/nfp: fix MTU settings
+* net/octeontx: add channel to port id mapping
+* net/pcap: fix the NUMA id display in logs
+* net/qede/base: fix VF LRO tunnel configuration
+* net/qede: check tunnel L3 header
+* net/qede: fix clearing of queue stats
+* net/qede: fix few log messages
+* net/qede: fix MTU set and max Rx length
+* net/qede: fix to enable LRO over tunnels
+* net/qede: fix to reject config with no Rx queue
+* net/qede: fix tunnel header size in Tx BD configuration
+* net/qede: replace config option with run-time arg
+* net/sfc: do not hold management event queue lock while MCDI
+* net/sfc: fix DMA memory leak after kvarg processing failure
+* net/sfc: fix flow RSS check in error handling
+* net/sfc: fix incorrect bitwise ORing of L3/L4 packet types
+* net/sfc: fix initialization of flow structure
+* net/sfc: fix label name to be consistent
+* net/sfc: fix main MAC address handling
+* net/sfc: fix multicast address list copy memory leak
+* net/sfc: stop periodic DMA if MAC stats upload fails
+* net/szedata2: fix check of mmap return value
+* net/tap: fix cleanup on allocation failure
+* net/tap: remove unused kernel version definitions
+* net/thunderx: fix multi segment Tx function return
+* net/virtio: fix incorrect cast
+* net/virtio: fix memory leak when reinitializing device
+* net/virtio: fix queue flushing with vector Rx enabled
+* net/virtio: fix Rx and Tx handler selection for ARM32
+* net/virtio: fix typo in LRO support
+* net/virtio: fix vector Rx flushing
+* net/virtio-user: fix crash as features change
+* pdump: fix error check when creating/canceling thread
+* pmdinfogen: fix cross compilation for ARM big endian
+* security: fix device operation type
+* security: fix enum start value
+* security: fix pedantic compilation
+* service: fix lcore role after delete
+* service: fix number mapped cores count
+* service: fix possible mem leak on initialize
+* service: fix service core launch
+* test/bitmap: fix memory leak
+* test/crypto: fix missing include
+* test/eventdev: use CPU event type
+* test/memzone: fix freeing test
+* test/memzone: fix NULL freeing
+* test/memzone: fix wrong test
+* test: register test as failed if setup failed
+* test/reorder: fix memory leak
+* test/ring: fix memory leak
+* test/ring_perf: fix memory leak
+* test/table: fix memory leak
+* test/table: fix uninitialized parameter
+* test/timer_perf: fix memory leak
+* timer: fix reset on service cores
+* usertools/devbind: fix kernel module reporting
+* vfio: fix enabled check on error
+* vhost: fix crash
+* vhost: fix dequeue zero copy with virtio1
+* vhost: fix error code check when creating thread
+* vhost: fix IOTLB pool out-of-memory handling
+* vhost: fix mbuf free
+* vhost: protect active rings from async ring changes
+* vhost: remove pending IOTLB entry if miss request failed
index d6cfdbf..ae18acd 100644 (file)
@@ -61,6 +61,12 @@ In case of complete protocol offload, the processing of headers(ESP and outer
 IP header) is done by the hardware and the application does not need to
 add/remove them during outbound/inbound processing.
 
+For inline offloaded outbound traffic, the application will not do the LPM
+lookup for routing, as the port on which the packet has to be forwarded will be
+part of the SA. Security parameters will be configured on that port only, and
+sending the packet on other ports could result in unencrypted packets being
+sent out.
+
 The Path for IPsec Inbound traffic is:
 
 *  Read packets from the port.
@@ -543,7 +549,9 @@ where each options means:
  ``<port_id>``
 
  * Port/device ID of the ethernet/crypto accelerator for which the SA is
-   configured. This option is used when *type* is NOT *no-offload*
+   configured. For *inline-crypto-offload* and *inline-protocol-offload*, this
+   port will be used for routing. The routing table will not be referred in
+   this case.
 
  * Optional: No, if *type* is not *no-offload*
 
index 9b8be48..6c131a8 100644 (file)
@@ -168,5 +168,5 @@ The rte_keepalive_mark_alive function simply sets the core state to alive.
     static inline void
     rte_keepalive_mark_alive(struct rte_keepalive *keepcfg)
     {
-        keepcfg->state_flags[rte_lcore_id()] = ALIVE;
+        keepcfg->live_data[rte_lcore_id()].core_state = RTE_KA_STATE_ALIVE;
     }
index 4b088da..ef0a896 100644 (file)
@@ -228,7 +228,9 @@ static inline void bm_rcr_finish(struct bm_portal *portal)
        u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
        u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(!rcr->busy);
+#endif
        if (pi != RCR_PTR2IDX(rcr->cursor))
                pr_crit("losing uncommitted RCR entries\n");
        if (ci != rcr->ci)
@@ -241,7 +243,9 @@ static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
 {
        register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(!rcr->busy);
+#endif
        if (!rcr->available)
                return NULL;
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
@@ -255,8 +259,8 @@ static inline void bm_rcr_abort(struct bm_portal *portal)
 {
        __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
 
-       DPAA_ASSERT(rcr->busy);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(rcr->busy);
        rcr->busy = 0;
 #endif
 }
@@ -266,8 +270,10 @@ static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
 {
        register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->busy);
        DPAA_ASSERT(rcr->pmode != bm_rcr_pvb);
+#endif
        if (rcr->available == 1)
                return NULL;
        rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
@@ -282,8 +288,10 @@ static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
 {
        register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->busy);
        DPAA_ASSERT(rcr->pmode == bm_rcr_pci);
+#endif
        rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
        RCR_INC(rcr);
        rcr->available--;
@@ -298,7 +306,9 @@ static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
 {
        __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->pmode == bm_rcr_pce);
+#endif
        bm_cl_invalidate(RCR_PI);
        bm_cl_touch_rw(RCR_PI);
 }
@@ -307,8 +317,10 @@ static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
 {
        register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->busy);
        DPAA_ASSERT(rcr->pmode == bm_rcr_pce);
+#endif
        rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
        RCR_INC(rcr);
        rcr->available--;
@@ -324,8 +336,10 @@ static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
        register struct bm_rcr *rcr = &portal->rcr;
        struct bm_rcr_entry *rcursor;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->busy);
        DPAA_ASSERT(rcr->pmode == bm_rcr_pvb);
+#endif
        lwsync();
        rcursor = rcr->cursor;
        rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
@@ -342,7 +356,9 @@ static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
        register struct bm_rcr *rcr = &portal->rcr;
        u8 diff, old_ci = rcr->ci;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->cmode == bm_rcr_cci);
+#endif
        rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
        diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
        rcr->available += diff;
@@ -353,7 +369,9 @@ static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
 {
        __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
+#endif
        bm_cl_touch_ro(RCR_CI);
 }
 
@@ -362,7 +380,9 @@ static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
        register struct bm_rcr *rcr = &portal->rcr;
        u8 diff, old_ci = rcr->ci;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
+#endif
        rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
        bm_cl_invalidate(RCR_CI);
        diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
@@ -420,8 +440,8 @@ static inline void bm_mc_finish(struct bm_portal *portal)
 {
        __maybe_unused register struct bm_mc *mc = &portal->mc;
 
-       DPAA_ASSERT(mc->state == mc_idle);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(mc->state == mc_idle);
        if (mc->state != mc_idle)
                pr_crit("Losing incomplete MC command\n");
 #endif
@@ -431,8 +451,8 @@ static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
 {
        register struct bm_mc *mc = &portal->mc;
 
-       DPAA_ASSERT(mc->state == mc_idle);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(mc->state == mc_idle);
        mc->state = mc_user;
 #endif
        dcbz_64(mc->cr);
@@ -443,8 +463,8 @@ static inline void bm_mc_abort(struct bm_portal *portal)
 {
        __maybe_unused register struct bm_mc *mc = &portal->mc;
 
-       DPAA_ASSERT(mc->state == mc_user);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(mc->state == mc_user);
        mc->state = mc_idle;
 #endif
 }
@@ -454,7 +474,9 @@ static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
        register struct bm_mc *mc = &portal->mc;
        struct bm_mc_result *rr = mc->rr + mc->rridx;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mc->state == mc_user);
+#endif
        lwsync();
        mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
        dcbf(mc->cr);
@@ -469,7 +491,9 @@ static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
        register struct bm_mc *mc = &portal->mc;
        struct bm_mc_result *rr = mc->rr + mc->rridx;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mc->state == mc_hw);
+#endif
        /* The inactive response register's verb byte always returns zero until
         * its command is submitted and completed. This includes the valid-bit,
         * in case you were wondering.
index 87fec60..b851110 100644 (file)
@@ -416,7 +416,9 @@ static inline void qm_eqcr_finish(struct qm_portal *portal)
        qm_cl_invalidate(EQCR_CI);
        eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(!eqcr->busy);
+#endif
        if (pi != EQCR_PTR2IDX(eqcr->cursor))
                pr_crit("losing uncommitted EQCR entries\n");
        if (ci != eqcr->ci)
@@ -505,7 +507,9 @@ static inline void qm_mr_pvb_update(struct qm_portal *portal)
        register struct qm_mr *mr = &portal->mr;
        const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mr->pmode == qm_mr_pvb);
+#endif
        /* when accessing 'verb', use __raw_readb() to ensure that compiler
         * inlining doesn't try to optimise out "excess reads".
         */
@@ -1267,6 +1271,7 @@ void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
        switch (fq->state) {
        case qman_fq_state_parked:
                DPAA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
+               /* Fallthrough */
        case qman_fq_state_oos:
                if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
                        qman_release_fqid(fq->fqid);
index 2c0f694..283cd31 100644 (file)
@@ -267,7 +267,9 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
 {
        register struct qm_eqcr *eqcr = &portal->eqcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(!eqcr->busy);
+#endif
        if (!eqcr->available)
                return NULL;
 
@@ -284,7 +286,9 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
        register struct qm_eqcr *eqcr = &portal->eqcr;
        u8 diff, old_ci;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(!eqcr->busy);
+#endif
        if (!eqcr->available) {
                old_ci = eqcr->ci;
                eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
@@ -303,8 +307,8 @@ static inline void qm_eqcr_abort(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
 
-       DPAA_ASSERT(eqcr->busy);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(eqcr->busy);
        eqcr->busy = 0;
 #endif
 }
@@ -314,8 +318,10 @@ static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
 {
        register struct qm_eqcr *eqcr = &portal->eqcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(eqcr->busy);
        DPAA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
+#endif
        if (eqcr->available == 1)
                return NULL;
        eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
@@ -336,8 +342,10 @@ static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
 {
        register struct qm_eqcr *eqcr = &portal->eqcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        EQCR_COMMIT_CHECKS(eqcr);
        DPAA_ASSERT(eqcr->pmode == qm_eqcr_pci);
+#endif
        eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
        EQCR_INC(eqcr);
        eqcr->available--;
@@ -353,7 +361,9 @@ static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce);
+#endif
        qm_cl_invalidate(EQCR_PI);
        qm_cl_touch_rw(EQCR_PI);
 }
@@ -362,8 +372,10 @@ static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
 {
        register struct qm_eqcr *eqcr = &portal->eqcr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        EQCR_COMMIT_CHECKS(eqcr);
        DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce);
+#endif
        eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
        EQCR_INC(eqcr);
        eqcr->available--;
@@ -380,8 +392,10 @@ static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
        register struct qm_eqcr *eqcr = &portal->eqcr;
        struct qm_eqcr_entry *eqcursor;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        EQCR_COMMIT_CHECKS(eqcr);
        DPAA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
+#endif
        lwsync();
        eqcursor = eqcr->cursor;
        eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
@@ -503,7 +517,9 @@ static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
        register struct qm_dqrr *dqrr = &portal->dqrr;
        u8 diff, old_pi = dqrr->pi;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->pmode == qm_dqrr_pci);
+#endif
        dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
        diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
        dqrr->fill += diff;
@@ -514,7 +530,9 @@ static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce);
+#endif
        qm_cl_invalidate(DQRR_PI);
        qm_cl_touch_ro(DQRR_PI);
 }
@@ -524,7 +542,9 @@ static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
        register struct qm_dqrr *dqrr = &portal->dqrr;
        u8 diff, old_pi = dqrr->pi;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce);
+#endif
        dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
        diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
        dqrr->fill += diff;
@@ -536,7 +556,9 @@ static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
        register struct qm_dqrr *dqrr = &portal->dqrr;
        const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
+#endif
        /* when accessing 'verb', use __raw_readb() to ensure that compiler
         * inlining doesn't try to optimise out "excess reads".
         */
@@ -552,7 +574,9 @@ static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci);
+#endif
        dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
        qm_out(DQRR_CI_CINH, dqrr->ci);
 }
@@ -561,7 +585,9 @@ static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci);
+#endif
        dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
        qm_out(DQRR_CI_CINH, dqrr->ci);
 }
@@ -570,7 +596,9 @@ static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
+#endif
        qm_cl_invalidate(DQRR_CI);
        qm_cl_touch_rw(DQRR_CI);
 }
@@ -579,7 +607,9 @@ static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
+#endif
        dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
        qm_cl_out(DQRR_CI, dqrr->ci);
 }
@@ -588,7 +618,9 @@ static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce);
+#endif
        dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
        qm_cl_out(DQRR_CI, dqrr->ci);
 }
@@ -598,7 +630,9 @@ static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        DPAA_ASSERT(idx < QM_DQRR_SIZE);
        qm_out(DQRR_DCAP, (0 << 8) |    /* S */
                ((park ? 1 : 0) << 6) | /* PK */
@@ -612,7 +646,9 @@ static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
        u8 idx = DQRR_PTR2IDX(dq);
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        DPAA_ASSERT(idx < QM_DQRR_SIZE);
        qm_out(DQRR_DCAP, (0 << 8) |            /* DQRR_DCAP::S */
                ((park ? 1 : 0) << 6) |         /* DQRR_DCAP::PK */
@@ -623,7 +659,9 @@ static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        qm_out(DQRR_DCAP, (1 << 8) |            /* DQRR_DCAP::S */
                ((u32)bitmask << 16));          /* DQRR_DCAP::DCAP_CI */
        dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
@@ -634,7 +672,9 @@ static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
 }
 
@@ -642,7 +682,9 @@ static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        qm_cl_invalidate(DQRR_CI);
        qm_cl_touch_ro(DQRR_CI);
 }
@@ -651,7 +693,9 @@ static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
+#endif
        return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
 }
 
@@ -659,7 +703,9 @@ static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
+#endif
        return dqrr->ci;
 }
 
@@ -667,7 +713,9 @@ static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
 {
        __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
+#endif
        qm_out(DQRR_DCAP, (0 << 8) |            /* S */
                (1 << 6) |                      /* PK */
                (idx & (QM_DQRR_SIZE - 1)));    /* DCAP_CI */
@@ -677,7 +725,9 @@ static inline void qm_dqrr_park_current(struct qm_portal *portal)
 {
        register struct qm_dqrr *dqrr = &portal->dqrr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
+#endif
        qm_out(DQRR_DCAP, (0 << 8) |            /* S */
                (1 << 6) |                      /* PK */
                DQRR_PTR2IDX(dqrr->cursor));    /* DCAP_CI */
@@ -766,7 +816,9 @@ static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
 {
        register struct qm_mr *mr = &portal->mr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mr->cmode == qm_mr_cci);
+#endif
        mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
        qm_out(MR_CI_CINH, mr->ci);
 }
@@ -775,7 +827,9 @@ static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
 {
        register struct qm_mr *mr = &portal->mr;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mr->cmode == qm_mr_cci);
+#endif
        mr->ci = MR_PTR2IDX(mr->cursor);
        qm_out(MR_CI_CINH, mr->ci);
 }
@@ -806,8 +860,8 @@ static inline void qm_mc_finish(struct qm_portal *portal)
 {
        __maybe_unused register struct qm_mc *mc = &portal->mc;
 
-       DPAA_ASSERT(mc->state == qman_mc_idle);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(mc->state == qman_mc_idle);
        if (mc->state != qman_mc_idle)
                pr_crit("Losing incomplete MC command\n");
 #endif
@@ -817,8 +871,8 @@ static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
 {
        register struct qm_mc *mc = &portal->mc;
 
-       DPAA_ASSERT(mc->state == qman_mc_idle);
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
+       DPAA_ASSERT(mc->state == qman_mc_idle);
        mc->state = qman_mc_user;
 #endif
        dcbz_64(mc->cr);
@@ -830,7 +884,9 @@ static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
        register struct qm_mc *mc = &portal->mc;
        struct qm_mc_result *rr = mc->rr + mc->rridx;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mc->state == qman_mc_user);
+#endif
        lwsync();
        mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
        dcbf(mc->cr);
@@ -845,7 +901,9 @@ static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
        register struct qm_mc *mc = &portal->mc;
        struct qm_mc_result *rr = mc->rr + mc->rridx;
 
+#ifdef RTE_LIBRTE_DPAA_HWDEBUG
        DPAA_ASSERT(mc->state == qman_mc_hw);
+#endif
        /* The inactive response register's verb byte always returns zero until
         * its command is submitted and completed. This includes the valid-bit,
         * in case you were wondering.
index 1cc8c89..3a0b255 100644 (file)
@@ -490,6 +490,10 @@ rte_dpaa_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
 static enum rte_iova_mode
 rte_dpaa_get_iommu_class(void)
 {
+       if ((access(DPAA_DEV_PATH1, F_OK) != 0) &&
+           (access(DPAA_DEV_PATH2, F_OK) != 0)) {
+               return RTE_IOVA_DC;
+       }
        return RTE_IOVA_PA;
 }
 
index eedfd7e..72556dc 100644 (file)
@@ -1993,8 +1993,8 @@ static inline int qman_poll_fq_for_init(struct qman_fq *fq)
 }
 
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define cpu_to_hw_sg(x) (x)
-#define hw_sg_to_cpu(x) (x)
+#define cpu_to_hw_sg(x)
+#define hw_sg_to_cpu(x)
 #else
 #define cpu_to_hw_sg(x)  __cpu_to_hw_sg(x)
 #define hw_sg_to_cpu(x)  __hw_sg_to_cpu(x)
index eafc944..bc933af 100644 (file)
@@ -113,10 +113,10 @@ static inline void *rte_dpaa_mem_ptov(phys_addr_t paddr)
        int i;
 
        for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr != NULL; i++) {
-               if (paddr >= memseg[i].phys_addr && paddr <
-                       memseg[i].phys_addr + memseg[i].len)
+               if (paddr >= memseg[i].iova && paddr <
+                       memseg[i].iova + memseg[i].len)
                        return (uint8_t *)(memseg[i].addr) +
-                              (paddr - memseg[i].phys_addr);
+                              (paddr - memseg[i].iova);
        }
 
        return NULL;
index 7831201..a936321 100644 (file)
@@ -249,7 +249,7 @@ int rte_fslmc_vfio_dmamap(void)
                dma_map.size = memseg[i].len;
                dma_map.vaddr = memseg[i].addr_64;
 #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
-               dma_map.iova = memseg[i].phys_addr;
+               dma_map.iova = memseg[i].iova;
 #else
                dma_map.iova = dma_map.vaddr;
 #endif
index d803205..e4b2404 100644 (file)
@@ -60,7 +60,6 @@ struct fsl_mc_io {
 #else /* __linux_driver__ */
 
 #include <stdio.h>
-#include <libio.h>
 #include <stdint.h>
 #include <errno.h>
 #include <sys/uio.h>
index c1b842f..ece1a7d 100644 (file)
@@ -284,10 +284,10 @@ static void *dpaa2_mem_ptov(phys_addr_t paddr)
        int i;
 
        for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
-               if (paddr >= memseg[i].phys_addr &&
-                  (char *)paddr < (char *)memseg[i].phys_addr + memseg[i].len)
+               if (paddr >= memseg[i].iova &&
+                  (char *)paddr < (char *)memseg[i].iova + memseg[i].len)
                        return (void *)(memseg[i].addr_64
-                               + (paddr - memseg[i].phys_addr));
+                               + (paddr - memseg[i].iova));
        }
        return NULL;
 }
@@ -301,7 +301,7 @@ static phys_addr_t dpaa2_mem_vtop(uint64_t vaddr)
        for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
                if (vaddr >= memseg[i].addr_64 &&
                    vaddr < memseg[i].addr_64 + memseg[i].len)
-                       return memseg[i].phys_addr
+                       return memseg[i].iova
                                + (vaddr - memseg[i].addr_64);
        }
        return (phys_addr_t)(NULL);
index 4c32db6..0814e69 100644 (file)
@@ -175,10 +175,6 @@ static void dpaa2initfn_ ##nm(void) \
 } \
 RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
-#ifdef __cplusplus
-}
-#endif
-
 /**
  * Register a DPAA2 MC Object driver.
  *
@@ -198,4 +194,8 @@ static void dpaa2objinitfn_ ##nm(void) \
 } \
 RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _RTE_FSLMC_H_ */
index 5da6728..74deef3 100644 (file)
@@ -576,6 +576,82 @@ pci_one_device_has_iova_va(void)
        return 0;
 }
 
+#if defined(RTE_ARCH_X86)
+static bool
+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 X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */
+       struct rte_pci_addr *addr = &dev->addr;
+       char filename[PATH_MAX];
+       FILE *fp;
+       uint64_t mgaw, vtd_cap_reg = 0;
+
+       snprintf(filename, sizeof(filename),
+                "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap",
+                rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+                addr->function);
+       if (access(filename, F_OK) == -1) {
+               /* We don't have an Intel IOMMU, assume VA supported*/
+               return true;
+       }
+
+       /* We have an intel IOMMU */
+       fp = fopen(filename, "r");
+       if (fp == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): can't open %s\n", __func__, filename);
+               return false;
+       }
+
+       if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) {
+               RTE_LOG(ERR, EAL, "%s(): can't read %s\n", __func__, filename);
+               fclose(fp);
+               return false;
+       }
+
+       fclose(fp);
+
+       mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1;
+       if (mgaw < X86_VA_WIDTH)
+               return false;
+
+       return true;
+}
+#elif defined(RTE_ARCH_PPC_64)
+static bool
+pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev)
+{
+       return false;
+}
+#else
+static bool
+pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev)
+{
+       return true;
+}
+#endif
+
+/*
+ * All devices IOMMUs support VA as IOVA
+ */
+static bool
+pci_devices_iommu_support_va(void)
+{
+       struct rte_pci_device *dev = NULL;
+       struct rte_pci_driver *drv = NULL;
+
+       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;
+               }
+       }
+       return true;
+}
+
 /*
  * Get iommu class of PCI devices on the bus.
  */
@@ -586,12 +662,7 @@ rte_pci_get_iommu_class(void)
        bool is_vfio_noiommu_enabled = true;
        bool has_iova_va;
        bool is_bound_uio;
-       bool spapr_iommu =
-#if defined(RTE_ARCH_PPC_64)
-               true;
-#else
-               false;
-#endif
+       bool iommu_no_va;
 
        is_bound = pci_one_device_is_bound();
        if (!is_bound)
@@ -599,13 +670,14 @@ rte_pci_get_iommu_class(void)
 
        has_iova_va = pci_one_device_has_iova_va();
        is_bound_uio = pci_one_device_bound_uio();
+       iommu_no_va = !pci_devices_iommu_support_va();
 #ifdef VFIO_PRESENT
        is_vfio_noiommu_enabled = rte_vfio_noiommu_is_enabled() == true ?
                                        true : false;
 #endif
 
        if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled &&
-                       !spapr_iommu)
+                       !iommu_no_va)
                return RTE_IOVA_VA;
 
        if (has_iova_va) {
@@ -614,8 +686,8 @@ rte_pci_get_iommu_class(void)
                        RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
                if (is_bound_uio)
                        RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
-               if (spapr_iommu)
-                       RTE_LOG(WARNING, EAL, "sPAPR IOMMU does not support IOVA as VA\n");
+               if (iommu_no_va)
+                       RTE_LOG(WARNING, EAL, "IOMMU does not support IOVA as VA\n");
        }
 
        return RTE_IOVA_PA;
@@ -723,7 +795,6 @@ pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
        if (!found)
                return -1;
 
-       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
        p->base = start;
        RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
 
index 1f93fa4..e7d7f5d 100644 (file)
@@ -459,7 +459,6 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)
        struct pci_map *maps;
 
        dev->intr_handle.fd = -1;
-       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
 
        /* store PCI address string */
        snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
@@ -576,7 +575,6 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
        struct pci_map *maps;
 
        dev->intr_handle.fd = -1;
-       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
 
        /* store PCI address string */
        snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
index 0671131..b75988d 100644 (file)
@@ -119,7 +119,6 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 
        dev->intr_handle.fd = -1;
        dev->intr_handle.uio_cfg_fd = -1;
-       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
 
        /* secondary processes - use already recorded details */
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
index fd7736d..ba0ed7a 100644 (file)
@@ -289,6 +289,7 @@ static int
 vdev_probe(void)
 {
        struct rte_vdev_device *dev;
+       int ret = 0;
 
        /* call the init function for each virtual device */
        TAILQ_FOREACH(dev, &vdev_device_list, next) {
@@ -299,11 +300,11 @@ vdev_probe(void)
                if (vdev_probe_all_drivers(dev)) {
                        VDEV_LOG(ERR, "failed to initialize %s device\n",
                                rte_vdev_device_name(dev));
-                       return -1;
+                       ret = -1;
                }
        }
 
-       return 0;
+       return ret;
 }
 
 static struct rte_device *
index 9c64c5d..67fb6e2 100644 (file)
@@ -1309,7 +1309,7 @@ dpaa2_sec_aead_init(struct rte_cryptodev *dev,
        case RTE_CRYPTO_AEAD_AES_GCM:
                aeaddata.algtype = OP_ALG_ALGSEL_AES;
                aeaddata.algmode = OP_ALG_AAI_GCM;
-               session->cipher_alg = RTE_CRYPTO_AEAD_AES_GCM;
+               session->aead_alg = RTE_CRYPTO_AEAD_AES_GCM;
                break;
        case RTE_CRYPTO_AEAD_AES_CCM:
                RTE_LOG(ERR, PMD, "Crypto: Unsupported AEAD alg %u\n",
index 14e71df..8e58380 100644 (file)
@@ -169,6 +169,7 @@ typedef struct dpaa2_sec_session_entry {
        uint8_t dir;         /*!< Operation Direction */
        enum rte_crypto_cipher_algorithm cipher_alg; /*!< Cipher Algorithm*/
        enum rte_crypto_auth_algorithm auth_alg; /*!< Authentication Algorithm*/
+       enum rte_crypto_aead_algorithm aead_alg; /*!< AEAD Algorithm*/
        union {
                struct {
                        uint8_t *data;  /**< pointer to key data */
index 16155b1..438dd3b 100644 (file)
@@ -121,7 +121,7 @@ dpaa_mem_vtop(void *vaddr)
        for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
                if (vaddr_64 >= memseg[i].addr_64 &&
                    vaddr_64 < memseg[i].addr_64 + memseg[i].len) {
-                       paddr = memseg[i].phys_addr +
+                       paddr = memseg[i].iova +
                                (vaddr_64 - memseg[i].addr_64);
 
                        return (rte_iova_t)paddr;
@@ -137,10 +137,10 @@ dpaa_mem_ptov(rte_iova_t paddr)
        int i;
 
        for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) {
-               if (paddr >= memseg[i].phys_addr &&
-                   (char *)paddr < (char *)memseg[i].phys_addr + memseg[i].len)
+               if (paddr >= memseg[i].iova &&
+                   (char *)paddr < (char *)memseg[i].iova + memseg[i].len)
                        return (void *)(memseg[i].addr_64 +
-                                       (paddr - memseg[i].phys_addr));
+                                       (paddr - memseg[i].iova));
        }
        return NULL;
 }
index db6c9a3..26f854c 100644 (file)
@@ -359,6 +359,11 @@ static int qat_alg_do_precomputes(enum icp_qat_hw_auth_algo hash_alg,
 
                in = rte_zmalloc("working mem for key",
                                ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ, 16);
+               if (in == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory");
+                       return -ENOMEM;
+               }
+
                rte_memcpy(in, qat_aes_xcbc_key_seed,
                                ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ);
                for (x = 0; x < HASH_XCBC_PRECOMP_KEY_NUM; x++) {
@@ -389,6 +394,11 @@ static int qat_alg_do_precomputes(enum icp_qat_hw_auth_algo hash_alg,
                                ICP_QAT_HW_GALOIS_E_CTR0_SZ);
                in = rte_zmalloc("working mem for key",
                                ICP_QAT_HW_GALOIS_H_SZ, 16);
+               if (in == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory");
+                       return -ENOMEM;
+               }
+
                memset(in, 0, ICP_QAT_HW_GALOIS_H_SZ);
                if (AES_set_encrypt_key(auth_key, auth_keylen << 3,
                        &enc_key) != 0) {
index a572967..acd979d 100644 (file)
 #include "adf_transport_access_macros.h"
 
 #define BYTE_LENGTH    8
+/* bpi is only used for partial blocks of DES and AES
+ * so AES block len can be assumed as max len for iv, src and dst
+ */
+#define BPI_MAX_ENCR_IV_LEN ICP_QAT_HW_AES_BLK_SZ
 
 static int
 qat_is_cipher_alg_supported(enum rte_crypto_cipher_algorithm algo,
@@ -121,16 +125,16 @@ bpi_cipher_encrypt(uint8_t *src, uint8_t *dst,
 {
        EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)bpi_ctx;
        int encrypted_ivlen;
-       uint8_t encrypted_iv[16];
-       int i;
+       uint8_t encrypted_iv[BPI_MAX_ENCR_IV_LEN];
+       uint8_t *encr = encrypted_iv;
 
        /* ECB method: encrypt the IV, then XOR this with plaintext */
        if (EVP_EncryptUpdate(ctx, encrypted_iv, &encrypted_ivlen, iv, ivlen)
                                                                <= 0)
                goto cipher_encrypt_err;
 
-       for (i = 0; i < srclen; i++)
-               *(dst+i) = *(src+i)^(encrypted_iv[i]);
+       for (; srclen != 0; --srclen, ++dst, ++src, ++encr)
+               *dst = *src ^ *encr;
 
        return 0;
 
@@ -150,16 +154,16 @@ bpi_cipher_decrypt(uint8_t *src, uint8_t *dst,
 {
        EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)bpi_ctx;
        int encrypted_ivlen;
-       uint8_t encrypted_iv[16];
-       int i;
+       uint8_t encrypted_iv[BPI_MAX_ENCR_IV_LEN];
+       uint8_t *encr = encrypted_iv;
 
        /* ECB method: encrypt (not decrypt!) the IV, then XOR with plaintext */
        if (EVP_EncryptUpdate(ctx, encrypted_iv, &encrypted_ivlen, iv, ivlen)
                                                                <= 0)
                goto cipher_decrypt_err;
 
-       for (i = 0; i < srclen; i++)
-               *(dst+i) = *(src+i)^(encrypted_iv[i]);
+       for (; srclen != 0; --srclen, ++dst, ++src, ++encr)
+               *dst = *src ^ *encr;
 
        return 0;
 
@@ -844,7 +848,7 @@ static inline uint32_t
 qat_bpicipher_preprocess(struct qat_session *ctx,
                                struct rte_crypto_op *op)
 {
-       uint8_t block_len = qat_cipher_get_block_size(ctx->qat_cipher_alg);
+       int block_len = qat_cipher_get_block_size(ctx->qat_cipher_alg);
        struct rte_crypto_sym_op *sym_op = op->sym;
        uint8_t last_block_len = block_len > 0 ?
                        sym_op->cipher.data.length % block_len : 0;
@@ -899,7 +903,7 @@ static inline uint32_t
 qat_bpicipher_postprocess(struct qat_session *ctx,
                                struct rte_crypto_op *op)
 {
-       uint8_t block_len = qat_cipher_get_block_size(ctx->qat_cipher_alg);
+       int block_len = qat_cipher_get_block_size(ctx->qat_cipher_alg);
        struct rte_crypto_sym_op *sym_op = op->sym;
        uint8_t last_block_len = block_len > 0 ?
                        sym_op->cipher.data.length % block_len : 0;
@@ -1367,7 +1371,9 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg,
                }
                min_ofs = auth_ofs;
 
-               auth_param->auth_res_addr = op->sym->auth.digest.phys_addr;
+               if (likely(ctx->qat_hash_alg != ICP_QAT_HW_AUTH_ALGO_NULL))
+                       auth_param->auth_res_addr =
+                                       op->sym->auth.digest.phys_addr;
 
        }
 
index ced3aa6..c02971e 100644 (file)
@@ -180,6 +180,11 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
        qp->op_cookies = rte_zmalloc("qat PMD op cookie pointer",
                        qp_conf->nb_descriptors * sizeof(*qp->op_cookies),
                        RTE_CACHE_LINE_SIZE);
+       if (qp->op_cookies == NULL) {
+               PMD_DRV_LOG(ERR, "Failed to alloc mem for cookie");
+               rte_free(qp);
+               return -ENOMEM;
+       }
 
        qp->mmap_bar_addr = pci_dev->mem_resource[0].addr;
        qp->inflights16 = 0;
@@ -221,7 +226,7 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
        for (i = 0; i < qp->nb_descriptors; i++) {
                if (rte_mempool_get(qp->op_cookie_pool, &qp->op_cookies[i])) {
                        PMD_DRV_LOG(ERR, "QAT PMD Cannot get op_cookie");
-                       return -EFAULT;
+                       goto create_err;
                }
 
                struct qat_crypto_op_cookie *sql_cookie =
@@ -246,6 +251,9 @@ int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
        return 0;
 
 create_err:
+       if (qp->op_cookie_pool)
+               rte_mempool_free(qp->op_cookie_pool);
+       rte_free(qp->op_cookies);
        rte_free(qp);
        return -EFAULT;
 }
index df8634a..822ce27 100644 (file)
@@ -467,8 +467,8 @@ rte_cryptodev_scheduler_load_user_scheduler(uint8_t scheduler_id,
                                RTE_CRYPTODEV_NAME_MAX_LEN);
                return -EINVAL;
        }
-       strncpy(sched_ctx->name, scheduler->name,
-                       RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN);
+       snprintf(sched_ctx->name, sizeof(sched_ctx->name), "%s",
+                       scheduler->name);
 
        if (strlen(scheduler->description) >
                        RTE_CRYPTODEV_SCHEDULER_DESC_MAX_LEN - 1) {
@@ -477,8 +477,8 @@ rte_cryptodev_scheduler_load_user_scheduler(uint8_t scheduler_id,
                                RTE_CRYPTODEV_SCHEDULER_DESC_MAX_LEN - 1);
                return -EINVAL;
        }
-       strncpy(sched_ctx->description, scheduler->description,
-                       RTE_CRYPTODEV_SCHEDULER_DESC_MAX_LEN);
+       snprintf(sched_ctx->description, sizeof(sched_ctx->description), "%s",
+                       scheduler->description);
 
        /* load scheduler instance operations functions */
        sched_ctx->ops.config_queue_pair = scheduler->ops->config_queue_pair;
index fdf1b73..2604412 100644 (file)
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
-LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
+LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx -lrte_pmd_octeontx
 LDLIBS += -lrte_bus_pci
 LDLIBS += -lrte_bus_vdev
 
index bf76ac8..4c9a4c4 100644 (file)
@@ -53,7 +53,7 @@ enum {
 /* SSO Operations */
 
 static __rte_always_inline struct rte_mbuf *
-ssovf_octeontx_wqe_to_pkt(uint64_t work, uint16_t port_id)
+ssovf_octeontx_wqe_to_pkt(uint64_t work, uint16_t port_info)
 {
        struct rte_mbuf *mbuf;
        octtx_wqe_t *wqe = (octtx_wqe_t *)(uintptr_t)work;
@@ -69,7 +69,7 @@ ssovf_octeontx_wqe_to_pkt(uint64_t work, uint16_t port_id)
        mbuf->data_len = mbuf->pkt_len;
        mbuf->nb_segs = 1;
        mbuf->ol_flags = 0;
-       mbuf->port = port_id;
+       mbuf->port = rte_octeontx_pchan_map[port_info >> 4][port_info & 0xF];
        rte_mbuf_refcnt_set(mbuf, 1);
        return mbuf;
 }
@@ -89,7 +89,7 @@ ssows_get_work(struct ssows *ws, struct rte_event *ev)
        ev->event = sched_type_queue | (get_work0 & 0xffffffff);
        if (get_work1 && ev->event_type == RTE_EVENT_TYPE_ETHDEV) {
                ev->mbuf = ssovf_octeontx_wqe_to_pkt(get_work1,
-                               (ev->event >> 20) & 0xF);
+                               (ev->event >> 20) & 0x7F);
        } else {
                ev->u64 = get_work1;
        }
index fd11079..d989346 100644 (file)
@@ -62,6 +62,7 @@ sw_port_link(struct rte_eventdev *dev, void *port, const uint8_t queues[],
        RTE_SET_USED(priorities);
        for (i = 0; i < num; i++) {
                struct sw_qid *q = &sw->qids[queues[i]];
+               unsigned int j;
 
                /* check for qid map overflow */
                if (q->cq_num_mapped_cqs >= RTE_DIM(q->cq_map)) {
@@ -74,6 +75,15 @@ sw_port_link(struct rte_eventdev *dev, void *port, const uint8_t queues[],
                        break;
                }
 
+               for (j = 0; j < q->cq_num_mapped_cqs; j++) {
+                       if (q->cq_map[j] == p->id)
+                               break;
+               }
+
+               /* check if port is already linked */
+               if (j < q->cq_num_mapped_cqs)
+                       continue;
+
                if (q->type == SW_SCHED_TYPE_DIRECT) {
                        /* check directed qids only map to one port */
                        if (p->num_qids_mapped > 0) {
@@ -338,6 +348,23 @@ cleanup:
        return -EINVAL;
 }
 
+static void
+sw_queue_release(struct rte_eventdev *dev, uint8_t id)
+{
+       struct sw_evdev *sw = sw_pmd_priv(dev);
+       struct sw_qid *qid = &sw->qids[id];
+       uint32_t i;
+
+       for (i = 0; i < SW_IQS_MAX; i++)
+               iq_ring_destroy(qid->iq[i]);
+
+       if (qid->type == RTE_SCHED_TYPE_ORDERED) {
+               rte_free(qid->reorder_buffer);
+               rte_ring_free(qid->reorder_buffer_freelist);
+       }
+       memset(qid, 0, sizeof(*qid));
+}
+
 static int
 sw_queue_setup(struct rte_eventdev *dev, uint8_t queue_id,
                const struct rte_event_queue_conf *conf)
@@ -355,24 +382,11 @@ sw_queue_setup(struct rte_eventdev *dev, uint8_t queue_id,
        }
 
        struct sw_evdev *sw = sw_pmd_priv(dev);
-       return qid_init(sw, queue_id, type, conf);
-}
-
-static void
-sw_queue_release(struct rte_eventdev *dev, uint8_t id)
-{
-       struct sw_evdev *sw = sw_pmd_priv(dev);
-       struct sw_qid *qid = &sw->qids[id];
-       uint32_t i;
 
-       for (i = 0; i < SW_IQS_MAX; i++)
-               iq_ring_destroy(qid->iq[i]);
+       if (sw->qids[queue_id].initialized)
+               sw_queue_release(dev, queue_id);
 
-       if (qid->type == RTE_SCHED_TYPE_ORDERED) {
-               rte_free(qid->reorder_buffer);
-               rte_ring_free(qid->reorder_buffer_freelist);
-       }
-       memset(qid, 0, sizeof(*qid));
+       return qid_init(sw, queue_id, type, conf);
 }
 
 static void
index e0dec91..ee0edb3 100644 (file)
@@ -88,7 +88,7 @@ static const uint8_t sw_qe_flag_map[] = {
                QE_FLAG_VALID | QE_FLAG_COMPLETE | QE_FLAG_NOT_EOP,
 };
 
-#ifdef RTE_LIBRTE_PMD_EVDEV_SW_DEBUG
+#ifdef RTE_LIBRTE_PMD_SW_EVENTDEV_DEBUG
 #define SW_LOG_INFO(fmt, args...) \
        RTE_LOG(INFO, EVENTDEV, "[%s] %s() line %u: " fmt "\n", \
                        SW_PMD_NAME, \
index 3bc50f3..28f431e 100644 (file)
@@ -386,8 +386,8 @@ err:
        return ret;
 }
 
-static int
-octeontx_fpavf_pool_setup(uintptr_t handle, unsigned long memsz,
+int
+octeontx_fpavf_pool_set_range(uintptr_t handle, unsigned long memsz,
                          void *memva, uint16_t gpool)
 {
        uint64_t va_end;
@@ -509,12 +509,9 @@ octeontx_fpa_bufpool_free_count(uintptr_t handle)
 
 uintptr_t
 octeontx_fpa_bufpool_create(unsigned int object_size, unsigned int object_count,
-                               unsigned int buf_offset, char **va_start,
-                               int node_id)
+                               unsigned int buf_offset, int node_id)
 {
        unsigned int gpool;
-       void *memva;
-       unsigned long memsz;
        uintptr_t gpool_handle;
        uintptr_t pool_bar;
        int res;
@@ -522,9 +519,6 @@ octeontx_fpa_bufpool_create(unsigned int object_size, unsigned int object_count,
        RTE_SET_USED(node_id);
        RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) > OCTEONTX_FPAVF_BUF_OFFSET);
 
-       if (unlikely(*va_start == NULL))
-               goto error_end;
-
        object_size = RTE_CACHE_LINE_ROUNDUP(object_size);
        if (object_size > FPA_MAX_OBJ_SIZE) {
                errno = EINVAL;
@@ -567,15 +561,6 @@ octeontx_fpa_bufpool_create(unsigned int object_size, unsigned int object_count,
                goto error_pool_destroy;
        }
 
-       /* vf pool setup */
-       memsz = object_size * object_count;
-       memva = *va_start;
-       res = octeontx_fpavf_pool_setup(pool_bar, memsz, memva, gpool);
-       if (res < 0) {
-               errno = res;
-               goto error_gaura_detach;
-       }
-
        /* Release lock */
        rte_spinlock_unlock(&fpadev.lock);
 
@@ -591,8 +576,6 @@ octeontx_fpa_bufpool_create(unsigned int object_size, unsigned int object_count,
 
        return gpool_handle;
 
-error_gaura_detach:
-       (void) octeontx_fpapf_aura_detach(gpool);
 error_pool_destroy:
        octeontx_fpavf_free(gpool);
        octeontx_fpapf_pool_destroy(gpool);
index 1d09f00..bc5dc3b 100644 (file)
@@ -114,8 +114,10 @@ do {                                                       \
 
 uintptr_t
 octeontx_fpa_bufpool_create(unsigned int object_size, unsigned int object_count,
-                               unsigned int buf_offset, char **va_start,
-                               int node);
+                               unsigned int buf_offset, int node);
+int
+octeontx_fpavf_pool_set_range(uintptr_t handle, unsigned long memsz,
+                         void *memva, uint16_t gpool);
 int
 octeontx_fpa_bufpool_destroy(uintptr_t handle, int node);
 int
index 9525da1..a38bfe6 100644 (file)
@@ -89,7 +89,7 @@ struct mbox_ram_hdr {
 };
 
 static inline void
-mbox_msgcpy(uint8_t *d, const uint8_t *s, uint16_t size)
+mbox_msgcpy(volatile uint8_t *d, volatile const uint8_t *s, uint16_t size)
 {
        uint16_t i;
 
@@ -128,7 +128,7 @@ mbox_send_request(struct mbox *m, struct octeontx_mbox_hdr *hdr,
 
        /* Write the msg header */
        rte_write64(new_hdr.u64, ram_mbox_hdr);
-       rte_io_wmb();
+       rte_smp_wmb();
        /* Notify PF about the new msg - write to MBOX reg generates PF IRQ */
        rte_write64(0, m->reg);
 }
index e89355c..fc0cab9 100644 (file)
 
 #include "octeontx_fpavf.h"
 
-/*
- * Per-pool descriptor.
- * Links mempool with the corresponding memzone,
- * that provides memory under the pool's elements.
- */
-struct octeontx_pool_info {
-       const struct rte_mempool *mp;
-       uintptr_t mz_addr;
-
-       SLIST_ENTRY(octeontx_pool_info) link;
-};
-
-SLIST_HEAD(octeontx_pool_list, octeontx_pool_info);
-
-/* List of the allocated pools */
-static struct octeontx_pool_list octeontx_pool_head =
-                               SLIST_HEAD_INITIALIZER(octeontx_pool_head);
-/* Spinlock to protect pool list */
-static rte_spinlock_t pool_list_lock = RTE_SPINLOCK_INITIALIZER;
-
 static int
 octeontx_fpavf_alloc(struct rte_mempool *mp)
 {
        uintptr_t pool;
-       struct octeontx_pool_info *pool_info;
        uint32_t memseg_count = mp->size;
        uint32_t object_size;
-       uintptr_t va_start;
        int rc = 0;
 
-       rte_spinlock_lock(&pool_list_lock);
-       SLIST_FOREACH(pool_info, &octeontx_pool_head, link) {
-               if (pool_info->mp == mp)
-                       break;
-       }
-       if (pool_info == NULL) {
-               rte_spinlock_unlock(&pool_list_lock);
-               return -ENXIO;
-       }
-
-       /* virtual hugepage mapped addr */
-       va_start = pool_info->mz_addr;
-       rte_spinlock_unlock(&pool_list_lock);
-
        object_size = mp->elt_size + mp->header_size + mp->trailer_size;
 
        pool = octeontx_fpa_bufpool_create(object_size, memseg_count,
                                                OCTEONTX_FPAVF_BUF_OFFSET,
-                                               (char **)&va_start,
                                                mp->socket_id);
        rc = octeontx_fpa_bufpool_block_size(pool);
        if (rc < 0)
@@ -109,27 +72,9 @@ _end:
 static void
 octeontx_fpavf_free(struct rte_mempool *mp)
 {
-       struct octeontx_pool_info *pool_info;
        uintptr_t pool;
-
        pool = (uintptr_t)mp->pool_id;
 
-       rte_spinlock_lock(&pool_list_lock);
-       SLIST_FOREACH(pool_info, &octeontx_pool_head, link) {
-               if (pool_info->mp == mp)
-                       break;
-       }
-
-       if (pool_info == NULL) {
-               rte_spinlock_unlock(&pool_list_lock);
-               rte_panic("%s: trying to free pool with no valid metadata",
-                   __func__);
-       }
-
-       SLIST_REMOVE(&octeontx_pool_head, pool_info, octeontx_pool_info, link);
-       rte_spinlock_unlock(&pool_list_lock);
-
-       rte_free(pool_info);
        octeontx_fpa_bufpool_destroy(pool, mp->socket_id);
 }
 
@@ -222,21 +167,14 @@ static int
 octeontx_fpavf_register_memory_area(const struct rte_mempool *mp,
                                    char *vaddr, rte_iova_t paddr, size_t len)
 {
-       struct octeontx_pool_info *pool_info;
-
        RTE_SET_USED(paddr);
-       RTE_SET_USED(len);
+       uint8_t gpool;
+       uintptr_t pool_bar;
 
-       pool_info = rte_malloc("octeontx_pool_info", sizeof(*pool_info), 0);
-       if (pool_info == NULL)
-               return -ENOMEM;
+       gpool = octeontx_fpa_bufpool_gpool(mp->pool_id);
+       pool_bar = mp->pool_id & ~(uint64_t)FPA_GPOOL_MASK;
 
-       pool_info->mp = mp;
-       pool_info->mz_addr = (uintptr_t)vaddr;
-       rte_spinlock_lock(&pool_list_lock);
-       SLIST_INSERT_HEAD(&octeontx_pool_head, pool_info, link);
-       rte_spinlock_unlock(&pool_list_lock);
-       return 0;
+       return octeontx_fpavf_pool_set_range(pool_bar, len, vaddr, gpool);
 }
 
 static struct rte_mempool_ops octeontx_fpavf_ops = {
index fa84eb9..d515408 100644 (file)
@@ -124,7 +124,7 @@ static struct rte_eth_link pmd_link = {
        .link_speed = ETH_SPEED_NUM_10G,
        .link_duplex = ETH_LINK_FULL_DUPLEX,
        .link_status = ETH_LINK_DOWN,
-       .link_autoneg = ETH_LINK_SPEED_AUTONEG
+       .link_autoneg = ETH_LINK_AUTONEG
 };
 
 static uint16_t
index 54437e9..81dfe5e 100644 (file)
@@ -63,6 +63,7 @@
 #else
 #include <stdint.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_memory.h>
 #include <rte_ether.h>
 #include <rte_atomic.h>
index 8ab1c7f..3bc2b93 100644 (file)
@@ -162,6 +162,7 @@ struct bnxt_link_info {
        uint16_t                link_speed;
        uint16_t                support_speeds;
        uint16_t                auto_link_speed;
+       uint16_t                force_link_speed;
        uint16_t                auto_link_speed_mask;
        uint32_t                preemphasis;
        uint8_t                 phy_type;
index 19c684c..cde8adc 100644 (file)
@@ -165,7 +165,6 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
                goto err_out;
        cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
        B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
-       bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
        if (BNXT_PF(bp))
                rc = bnxt_hwrm_func_cfg_def_cp(bp);
        else
index 3b6813c..3eeca6f 100644 (file)
@@ -393,7 +393,10 @@ static int bnxt_init_nic(struct bnxt *bp)
 {
        int rc;
 
-       bnxt_init_ring_grps(bp);
+       rc = bnxt_init_ring_grps(bp);
+       if (rc)
+               return rc;
+
        bnxt_init_vnics(bp);
        bnxt_init_filters(bp);
 
@@ -713,7 +716,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
                if (filter->mac_index == index) {
                        RTE_LOG(ERR, PMD,
                                "MAC addr already existed for pool %d\n", pool);
-                       return -EINVAL;
+                       return 0;
                }
        }
        filter = bnxt_alloc_filter(bp);
@@ -1723,9 +1726,9 @@ bnxt_match_and_validate_ether_filter(struct bnxt *bp,
        int match = 0;
        *ret = 0;
 
-       if (efilter->ether_type != ETHER_TYPE_IPv4 &&
-               efilter->ether_type != ETHER_TYPE_IPv6) {
-               RTE_LOG(ERR, PMD, "unsupported ether_type(0x%04x) in"
+       if (efilter->ether_type == ETHER_TYPE_IPv4 ||
+               efilter->ether_type == ETHER_TYPE_IPv6) {
+               RTE_LOG(ERR, PMD, "invalid ether_type(0x%04x) in"
                        " ethertype filter.", efilter->ether_type);
                *ret = -EINVAL;
                goto exit;
@@ -1953,7 +1956,8 @@ parse_ntuple_filter(struct bnxt *bp,
 
 static struct bnxt_filter_info*
 bnxt_match_ntuple_filter(struct bnxt *bp,
-                        struct bnxt_filter_info *bfilter)
+                        struct bnxt_filter_info *bfilter,
+                        struct bnxt_vnic_info **mvnic)
 {
        struct bnxt_filter_info *mfilter = NULL;
        int i;
@@ -1972,8 +1976,11 @@ bnxt_match_ntuple_filter(struct bnxt *bp,
                            bfilter->dst_port == mfilter->dst_port &&
                            bfilter->dst_port_mask == mfilter->dst_port_mask &&
                            bfilter->flags == mfilter->flags &&
-                           bfilter->enables == mfilter->enables)
+                           bfilter->enables == mfilter->enables) {
+                               if (mvnic)
+                                       *mvnic = vnic;
                                return mfilter;
+                       }
                }
        }
        return NULL;
@@ -1985,7 +1992,7 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp,
                       enum rte_filter_op filter_op)
 {
        struct bnxt_filter_info *bfilter, *mfilter, *filter1;
-       struct bnxt_vnic_info *vnic, *vnic0;
+       struct bnxt_vnic_info *vnic, *vnic0, *mvnic;
        int ret;
 
        if (nfilter->flags != RTE_5TUPLE_FLAGS) {
@@ -2023,12 +2030,22 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp,
        bfilter->ethertype = 0x800;
        bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
 
-       mfilter = bnxt_match_ntuple_filter(bp, bfilter);
+       mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic);
 
-       if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD) {
-               RTE_LOG(ERR, PMD, "filter exists.");
+       if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+           bfilter->dst_id == mfilter->dst_id) {
+               RTE_LOG(ERR, PMD, "filter exists.\n");
                ret = -EEXIST;
                goto free_filter;
+       } else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+                  bfilter->dst_id != mfilter->dst_id) {
+               mfilter->dst_id = vnic->fw_vnic_id;
+               ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter);
+               STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next);
+               STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next);
+               RTE_LOG(ERR, PMD, "filter with matching pattern exists.\n");
+               RTE_LOG(ERR, PMD, " Updated it to the new destination queue\n");
+               goto free_filter;
        }
        if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
                RTE_LOG(ERR, PMD, "filter doesn't exist.");
@@ -2050,11 +2067,11 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp,
                }
                ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter);
 
-               STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info,
-                             next);
+               STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next);
                bnxt_free_filter(bp, mfilter);
-               bfilter->fw_l2_filter_id = -1;
+               mfilter->fw_l2_filter_id = -1;
                bnxt_free_filter(bp, bfilter);
+               bfilter->fw_l2_filter_id = -1;
        }
 
        return 0;
@@ -2939,11 +2956,19 @@ skip_init:
        /* Copy the permanent MAC from the qcap response address now. */
        memcpy(bp->mac_addr, bp->dflt_mac_addr, sizeof(bp->mac_addr));
        memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+       if (bp->max_ring_grps < bp->rx_cp_nr_rings) {
+               /* 1 ring is for default completion ring */
+               RTE_LOG(ERR, PMD, "Insufficient resource: Ring Group\n");
+               rc = -ENOSPC;
+               goto error_free;
+       }
+
        bp->grp_info = rte_zmalloc("bnxt_grp_info",
                                sizeof(*bp->grp_info) * bp->max_ring_grps, 0);
        if (!bp->grp_info) {
                RTE_LOG(ERR, PMD,
-                       "Failed to alloc %zu bytes needed to store group info table\n",
+                       "Failed to alloc %zu bytes to store group info table\n",
                        sizeof(*bp->grp_info) * bp->max_ring_grps);
                rc = -ENOMEM;
                goto error_free;
index 65d30fb..32af606 100644 (file)
@@ -1042,8 +1042,23 @@ bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
                            !memcmp(mf->dst_ipaddr, nf->dst_ipaddr,
                                    sizeof(nf->dst_ipaddr)) &&
                            !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask,
-                                   sizeof(nf->dst_ipaddr_mask)))
-                               return -EEXIST;
+                                   sizeof(nf->dst_ipaddr_mask))) {
+                               if (mf->dst_id == nf->dst_id)
+                                       return -EEXIST;
+                               /* Same Flow, Different queue
+                                * Clear the old 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)
+                                       bnxt_hwrm_clear_ntuple_filter(bp, mf);
+                               /* Free the old filter, update flow
+                                * with new filter
+                                */
+                               bnxt_free_filter(bp, mf);
+                               flow->filter = nf;
+                               return -EXDEV;
+                       }
                }
        }
        return 0;
@@ -1059,6 +1074,7 @@ bnxt_flow_create(struct rte_eth_dev *dev,
        struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
        struct bnxt_filter_info *filter;
        struct bnxt_vnic_info *vnic = NULL;
+       bool update_flow = false;
        struct rte_flow *flow;
        unsigned int i;
        int ret = 0;
@@ -1089,9 +1105,17 @@ bnxt_flow_create(struct rte_eth_dev *dev,
                goto free_filter;
 
        ret = bnxt_match_filter(bp, filter);
-       if (ret != 0) {
+       if (ret == -EEXIST) {
                RTE_LOG(DEBUG, PMD, "Flow already exists.\n");
+               /* Clear the filter that was created as part of
+                * validate_and_parse_flow() above
+                */
+               bnxt_hwrm_clear_l2_filter(bp, filter);
                goto free_filter;
+       } else if (ret == -EXDEV) {
+               RTE_LOG(DEBUG, PMD, "Flow with same pattern exists");
+               RTE_LOG(DEBUG, PMD, "Updating with different destination\n");
+               update_flow = true;
        }
 
        if (filter->filter_type == HWRM_CFA_EM_FILTER) {
@@ -1114,22 +1138,29 @@ bnxt_flow_create(struct rte_eth_dev *dev,
        if (!ret) {
                flow->filter = filter;
                flow->vnic = vnic;
+               if (update_flow) {
+                       ret = -EXDEV;
+                       goto free_flow;
+               }
                RTE_LOG(ERR, PMD, "Successfully created flow.\n");
                STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next);
                return flow;
        }
 free_filter:
-       filter->fw_l2_filter_id = -1;
        bnxt_free_filter(bp, filter);
 free_flow:
        if (ret == -EEXIST)
                rte_flow_error_set(error, ret,
                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                                   "Matching Flow exists.");
+       else if (ret == -EXDEV)
+               rte_flow_error_set(error, ret,
+                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+                                  "Flow with pattern exists, updating destination queue");
        else
                rte_flow_error_set(error, -ret,
                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-                          "Failed to create flow.");
+                                  "Failed to create flow.");
        rte_free(flow);
        flow = NULL;
        return flow;
@@ -1153,6 +1184,7 @@ bnxt_flow_destroy(struct rte_eth_dev *dev,
        if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
                ret = bnxt_hwrm_clear_ntuple_filter(bp, filter);
 
+       bnxt_hwrm_clear_l2_filter(bp, filter);
        if (!ret) {
                STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next);
                rte_free(flow);
index d2c800d..ce214d7 100644 (file)
@@ -738,7 +738,8 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
                                HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS;
                }
                /* AutoNeg - Advertise speeds specified. */
-               if (conf->auto_link_speed_mask) {
+               if (conf->auto_link_speed_mask &&
+                   !(conf->phy_flags & HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE)) {
                        req.auto_mode =
                                HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
                        req.auto_link_speed_mask =
@@ -801,12 +802,22 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
        link_info->support_speeds = rte_le_to_cpu_16(resp->support_speeds);
        link_info->auto_link_speed = rte_le_to_cpu_16(resp->auto_link_speed);
        link_info->preemphasis = rte_le_to_cpu_32(resp->preemphasis);
+       link_info->force_link_speed = rte_le_to_cpu_16(resp->force_link_speed);
        link_info->phy_ver[0] = resp->phy_maj;
        link_info->phy_ver[1] = resp->phy_min;
        link_info->phy_ver[2] = resp->phy_bld;
 
        HWRM_UNLOCK();
 
+       RTE_LOG(DEBUG, PMD, "Link Speed %d\n", link_info->link_speed);
+       RTE_LOG(DEBUG, PMD, "Auto Mode %d\n", link_info->auto_mode);
+       RTE_LOG(DEBUG, PMD, "Support Speeds %x\n", link_info->support_speeds);
+       RTE_LOG(DEBUG, PMD, "Auto Link Speed %x\n", link_info->auto_link_speed);
+       RTE_LOG(DEBUG, PMD, "Auto Link Speed Mask %x\n",
+                   link_info->auto_link_speed_mask);
+       RTE_LOG(DEBUG, PMD, "Forced Link Speed %x\n",
+                   link_info->force_link_speed);
+
        return rc;
 }
 
@@ -1046,7 +1057,6 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
        cpr->hw_stats_ctx_id = rte_le_to_cpu_16(resp->stat_ctx_id);
 
        HWRM_UNLOCK();
-       bp->grp_info[idx].fw_stats_ctx = cpr->hw_stats_ctx_id;
 
        return rc;
 }
@@ -1569,19 +1579,15 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
 
        for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
 
-               if (i >= bp->rx_cp_nr_rings)
+               if (i >= bp->rx_cp_nr_rings) {
                        cpr = bp->tx_queues[i - bp->rx_cp_nr_rings]->cp_ring;
-               else
+               } else {
                        cpr = bp->rx_queues[i]->cp_ring;
+                       bp->grp_info[i].fw_stats_ctx = -1;
+               }
                if (cpr->hw_stats_ctx_id != HWRM_NA_SIGNATURE) {
                        rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
                        cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
-                       /*
-                        * TODO. Need a better way to reset grp_info.stats_ctx
-                        * for Rx rings only. stats_ctx is not saved for Tx
-                        * in grp_info.
-                        */
-                       bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
                        if (rc)
                                return rc;
                }
@@ -1641,7 +1647,6 @@ static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
        bnxt_hwrm_ring_free(bp, cp_ring,
                        HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL);
        cp_ring->fw_ring_id = INVALID_HW_RING_ID;
-       bp->grp_info[idx].cp_fw_ring_id = INVALID_HW_RING_ID;
        memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *
                        sizeof(*cpr->cp_desc_ring));
        cpr->cp_raw_cons = 0;
@@ -1697,10 +1702,17 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
                                        rxr->rx_ring_struct->ring_size *
                                        sizeof(*rxr->rx_buf_ring));
                        rxr->rx_prod = 0;
+               }
+               ring = rxr->ag_ring_struct;
+               if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+                       bnxt_hwrm_ring_free(bp, ring,
+                                           HWRM_RING_FREE_INPUT_RING_TYPE_RX);
+                       ring->fw_ring_id = INVALID_HW_RING_ID;
                        memset(rxr->ag_buf_ring, 0,
-                                       rxr->ag_ring_struct->ring_size *
-                                       sizeof(*rxr->ag_buf_ring));
+                              rxr->ag_ring_struct->ring_size *
+                              sizeof(*rxr->ag_buf_ring));
                        rxr->ag_prod = 0;
+                       bp->grp_info[i].ag_fw_ring_id = INVALID_HW_RING_ID;
                }
                if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
                        bnxt_free_cp_ring(bp, cpr, idx);
@@ -2123,7 +2135,9 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
        autoneg = bnxt_check_eth_link_autoneg(dev_conf->link_speeds);
        speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
        link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
-       if (autoneg == 1) {
+       /* Autoneg can be done only when the FW allows */
+       if (autoneg == 1 && !(bp->link_info.auto_link_speed ||
+                               bp->link_info.force_link_speed)) {
                link_req.phy_flags |=
                                HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
                link_req.auto_link_speed_mask =
@@ -2141,7 +2155,13 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
                }
 
                link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
-               link_req.link_speed = speed;
+               /* If user wants a particular speed try that first. */
+               if (speed)
+                       link_req.link_speed = speed;
+               else if (bp->link_info.force_link_speed)
+                       link_req.link_speed = bp->link_info.force_link_speed;
+               else
+                       link_req.link_speed = bp->link_info.auto_link_speed;
        }
        link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds);
        link_req.auto_pause = bp->link_info.auto_pause;
@@ -3575,7 +3595,6 @@ int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
        HWRM_UNLOCK();
 
        filter->fw_ntuple_filter_id = -1;
-       filter->fw_l2_filter_id = -1;
 
        return 0;
 }
index 0fa2f0c..59d1035 100644 (file)
@@ -63,13 +63,15 @@ void bnxt_free_ring(struct bnxt_ring *ring)
  * Ring groups
  */
 
-void bnxt_init_ring_grps(struct bnxt *bp)
+int bnxt_init_ring_grps(struct bnxt *bp)
 {
        unsigned int i;
 
        for (i = 0; i < bp->max_ring_grps; i++)
                memset(&bp->grp_info[i], (uint8_t)HWRM_NA_SIGNATURE,
                       sizeof(struct bnxt_ring_grp_info));
+
+       return 0;
 }
 
 /*
@@ -362,9 +364,6 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
                struct bnxt_ring *ring = txr->tx_ring_struct;
                unsigned int idx = i + 1 + bp->rx_cp_nr_rings;
 
-               /* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
-               idx += bp->rx_cp_nr_rings;
-
                /* Tx cmpl */
                rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
                                        HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
index 164f482..a88ab55 100644 (file)
@@ -94,7 +94,7 @@ struct bnxt_tx_ring_info;
 struct bnxt_rx_ring_info;
 struct bnxt_cp_ring_info;
 void bnxt_free_ring(struct bnxt_ring *ring);
-void bnxt_init_ring_grps(struct bnxt *bp);
+int bnxt_init_ring_grps(struct bnxt *bp);
 int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
                            struct bnxt_tx_ring_info *tx_ring_info,
                            struct bnxt_rx_ring_info *rx_ring_info,
index c4da474..b4e9f38 100644 (file)
@@ -118,7 +118,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
                                pools = max_pools;
                        break;
                case ETH_MQ_RX_RSS:
-                       pools = bp->rx_cp_nr_rings;
+                       pools = 1;
                        break;
                default:
                        RTE_LOG(ERR, PMD, "Unsupported mq_mod %d\n",
index 30891b7..5128335 100644 (file)
@@ -470,12 +470,12 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
        if (likely(RX_CMP_IP_CS_OK(rxcmp1)))
                mbuf->ol_flags |= PKT_RX_IP_CKSUM_GOOD;
        else
-               mbuf->ol_flags |= PKT_RX_IP_CKSUM_NONE;
+               mbuf->ol_flags |= PKT_RX_IP_CKSUM_BAD;
 
        if (likely(RX_CMP_L4_CS_OK(rxcmp1)))
                mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
        else
-               mbuf->ol_flags |= PKT_RX_L4_CKSUM_NONE;
+               mbuf->ol_flags |= PKT_RX_L4_CKSUM_BAD;
 
        mbuf->packet_type = bnxt_parse_pkt_type(rxcmp, rxcmp1);
 
index 8ca4bbd..03d2652 100644 (file)
@@ -101,7 +101,7 @@ int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id)
        if (ring == NULL)
                return -ENOMEM;
        txr->tx_ring_struct = ring;
-       ring->ring_size = rte_align32pow2(txq->nb_tx_desc + 1);
+       ring->ring_size = rte_align32pow2(txq->nb_tx_desc);
        ring->ring_mask = ring->ring_size - 1;
        ring->bd = (void *)txr->tx_desc_ring;
        ring->bd_dma = txr->tx_desc_mapping;
@@ -217,23 +217,28 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
                                        tx_pkt->outer_l3_len;
                        txbd1->mss = tx_pkt->tso_segsz;
 
-               } else if (tx_pkt->ol_flags & PKT_TX_OIP_IIP_TCP_UDP_CKSUM) {
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_TCP_UDP_CKSUM) ==
+                          PKT_TX_OIP_IIP_TCP_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) {
+               } 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_OIP_TCP_UDP_CKSUM) {
+               } 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_IIP_CKSUM) {
+               } else if ((tx_pkt->ol_flags & PKT_TX_OIP_IIP_CKSUM) ==
+                          PKT_TX_OIP_IIP_CKSUM) {
                        /* Outer IP, Inner IP CSO */
                        txbd1->lflags |= TX_BD_FLG_TIP_IP_CHKSUM;
                        txbd1->mss = 0;
-               } else if (tx_pkt->ol_flags & PKT_TX_TCP_UDP_CKSUM) {
+               } else if ((tx_pkt->ol_flags & PKT_TX_TCP_UDP_CKSUM) ==
+                          PKT_TX_TCP_UDP_CKSUM) {
                        /* TCP/UDP CSO */
                        txbd1->lflags |= TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
                        txbd1->mss = 0;
index eee9e50..1351808 100644 (file)
@@ -1173,7 +1173,8 @@ bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
        uint8_t i;
 
        for (i = 0; i < internals->active_slave_count; i++)
-               bond_mode_8023ad_activate_slave(bond_dev, i);
+               bond_mode_8023ad_activate_slave(bond_dev,
+                               internals->active_slaves[i]);
 
        return 0;
 }
index 980e636..b834035 100644 (file)
@@ -62,6 +62,25 @@ valid_bonded_port_id(uint16_t port_id)
        return check_for_bonded_ethdev(&rte_eth_devices[port_id]);
 }
 
+int
+check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev)
+{
+       int i;
+       struct bond_dev_private *internals;
+
+       if (check_for_bonded_ethdev(eth_dev) != 0)
+               return 0;
+
+       internals = eth_dev->data->dev_private;
+
+       /* Check if any of slave devices is a bonded device */
+       for (i = 0; i < internals->slave_count; i++)
+               if (valid_bonded_port_id(internals->slaves[i].port_id) == 0)
+                       return 1;
+
+       return 0;
+}
+
 int
 valid_slave_port_id(uint16_t port_id, uint8_t mode)
 {
@@ -272,8 +291,13 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id)
        if (internals->slave_count < 1) {
                /* if MAC is not user defined then use MAC of first slave add to
                 * bonded device */
-               if (!internals->user_defined_mac)
-                       mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
+               if (!internals->user_defined_mac) {
+                       if (mac_address_set(bonded_eth_dev,
+                                           slave_eth_dev->data->mac_addrs)) {
+                               RTE_BOND_LOG(ERR, "Failed to set MAC address");
+                               return -1;
+                       }
+               }
 
                /* Inherit eth dev link properties from first slave */
                link_properties_set(bonded_eth_dev,
@@ -434,7 +458,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id,
                        &rte_eth_devices[bonded_port_id].data->port_id);
 
        /* Restore original MAC address of slave device */
-       mac_address_set(&rte_eth_devices[slave_port_id],
+       rte_eth_dev_default_mac_addr_set(slave_port_id,
                        &(internals->slaves[slave_idx].persisted_mac_addr));
 
        slave_eth_dev = &rte_eth_devices[slave_port_id];
@@ -496,10 +520,18 @@ rte_eth_bond_slave_remove(uint16_t bonded_port_id, uint16_t slave_port_id)
 int
 rte_eth_bond_mode_set(uint16_t bonded_port_id, uint8_t mode)
 {
+       struct rte_eth_dev *bonded_eth_dev;
+
        if (valid_bonded_port_id(bonded_port_id) != 0)
                return -1;
 
-       return bond_ethdev_mode_set(&rte_eth_devices[bonded_port_id], mode);
+       bonded_eth_dev = &rte_eth_devices[bonded_port_id];
+
+       if (check_for_master_bonded_ethdev(bonded_eth_dev) != 0 &&
+                       mode == BONDING_MODE_8023AD)
+               return -1;
+
+       return bond_ethdev_mode_set(bonded_eth_dev, mode);
 }
 
 int
index fe23289..1d3fbeb 100644 (file)
@@ -1500,7 +1500,8 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
        case BONDING_MODE_BALANCE:
        case BONDING_MODE_BROADCAST:
                for (i = 0; i < internals->slave_count; i++) {
-                       if (mac_address_set(&rte_eth_devices[internals->slaves[i].port_id],
+                       if (rte_eth_dev_default_mac_addr_set(
+                                       internals->slaves[i].port_id,
                                        bonded_eth_dev->data->mac_addrs)) {
                                RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
                                                internals->slaves[i].port_id);
@@ -1518,15 +1519,16 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
                for (i = 0; i < internals->slave_count; i++) {
                        if (internals->slaves[i].port_id ==
                                        internals->current_primary_port) {
-                               if (mac_address_set(&rte_eth_devices[internals->primary_port],
+                               if (rte_eth_dev_default_mac_addr_set(
+                                               internals->primary_port,
                                                bonded_eth_dev->data->mac_addrs)) {
                                        RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
                                                        internals->current_primary_port);
                                        return -1;
                                }
                        } else {
-                               if (mac_address_set(
-                                               &rte_eth_devices[internals->slaves[i].port_id],
+                               if (rte_eth_dev_default_mac_addr_set(
+                                               internals->slaves[i].port_id,
                                                &internals->slaves[i].persisted_mac_addr)) {
                                        RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
                                                        internals->slaves[i].port_id);
index 1392da9..a5cfa6a 100644 (file)
@@ -182,6 +182,9 @@ struct bond_dev_private {
 
 extern const struct eth_dev_ops default_dev_ops;
 
+int
+check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev);
+
 int
 check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev);
 
index cf5a2ec..e4375c3 100644 (file)
@@ -212,19 +212,15 @@ dpaa_fw_version_get(struct rte_eth_dev *dev __rte_unused,
                DPAA_PMD_ERR("Unable to open SoC device");
                return -ENOTSUP; /* Not supported on this infra */
        }
-
-       ret = fscanf(svr_file, "svr:%x", &svr_ver);
-       if (ret <= 0) {
+       if (fscanf(svr_file, "svr:%x", &svr_ver) <= 0)
                DPAA_PMD_ERR("Unable to read SoC device");
-               return -ENOTSUP; /* Not supported on this infra */
-       }
 
-       ret = snprintf(fw_version, fw_size,
-                      "svr:%x-fman-v%x",
-                      svr_ver,
-                      fman_ip_rev);
+       fclose(svr_file);
 
+       ret = snprintf(fw_version, fw_size, "SVR:%x-fman-v%x",
+                      svr_ver, fman_ip_rev);
        ret += 1; /* add the size of '\0' */
+
        if (fw_size < (uint32_t)ret)
                return ret;
        else
@@ -723,7 +719,7 @@ static int dpaa_fc_set_default(struct dpaa_if *dpaa_intf)
 static int dpaa_rx_queue_init(struct qman_fq *fq,
                              uint32_t fqid)
 {
-       struct qm_mcc_initfq opts;
+       struct qm_mcc_initfq opts = {0};
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -769,7 +765,7 @@ static int dpaa_rx_queue_init(struct qman_fq *fq,
 static int dpaa_tx_queue_init(struct qman_fq *fq,
                              struct fman_if *fman_intf)
 {
-       struct qm_mcc_initfq opts;
+       struct qm_mcc_initfq opts = {0};
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -800,7 +796,7 @@ static int dpaa_tx_queue_init(struct qman_fq *fq,
 /* Initialise a DEBUG FQ ([rt]x_error, rx_default). */
 static int dpaa_debug_queue_init(struct qman_fq *fq, uint32_t fqid)
 {
-       struct qm_mcc_initfq opts;
+       struct qm_mcc_initfq opts = {0};
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -877,12 +873,17 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
 
        dpaa_intf->rx_queues = rte_zmalloc(NULL,
                sizeof(struct qman_fq) * num_rx_fqs, MAX_CACHELINE);
+       if (!dpaa_intf->rx_queues) {
+               DPAA_PMD_ERR("Failed to alloc mem for RX queues\n");
+               return -ENOMEM;
+       }
+
        for (loop = 0; loop < num_rx_fqs; loop++) {
                fqid = DPAA_PCD_FQID_START + dpaa_intf->ifid *
                        DPAA_PCD_FQID_MULTIPLIER + loop;
                ret = dpaa_rx_queue_init(&dpaa_intf->rx_queues[loop], fqid);
                if (ret)
-                       return ret;
+                       goto free_rx;
                dpaa_intf->rx_queues[loop].dpaa_intf = dpaa_intf;
        }
        dpaa_intf->nb_rx_queues = num_rx_fqs;
@@ -891,14 +892,17 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
        num_cores = rte_lcore_count();
        dpaa_intf->tx_queues = rte_zmalloc(NULL, sizeof(struct qman_fq) *
                num_cores, MAX_CACHELINE);
-       if (!dpaa_intf->tx_queues)
-               return -ENOMEM;
+       if (!dpaa_intf->tx_queues) {
+               DPAA_PMD_ERR("Failed to alloc mem for TX queues\n");
+               ret = -ENOMEM;
+               goto free_rx;
+       }
 
        for (loop = 0; loop < num_cores; loop++) {
                ret = dpaa_tx_queue_init(&dpaa_intf->tx_queues[loop],
                                         fman_intf);
                if (ret)
-                       return ret;
+                       goto free_tx;
                dpaa_intf->tx_queues[loop].dpaa_intf = dpaa_intf;
        }
        dpaa_intf->nb_tx_queues = num_cores;
@@ -935,13 +939,8 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
                DPAA_PMD_ERR("Failed to allocate %d bytes needed to "
                                                "store MAC addresses",
                                ETHER_ADDR_LEN * DPAA_MAX_MAC_FILTER);
-               rte_free(dpaa_intf->rx_queues);
-               rte_free(dpaa_intf->tx_queues);
-               dpaa_intf->rx_queues = NULL;
-               dpaa_intf->tx_queues = NULL;
-               dpaa_intf->nb_rx_queues = 0;
-               dpaa_intf->nb_tx_queues = 0;
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto free_tx;
        }
 
        /* copy the primary mac address */
@@ -967,6 +966,17 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
        fman_if_stats_reset(fman_intf);
 
        return 0;
+
+free_tx:
+       rte_free(dpaa_intf->tx_queues);
+       dpaa_intf->tx_queues = NULL;
+       dpaa_intf->nb_tx_queues = 0;
+
+free_rx:
+       rte_free(dpaa_intf->rx_queues);
+       dpaa_intf->rx_queues = NULL;
+       dpaa_intf->nb_rx_queues = 0;
+       return ret;
 }
 
 static int
index 5457d61..ec5ae13 100644 (file)
@@ -46,7 +46,7 @@
 /* DPAA SoC identifier; If this is not available, it can be concluded
  * that board is non-DPAA. Single slot is currently supported.
  */
-#define DPAA_SOC_ID_FILE               "sys/devices/soc0/soc_id"
+#define DPAA_SOC_ID_FILE               "/sys/devices/soc0/soc_id"
 
 #define DPAA_MBUF_HW_ANNOTATION                64
 #define DPAA_FD_PTA_SIZE               64
index 41e57f2..c0cfec9 100644 (file)
@@ -58,6 +58,7 @@
 #include <rte_ip.h>
 #include <rte_tcp.h>
 #include <rte_udp.h>
+#include <rte_net.h>
 
 #include "dpaa_ethdev.h"
 #include "dpaa_rxtx.h"
@@ -504,6 +505,15 @@ dpaa_eth_mbuf_to_sg_fd(struct rte_mbuf *mbuf,
        fd->opaque_addr = 0;
 
        if (mbuf->ol_flags & DPAA_TX_CKSUM_OFFLOAD_MASK) {
+               if (!mbuf->packet_type) {
+                       struct rte_net_hdr_lens hdr_lens;
+
+                       mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens,
+                                       RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK
+                                       | RTE_PTYPE_L4_MASK);
+                       mbuf->l2_len = hdr_lens.l2_len;
+                       mbuf->l3_len = hdr_lens.l3_len;
+               }
                if (temp->data_off < DEFAULT_TX_ICEOF
                        + sizeof(struct dpaa_eth_parse_results_t))
                        temp->data_off = DEFAULT_TX_ICEOF
@@ -611,6 +621,15 @@ tx_on_dpaa_pool_unsegmented(struct rte_mbuf *mbuf,
        }
 
        if (mbuf->ol_flags & DPAA_TX_CKSUM_OFFLOAD_MASK) {
+               if (!mbuf->packet_type) {
+                       struct rte_net_hdr_lens hdr_lens;
+
+                       mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens,
+                                       RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK
+                                       | RTE_PTYPE_L4_MASK);
+                       mbuf->l2_len = hdr_lens.l2_len;
+                       mbuf->l3_len = hdr_lens.l3_len;
+               }
                if (mbuf->data_off < (DEFAULT_TX_ICEOF +
                    sizeof(struct dpaa_eth_parse_results_t))) {
                        DPAA_DP_LOG(DEBUG, "Checksum offload Err: "
@@ -665,7 +684,7 @@ tx_on_external_pool(struct qman_fq *txq, struct rte_mbuf *mbuf,
                return 1;
        }
 
-       DPAA_MBUF_TO_CONTIG_FD(mbuf, fd_arr, dpaa_intf->bp_info->bpid);
+       DPAA_MBUF_TO_CONTIG_FD(dmable_mbuf, fd_arr, dpaa_intf->bp_info->bpid);
 
        return 0;
 }
index a0c3b4d..29dac6e 100644 (file)
@@ -1209,7 +1209,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
                link.link_speed = 0;
                link.link_duplex = ETH_LINK_HALF_DUPLEX;
                link.link_status = ETH_LINK_DOWN;
-               link.link_autoneg = ETH_LINK_SPEED_FIXED;
+               link.link_autoneg = ETH_LINK_FIXED;
        }
        rte_em_dev_atomic_write_link_status(dev, &link);
 
index fdc139f..79d0244 100644 (file)
@@ -1212,7 +1212,7 @@ igb_check_mq_mode(struct rte_eth_dev *dev)
        enum rte_eth_rx_mq_mode rx_mq_mode = dev->data->dev_conf.rxmode.mq_mode;
        enum rte_eth_tx_mq_mode tx_mq_mode = dev->data->dev_conf.txmode.mq_mode;
        uint16_t nb_rx_q = dev->data->nb_rx_queues;
-       uint16_t nb_tx_q = dev->data->nb_rx_queues;
+       uint16_t nb_tx_q = dev->data->nb_tx_queues;
 
        if ((rx_mq_mode & ETH_MQ_RX_DCB_FLAG) ||
            tx_mq_mode == ETH_MQ_TX_DCB ||
@@ -2435,7 +2435,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
                link.link_speed = 0;
                link.link_duplex = ETH_LINK_HALF_DUPLEX;
                link.link_status = ETH_LINK_DOWN;
-               link.link_autoneg = ETH_LINK_SPEED_FIXED;
+               link.link_autoneg = ETH_LINK_FIXED;
        }
        rte_igb_dev_atomic_write_link_status(dev, &link);
 
@@ -3300,7 +3300,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
        }
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if (rte_intr_cap_multiple(intr_handle) &&
+           dev->data->dev_conf.intr_conf.rxq) {
                intr_vector = dev->data->nb_rx_queues;
                ret = rte_intr_efd_enable(intr_handle, intr_vector);
                if (ret)
index 22bad26..057579b 100644 (file)
@@ -1345,6 +1345,11 @@ igb_flow_create(struct rte_eth_dev *dev,
                if (!ret) {
                        ntuple_filter_ptr = rte_zmalloc("igb_ntuple_filter",
                                sizeof(struct igb_ntuple_filter_ele), 0);
+                       if (!ntuple_filter_ptr) {
+                               PMD_DRV_LOG(ERR, "failed to allocate memory");
+                               goto out;
+                       }
+
                        rte_memcpy(&ntuple_filter_ptr->filter_info,
                                &ntuple_filter,
                                sizeof(struct rte_eth_ntuple_filter));
@@ -1367,6 +1372,11 @@ igb_flow_create(struct rte_eth_dev *dev,
                        ethertype_filter_ptr = rte_zmalloc(
                                "igb_ethertype_filter",
                                sizeof(struct igb_ethertype_filter_ele), 0);
+                       if (!ethertype_filter_ptr) {
+                               PMD_DRV_LOG(ERR, "failed to allocate memory");
+                               goto out;
+                       }
+
                        rte_memcpy(&ethertype_filter_ptr->filter_info,
                                &ethertype_filter,
                                sizeof(struct rte_eth_ethertype_filter));
@@ -1387,6 +1397,11 @@ igb_flow_create(struct rte_eth_dev *dev,
                if (!ret) {
                        syn_filter_ptr = rte_zmalloc("igb_syn_filter",
                                sizeof(struct igb_eth_syn_filter_ele), 0);
+                       if (!syn_filter_ptr) {
+                               PMD_DRV_LOG(ERR, "failed to allocate memory");
+                               goto out;
+                       }
+
                        rte_memcpy(&syn_filter_ptr->filter_info,
                                &syn_filter,
                                sizeof(struct rte_eth_syn_filter));
@@ -1408,6 +1423,11 @@ igb_flow_create(struct rte_eth_dev *dev,
                if (!ret) {
                        flex_filter_ptr = rte_zmalloc("igb_flex_filter",
                                sizeof(struct igb_flex_filter_ele), 0);
+                       if (!flex_filter_ptr) {
+                               PMD_DRV_LOG(ERR, "failed to allocate memory");
+                               goto out;
+                       }
+
                        rte_memcpy(&flex_filter_ptr->filter_info,
                                &flex_filter,
                                sizeof(struct rte_eth_flex_filter));
index 22db895..aa24ef3 100644 (file)
@@ -260,16 +260,17 @@ static inline void ena_rx_mbuf_prepare(struct rte_mbuf *mbuf,
                                       struct ena_com_rx_ctx *ena_rx_ctx)
 {
        uint64_t ol_flags = 0;
+       uint32_t packet_type = 0;
 
        if (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_TCP)
-               ol_flags |= PKT_TX_TCP_CKSUM;
+               packet_type |= RTE_PTYPE_L4_TCP;
        else if (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP)
-               ol_flags |= PKT_TX_UDP_CKSUM;
+               packet_type |= RTE_PTYPE_L4_UDP;
 
        if (ena_rx_ctx->l3_proto == ENA_ETH_IO_L3_PROTO_IPV4)
-               ol_flags |= PKT_TX_IPV4;
+               packet_type |= RTE_PTYPE_L3_IPV4;
        else if (ena_rx_ctx->l3_proto == ENA_ETH_IO_L3_PROTO_IPV6)
-               ol_flags |= PKT_TX_IPV6;
+               packet_type |= RTE_PTYPE_L3_IPV6;
 
        if (unlikely(ena_rx_ctx->l4_csum_err))
                ol_flags |= PKT_RX_L4_CKSUM_BAD;
@@ -277,6 +278,7 @@ static inline void ena_rx_mbuf_prepare(struct rte_mbuf *mbuf,
                ol_flags |= PKT_RX_IP_CKSUM_BAD;
 
        mbuf->ol_flags = ol_flags;
+       mbuf->packet_type = packet_type;
 }
 
 static inline void ena_tx_mbuf_prepare(struct rte_mbuf *mbuf,
index e36ec38..a43fddc 100644 (file)
 #define DRV_DESCRIPTION                "Cisco VIC Ethernet NIC Poll-mode Driver"
 #define DRV_COPYRIGHT          "Copyright 2008-2015 Cisco Systems, Inc"
 
-#define ENIC_WQ_MAX            8
-/* With Rx scatter support, we use two RQs on VIC per RQ used by app. Both
- * RQs use the same CQ.
- */
-#define ENIC_RQ_MAX            16
-#define ENIC_CQ_MAX            (ENIC_WQ_MAX + (ENIC_RQ_MAX / 2))
-#define ENIC_INTR_MAX          (ENIC_CQ_MAX + 2)
 #define ENIC_MAX_MAC_ADDR      64
 
 #define VLAN_ETH_HLEN           18
@@ -150,17 +143,17 @@ struct enic {
        unsigned int flags;
        unsigned int priv_flags;
 
-       /* work queue */
-       struct vnic_wq wq[ENIC_WQ_MAX];
-       unsigned int wq_count;
+       /* work queue (len = conf_wq_count) */
+       struct vnic_wq *wq;
+       unsigned int wq_count; /* equals eth_dev nb_tx_queues */
 
-       /* receive queue */
-       struct vnic_rq rq[ENIC_RQ_MAX];
-       unsigned int rq_count;
+       /* receive queue (len = conf_rq_count) */
+       struct vnic_rq *rq;
+       unsigned int rq_count; /* equals eth_dev nb_rx_queues */
 
-       /* completion queue */
-       struct vnic_cq cq[ENIC_CQ_MAX];
-       unsigned int cq_count;
+       /* completion queue (len = conf_cq_count) */
+       struct vnic_cq *cq;
+       unsigned int cq_count; /* equals rq_count + wq_count */
 
        /* interrupt resource */
        struct vnic_intr intr;
index 669dbf3..98391b0 100644 (file)
@@ -205,13 +205,7 @@ static int enicpmd_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
                return -E_RTE_SECONDARY;
 
        ENICPMD_FUNC_TRACE();
-       if (queue_idx >= ENIC_WQ_MAX) {
-               dev_err(enic,
-                       "Max number of TX queues exceeded.  Max is %d\n",
-                       ENIC_WQ_MAX);
-               return -EINVAL;
-       }
-
+       RTE_ASSERT(queue_idx < enic->conf_wq_count);
        eth_dev->data->tx_queues[queue_idx] = (void *)&enic->wq[queue_idx];
 
        ret = enic_alloc_wq(enic, queue_idx, socket_id, nb_desc);
@@ -325,17 +319,7 @@ static int enicpmd_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return -E_RTE_SECONDARY;
-
-       /* With Rx scatter support, two RQs are now used on VIC per RQ used
-        * by the application.
-        */
-       if (queue_idx * 2 >= ENIC_RQ_MAX) {
-               dev_err(enic,
-                       "Max number of RX queues exceeded.  Max is %d. This PMD uses 2 RQs on VIC per RQ used by DPDK.\n",
-                       ENIC_RQ_MAX);
-               return -EINVAL;
-       }
-
+       RTE_ASSERT(enic_rte_rq_idx_to_sop_idx(queue_idx) < enic->conf_rq_count);
        eth_dev->data->rx_queues[queue_idx] =
                (void *)&enic->rq[enic_rte_rq_idx_to_sop_idx(queue_idx)];
 
index 8af0ccd..1694aed 100644 (file)
@@ -1075,6 +1075,9 @@ static void enic_dev_deinit(struct enic *enic)
        vnic_dev_notify_unset(enic->vdev);
 
        rte_free(eth_dev->data->mac_addrs);
+       rte_free(enic->cq);
+       rte_free(enic->rq);
+       rte_free(enic->wq);
 }
 
 
@@ -1082,27 +1085,28 @@ int enic_set_vnic_res(struct enic *enic)
 {
        struct rte_eth_dev *eth_dev = enic->rte_dev;
        int rc = 0;
+       unsigned int required_rq, required_wq, required_cq;
 
-       /* With Rx scatter support, two RQs are now used per RQ used by
-        * the application.
-        */
-       if (enic->conf_rq_count < eth_dev->data->nb_rx_queues) {
+       /* Always use two vNIC RQs per eth_dev RQ, regardless of Rx scatter. */
+       required_rq = eth_dev->data->nb_rx_queues * 2;
+       required_wq = eth_dev->data->nb_tx_queues;
+       required_cq = eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues;
+
+       if (enic->conf_rq_count < required_rq) {
                dev_err(dev, "Not enough Receive queues. Requested:%u which uses %d RQs on VIC, Configured:%u\n",
                        eth_dev->data->nb_rx_queues,
-                       eth_dev->data->nb_rx_queues * 2, enic->conf_rq_count);
+                       required_rq, enic->conf_rq_count);
                rc = -EINVAL;
        }
-       if (enic->conf_wq_count < eth_dev->data->nb_tx_queues) {
+       if (enic->conf_wq_count < required_wq) {
                dev_err(dev, "Not enough Transmit queues. Requested:%u, Configured:%u\n",
                        eth_dev->data->nb_tx_queues, enic->conf_wq_count);
                rc = -EINVAL;
        }
 
-       if (enic->conf_cq_count < (eth_dev->data->nb_rx_queues +
-                                  eth_dev->data->nb_tx_queues)) {
+       if (enic->conf_cq_count < required_cq) {
                dev_err(dev, "Not enough Completion queues. Required:%u, Configured:%u\n",
-                       (eth_dev->data->nb_rx_queues +
-                        eth_dev->data->nb_tx_queues), enic->conf_cq_count);
+                       required_cq, enic->conf_cq_count);
                rc = -EINVAL;
        }
 
@@ -1307,6 +1311,25 @@ static int enic_dev_init(struct enic *enic)
                dev_err(enic, "See the ENIC PMD guide for more information.\n");
                return -EINVAL;
        }
+       /* Queue counts may be zeros. rte_zmalloc returns NULL in that case. */
+       enic->cq = rte_zmalloc("enic_vnic_cq", sizeof(struct vnic_cq) *
+                              enic->conf_cq_count, 8);
+       enic->rq = rte_zmalloc("enic_vnic_rq", sizeof(struct vnic_rq) *
+                              enic->conf_rq_count, 8);
+       enic->wq = rte_zmalloc("enic_vnic_wq", sizeof(struct vnic_wq) *
+                              enic->conf_wq_count, 8);
+       if (enic->conf_cq_count > 0 && enic->cq == NULL) {
+               dev_err(enic, "failed to allocate vnic_cq, aborting.\n");
+               return -1;
+       }
+       if (enic->conf_rq_count > 0 && enic->rq == NULL) {
+               dev_err(enic, "failed to allocate vnic_rq, aborting.\n");
+               return -1;
+       }
+       if (enic->conf_wq_count > 0 && enic->wq == NULL) {
+               dev_err(enic, "failed to allocate vnic_wq, aborting.\n");
+               return -1;
+       }
 
        /* Get the supported filters */
        enic_fdir_info(enic);
index a3663d5..831c90a 100644 (file)
@@ -285,7 +285,8 @@ enic_cq_rx_to_pkt_flags(struct cq_desc *cqd, struct rte_mbuf *mbuf)
                        else
                                pkt_flags |= PKT_RX_IP_CKSUM_BAD;
 
-                       if (l4_flags & (RTE_PTYPE_L4_UDP | RTE_PTYPE_L4_TCP)) {
+                       if (l4_flags == RTE_PTYPE_L4_UDP ||
+                           l4_flags == RTE_PTYPE_L4_TCP) {
                                if (enic_cq_rx_desc_tcp_udp_csum_ok(cqrd))
                                        pkt_flags |= PKT_RX_L4_CKSUM_GOOD;
                                else
index 6bc5aba..8336510 100644 (file)
@@ -46,7 +46,7 @@ static const struct rte_eth_link eth_link = {
        .link_speed = ETH_SPEED_NUM_10G,
        .link_duplex = ETH_LINK_FULL_DUPLEX,
        .link_status = ETH_LINK_UP,
-       .link_autoneg = ETH_LINK_SPEED_AUTONEG,
+       .link_autoneg = ETH_LINK_AUTONEG,
 };
 
 static int
index cfc83e3..ec63ac9 100644 (file)
@@ -407,7 +407,7 @@ failsafe_args_free(struct rte_eth_dev *dev)
        uint8_t i;
 
        FOREACH_SUBDEV(sdev, i, dev) {
-               rte_free(sdev->cmdline);
+               free(sdev->cmdline);
                sdev->cmdline = NULL;
                free(sdev->devargs.args);
                sdev->devargs.args = NULL;
index 70157c8..178294c 100644 (file)
@@ -111,7 +111,7 @@ failsafe_rx_burst(void *queue,
                if (i == priv->subs_tail)
                        i = priv->subs_head;
                sdev = &priv->subs[i];
-               if (unlikely(fs_rx_unsafe(sdev)))
+               if (fs_rx_unsafe(sdev))
                        continue;
                sub_rxq = ETH(sdev)->data->rx_queues[rxq->qid];
                FS_ATOMIC_P(rxq->refcnt[sdev->sid]);
index 2d05a46..58dac38 100644 (file)
@@ -54,7 +54,7 @@
 /* Wait interval to get switch status */
 #define WAIT_SWITCH_MSG_US    100000
 /* A period of quiescence for switch */
-#define FM10K_SWITCH_QUIESCE_US 10000
+#define FM10K_SWITCH_QUIESCE_US 100000
 /* Number of chars per uint32 type */
 #define CHARS_PER_UINT32 (sizeof(uint32_t))
 #define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1)
@@ -1242,7 +1242,7 @@ fm10k_dev_close(struct rte_eth_dev *dev)
                MAX_LPORT_NUM, false);
        fm10k_mbx_unlock(hw);
 
-       /* allow 10ms for device to quiesce */
+       /* allow 100ms for device to quiesce */
        rte_delay_us(FM10K_SWITCH_QUIESCE_US);
 
        /* Stop mailbox service first */
index 811cc9f..290ef24 100644 (file)
@@ -684,6 +684,15 @@ rte_i40e_dev_atomic_write_link_status(struct rte_eth_dev *dev,
        return 0;
 }
 
+static inline void
+i40e_write_global_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
+{
+       i40e_write_rx_ctl(hw, reg_addr, reg_val);
+       PMD_DRV_LOG(DEBUG, "Global register 0x%08x is modified "
+                   "with value 0x%08x",
+                   reg_addr, reg_val);
+}
+
 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci");
@@ -707,9 +716,10 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
         * configuration API is added to avoid configuration conflicts
         * between ports of the same device.
         */
-       I40E_WRITE_REG(hw, I40E_GLQF_ORT(33), 0x000000E0);
-       I40E_WRITE_REG(hw, I40E_GLQF_ORT(34), 0x000000E3);
-       I40E_WRITE_REG(hw, I40E_GLQF_ORT(35), 0x000000E6);
+       I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33), 0x000000E0);
+       I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(34), 0x000000E3);
+       I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(35), 0x000000E6);
+       i40e_global_cfg_warning(I40E_WARNING_ENA_FLX_PLD);
 
        /*
         * Initialize registers for parsing packet type of QinQ
@@ -717,8 +727,26 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
         * configuration API is added to avoid configuration conflicts
         * between ports of the same device.
         */
-       I40E_WRITE_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
-       I40E_WRITE_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
+       I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
+       I40E_WRITE_GLB_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
+       i40e_global_cfg_warning(I40E_WARNING_QINQ_PARSER);
+}
+
+static inline void i40e_config_automask(struct i40e_pf *pf)
+{
+       struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+       uint32_t val;
+
+       /* INTENA flag is not auto-cleared for interrupt */
+       val = I40E_READ_REG(hw, I40E_GLINT_CTL);
+       val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
+               I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
+
+       /* If support multi-driver, PF will use INT0. */
+       if (!pf->support_multi_driver)
+               val |= I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK;
+
+       I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
 }
 
 #define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
@@ -1006,7 +1034,7 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev)
        struct rte_hash_parameters fdir_hash_params = {
                .name = fdir_hash_name,
                .entries = I40E_MAX_FDIR_FILTER_NUM,
-               .key_len = sizeof(struct rte_eth_fdir_input),
+               .key_len = sizeof(struct i40e_fdir_input),
                .hash_func = rte_hash_crc,
                .hash_func_init_val = 0,
                .socket_id = rte_socket_id(),
@@ -1068,6 +1096,68 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev)
        memset(info, 0, sizeof(struct i40e_queue_regions));
 }
 
+#define ETH_I40E_SUPPORT_MULTI_DRIVER  "support-multi-driver"
+
+static int
+i40e_parse_multi_drv_handler(__rte_unused const char *key,
+                              const char *value,
+                              void *opaque)
+{
+       struct i40e_pf *pf;
+       unsigned long support_multi_driver;
+       char *end;
+
+       pf = (struct i40e_pf *)opaque;
+
+       errno = 0;
+       support_multi_driver = strtoul(value, &end, 10);
+       if (errno != 0 || end == value || *end != 0) {
+               PMD_DRV_LOG(WARNING, "Wrong global configuration");
+               return -(EINVAL);
+       }
+
+       if (support_multi_driver == 1 || support_multi_driver == 0)
+               pf->support_multi_driver = (bool)support_multi_driver;
+       else
+               PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
+                           "enable global configuration by default."
+                           ETH_I40E_SUPPORT_MULTI_DRIVER);
+       return 0;
+}
+
+static int
+i40e_support_multi_driver(struct rte_eth_dev *dev)
+{
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       static const char *const valid_keys[] = {
+               ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
+       struct rte_kvargs *kvlist;
+
+       /* Enable global configuration by default */
+       pf->support_multi_driver = false;
+
+       if (!dev->device->devargs)
+               return 0;
+
+       kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+       if (!kvlist)
+               return -EINVAL;
+
+       if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER) > 1)
+               PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+                           "the first invalid or last valid one is used !",
+                           ETH_I40E_SUPPORT_MULTI_DRIVER);
+
+       if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
+                              i40e_parse_multi_drv_handler, pf) < 0) {
+               rte_kvargs_free(kvlist);
+               return -EINVAL;
+       }
+
+       rte_kvargs_free(kvlist);
+       return 0;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -1096,7 +1186,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                return 0;
        }
        i40e_set_default_ptype_table(dev);
-       i40e_set_default_pctype_table(dev);
        pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        intr_handle = &pci_dev->intr_handle;
 
@@ -1122,6 +1211,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        hw->bus.func = pci_dev->addr.function;
        hw->adapter_stopped = 0;
 
+       /* Check if need to support multi-driver */
+       i40e_support_multi_driver(dev);
+
        /* Make sure all is clean before doing PF reset */
        i40e_clear_hw(hw);
 
@@ -1142,13 +1234,18 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                return ret;
        }
 
+       i40e_config_automask(pf);
+
+       i40e_set_default_pctype_table(dev);
+
        /*
         * To work around the NVM issue, initialize registers
         * for flexible payload and packet type of QinQ by
         * software. It should be removed once issues are fixed
         * in NVM.
         */
-       i40e_GLQF_reg_init(hw);
+       if (!pf->support_multi_driver)
+               i40e_GLQF_reg_init(hw);
 
        /* Initialize the input set for filters (hash and fd) to default value */
        i40e_filter_input_set_init(pf);
@@ -1168,10 +1265,17 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
                     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
        /* initialise the L3_MAP register */
-       ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
-                                  0x00000028,  NULL);
-       if (ret)
-               PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d", ret);
+       if (!pf->support_multi_driver) {
+               ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
+                                                  0x00000028,  NULL);
+               if (ret)
+                       PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d",
+                                    ret);
+               PMD_INIT_LOG(DEBUG,
+                            "Global register 0x%08x is changed with 0x28",
+                            I40E_GLQF_L3_MAP(40));
+               i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
+       }
 
        /* Need the special FW version to support floating VEB */
        config_floating_veb(dev);
@@ -1247,11 +1351,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
        i40e_set_fc(hw, &aq_fail, TRUE);
 
        /* Set the global registers with default ether type value */
-       ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
-       if (ret != I40E_SUCCESS) {
-               PMD_INIT_LOG(ERR,
-                       "Failed to set the default outer VLAN ether type");
-               goto err_setup_pf_switch;
+       if (!pf->support_multi_driver) {
+               ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
+                                        ETHER_TYPE_VLAN);
+               if (ret != I40E_SUCCESS) {
+                       PMD_INIT_LOG(ERR,
+                                    "Failed to set the default outer "
+                                    "VLAN ether type");
+                       goto err_setup_pf_switch;
+               }
        }
 
        /* PF setup, which includes VSI setup */
@@ -1640,6 +1748,7 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
        int i;
        uint32_t val;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
 
        /* Bind all RX queues to allocated MSIX interrupt */
        for (i = 0; i < nb_queue; i++) {
@@ -1658,7 +1767,8 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
        /* Write first RX queue to Link list register as the head element */
        if (vsi->type != I40E_VSI_SRIOV) {
                uint16_t interval =
-                       i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
+                       i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL,
+                                              pf->support_multi_driver);
 
                if (msix_vect == I40E_MISC_VEC_ID) {
                        I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
@@ -1717,7 +1827,6 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
        uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
        uint16_t queue_idx = 0;
        int record = 0;
-       uint32_t val;
        int i;
 
        for (i = 0; i < vsi->nb_qps; i++) {
@@ -1725,13 +1834,6 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
                I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0);
        }
 
-       /* INTENA flag is not auto-cleared for interrupt */
-       val = I40E_READ_REG(hw, I40E_GLINT_CTL);
-       val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
-               I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK |
-               I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
-       I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
-
        /* VF bind interrupt */
        if (vsi->type == I40E_VSI_SRIOV) {
                __vsi_queues_bind_intr(vsi, msix_vect,
@@ -1788,27 +1890,22 @@ i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
-       uint16_t interval = i40e_calc_itr_interval(\
-               RTE_LIBRTE_I40E_ITR_INTERVAL);
+       struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
        uint16_t msix_intr, i;
 
-       if (rte_intr_allow_others(intr_handle))
+       if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
                for (i = 0; i < vsi->nb_msix; i++) {
                        msix_intr = vsi->msix_intr + i;
                        I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
                                I40E_PFINT_DYN_CTLN_INTENA_MASK |
                                I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-                               (0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-                               (interval <<
-                                I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+                               I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
                }
        else
                I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
                               I40E_PFINT_DYN_CTL0_INTENA_MASK |
                               I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
-                              (0 << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT) |
-                              (interval <<
-                               I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT));
+                              I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 
        I40E_WRITE_FLUSH(hw);
 }
@@ -1820,16 +1917,18 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
        uint16_t msix_intr, i;
 
-       if (rte_intr_allow_others(intr_handle))
+       if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
                for (i = 0; i < vsi->nb_msix; i++) {
                        msix_intr = vsi->msix_intr + i;
                        I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
-                                      0);
+                                      I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
                }
        else
-               I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+               I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+                              I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
 
        I40E_WRITE_FLUSH(hw);
 }
@@ -2154,9 +2253,6 @@ i40e_dev_stop(struct rte_eth_dev *dev)
        /* reset hierarchy commit */
        pf->tm_conf.committed = false;
 
-       /* Remove all the queue region configuration */
-       i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
-
        hw->adapter_stopped = 1;
 }
 
@@ -2531,6 +2627,22 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
                            pf->offset_loaded,
                            &pf->internal_stats_offset.rx_broadcast,
                            &pf->internal_stats.rx_broadcast);
+       /* Get total internal tx packet count */
+       i40e_stat_update_48(hw, I40E_GLV_UPTCH(hw->port),
+                           I40E_GLV_UPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_unicast,
+                           &pf->internal_stats.tx_unicast);
+       i40e_stat_update_48(hw, I40E_GLV_MPTCH(hw->port),
+                           I40E_GLV_MPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_multicast,
+                           &pf->internal_stats.tx_multicast);
+       i40e_stat_update_48(hw, I40E_GLV_BPTCH(hw->port),
+                           I40E_GLV_BPTCL(hw->port),
+                           pf->offset_loaded,
+                           &pf->internal_stats_offset.tx_broadcast,
+                           &pf->internal_stats.tx_broadcast);
 
        /* exclude CRC size */
        pf->internal_stats.rx_bytes -= (pf->internal_stats.rx_unicast +
@@ -2560,16 +2672,32 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
        ns->eth.rx_bytes -= (ns->eth.rx_unicast + ns->eth.rx_multicast +
                ns->eth.rx_broadcast) * ETHER_CRC_LEN;
 
-       /* Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
-        * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negtive
+       /* exclude internal rx bytes
+        * Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
+        * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negative
         * value.
+        * same to I40E_GLV_UPRC[H/L], I40E_GLV_MPRC[H/L], I40E_GLV_BPRC[H/L].
         */
        if (ns->eth.rx_bytes < pf->internal_stats.rx_bytes)
                ns->eth.rx_bytes = 0;
-       /* exlude internal rx bytes */
        else
                ns->eth.rx_bytes -= pf->internal_stats.rx_bytes;
 
+       if (ns->eth.rx_unicast < pf->internal_stats.rx_unicast)
+               ns->eth.rx_unicast = 0;
+       else
+               ns->eth.rx_unicast -= pf->internal_stats.rx_unicast;
+
+       if (ns->eth.rx_multicast < pf->internal_stats.rx_multicast)
+               ns->eth.rx_multicast = 0;
+       else
+               ns->eth.rx_multicast -= pf->internal_stats.rx_multicast;
+
+       if (ns->eth.rx_broadcast < pf->internal_stats.rx_broadcast)
+               ns->eth.rx_broadcast = 0;
+       else
+               ns->eth.rx_broadcast -= pf->internal_stats.rx_broadcast;
+
        i40e_stat_update_32(hw, I40E_GLPRT_RDPC(hw->port),
                            pf->offset_loaded, &os->eth.rx_discards,
                            &ns->eth.rx_discards);
@@ -2598,12 +2726,32 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
        ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast +
                ns->eth.tx_broadcast) * ETHER_CRC_LEN;
 
-       /* exclude internal tx bytes */
+       /* exclude internal tx bytes
+        * Workaround: it is possible I40E_GLV_GOTCH[H/L] is updated before
+        * I40E_GLPRT_GOTCH[H/L], so there is a small window that cause negative
+        * value.
+        * same to I40E_GLV_UPTC[H/L], I40E_GLV_MPTC[H/L], I40E_GLV_BPTC[H/L].
+        */
        if (ns->eth.tx_bytes < pf->internal_stats.tx_bytes)
                ns->eth.tx_bytes = 0;
        else
                ns->eth.tx_bytes -= pf->internal_stats.tx_bytes;
 
+       if (ns->eth.tx_unicast < pf->internal_stats.tx_unicast)
+               ns->eth.tx_unicast = 0;
+       else
+               ns->eth.tx_unicast -= pf->internal_stats.tx_unicast;
+
+       if (ns->eth.tx_multicast < pf->internal_stats.tx_multicast)
+               ns->eth.tx_multicast = 0;
+       else
+               ns->eth.tx_multicast -= pf->internal_stats.tx_multicast;
+
+       if (ns->eth.tx_broadcast < pf->internal_stats.tx_broadcast)
+               ns->eth.tx_broadcast = 0;
+       else
+               ns->eth.tx_broadcast -= pf->internal_stats.tx_broadcast;
+
        /* GLPRT_TEPC not supported */
 
        /* additional port specific stats */
@@ -3173,8 +3321,8 @@ i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev,
                return -EIO;
        }
        PMD_DRV_LOG(DEBUG,
-                   "Debug write 0x%08"PRIx64" to I40E_GL_SWT_L2TAGCTRL[%d]",
-                   reg_w, reg_id);
+                   "Global register 0x%08x is changed with value 0x%08x",
+                   I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w);
 
        return 0;
 }
@@ -3185,6 +3333,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
                   uint16_t tpid)
 {
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        int qinq = dev->data->dev_conf.rxmode.hw_vlan_extend;
        int ret = 0;
 
@@ -3195,6 +3344,12 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
                            "Unsupported vlan type.");
                return -EINVAL;
        }
+
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Setting TPID is not supported.");
+               return -ENOTSUP;
+       }
+
        /* 802.1ad frames ability is added in NVM API 1.7*/
        if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
                if (qinq) {
@@ -3217,6 +3372,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
                /* If NVM API < 1.7, keep the register setting */
                ret = i40e_vlan_tpid_set_by_registers(dev, vlan_type,
                                                      tpid, qinq);
+       i40e_global_cfg_warning(I40E_WARNING_TPID);
 
        return ret;
 }
@@ -3446,19 +3602,25 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
                I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg);
        }
 
-       /* config the water marker both based on the packets and bytes */
-       I40E_WRITE_REG(hw, I40E_GLRPB_PHW,
-                      (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-                      << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-       I40E_WRITE_REG(hw, I40E_GLRPB_PLW,
-                      (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-                      << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
-       I40E_WRITE_REG(hw, I40E_GLRPB_GHW,
-                      pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
-                      << I40E_KILOSHIFT);
-       I40E_WRITE_REG(hw, I40E_GLRPB_GLW,
-                      pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
-                      << I40E_KILOSHIFT);
+       if (!pf->support_multi_driver) {
+               /* config water marker both based on the packets and bytes */
+               I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW,
+                                (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+                                << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+               I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
+                                 (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+                                << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+               I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
+                                 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+                                 << I40E_KILOSHIFT);
+               I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
+                                  pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+                                  << I40E_KILOSHIFT);
+               i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
+       } else {
+               PMD_DRV_LOG(ERR,
+                           "Water marker configuration is not supported.");
+       }
 
        I40E_WRITE_FLUSH(hw);
 
@@ -4950,16 +5112,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 
        /* VF has MSIX interrupt in VF range, don't allocate here */
        if (type == I40E_VSI_MAIN) {
-               ret = i40e_res_pool_alloc(&pf->msix_pool,
-                                         RTE_MIN(vsi->nb_qps,
-                                                 RTE_MAX_RXTX_INTR_VEC_ID));
-               if (ret < 0) {
-                       PMD_DRV_LOG(ERR, "VSI MAIN %d get heap failed %d",
-                                   vsi->seid, ret);
-                       goto fail_queue_alloc;
+               if (pf->support_multi_driver) {
+                       /* If support multi-driver, need to use INT0 instead of
+                        * allocating from msix pool. The Msix pool is init from
+                        * INT1, so it's OK just set msix_intr to 0 and nb_msix
+                        * to 1 without calling i40e_res_pool_alloc.
+                        */
+                       vsi->msix_intr = 0;
+                       vsi->nb_msix = 1;
+               } else {
+                       ret = i40e_res_pool_alloc(&pf->msix_pool,
+                                                 RTE_MIN(vsi->nb_qps,
+                                                    RTE_MAX_RXTX_INTR_VEC_ID));
+                       if (ret < 0) {
+                               PMD_DRV_LOG(ERR,
+                                           "VSI MAIN %d get heap failed %d",
+                                           vsi->seid, ret);
+                               goto fail_queue_alloc;
+                       }
+                       vsi->msix_intr = ret;
+                       vsi->nb_msix = RTE_MIN(vsi->nb_qps,
+                                              RTE_MAX_RXTX_INTR_VEC_ID);
                }
-               vsi->msix_intr = ret;
-               vsi->nb_msix = RTE_MIN(vsi->nb_qps, RTE_MAX_RXTX_INTR_VEC_ID);
        } else if (type != I40E_VSI_SRIOV) {
                ret = i40e_res_pool_alloc(&pf->msix_pool, 1);
                if (ret < 0) {
@@ -5315,15 +5489,15 @@ i40e_dev_init_vlan(struct rte_eth_dev *dev)
        int mask = 0;
 
        /* Apply vlan offload setting */
-       mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
+       mask = ETH_VLAN_STRIP_MASK |
+              ETH_VLAN_FILTER_MASK |
+              ETH_VLAN_EXTEND_MASK;
        ret = i40e_vlan_offload_set(dev, mask);
        if (ret) {
                PMD_DRV_LOG(INFO, "Failed to update vlan offload");
                return ret;
        }
 
-       /* Apply double-vlan setting, not implemented yet */
-
        /* Apply pvid setting */
        ret = i40e_vlan_pvid_set(dev, data->dev_conf.txmode.pvid,
                                data->dev_conf.txmode.hw_vlan_insert_pvid);
@@ -5876,7 +6050,8 @@ void
 i40e_pf_disable_irq0(struct i40e_hw *hw)
 {
        /* Disable all interrupt types */
-       I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+       I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+                      I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
        I40E_WRITE_FLUSH(hw);
 }
 
@@ -6951,7 +7126,7 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
                        uint8_t add)
 {
        uint16_t ip_type;
-       uint32_t ipv4_addr;
+       uint32_t ipv4_addr, ipv4_addr_le;
        uint8_t i, tun_type = 0;
        /* internal varialbe to convert ipv6 byte order */
        uint32_t convert_ipv6[4];
@@ -6984,8 +7159,9 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        if (tunnel_filter->ip_type == RTE_TUNNEL_IPTYPE_IPV4) {
                ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4;
                ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr);
+               ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr);
                rte_memcpy(&pfilter->element.ipaddr.v4.data,
-                               &rte_cpu_to_le_32(ipv4_addr),
+                               &ipv4_addr_le,
                                sizeof(pfilter->element.ipaddr.v4.data));
        } else {
                ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6;
@@ -7036,11 +7212,13 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input);
        if (add && node) {
                PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
+               rte_free(cld_filter);
                return -EINVAL;
        }
 
        if (!add && !node) {
                PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!");
+               rte_free(cld_filter);
                return -EINVAL;
        }
 
@@ -7049,16 +7227,26 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
                                        vsi->seid, &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to add a tunnel filter.");
+                       rte_free(cld_filter);
                        return -ENOTSUP;
                }
                tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
+               if (tunnel == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory.");
+                       rte_free(cld_filter);
+                       return -ENOMEM;
+               }
+
                rte_memcpy(tunnel, &check_filter, sizeof(check_filter));
                ret = i40e_sw_tunnel_filter_insert(pf, tunnel);
+               if (ret < 0)
+                       rte_free(tunnel);
        } else {
                ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
                                                   &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
+                       rte_free(cld_filter);
                        return -ENOTSUP;
                }
                ret = i40e_sw_tunnel_filter_del(pf, &node->input);
@@ -7084,6 +7272,11 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        enum i40e_status_code status = I40E_SUCCESS;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+               return I40E_NOT_SUPPORTED;
+       }
+
        memset(&filter_replace, 0,
               sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
        memset(&filter_replace_buf, 0,
@@ -7120,6 +7313,8 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
+       if (!status)
+               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
        return status;
 }
 
@@ -7131,6 +7326,11 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        enum i40e_status_code status = I40E_SUCCESS;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+               return I40E_NOT_SUPPORTED;
+       }
+
        /* For MPLSoUDP */
        memset(&filter_replace, 0,
               sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7174,6 +7374,8 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
+       if (!status)
+               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
        return status;
 }
 
@@ -7185,6 +7387,11 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        enum i40e_status_code status = I40E_SUCCESS;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+               return I40E_NOT_SUPPORTED;
+       }
+
        /* For GTP-C */
        memset(&filter_replace, 0,
               sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7213,6 +7420,10 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
                                               &filter_replace_buf);
        if (status < 0)
                return status;
+       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                   "cloud l1 type is changed from 0x%x to 0x%x",
+                   filter_replace.old_filter_type,
+                   filter_replace.new_filter_type);
 
        /* for GTP-U */
        memset(&filter_replace, 0,
@@ -7241,6 +7452,13 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
+       if (!status) {
+               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                           "cloud l1 type is changed from 0x%x to 0x%x",
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
+       }
        return status;
 }
 
@@ -7252,6 +7470,11 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        enum i40e_status_code status = I40E_SUCCESS;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+               return I40E_NOT_SUPPORTED;
+       }
+
        /* for GTP-C */
        memset(&filter_replace, 0,
               sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7272,6 +7495,10 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
                                               &filter_replace_buf);
        if (status < 0)
                return status;
+       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                   "cloud filter type is changed from 0x%x to 0x%x",
+                   filter_replace.old_filter_type,
+                   filter_replace.new_filter_type);
 
        /* for GTP-U */
        memset(&filter_replace, 0,
@@ -7293,6 +7520,13 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
 
        status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                                               &filter_replace_buf);
+       if (!status) {
+               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                           "cloud filter type is changed from 0x%x to 0x%x",
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
+       }
        return status;
 }
 
@@ -7302,7 +7536,7 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
                      uint8_t add)
 {
        uint16_t ip_type;
-       uint32_t ipv4_addr;
+       uint32_t ipv4_addr, ipv4_addr_le;
        uint8_t i, tun_type = 0;
        /* internal variable to convert ipv6 byte order */
        uint32_t convert_ipv6[4];
@@ -7338,8 +7572,9 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
        if (tunnel_filter->ip_type == I40E_TUNNEL_IPTYPE_IPV4) {
                ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4;
                ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr);
+               ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr);
                rte_memcpy(&pfilter->element.ipaddr.v4.data,
-                               &rte_cpu_to_le_32(ipv4_addr),
+                               &ipv4_addr_le,
                                sizeof(pfilter->element.ipaddr.v4.data));
        } else {
                ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6;
@@ -7486,6 +7721,7 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
        else {
                if (tunnel_filter->vf_id >= pf->vf_num) {
                        PMD_DRV_LOG(ERR, "Invalid argument.");
+                       rte_free(cld_filter);
                        return -EINVAL;
                }
                vf = &pf->vfs[tunnel_filter->vf_id];
@@ -7500,11 +7736,13 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
        node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input);
        if (add && node) {
                PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
+               rte_free(cld_filter);
                return -EINVAL;
        }
 
        if (!add && !node) {
                PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!");
+               rte_free(cld_filter);
                return -EINVAL;
        }
 
@@ -7517,11 +7755,20 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
                                        vsi->seid, &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to add a tunnel filter.");
+                       rte_free(cld_filter);
                        return -ENOTSUP;
                }
                tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
+               if (tunnel == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory.");
+                       rte_free(cld_filter);
+                       return -ENOMEM;
+               }
+
                rte_memcpy(tunnel, &check_filter, sizeof(check_filter));
                ret = i40e_sw_tunnel_filter_insert(pf, tunnel);
+               if (ret < 0)
+                       rte_free(tunnel);
        } else {
                if (big_buffer)
                        ret = i40e_aq_remove_cloud_filters_big_buffer(
@@ -7531,6 +7778,7 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
                                                   &cld_filter->element, 1);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
+                       rte_free(cld_filter);
                        return -ENOTSUP;
                }
                ret = i40e_sw_tunnel_filter_del(pf, &node->input);
@@ -7808,9 +8056,15 @@ i40e_tunnel_filter_param_check(struct i40e_pf *pf,
 static int
 i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
 {
+       struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
        uint32_t val, reg;
        int ret = -EINVAL;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported");
+               return -ENOTSUP;
+       }
+
        val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2));
        PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x", val);
 
@@ -7828,6 +8082,10 @@ i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
                                                   reg, NULL);
                if (ret != 0)
                        return ret;
+               PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed "
+                           "with value 0x%08x",
+                           I40E_GL_PRS_FVBM(2), reg);
+               i40e_global_cfg_warning(I40E_WARNING_GRE_KEY_LEN);
        } else {
                ret = 0;
        }
@@ -8058,6 +8316,7 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
                                   struct rte_eth_hash_global_conf *g_cfg)
 {
        struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+       struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
        int ret;
        uint16_t i, j;
        uint32_t reg;
@@ -8070,6 +8329,11 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
        uint32_t mask0 = g_cfg->valid_bit_mask[0] &
                                        (uint32_t)adapter->flow_types_mask;
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Hash global configuration is not supported.");
+               return -ENOTSUP;
+       }
+
        /* Check the input parameters */
        ret = i40e_hash_global_config_check(adapter, g_cfg);
        if (ret < 0)
@@ -8083,10 +8347,11 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
                        for (j = I40E_FILTER_PCTYPE_INVALID + 1;
                             j < I40E_FILTER_PCTYPE_MAX; j++) {
                                if (adapter->pctypes_tbl[i] & (1ULL << j))
-                                       i40e_write_rx_ctl(hw,
+                                       i40e_write_global_rx_ctl(hw,
                                                          I40E_GLQF_HSYM(j),
                                                          reg);
                        }
+                       i40e_global_cfg_warning(I40E_WARNING_HSYM);
                }
        }
 
@@ -8111,7 +8376,8 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
                /* Use the default, and keep it as it is */
                goto out;
 
-       i40e_write_rx_ctl(hw, I40E_GLQF_CTL, reg);
+       i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg);
+       i40e_global_cfg_warning(I40E_WARNING_QF_CTL);
 
 out:
        I40E_WRITE_FLUSH(hw);
@@ -8700,6 +8966,18 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
                    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+void
+i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
+{
+       uint32_t reg = i40e_read_rx_ctl(hw, addr);
+
+       PMD_DRV_LOG(DEBUG, "[0x%08x] original: 0x%08x", addr, reg);
+       if (reg != val)
+               i40e_write_global_rx_ctl(hw, addr, val);
+       PMD_DRV_LOG(DEBUG, "[0x%08x] after: 0x%08x", addr,
+                   (uint32_t)i40e_read_rx_ctl(hw, addr));
+}
+
 static void
 i40e_filter_input_set_init(struct i40e_pf *pf)
 {
@@ -8723,6 +9001,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
                                                   I40E_INSET_MASK_NUM_REG);
                if (num < 0)
                        return;
+               if (pf->support_multi_driver && num > 0) {
+                       PMD_DRV_LOG(ERR, "Input set setting is not supported.");
+                       return;
+               }
                inset_reg = i40e_translate_input_set_reg(hw->mac.type,
                                        input_set);
 
@@ -8731,31 +9013,48 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
                i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
                                     (uint32_t)((inset_reg >>
                                     I40E_32_BIT_WIDTH) & UINT32_MAX));
-               i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-                                     (uint32_t)(inset_reg & UINT32_MAX));
-               i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-                                    (uint32_t)((inset_reg >>
-                                    I40E_32_BIT_WIDTH) & UINT32_MAX));
-
-               for (i = 0; i < num; i++) {
-                       i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-                                            mask_reg[i]);
-                       i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-                                            mask_reg[i]);
-               }
-               /*clear unused mask registers of the pctype */
-               for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
-                       i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-                                            0);
-                       i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-                                            0);
+               if (!pf->support_multi_driver) {
+                       i40e_check_write_global_reg(hw,
+                                           I40E_GLQF_HASH_INSET(0, pctype),
+                                           (uint32_t)(inset_reg & UINT32_MAX));
+                       i40e_check_write_global_reg(hw,
+                                            I40E_GLQF_HASH_INSET(1, pctype),
+                                            (uint32_t)((inset_reg >>
+                                             I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+                       for (i = 0; i < num; i++) {
+                               i40e_check_write_global_reg(hw,
+                                                   I40E_GLQF_FD_MSK(i, pctype),
+                                                   mask_reg[i]);
+                               i40e_check_write_global_reg(hw,
+                                                 I40E_GLQF_HASH_MSK(i, pctype),
+                                                 mask_reg[i]);
+                       }
+                       /*clear unused mask registers of the pctype */
+                       for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+                               i40e_check_write_global_reg(hw,
+                                                   I40E_GLQF_FD_MSK(i, pctype),
+                                                   0);
+                               i40e_check_write_global_reg(hw,
+                                                 I40E_GLQF_HASH_MSK(i, pctype),
+                                                 0);
+                       }
+               } else {
+                       PMD_DRV_LOG(ERR, "Input set setting is not supported.");
                }
                I40E_WRITE_FLUSH(hw);
 
                /* store the default input set */
-               pf->hash_input_set[pctype] = input_set;
+               if (!pf->support_multi_driver)
+                       pf->hash_input_set[pctype] = input_set;
                pf->fdir.input_set[pctype] = input_set;
        }
+
+       if (!pf->support_multi_driver) {
+               i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
+               i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+               i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
+       }
 }
 
 int
@@ -8778,6 +9077,11 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
                return -EINVAL;
        }
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Hash input set setting is not supported.");
+               return -ENOTSUP;
+       }
+
        pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
        if (pctype == I40E_FILTER_PCTYPE_INVALID) {
                PMD_DRV_LOG(ERR, "invalid flow_type input.");
@@ -8811,19 +9115,21 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
 
        inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
 
-       i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-                             (uint32_t)(inset_reg & UINT32_MAX));
-       i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-                            (uint32_t)((inset_reg >>
-                            I40E_32_BIT_WIDTH) & UINT32_MAX));
+       i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+                                   (uint32_t)(inset_reg & UINT32_MAX));
+       i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+                                   (uint32_t)((inset_reg >>
+                                   I40E_32_BIT_WIDTH) & UINT32_MAX));
+       i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
 
        for (i = 0; i < num; i++)
-               i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-                                    mask_reg[i]);
+               i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+                                           mask_reg[i]);
        /*clear unused mask registers of the pctype */
        for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
-               i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-                                    0);
+               i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+                                           0);
+       i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
        I40E_WRITE_FLUSH(hw);
 
        pf->hash_input_set[pctype] = input_set;
@@ -8881,6 +9187,10 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
                                           I40E_INSET_MASK_NUM_REG);
        if (num < 0)
                return -EINVAL;
+       if (pf->support_multi_driver && num > 0) {
+               PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+               return -ENOTSUP;
+       }
 
        inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
 
@@ -8890,13 +9200,20 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
                             (uint32_t)((inset_reg >>
                             I40E_32_BIT_WIDTH) & UINT32_MAX));
 
-       for (i = 0; i < num; i++)
-               i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-                                    mask_reg[i]);
-       /*clear unused mask registers of the pctype */
-       for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
-               i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-                                    0);
+       if (!pf->support_multi_driver) {
+               for (i = 0; i < num; i++)
+                       i40e_check_write_global_reg(hw,
+                                                   I40E_GLQF_FD_MSK(i, pctype),
+                                                   mask_reg[i]);
+               /*clear unused mask registers of the pctype */
+               for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+                       i40e_check_write_global_reg(hw,
+                                                   I40E_GLQF_FD_MSK(i, pctype),
+                                                   0);
+               i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+       } else {
+               PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+       }
        I40E_WRITE_FLUSH(hw);
 
        pf->fdir.input_set[pctype] = input_set;
@@ -9142,9 +9459,16 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
        if (add) {
                ethertype_filter = rte_zmalloc("ethertype_filter",
                                       sizeof(*ethertype_filter), 0);
+               if (ethertype_filter == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory.");
+                       return -ENOMEM;
+               }
+
                rte_memcpy(ethertype_filter, &check_filter,
                           sizeof(check_filter));
                ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter);
+               if (ret < 0)
+                       rte_free(ethertype_filter);
        } else {
                ret = i40e_sw_ethertype_filter_del(pf, &node->input);
        }
@@ -10679,27 +11003,21 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint16_t interval =
-               i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
        uint16_t msix_intr;
 
        msix_intr = intr_handle->intr_vec[queue_id];
        if (msix_intr == I40E_MISC_VEC_ID)
                I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
-                              I40E_PFINT_DYN_CTLN_INTENA_MASK |
-                              I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-                              (0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-                              (interval <<
-                               I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+                              I40E_PFINT_DYN_CTL0_INTENA_MASK |
+                              I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
+                              I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
        else
                I40E_WRITE_REG(hw,
                               I40E_PFINT_DYN_CTLN(msix_intr -
                                                   I40E_RX_VEC_START),
                               I40E_PFINT_DYN_CTLN_INTENA_MASK |
                               I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
-                              (0 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-                              (interval <<
-                               I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
+                              I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
 
        I40E_WRITE_FLUSH(hw);
        rte_intr_enable(&pci_dev->intr_handle);
@@ -10717,12 +11035,13 @@ i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 
        msix_intr = intr_handle->intr_vec[queue_id];
        if (msix_intr == I40E_MISC_VEC_ID)
-               I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 0);
+               I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
+                              I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
        else
                I40E_WRITE_REG(hw,
                               I40E_PFINT_DYN_CTLN(msix_intr -
                                                   I40E_RX_VEC_START),
-                              0);
+                              I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
        I40E_WRITE_FLUSH(hw);
 
        return 0;
@@ -10818,14 +11137,43 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
                                      struct ether_addr *mac_addr)
 {
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_vsi *vsi = pf->main_vsi;
+       struct i40e_mac_filter_info mac_filter;
+       struct i40e_mac_filter *f;
+       int ret;
 
        if (!is_valid_assigned_ether_addr(mac_addr)) {
                PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
                return;
        }
 
-       /* Flags: 0x3 updates port address */
-       i40e_aq_mac_address_write(hw, 0x3, mac_addr->addr_bytes, NULL);
+       TAILQ_FOREACH(f, &vsi->mac_list, next) {
+               if (is_same_ether_addr(&pf->dev_addr, &f->mac_info.mac_addr))
+                       break;
+       }
+
+       if (f == NULL) {
+               PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
+               return;
+       }
+
+       mac_filter = f->mac_info;
+       ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
+       if (ret != I40E_SUCCESS) {
+               PMD_DRV_LOG(ERR, "Failed to delete mac filter");
+               return;
+       }
+       memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
+       ret = i40e_vsi_add_mac(vsi, &mac_filter);
+       if (ret != I40E_SUCCESS) {
+               PMD_DRV_LOG(ERR, "Failed to add mac filter");
+               return;
+       }
+       memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
+
+       i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+                                 mac_addr->addr_bytes, NULL);
 }
 
 static int
@@ -11312,6 +11660,11 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
        struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 
+       if (pf->support_multi_driver) {
+               PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+               return ret;
+       }
+
        /* Init */
        memset(&filter_replace, 0,
               sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -11342,6 +11695,10 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
                        &filter_replace_buf);
        if (ret != I40E_SUCCESS)
                return ret;
+       PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                   "cloud l1 type is changed from 0x%x to 0x%x",
+                   filter_replace.old_filter_type,
+                   filter_replace.new_filter_type);
 
        /* Apply the second L2 cloud filter */
        memset(&filter_replace, 0,
@@ -11363,6 +11720,13 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
                I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
        ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
                        &filter_replace_buf);
+       if (!ret) {
+               i40e_global_cfg_warning(I40E_WARNING_RPL_CLD_FILTER);
+               PMD_DRV_LOG(DEBUG, "Global configuration modification: "
+                           "cloud filter type is changed from 0x%x to 0x%x",
+                           filter_replace.old_filter_type,
+                           filter_replace.new_filter_type);
+       }
        return ret;
 }
 
@@ -11377,3 +11741,6 @@ i40e_init_log(void)
        if (i40e_logtype_driver >= 0)
                rte_log_set_level(i40e_logtype_driver, RTE_LOG_NOTICE);
 }
+
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
+                             ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
index cd67453..229c974 100644 (file)
        (((vf)->version_major == VIRTCHNL_VERSION_MAJOR) && \
        ((vf)->version_minor == 1))
 
+#define I40E_WRITE_GLB_REG(hw, reg, value)                             \
+       do {                                                            \
+               I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw),              \
+                                                    (reg)), (value));  \
+               PMD_DRV_LOG(DEBUG, "Global register 0x%08x is modified " \
+                           "with value 0x%08x",                        \
+                           (reg), (value));                            \
+       } while (0)
+
 /* index flex payload per layer */
 enum i40e_flxpld_layer_idx {
        I40E_FLXPLD_L2_IDX    = 0,
@@ -957,6 +966,7 @@ struct i40e_pf {
        bool gtp_replace_flag;   /* 1 - GTP-C/U filter replace is done */
        bool qinq_replace_flag;  /* QINQ filter replace is done */
        struct i40e_tm_conf tm_conf;
+       bool support_multi_driver; /* 1 - support multiple driver */
 
        /* Dynamic Device Personalization */
        bool gtp_support; /* 1 - support GTP-C and GTP-U */
@@ -1084,6 +1094,22 @@ struct i40e_valid_pattern {
        parse_filter_t parse_filter;
 };
 
+enum I40E_WARNING_IDX {
+       I40E_WARNING_DIS_FLX_PLD,
+       I40E_WARNING_ENA_FLX_PLD,
+       I40E_WARNING_QINQ_PARSER,
+       I40E_WARNING_QINQ_CLOUD_FILTER,
+       I40E_WARNING_TPID,
+       I40E_WARNING_FLOW_CTL,
+       I40E_WARNING_GRE_KEY_LEN,
+       I40E_WARNING_QF_CTL,
+       I40E_WARNING_HASH_INSET,
+       I40E_WARNING_HSYM,
+       I40E_WARNING_HASH_MSK,
+       I40E_WARNING_FD_MSK,
+       I40E_WARNING_RPL_CLD_FILTER,
+};
+
 int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);
 int i40e_vsi_release(struct i40e_vsi *vsi);
 struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf,
@@ -1186,6 +1212,8 @@ int i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask,
                                 uint8_t nb_elem);
 uint64_t i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input);
 void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val);
+void i40e_check_write_global_reg(struct i40e_hw *hw,
+                                uint32_t addr, uint32_t val);
 
 int i40e_tm_ops_get(struct rte_eth_dev *dev, void *ops);
 void i40e_tm_conf_init(struct rte_eth_dev *dev);
@@ -1274,15 +1302,44 @@ i40e_align_floor(int n)
 }
 
 static inline uint16_t
-i40e_calc_itr_interval(int16_t interval)
+i40e_calc_itr_interval(int16_t interval, bool is_multi_drv)
 {
-       if (interval < 0 || interval > I40E_QUEUE_ITR_INTERVAL_MAX)
+       if (is_multi_drv)
+               interval = I40E_QUEUE_ITR_INTERVAL_MAX;
+       else if (interval < 0 || interval > I40E_QUEUE_ITR_INTERVAL_MAX)
                interval = I40E_QUEUE_ITR_INTERVAL_DEFAULT;
 
        /* Convert to hardware count, as writing each 1 represents 2 us */
        return interval / 2;
 }
 
+static inline void
+i40e_global_cfg_warning(enum I40E_WARNING_IDX idx)
+{
+       const char *warning;
+       static const char *const warning_list[] = {
+               [I40E_WARNING_DIS_FLX_PLD] = "disable FDIR flexible payload",
+               [I40E_WARNING_ENA_FLX_PLD] = "enable FDIR flexible payload",
+               [I40E_WARNING_QINQ_PARSER] = "support QinQ parser",
+               [I40E_WARNING_QINQ_CLOUD_FILTER] = "support QinQ cloud filter",
+               [I40E_WARNING_TPID] = "support TPID configuration",
+               [I40E_WARNING_FLOW_CTL] = "configure water marker",
+               [I40E_WARNING_GRE_KEY_LEN] = "support GRE key length setting",
+               [I40E_WARNING_QF_CTL] = "support hash function setting",
+               [I40E_WARNING_HASH_INSET] = "configure hash input set",
+               [I40E_WARNING_HSYM] = "set symmetric hash",
+               [I40E_WARNING_HASH_MSK] = "configure hash mask",
+               [I40E_WARNING_FD_MSK] = "configure fdir mask",
+               [I40E_WARNING_RPL_CLD_FILTER] = "replace cloud filter",
+       };
+
+       warning = warning_list[idx];
+
+       RTE_LOG(WARNING, PMD,
+               "Global register is changed during %s\n",
+               warning);
+}
+
 #define I40E_VALID_FLOW(flow_type) \
        ((flow_type) == RTE_ETH_FLOW_FRAG_IPV4 || \
        (flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP || \
index 91b5bb0..b36ba9f 100644 (file)
@@ -945,14 +945,16 @@ i40evf_update_stats(struct i40e_vsi *vsi,
 static void
 i40evf_dev_xstats_reset(struct rte_eth_dev *dev)
 {
+       int ret;
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
        struct i40e_eth_stats *pstats = NULL;
 
        /* read stat values to clear hardware registers */
-       i40evf_query_stats(dev, &pstats);
+       ret = i40evf_query_stats(dev, &pstats);
 
        /* set stats offset base on current values */
-       vf->vsi.eth_stats_offset = *pstats;
+       if (ret == 0)
+               vf->vsi.eth_stats_offset = *pstats;
 }
 
 static int i40evf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
@@ -1165,7 +1167,7 @@ i40evf_init_vf(struct rte_eth_dev *dev)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
        uint16_t interval =
-               i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
+               i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX, 0);
 
        vf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        vf->dev_data = dev->data;
@@ -1585,13 +1587,19 @@ static int
 i40evf_init_vlan(struct rte_eth_dev *dev)
 {
        /* Apply vlan offload setting */
-       return i40evf_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK);
+       i40evf_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK);
+
+       return 0;
 }
 
 static int
 i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
        struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+       struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+       if (!(vf->vf_res->vf_offload_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+               return -ENOTSUP;
 
        /* Vlan stripping setting */
        if (mask & ETH_VLAN_STRIP_MASK) {
@@ -1862,7 +1870,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint16_t interval =
-               i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
+               i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL, 0);
        uint16_t msix_intr;
 
        msix_intr = intr_handle->intr_vec[queue_id];
@@ -1997,7 +2005,8 @@ i40evf_dev_start(struct rte_eth_dev *dev)
                                        dev->data->nb_tx_queues);
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if (rte_intr_cap_multiple(intr_handle) &&
+           dev->data->dev_conf.intr_conf.rxq) {
                intr_vector = dev->data->nb_rx_queues;
                if (rte_intr_efd_enable(intr_handle, intr_vector))
                        return -1;
@@ -2675,19 +2684,19 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
                            struct ether_addr *mac_addr)
 {
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (!is_valid_assigned_ether_addr(mac_addr)) {
                PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
                return;
        }
 
-       if (is_same_ether_addr(mac_addr, dev->data->mac_addrs))
-               return;
-
        if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
                return;
 
-       i40evf_del_mac_addr_by_addr(dev, dev->data->mac_addrs);
+       i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
        i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+
+       ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
 }
index 3d7170d..6802995 100644 (file)
@@ -168,7 +168,6 @@ i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq)
 
        rte_wmb();
        /* Init the RX tail regieter. */
-       I40E_PCI_REG_WRITE(rxq->qrx_tail, 0);
        I40E_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
 
        return err;
@@ -670,22 +669,31 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
                PMD_DRV_LOG(ERR, " invalid configuration arguments.");
                return -EINVAL;
        }
-       /* configure flex payload */
-       for (i = 0; i < conf->nb_payloads; i++)
-               i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
-       /* configure flex mask*/
-       for (i = 0; i < conf->nb_flexmasks; i++) {
-               if (hw->mac.type == I40E_MAC_X722) {
-                       /* get translated pctype value in fd pctype register */
-                       pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
-                               hw, I40E_GLQF_FD_PCTYPES(
-                               (int)i40e_flowtype_to_pctype(pf->adapter,
-                               conf->flex_mask[i].flow_type)));
-               } else
-                       pctype = i40e_flowtype_to_pctype(pf->adapter,
-                                               conf->flex_mask[i].flow_type);
 
-               i40e_set_flex_mask_on_pctype(pf, pctype, &conf->flex_mask[i]);
+       if (!pf->support_multi_driver) {
+               /* configure flex payload */
+               for (i = 0; i < conf->nb_payloads; i++)
+                       i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
+               /* configure flex mask*/
+               for (i = 0; i < conf->nb_flexmasks; i++) {
+                       if (hw->mac.type == I40E_MAC_X722) {
+                               /* get pctype value in fd pctype register */
+                               pctype = (enum i40e_filter_pctype)
+                                         i40e_read_rx_ctl(hw,
+                                               I40E_GLQF_FD_PCTYPES(
+                                               (int)i40e_flowtype_to_pctype(
+                                               pf->adapter,
+                                               conf->flex_mask[i].flow_type)));
+                       } else {
+                               pctype = i40e_flowtype_to_pctype(pf->adapter,
+                                                 conf->flex_mask[i].flow_type);
+                       }
+
+                       i40e_set_flex_mask_on_pctype(pf, pctype,
+                                                    &conf->flex_mask[i]);
+               }
+       } else {
+               PMD_DRV_LOG(ERR, "Not support flexible payload.");
        }
 
        return ret;
@@ -1363,13 +1371,18 @@ i40e_check_fdir_programming_status(struct i40e_rx_queue *rxq)
                                PMD_DRV_LOG(ERR, "invalid programming status"
                                            " reported, error = %u.", error);
                } else
-                       PMD_DRV_LOG(ERR, "unknown programming status"
+                       PMD_DRV_LOG(INFO, "unknown programming status"
                                    " reported, len = %d, id = %u.", len, id);
                rxdp->wb.qword1.status_error_len = 0;
                rxq->rx_tail++;
                if (unlikely(rxq->rx_tail == rxq->nb_rx_desc))
                        rxq->rx_tail = 0;
+               if (rxq->rx_tail == 0)
+                       I40E_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
+               else
+                       I40E_PCI_REG_WRITE(rxq->qrx_tail, rxq->rx_tail - 1);
        }
+
        return ret;
 }
 
@@ -1612,8 +1625,15 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
        if (add) {
                fdir_filter = rte_zmalloc("fdir_filter",
                                          sizeof(*fdir_filter), 0);
+               if (fdir_filter == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to alloc memory.");
+                       return -ENOMEM;
+               }
+
                rte_memcpy(fdir_filter, &check_filter, sizeof(check_filter));
                ret = i40e_sw_fdir_filter_insert(pf, fdir_filter);
+               if (ret < 0)
+                       rte_free(fdir_filter);
        } else {
                ret = i40e_sw_fdir_filter_del(pf, &node->fdir.input);
        }
index 7e4936e..37380e6 100644 (file)
@@ -2877,6 +2877,14 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
                                return -rte_errno;
                        }
 
+                       if (pf->support_multi_driver) {
+                               rte_flow_error_set(error, ENOTSUP,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "Unsupported flexible payload.");
+                               return -rte_errno;
+                       }
+
                        ret = i40e_flow_check_raw_item(item, raw_spec, error);
                        if (ret < 0)
                                return ret;
@@ -3610,6 +3618,41 @@ i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev,
                                                       "Invalid TNI mask");
                                        return -rte_errno;
                                }
+                               if (nvgre_mask->protocol &&
+                                       nvgre_mask->protocol != 0xFFFF) {
+                                       rte_flow_error_set(error, EINVAL,
+                                               RTE_FLOW_ERROR_TYPE_ITEM,
+                                               item,
+                                               "Invalid NVGRE item");
+                                       return -rte_errno;
+                               }
+                               if (nvgre_mask->c_k_s_rsvd0_ver &&
+                                       nvgre_mask->c_k_s_rsvd0_ver !=
+                                       rte_cpu_to_be_16(0xFFFF)) {
+                                       rte_flow_error_set(error, EINVAL,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "Invalid NVGRE item");
+                                       return -rte_errno;
+                               }
+                               if (nvgre_spec->c_k_s_rsvd0_ver !=
+                                       rte_cpu_to_be_16(0x2000) &&
+                                       nvgre_mask->c_k_s_rsvd0_ver) {
+                                       rte_flow_error_set(error, EINVAL,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "Invalid NVGRE item");
+                                       return -rte_errno;
+                               }
+                               if (nvgre_mask->protocol &&
+                                       nvgre_spec->protocol !=
+                                       rte_cpu_to_be_16(0x6558)) {
+                                       rte_flow_error_set(error, EINVAL,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "Invalid NVGRE item");
+                                       return -rte_errno;
+                               }
                                rte_memcpy(((uint8_t *)&tenant_id_be + 1),
                                           nvgre_spec->tni, 3);
                                filter->tenant_id =
@@ -4406,6 +4449,7 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf)
        struct rte_eth_dev *dev = pf->adapter->eth_dev;
        struct i40e_fdir_info *fdir_info = &pf->fdir;
        struct i40e_fdir_filter *fdir_filter;
+       enum i40e_filter_pctype pctype;
        struct rte_flow *flow;
        void *temp;
        int ret;
@@ -4427,6 +4471,10 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf)
                                rte_free(flow);
                        }
                }
+
+               for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+                    pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++)
+                       pf->fdir.inset_flag[pctype] = 0;
        }
 
        return ret;
index ad06b71..078b405 100644 (file)
@@ -2749,6 +2749,7 @@ i40e_fdir_setup_rx_resources(struct i40e_pf *pf)
        rxq->vsi = pf->fdir.fdir_vsi;
 
        rxq->rx_ring_phys_addr = rz->iova;
+       memset(rz->addr, 0, I40E_FDIR_NUM_RX_DESC * sizeof(union i40e_rx_desc));
        rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
 
        /*
index aeb92af..f726a9c 100644 (file)
@@ -1525,7 +1525,14 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec)
        struct rte_pmd_i40e_profile_info *pinfo, *p;
        uint32_t i;
        int ret;
+       static const uint32_t group_mask = 0x00ff0000;
 
+       pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
+                            sizeof(struct i40e_profile_section_header));
+       if (pinfo->track_id == 0) {
+               PMD_DRV_LOG(INFO, "Read-only profile.");
+               return 0;
+       }
        buff = rte_zmalloc("pinfo_list",
                           (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
                           0);
@@ -1544,8 +1551,6 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec)
                return -1;
        }
        p_list = (struct rte_pmd_i40e_profile_list *)buff;
-       pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
-                            sizeof(struct i40e_profile_section_header));
        for (i = 0; i < p_list->p_count; i++) {
                p = &p_list->p_info[i];
                if (pinfo->track_id == p->track_id) {
@@ -1554,6 +1559,23 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec)
                        return 1;
                }
        }
+       for (i = 0; i < p_list->p_count; i++) {
+               p = &p_list->p_info[i];
+               if ((p->track_id & group_mask) == 0) {
+                       PMD_DRV_LOG(INFO, "Profile of the group 0 exists.");
+                       rte_free(buff);
+                       return 2;
+               }
+       }
+       for (i = 0; i < p_list->p_count; i++) {
+               p = &p_list->p_info[i];
+               if ((pinfo->track_id & group_mask) !=
+                   (p->track_id & group_mask)) {
+                       PMD_DRV_LOG(INFO, "Profile of different group exists.");
+                       rte_free(buff);
+                       return 3;
+               }
+       }
 
        rte_free(buff);
        return 0;
@@ -1573,6 +1595,7 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff,
        uint8_t *profile_info_sec;
        int is_exist;
        enum i40e_status_code status = I40E_SUCCESS;
+       static const uint32_t type_mask = 0xff000000;
 
        if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
                op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
@@ -1624,6 +1647,10 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff,
                return -EINVAL;
        }
 
+       /* force read-only track_id for type 0 */
+       if ((track_id & type_mask) == 0)
+               track_id = 0;
+
        /* Find profile segment */
        profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
                                                       pkg_hdr);
@@ -1657,12 +1684,17 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff,
 
        if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) {
                if (is_exist) {
-                       PMD_DRV_LOG(ERR, "Profile already exists.");
+                       if (is_exist == 1)
+                               PMD_DRV_LOG(ERR, "Profile already exists.");
+                       else if (is_exist == 2)
+                               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");
                        rte_free(profile_info_sec);
                        return -EEXIST;
                }
        } else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
-               if (!is_exist) {
+               if (is_exist != 1) {
                        PMD_DRV_LOG(ERR, "Profile does not exist.");
                        rte_free(profile_info_sec);
                        return -EACCES;
@@ -2845,22 +2877,23 @@ i40e_flush_queue_region_all_conf(struct rte_eth_dev *dev,
                return 0;
        }
 
-       info->queue_region_number = 1;
-       info->region[0].queue_num = main_vsi->nb_used_qps;
-       info->region[0].queue_start_index = 0;
+       if (info->queue_region_number) {
+               info->queue_region_number = 1;
+               info->region[0].queue_num = main_vsi->nb_used_qps;
+               info->region[0].queue_start_index = 0;
 
-       ret = i40e_vsi_update_queue_region_mapping(hw, pf);
-       if (ret != I40E_SUCCESS)
-               PMD_DRV_LOG(INFO, "Failed to flush queue region mapping.");
-
-       ret = i40e_dcb_init_configure(dev, TRUE);
-       if (ret != I40E_SUCCESS) {
-               PMD_DRV_LOG(INFO, "Failed to flush dcb.");
-               pf->flags &= ~I40E_FLAG_DCB;
-       }
+               ret = i40e_vsi_update_queue_region_mapping(hw, pf);
+               if (ret != I40E_SUCCESS)
+                       PMD_DRV_LOG(INFO, "Failed to flush queue region mapping.");
 
-       i40e_init_queue_region_conf(dev);
+               ret = i40e_dcb_init_configure(dev, TRUE);
+               if (ret != I40E_SUCCESS) {
+                       PMD_DRV_LOG(INFO, "Failed to flush dcb.");
+                       pf->flags &= ~I40E_FLAG_DCB;
+               }
 
+               i40e_init_queue_region_conf(dev);
+       }
        return 0;
 }
 
index 580ca4a..49f4427 100644 (file)
@@ -94,7 +94,7 @@ enum rte_pmd_i40e_package_info {
        RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST,
        RTE_PMD_I40E_PKG_INFO_PTYPE_NUM,
        RTE_PMD_I40E_PKG_INFO_PTYPE_LIST,
-       RTE_PMD_I40E_PKG_INFO_MAX = 0xFFFFFFFF
+       RTE_PMD_I40E_PKG_INFO_MAX = (int)0xFFFFFFFF
 };
 
 /**
index 7f85713..5e6ad95 100644 (file)
@@ -4607,7 +4607,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        /* first pull in the header so we know the buffer length */
        for (bi = 0; bi < dword_len; bi++) {
                buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
-               IXGBE_LE32_TO_CPUS(&buffer[bi]);
+               IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]);
        }
 
        /* If there is any thing in data position pull it in */
@@ -4627,7 +4627,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        /* Pull in the rest of the buffer (bi is where we left off) */
        for (; bi <= dword_len; bi++) {
                buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi);
-               IXGBE_LE32_TO_CPUS(&buffer[bi]);
+               IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]);
        }
 
 rel_out:
index ff19a56..f219866 100644 (file)
@@ -95,6 +95,9 @@
 /* Timer value included in XOFF frames. */
 #define IXGBE_FC_PAUSE 0x680
 
+/*Default value of Max Rx Queue*/
+#define IXGBE_MAX_RX_QUEUE_NUM 128
+
 #define IXGBE_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */
 #define IXGBE_LINK_UP_CHECK_TIMEOUT   1000 /* ms */
 #define IXGBE_VMDQ_NUM_UC_MAC         4096 /* Maximum nb. of UC MAC addr. */
@@ -2194,9 +2197,10 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
                return -EINVAL;
        }
 
-       RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
-       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = pci_dev->max_vfs * nb_rx_q;
-
+       RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool =
+               IXGBE_MAX_RX_QUEUE_NUM / RTE_ETH_DEV_SRIOV(dev).active;
+       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx =
+               pci_dev->max_vfs * RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool;
        return 0;
 }
 
@@ -2236,8 +2240,6 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                case ETH_MQ_RX_NONE:
                        /* if nothing mq mode configure, use default scheme */
                        dev->data->dev_conf.rxmode.mq_mode = ETH_MQ_RX_VMDQ_ONLY;
-                       if (RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool > 1)
-                               RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = 1;
                        break;
                default: /* ETH_MQ_RX_DCB, ETH_MQ_RX_DCB_RSS or ETH_MQ_TX_DCB*/
                        /* SRIOV only works in VMDq enable mode */
@@ -5025,7 +5027,11 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
-       hw->mac.ops.reset_hw(hw);
+       err = hw->mac.ops.reset_hw(hw);
+       if (err) {
+               PMD_INIT_LOG(ERR, "Unable to reset vf hardware (%d)", err);
+               return err;
+       }
        hw->mac.get_link_status = true;
 
        /* negotiate mailbox API version to use with the PF. */
@@ -5057,7 +5063,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
        ixgbevf_dev_rxtx_start(dev);
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if (rte_intr_cap_multiple(intr_handle) &&
+           dev->data->dev_conf.intr_conf.rxq) {
                /* According to datasheet, only vector 0/1/2 can be used,
                 * now only one vector is used for Rx queue
                 */
index 9281dc1..c117647 100644 (file)
@@ -1277,7 +1277,8 @@ ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
             IXGBE_ATR_FLOW_TYPE_IPV6) &&
            (info->mask.src_port_mask != 0 ||
             info->mask.dst_port_mask != 0) &&
-            rule->mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
+           (rule->mode != RTE_FDIR_MODE_PERFECT_MAC_VLAN &&
+            rule->mode != RTE_FDIR_MODE_PERFECT_TUNNEL)) {
                PMD_DRV_LOG(ERR, "By this device,"
                            " IPv4 is not supported without"
                            " L4 protocol and ports masked!");
index 19c2d47..07abb34 100644 (file)
@@ -2466,8 +2466,7 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
                                item, "Not supported by fdir filter");
                        return -rte_errno;
                }
-               if (nvgre_mask->c_k_s_rsvd0_ver !=
-                       rte_cpu_to_be_16(0x3000) ||
+               if (nvgre_mask->protocol &&
                    nvgre_mask->protocol != 0xFFFF) {
                        memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
                        rte_flow_error_set(error, EINVAL,
@@ -2475,6 +2474,15 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
                                item, "Not supported by fdir filter");
                        return -rte_errno;
                }
+               if (nvgre_mask->c_k_s_rsvd0_ver &&
+                   nvgre_mask->c_k_s_rsvd0_ver !=
+                       rte_cpu_to_be_16(0xFFFF)) {
+                       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
+                       rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ITEM,
+                               item, "Not supported by fdir filter");
+                       return -rte_errno;
+               }
                /* TNI must be totally masked or not. */
                if (nvgre_mask->tni[0] &&
                    ((nvgre_mask->tni[0] != 0xFF) ||
@@ -2496,7 +2504,15 @@ ixgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
                        nvgre_spec =
                                (const struct rte_flow_item_nvgre *)item->spec;
                        if (nvgre_spec->c_k_s_rsvd0_ver !=
-                           rte_cpu_to_be_16(0x2000) ||
+                           rte_cpu_to_be_16(0x2000) &&
+                               nvgre_mask->c_k_s_rsvd0_ver) {
+                               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
+                               rte_flow_error_set(error, EINVAL,
+                                       RTE_FLOW_ERROR_TYPE_ITEM,
+                                       item, "Not supported by fdir filter");
+                               return -rte_errno;
+                       }
+                       if (nvgre_mask->protocol &&
                            nvgre_spec->protocol !=
                            rte_cpu_to_be_16(NVGRE_PROTOCOL)) {
                                memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
index 676e92c..0114694 100644 (file)
@@ -273,7 +273,7 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 
        gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
        gpie &= ~IXGBE_GPIE_VTMODE_MASK;
-       gpie |= IXGBE_GPIE_MSIX_MODE;
+       gpie |= IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT;
 
        switch (RTE_ETH_DEV_SRIOV(eth_dev).active) {
        case ETH_64_POOLS:
index 8f26953..c1a2ea5 100644 (file)
@@ -90,7 +90,7 @@ static const struct rte_eth_link pmd_link = {
                .link_speed = ETH_SPEED_NUM_10G,
                .link_duplex = ETH_LINK_FULL_DUPLEX,
                .link_status = ETH_LINK_DOWN,
-               .link_autoneg = ETH_LINK_SPEED_AUTONEG,
+               .link_autoneg = ETH_LINK_AUTONEG,
 };
 static int is_kni_initialized;
 
index f1f47c2..1f95e0d 100644 (file)
@@ -82,10 +82,6 @@ ifdef CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE
 CFLAGS += -DMLX4_PMD_TX_MP_CACHE=$(CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE)
 endif
 
-ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS),y)
-CFLAGS += -DMLX4_PMD_DEBUG_BROKEN_VERBS
-endif
-
 include $(RTE_SDK)/mk/rte.lib.mk
 
 # Generate and clean-up mlx4_autoconf.h.
index f9e4f9d..97dac64 100644 (file)
@@ -707,6 +707,12 @@ RTE_INIT(rte_mlx4_pmd_init);
 static void
 rte_mlx4_pmd_init(void)
 {
+       /*
+        * MLX4_DEVICE_FATAL_CLEANUP tells ibv_destroy functions we
+        * want to get success errno value in case of calling them
+        * when the device was removed.
+        */
+       setenv("MLX4_DEVICE_FATAL_CLEANUP", "1", 1);
        /*
         * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
         * huge pages. Calling ibv_fork_init() during init allows
index 8b87b29..e81e24d 100644 (file)
@@ -1048,6 +1048,8 @@ mlx4_flow_toggle(struct priv *priv,
                flow->drop = missing;
        }
        if (flow->drop) {
+               if (flow->ibv_flow)
+                       return 0;
                mlx4_drop_get(priv);
                if (!priv->drop) {
                        err = rte_errno;
index 2bfa8b1..92b6257 100644 (file)
@@ -88,7 +88,8 @@ uint32_t mlx4_ptype_table[0x100] __rte_cache_aligned = {
         * giving a total of up to 256 entries.
         */
        [0x00] = RTE_PTYPE_L2_ETHER,
-       [0x01] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+       [0x01] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+                    RTE_PTYPE_L4_NONFRAG,
        [0x02] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
                     RTE_PTYPE_L4_FRAG,
        [0x03] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
@@ -468,7 +469,6 @@ mlx4_tx_burst_segs(struct rte_mbuf *buf, struct txq *txq,
                /* Memory region key (big endian) for this memory pool. */
                lkey = mlx4_txq_mp2mr(txq, mlx4_txq_mb2mp(sbuf));
                dseg->lkey = rte_cpu_to_be_32(lkey);
-#ifndef NDEBUG
                /* Calculate the needed work queue entry size for this packet */
                if (unlikely(dseg->lkey == rte_cpu_to_be_32((uint32_t)-1))) {
                        /* MR does not exist. */
@@ -486,7 +486,6 @@ mlx4_tx_burst_segs(struct rte_mbuf *buf, struct txq *txq,
                                        (sq->head & sq->txbb_cnt) ? 0 : 1);
                        return -1;
                }
-#endif /* NDEBUG */
                if (likely(sbuf->data_len)) {
                        byte_count = rte_cpu_to_be_32(sbuf->data_len);
                } else {
@@ -636,7 +635,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                        /* Memory region key (big endian). */
                        lkey = mlx4_txq_mp2mr(txq, mlx4_txq_mb2mp(buf));
                        dseg->lkey = rte_cpu_to_be_32(lkey);
-#ifndef NDEBUG
                        if (unlikely(dseg->lkey ==
                                rte_cpu_to_be_32((uint32_t)-1))) {
                                /* MR does not exist. */
@@ -655,7 +653,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                                elt->buf = NULL;
                                break;
                        }
-#endif /* NDEBUG */
                        /* Never be TXBB aligned, no need compiler barrier. */
                        dseg->byte_count = rte_cpu_to_be_32(buf->data_len);
                        /* Fill the control parameters for this packet. */
index 7882a4d..17f3b00 100644 (file)
@@ -59,7 +59,6 @@
 #include <rte_mempool.h>
 
 #include "mlx4.h"
-#include "mlx4_autoconf.h"
 #include "mlx4_prm.h"
 #include "mlx4_rxtx.h"
 #include "mlx4_utils.h"
index dc529c9..4f11405 100644 (file)
@@ -70,13 +70,7 @@ pmd_drv_log_basename(const char *s)
                        __func__, \
                        RTE_FMT_TAIL(__VA_ARGS__,)))
 #define DEBUG(...) PMD_DRV_LOG(DEBUG, __VA_ARGS__)
-#ifndef MLX4_PMD_DEBUG_BROKEN_VERBS
 #define claim_zero(...) assert((__VA_ARGS__) == 0)
-#else /* MLX4_PMD_DEBUG_BROKEN_VERBS */
-#define claim_zero(...) \
-       (void)(((__VA_ARGS__) == 0) || \
-               DEBUG("Assertion `(" # __VA_ARGS__ ") == 0' failed (IGNORED)."))
-#endif /* MLX4_PMD_DEBUG_BROKEN_VERBS */
 
 #else /* NDEBUG */
 
index 0548d17..45e0e8d 100644 (file)
@@ -158,7 +158,6 @@ mlx5_alloc_verbs_buf(size_t size, void *data)
        size_t alignment = sysconf(_SC_PAGESIZE);
 
        assert(data != NULL);
-       assert(!mlx5_is_secondary());
        ret = rte_malloc_socket(__func__, size, alignment,
                                priv->dev->device->numa_node);
        DEBUG("Extern alloc size: %lu, align: %lu: %p", size, alignment, ret);
@@ -177,7 +176,6 @@ static void
 mlx5_free_verbs_buf(void *ptr, void *data __rte_unused)
 {
        assert(data != NULL);
-       assert(!mlx5_is_secondary());
        DEBUG("Extern free request: %p", ptr);
        rte_free(ptr);
 }
@@ -662,6 +660,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        INFO("%u port(s) detected", device_attr.orig_attr.phys_port_cnt);
 
        for (i = 0; i < device_attr.orig_attr.phys_port_cnt; i++) {
+               char name[RTE_ETH_NAME_MAX_LEN];
                uint32_t port = i + 1; /* ports are indexed from one */
                uint32_t test = (1 << i);
                struct ibv_context *ctx = NULL;
@@ -685,14 +684,13 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                        .rx_vec_en = MLX5_ARG_UNSET,
                };
 
-               mlx5_dev[idx].ports |= test;
+               snprintf(name, sizeof(name), PCI_PRI_FMT,
+                        pci_dev->addr.domain, pci_dev->addr.bus,
+                        pci_dev->addr.devid, pci_dev->addr.function);
 
-               if (mlx5_is_secondary()) {
-                       /* from rte_ethdev.c */
-                       char name[RTE_ETH_NAME_MAX_LEN];
+               mlx5_dev[idx].ports |= test;
 
-                       snprintf(name, sizeof(name), "%s port %u",
-                                ibv_get_device_name(ibv_dev), port);
+               if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
                        eth_dev = rte_eth_dev_attach_secondary(name);
                        if (eth_dev == NULL) {
                                ERROR("can not attach rte ethdev");
@@ -802,7 +800,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                priv->hw_csum_l2tun = !!(exp_device_attr.exp_device_cap_flags &
                                         IBV_DEVICE_VXLAN_SUPPORT);
 #endif
-               DEBUG("L2 tunnel checksum offloads are %ssupported",
+               DEBUG("Rx L2 tunnel checksum offloads are %ssupported",
                      (priv->hw_csum_l2tun ? "" : "not "));
 
 #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
@@ -902,14 +900,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                priv_get_mtu(priv, &priv->mtu);
                DEBUG("port %u MTU is %u", priv->port, priv->mtu);
 
-               /* from rte_ethdev.c */
-               {
-                       char name[RTE_ETH_NAME_MAX_LEN];
-
-                       snprintf(name, sizeof(name), "%s port %u",
-                                ibv_get_device_name(ibv_dev), port);
-                       eth_dev = rte_eth_dev_allocate(name);
-               }
+               eth_dev = rte_eth_dev_allocate(name);
                if (eth_dev == NULL) {
                        ERROR("can not allocate rte ethdev");
                        err = ENOMEM;
@@ -920,6 +911,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                eth_dev->device = &pci_dev->device;
                rte_eth_copy_pci_info(eth_dev, pci_dev);
                eth_dev->device->driver = &mlx5_driver.driver;
+               /*
+                * Initialize burst functions to prevent crashes before link-up.
+                */
+               eth_dev->rx_pkt_burst = removed_rx_burst;
+               eth_dev->tx_pkt_burst = removed_tx_burst;
                priv->dev = eth_dev;
                eth_dev->dev_ops = &mlx5_dev_ops;
                /* Register MAC address. */
@@ -939,7 +935,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                /* Bring Ethernet device up. */
                DEBUG("forcing Ethernet interface up");
                priv_set_flags(priv, ~IFF_UP, IFF_UP);
-               mlx5_link_update(priv->dev, 1);
                continue;
 
 port_error:
index e6a69b8..d49595b 100644 (file)
@@ -164,6 +164,22 @@ priv_lock(struct priv *priv)
        rte_spinlock_lock(&priv->lock);
 }
 
+/**
+ * Try to lock private structure to protect it from concurrent access in the
+ * control path.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   1 if the lock is successfully taken; 0 otherwise.
+ */
+static inline int
+priv_trylock(struct priv *priv)
+{
+       return rte_spinlock_trylock(&priv->lock);
+}
+
 /**
  * Unlock private structure.
  *
@@ -194,6 +210,8 @@ int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
 const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
+int priv_link_update(struct priv *, int);
+int priv_force_link_status_change(struct priv *, int);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
index 3a7706c..24caf7e 100644 (file)
@@ -34,6 +34,8 @@
 #ifndef RTE_PMD_MLX5_DEFS_H_
 #define RTE_PMD_MLX5_DEFS_H_
 
+#include <rte_ethdev.h>
+
 #include "mlx5_autoconf.h"
 
 /* Reported driver name. */
 /* Number of packets vectorized Rx can simultaneously process in a loop. */
 #define MLX5_VPMD_DESCS_PER_LOOP      4
 
+/* Supported RSS */
+#define MLX5_RSS_HF_MASK (~(ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP))
+
+/* Maximum number of attempts to query link status before giving up. */
+#define MLX5_MAX_LINK_QUERY_ATTEMPTS 5
+
 #endif /* RTE_PMD_MLX5_DEFS_H_ */
index a3cef68..ffe1cdd 100644 (file)
@@ -133,18 +133,6 @@ mlx5_get_priv(struct rte_eth_dev *dev)
        return dev->data->dev_private;
 }
 
-/**
- * Check if running as a secondary process.
- *
- * @return
- *   Nonzero if running as a secondary process.
- */
-inline int
-mlx5_is_secondary(void)
-{
-       return rte_eal_process_type() == RTE_PROC_SECONDARY;
-}
-
 /**
  * Get interface name from private structure.
  *
@@ -577,7 +565,7 @@ dev_configure(struct rte_eth_dev *dev)
        unsigned int j;
        unsigned int reta_idx_n;
        const uint8_t use_app_rss_key =
-               !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len;
+               !!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
 
        if (use_app_rss_key &&
            (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
@@ -649,9 +637,6 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
        struct priv *priv = dev->data->dev_private;
        int ret;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        priv_lock(priv);
        ret = dev_configure(dev);
        assert(ret >= 0);
@@ -720,6 +705,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
                priv->reta_idx_n : priv->ind_table_max_size;
        info->hash_key_size = priv->rss_conf.rss_key_len;
        info->speed_capa = priv->link_speed_capa;
+       info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
        priv_unlock(priv);
 }
 
@@ -913,25 +899,131 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete)
 }
 
 /**
- * DPDK callback to retrieve physical link information.
+ * Enable receiving and transmitting traffic.
  *
- * @param dev
- *   Pointer to Ethernet device structure.
+ * @param priv
+ *   Pointer to private structure.
+ */
+static void
+priv_link_start(struct priv *priv)
+{
+       struct rte_eth_dev *dev = priv->dev;
+       int err;
+
+       priv_dev_select_tx_function(priv, dev);
+       priv_dev_select_rx_function(priv, dev);
+       err = priv_dev_traffic_enable(priv, dev);
+       if (err)
+               ERROR("%p: error occurred while configuring control flows: %s",
+                     (void *)priv, strerror(err));
+       err = priv_flow_start(priv, &priv->flows);
+       if (err)
+               ERROR("%p: error occurred while configuring flows: %s",
+                     (void *)priv, strerror(err));
+}
+
+/**
+ * Disable receiving and transmitting traffic.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ */
+static void
+priv_link_stop(struct priv *priv)
+{
+       struct rte_eth_dev *dev = priv->dev;
+
+       priv_flow_stop(priv, &priv->flows);
+       priv_dev_traffic_disable(priv, dev);
+       dev->rx_pkt_burst = removed_rx_burst;
+       dev->tx_pkt_burst = removed_tx_burst;
+}
+
+/**
+ * Retrieve physical link information and update rx/tx_pkt_burst callbacks
+ * accordingly.
+ *
+ * @param priv
+ *   Pointer to private structure.
  * @param wait_to_complete
  *   Wait for request completion (ignored).
  */
 int
-mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+priv_link_update(struct priv *priv, int wait_to_complete)
 {
+       struct rte_eth_dev *dev = priv->dev;
        struct utsname utsname;
        int ver[3];
+       int ret;
+       struct rte_eth_link dev_link = dev->data->dev_link;
 
        if (uname(&utsname) == -1 ||
            sscanf(utsname.release, "%d.%d.%d",
                   &ver[0], &ver[1], &ver[2]) != 3 ||
            KERNEL_VERSION(ver[0], ver[1], ver[2]) < KERNEL_VERSION(4, 9, 0))
-               return mlx5_link_update_unlocked_gset(dev, wait_to_complete);
-       return mlx5_link_update_unlocked_gs(dev, wait_to_complete);
+               ret = mlx5_link_update_unlocked_gset(dev, wait_to_complete);
+       else
+               ret = mlx5_link_update_unlocked_gs(dev, wait_to_complete);
+       /* If lsc interrupt is disabled, should always be ready for traffic. */
+       if (!dev->data->dev_conf.intr_conf.lsc) {
+               priv_link_start(priv);
+               return ret;
+       }
+       /* Re-select burst callbacks only if link status has been changed. */
+       if (!ret && dev_link.link_status != dev->data->dev_link.link_status) {
+               if (dev->data->dev_link.link_status == ETH_LINK_UP)
+                       priv_link_start(priv);
+               else
+                       priv_link_stop(priv);
+       }
+       return ret;
+}
+
+/**
+ * Querying the link status till it changes to the desired state.
+ * Number of query attempts is bounded by MLX5_MAX_LINK_QUERY_ATTEMPTS.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ * @param status
+ *   Link desired status.
+ *
+ * @return
+ *   0 on success, negative errno value on failure.
+ */
+int
+priv_force_link_status_change(struct priv *priv, int status)
+{
+       int try = 0;
+
+       while (try < MLX5_MAX_LINK_QUERY_ATTEMPTS) {
+               priv_link_update(priv, 0);
+               if (priv->dev->data->dev_link.link_status == status)
+                       return 0;
+               try++;
+               sleep(1);
+       }
+       return -EAGAIN;
+}
+
+/**
+ * DPDK callback to retrieve physical link information.
+ *
+ * @param dev
+ *   Pointer to Ethernet device structure.
+ * @param wait_to_complete
+ *   Wait for request completion (ignored).
+ */
+int
+mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+       struct priv *priv = dev->data->dev_private;
+       int ret;
+
+       priv_lock(priv);
+       ret = priv_link_update(priv, wait_to_complete);
+       priv_unlock(priv);
+       return ret;
 }
 
 /**
@@ -952,9 +1044,6 @@ mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        uint16_t kern_mtu;
        int ret = 0;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        priv_lock(priv);
        ret = priv_get_mtu(priv, &kern_mtu);
        if (ret)
@@ -1002,9 +1091,6 @@ mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        };
        int ret;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        ifr.ifr_data = (void *)&ethpause;
        priv_lock(priv);
        if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
@@ -1053,9 +1139,6 @@ mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        };
        int ret;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        ifr.ifr_data = (void *)&ethpause;
        ethpause.autoneg = fc_conf->autoneg;
        if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
@@ -1150,7 +1233,7 @@ priv_link_status_update(struct priv *priv)
 {
        struct rte_eth_link *link = &priv->dev->data->dev_link;
 
-       mlx5_link_update(priv->dev, 0);
+       priv_link_update(priv, 0);
        if (((link->link_speed == 0) && link->link_status) ||
                ((link->link_speed != 0) && !link->link_status)) {
                /*
@@ -1224,8 +1307,12 @@ mlx5_dev_link_status_handler(void *arg)
        struct priv *priv = dev->data->dev_private;
        int ret;
 
-       priv_lock(priv);
-       assert(priv->pending_alarm == 1);
+       while (!priv_trylock(priv)) {
+               /* Alarm is being canceled. */
+               if (priv->pending_alarm == 0)
+                       return;
+               rte_pause();
+       }
        priv->pending_alarm = 0;
        ret = priv_link_status_update(priv);
        priv_unlock(priv);
@@ -1295,9 +1382,10 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
        if (priv->primary_socket)
                rte_intr_callback_unregister(&priv->intr_handle_socket,
                                             mlx5_dev_handler_socket, dev);
-       if (priv->pending_alarm)
+       if (priv->pending_alarm) {
+               priv->pending_alarm = 0;
                rte_eal_alarm_cancel(mlx5_dev_link_status_handler, dev);
-       priv->pending_alarm = 0;
+       }
        priv->intr_handle.fd = 0;
        priv->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
        priv->intr_handle_socket.fd = 0;
@@ -1317,7 +1405,6 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev)
 {
        int rc, flags;
 
-       assert(!mlx5_is_secondary());
        assert(priv->ctx->async_fd > 0);
        flags = fcntl(priv->ctx->async_fd, F_GETFL);
        rc = fcntl(priv->ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
@@ -1348,8 +1435,6 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev)
  *
  * @param priv
  *   Pointer to private data structure.
- * @param dev
- *   Pointer to rte_eth_dev structure.
  * @param up
  *   Nonzero for link up, otherwise link down.
  *
@@ -1357,24 +1442,9 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev)
  *   0 on success, errno value on failure.
  */
 static int
-priv_dev_set_link(struct priv *priv, struct rte_eth_dev *dev, int up)
+priv_dev_set_link(struct priv *priv, int up)
 {
-       int err;
-
-       if (up) {
-               err = priv_set_flags(priv, ~IFF_UP, IFF_UP);
-               if (err)
-                       return err;
-               priv_dev_select_tx_function(priv, dev);
-               priv_dev_select_rx_function(priv, dev);
-       } else {
-               err = priv_set_flags(priv, ~IFF_UP, ~IFF_UP);
-               if (err)
-                       return err;
-               dev->rx_pkt_burst = removed_rx_burst;
-               dev->tx_pkt_burst = removed_tx_burst;
-       }
-       return 0;
+       return priv_set_flags(priv, ~IFF_UP, up ? IFF_UP : ~IFF_UP);
 }
 
 /**
@@ -1393,7 +1463,7 @@ mlx5_set_link_down(struct rte_eth_dev *dev)
        int err;
 
        priv_lock(priv);
-       err = priv_dev_set_link(priv, dev, 0);
+       err = priv_dev_set_link(priv, 0);
        priv_unlock(priv);
        return err;
 }
@@ -1414,7 +1484,7 @@ mlx5_set_link_up(struct rte_eth_dev *dev)
        int err;
 
        priv_lock(priv);
-       err = priv_dev_set_link(priv, dev, 1);
+       err = priv_dev_set_link(priv, 1);
        priv_unlock(priv);
        return err;
 }
index f32dfdd..092644f 100644 (file)
@@ -50,6 +50,7 @@
 #include <rte_malloc.h>
 
 #include "mlx5.h"
+#include "mlx5_defs.h"
 #include "mlx5_prm.h"
 
 /* Define minimal priority for control plane flows. */
@@ -250,11 +251,8 @@ struct rte_flow {
        uint8_t rss_key[40]; /**< copy of the RSS key. */
        struct ibv_counter_set *cs; /**< Holds the counters for the rule. */
        struct mlx5_flow_counter_stats counter_stats;/**<The counter stats. */
-       union {
-               struct mlx5_flow frxq[RTE_DIM(hash_rxq_init)];
-               /**< Flow with Rx queue. */
-               struct mlx5_flow_drop drxq; /**< Flow with drop Rx queue. */
-       };
+       struct mlx5_flow frxq[RTE_DIM(hash_rxq_init)];
+       /**< Flow with Rx queue. */
 };
 
 /** Static initializer for items. */
@@ -444,20 +442,12 @@ struct mlx5_flow_parse {
        uint8_t rss_key[40]; /**< copy of the RSS key. */
        enum hash_rxq_type layer; /**< Last pattern layer detected. */
        struct ibv_counter_set *cs; /**< Holds the counter set for the rule */
-       union {
-               struct {
-                       struct ibv_flow_attr *ibv_attr;
-                       /**< Pointer to Verbs attributes. */
-                       unsigned int offset;
-                       /**< Current position or total size of the attribute. */
-               } queue[RTE_DIM(hash_rxq_init)];
-               struct {
-                       struct ibv_flow_attr *ibv_attr;
-                       /**< Pointer to Verbs attributes. */
-                       unsigned int offset;
-                       /**< Current position or total size of the attribute. */
-               } drop_q;
-       };
+       struct {
+               struct ibv_flow_attr *ibv_attr;
+               /**< Pointer to Verbs attributes. */
+               unsigned int offset;
+               /**< Current position or total size of the attribute. */
+       } queue[RTE_DIM(hash_rxq_init)];
 };
 
 static const struct rte_flow_ops mlx5_flow_ops = {
@@ -537,7 +527,7 @@ mlx5_flow_item_validate(const struct rte_flow_item *item,
        }
        if (item->mask) {
                unsigned int i;
-               const uint8_t *spec = item->mask;
+               const uint8_t *spec = item->spec;
 
                for (i = 0; i < size; ++i)
                        if ((spec[i] | mask[i]) != mask[i])
@@ -561,7 +551,8 @@ mlx5_flow_item_validate(const struct rte_flow_item *item,
 }
 
 /**
- * Copy the RSS configuration from the user ones.
+ * Copy the RSS configuration from the user ones, of the rss_conf is null,
+ * uses the driver one.
  *
  * @param priv
  *   Pointer to private structure.
@@ -578,15 +569,25 @@ priv_flow_convert_rss_conf(struct priv *priv,
                           struct mlx5_flow_parse *parser,
                           const struct rte_eth_rss_conf *rss_conf)
 {
-       const struct rte_eth_rss_conf *rss =
-               rss_conf ? rss_conf : &priv->rss_conf;
-
-       if (rss->rss_key_len > 40)
-               return EINVAL;
-       parser->rss_conf.rss_key_len = rss->rss_key_len;
-       parser->rss_conf.rss_hf = rss->rss_hf;
-       memcpy(parser->rss_key, rss->rss_key, rss->rss_key_len);
-       parser->rss_conf.rss_key = parser->rss_key;
+       /*
+        * This function is also called at the beginning of
+        * priv_flow_convert_actions() to initialize the parser with the
+        * device default RSS configuration.
+        */
+       (void)priv;
+       if (rss_conf) {
+               if (rss_conf->rss_hf & MLX5_RSS_HF_MASK)
+                       return EINVAL;
+               if (rss_conf->rss_key_len != 40)
+                       return EINVAL;
+               if (rss_conf->rss_key_len && rss_conf->rss_key) {
+                       parser->rss_conf.rss_key_len = rss_conf->rss_key_len;
+                       memcpy(parser->rss_key, rss_conf->rss_key,
+                              rss_conf->rss_key_len);
+                       parser->rss_conf.rss_key = parser->rss_key;
+               }
+               parser->rss_conf.rss_hf = rss_conf->rss_hf;
+       }
        return 0;
 }
 
@@ -827,12 +828,8 @@ priv_flow_convert_items_validate(struct priv *priv,
 
        (void)priv;
        /* Initialise the offsets to start after verbs attribute. */
-       if (parser->drop) {
-               parser->drop_q.offset = sizeof(struct ibv_flow_attr);
-       } else {
-               for (i = 0; i != hash_rxq_init_n; ++i)
-                       parser->queue[i].offset = sizeof(struct ibv_flow_attr);
-       }
+       for (i = 0; i != hash_rxq_init_n; ++i)
+               parser->queue[i].offset = sizeof(struct ibv_flow_attr);
        for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
                const struct mlx5_flow_items *token = NULL;
                unsigned int n;
@@ -869,14 +866,16 @@ priv_flow_convert_items_validate(struct priv *priv,
                        parser->inner = IBV_FLOW_SPEC_INNER;
                }
                if (parser->drop) {
-                       parser->drop_q.offset += cur_item->dst_sz;
-               } else if (parser->queues_n == 1) {
                        parser->queue[HASH_RXQ_ETH].offset += cur_item->dst_sz;
                } else {
                        for (n = 0; n != hash_rxq_init_n; ++n)
                                parser->queue[n].offset += cur_item->dst_sz;
                }
        }
+       if (parser->drop) {
+               parser->queue[HASH_RXQ_ETH].offset +=
+                       sizeof(struct ibv_flow_spec_action_drop);
+       }
        if (parser->mark) {
                for (i = 0; i != hash_rxq_init_n; ++i)
                        parser->queue[i].offset +=
@@ -885,12 +884,8 @@ priv_flow_convert_items_validate(struct priv *priv,
        if (parser->count) {
                unsigned int size = sizeof(struct ibv_flow_spec_counter_action);
 
-               if (parser->drop) {
-                       parser->drop_q.offset += size;
-               } else {
-                       for (i = 0; i != hash_rxq_init_n; ++i)
-                               parser->queue[i].offset += size;
-               }
+               for (i = 0; i != hash_rxq_init_n; ++i)
+                       parser->queue[i].offset += size;
        }
        return 0;
 exit_item_not_supported:
@@ -1103,22 +1098,11 @@ priv_flow_convert(struct priv *priv,
         * Allocate the memory space to store verbs specifications.
         */
        if (parser->drop) {
-               parser->drop_q.ibv_attr =
-                       priv_flow_convert_allocate(priv, attr->priority,
-                                                  parser->drop_q.offset,
-                                                  error);
-               if (!parser->drop_q.ibv_attr)
-                       return ENOMEM;
-               parser->drop_q.offset = sizeof(struct ibv_flow_attr);
-       } else if (parser->queues_n == 1) {
-               unsigned int priority =
-                       attr->priority +
-                       hash_rxq_init[HASH_RXQ_ETH].flow_priority;
-               unsigned int offset = parser->queue[HASH_RXQ_ETH].offset;
-
                parser->queue[HASH_RXQ_ETH].ibv_attr =
-                       priv_flow_convert_allocate(priv, priority,
-                                                  offset, error);
+                       priv_flow_convert_allocate
+                       (priv, attr->priority,
+                        parser->queue[HASH_RXQ_ETH].offset,
+                        error);
                if (!parser->queue[HASH_RXQ_ETH].ibv_attr)
                        return ENOMEM;
                parser->queue[HASH_RXQ_ETH].offset =
@@ -1172,22 +1156,9 @@ priv_flow_convert(struct priv *priv,
         * Last step. Complete missing specification to reach the RSS
         * configuration.
         */
-       if (parser->drop) {
-               /*
-                * Drop queue priority needs to be adjusted to
-                * their most specific layer priority.
-                */
-               parser->drop_q.ibv_attr->priority =
-                       attr->priority +
-                       hash_rxq_init[parser->layer].flow_priority;
-       } else if (parser->queues_n > 1) {
+       if (!parser->drop) {
                priv_flow_convert_finalise(priv, parser);
        } else {
-               /*
-                * Action queue have their priority overridden with
-                * Ethernet priority, this priority needs to be adjusted to
-                * their most specific layer priority.
-                */
                parser->queue[HASH_RXQ_ETH].ibv_attr->priority =
                        attr->priority +
                        hash_rxq_init[parser->layer].flow_priority;
@@ -1195,10 +1166,6 @@ priv_flow_convert(struct priv *priv,
 exit_free:
        /* Only verification is expected, all resources should be released. */
        if (!parser->create) {
-               if (parser->drop) {
-                       rte_free(parser->drop_q.ibv_attr);
-                       parser->drop_q.ibv_attr = NULL;
-               }
                for (i = 0; i != hash_rxq_init_n; ++i) {
                        if (parser->queue[i].ibv_attr) {
                                rte_free(parser->queue[i].ibv_attr);
@@ -1240,14 +1207,6 @@ mlx5_flow_create_copy(struct mlx5_flow_parse *parser, void *src,
        unsigned int i;
        void *dst;
 
-       if (parser->drop) {
-               dst = (void *)((uintptr_t)parser->drop_q.ibv_attr +
-                               parser->drop_q.offset);
-               memcpy(dst, src, size);
-               ++parser->drop_q.ibv_attr->num_of_specs;
-               parser->drop_q.offset += size;
-               return;
-       }
        for (i = 0; i != hash_rxq_init_n; ++i) {
                if (!parser->queue[i].ibv_attr)
                        continue;
@@ -1340,14 +1299,6 @@ mlx5_flow_create_vlan(const struct rte_flow_item *item,
                if (!mask)
                        mask = default_mask;
 
-               if (parser->drop) {
-                       eth = (void *)((uintptr_t)parser->drop_q.ibv_attr +
-                                      parser->drop_q.offset - eth_size);
-                       eth->val.vlan_tag = spec->tci;
-                       eth->mask.vlan_tag = mask->tci;
-                       eth->val.vlan_tag &= eth->mask.vlan_tag;
-                       return 0;
-               }
                for (i = 0; i != hash_rxq_init_n; ++i) {
                        if (!parser->queue[i].ibv_attr)
                                continue;
@@ -1701,23 +1652,25 @@ priv_flow_create_action_queue_drop(struct priv *priv,
        assert(priv->pd);
        assert(priv->ctx);
        flow->drop = 1;
-       drop = (void *)((uintptr_t)parser->drop_q.ibv_attr +
-                       parser->drop_q.offset);
+       drop = (void *)((uintptr_t)parser->queue[HASH_RXQ_ETH].ibv_attr +
+                       parser->queue[HASH_RXQ_ETH].offset);
        *drop = (struct ibv_flow_spec_action_drop){
                        .type = IBV_FLOW_SPEC_ACTION_DROP,
                        .size = size,
        };
-       ++parser->drop_q.ibv_attr->num_of_specs;
-       parser->drop_q.offset += size;
-       flow->drxq.ibv_attr = parser->drop_q.ibv_attr;
+       ++parser->queue[HASH_RXQ_ETH].ibv_attr->num_of_specs;
+       parser->queue[HASH_RXQ_ETH].offset += size;
+       flow->frxq[HASH_RXQ_ETH].ibv_attr =
+               parser->queue[HASH_RXQ_ETH].ibv_attr;
        if (parser->count)
                flow->cs = parser->cs;
        if (!priv->dev->data->dev_started)
                return 0;
-       parser->drop_q.ibv_attr = NULL;
-       flow->drxq.ibv_flow = ibv_create_flow(priv->flow_drop_queue->qp,
-                                             flow->drxq.ibv_attr);
-       if (!flow->drxq.ibv_flow) {
+       parser->queue[HASH_RXQ_ETH].ibv_attr = NULL;
+       flow->frxq[HASH_RXQ_ETH].ibv_flow =
+               ibv_create_flow(priv->flow_drop_queue->qp,
+                               flow->frxq[HASH_RXQ_ETH].ibv_attr);
+       if (!flow->frxq[HASH_RXQ_ETH].ibv_flow) {
                rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
                                   NULL, "flow rule creation failure");
                err = ENOMEM;
@@ -1726,13 +1679,13 @@ priv_flow_create_action_queue_drop(struct priv *priv,
        return 0;
 error:
        assert(flow);
-       if (flow->drxq.ibv_flow) {
-               claim_zero(ibv_destroy_flow(flow->drxq.ibv_flow));
-               flow->drxq.ibv_flow = NULL;
+       if (flow->frxq[HASH_RXQ_ETH].ibv_flow) {
+               claim_zero(ibv_destroy_flow(flow->frxq[HASH_RXQ_ETH].ibv_flow));
+               flow->frxq[HASH_RXQ_ETH].ibv_flow = NULL;
        }
-       if (flow->drxq.ibv_attr) {
-               rte_free(flow->drxq.ibv_attr);
-               flow->drxq.ibv_attr = NULL;
+       if (flow->frxq[HASH_RXQ_ETH].ibv_attr) {
+               rte_free(flow->frxq[HASH_RXQ_ETH].ibv_attr);
+               flow->frxq[HASH_RXQ_ETH].ibv_attr = NULL;
        }
        if (flow->cs) {
                claim_zero(ibv_destroy_counter_set(flow->cs));
@@ -1947,13 +1900,9 @@ priv_flow_create(struct priv *priv,
        DEBUG("Flow created %p", (void *)flow);
        return flow;
 exit:
-       if (parser.drop) {
-               rte_free(parser.drop_q.ibv_attr);
-       } else {
-               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_free(flow);
        return NULL;
@@ -2055,9 +2004,10 @@ priv_flow_destroy(struct priv *priv,
        }
 free:
        if (flow->drop) {
-               if (flow->drxq.ibv_flow)
-                       claim_zero(ibv_destroy_flow(flow->drxq.ibv_flow));
-               rte_free(flow->drxq.ibv_attr);
+               if (flow->frxq[HASH_RXQ_ETH].ibv_flow)
+                       claim_zero(ibv_destroy_flow
+                                  (flow->frxq[HASH_RXQ_ETH].ibv_flow));
+               rte_free(flow->frxq[HASH_RXQ_ETH].ibv_attr);
        } else {
                for (i = 0; i != hash_rxq_init_n; ++i) {
                        struct mlx5_flow *frxq = &flow->frxq[i];
@@ -2224,23 +2174,34 @@ priv_flow_stop(struct priv *priv, struct mlx5_flows *list)
 
        TAILQ_FOREACH_REVERSE(flow, list, mlx5_flows, next) {
                unsigned int i;
+               struct mlx5_ind_table_ibv *ind_tbl = NULL;
 
                if (flow->drop) {
-                       if (!flow->drxq.ibv_flow)
+                       if (!flow->frxq[HASH_RXQ_ETH].ibv_flow)
                                continue;
-                       claim_zero(ibv_destroy_flow(flow->drxq.ibv_flow));
-                       flow->drxq.ibv_flow = NULL;
+                       claim_zero(ibv_destroy_flow
+                                  (flow->frxq[HASH_RXQ_ETH].ibv_flow));
+                       flow->frxq[HASH_RXQ_ETH].ibv_flow = NULL;
+                       DEBUG("Flow %p removed", (void *)flow);
                        /* Next flow. */
                        continue;
                }
+               /* Verify the flow has not already been cleaned. */
+               for (i = 0; i != hash_rxq_init_n; ++i) {
+                       if (!flow->frxq[i].ibv_flow)
+                               continue;
+                       /*
+                        * Indirection table may be necessary to remove the
+                        * flags in the Rx queues.
+                        * This helps to speed-up the process by avoiding
+                        * another loop.
+                        */
+                       ind_tbl = flow->frxq[i].hrxq->ind_table;
+                       break;
+               }
+               if (i == hash_rxq_init_n)
+                       return;
                if (flow->mark) {
-                       struct mlx5_ind_table_ibv *ind_tbl = NULL;
-
-                       for (i = 0; i != hash_rxq_init_n; ++i) {
-                               if (!flow->frxq[i].hrxq)
-                                       continue;
-                               ind_tbl = flow->frxq[i].hrxq->ind_table;
-                       }
                        assert(ind_tbl);
                        for (i = 0; i != ind_tbl->queues_n; ++i)
                                (*priv->rxqs)[ind_tbl->queues[i]]->mark = 0;
@@ -2277,10 +2238,11 @@ priv_flow_start(struct priv *priv, struct mlx5_flows *list)
                unsigned int i;
 
                if (flow->drop) {
-                       flow->drxq.ibv_flow =
-                               ibv_create_flow(priv->flow_drop_queue->qp,
-                                               flow->drxq.ibv_attr);
-                       if (!flow->drxq.ibv_flow) {
+                       flow->frxq[HASH_RXQ_ETH].ibv_flow =
+                               ibv_create_flow
+                               (priv->flow_drop_queue->qp,
+                                flow->frxq[HASH_RXQ_ETH].ibv_attr);
+                       if (!flow->frxq[HASH_RXQ_ETH].ibv_flow) {
                                DEBUG("Flow %p cannot be applied",
                                      (void *)flow);
                                rte_errno = EINVAL;
@@ -2875,13 +2837,13 @@ priv_fdir_filter_delete(struct priv *priv,
        if (parser.drop) {
                struct ibv_flow_spec_action_drop *drop;
 
-               drop = (void *)((uintptr_t)parser.drop_q.ibv_attr +
-                               parser.drop_q.offset);
+               drop = (void *)((uintptr_t)parser.queue[HASH_RXQ_ETH].ibv_attr +
+                               parser.queue[HASH_RXQ_ETH].offset);
                *drop = (struct ibv_flow_spec_action_drop){
                        .type = IBV_FLOW_SPEC_ACTION_DROP,
                        .size = sizeof(struct ibv_flow_spec_action_drop),
                };
-               parser.drop_q.ibv_attr->num_of_specs++;
+               parser.queue[HASH_RXQ_ETH].ibv_attr->num_of_specs++;
        }
        TAILQ_FOREACH(flow, &priv->flows, next) {
                struct ibv_flow_attr *attr;
@@ -2892,14 +2854,8 @@ priv_fdir_filter_delete(struct priv *priv,
                void *flow_spec;
                unsigned int specs_n;
 
-               if (parser.drop)
-                       attr = parser.drop_q.ibv_attr;
-               else
-                       attr = parser.queue[HASH_RXQ_ETH].ibv_attr;
-               if (flow->drop)
-                       flow_attr = flow->drxq.ibv_attr;
-               else
-                       flow_attr = flow->frxq[HASH_RXQ_ETH].ibv_attr;
+               attr = parser.queue[HASH_RXQ_ETH].ibv_attr;
+               flow_attr = flow->frxq[HASH_RXQ_ETH].ibv_attr;
                /* Compare first the attributes. */
                if (memcmp(attr, flow_attr, sizeof(struct ibv_flow_attr)))
                        continue;
@@ -2929,13 +2885,9 @@ wrong_flow:
        if (flow)
                priv_flow_destroy(priv, &priv->flows, flow);
 exit:
-       if (parser.drop) {
-               rte_free(parser.drop_q.ibv_attr);
-       } else {
-               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);
        }
        return -ret;
 }
index d17b991..9fb5ba5 100644 (file)
@@ -93,8 +93,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 void
 mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 {
-       if (mlx5_is_secondary())
-               return;
        assert(index < MLX5_MAX_MAC_ADDRESSES);
        memset(&dev->data->mac_addrs[index], 0, sizeof(struct ether_addr));
        if (!dev->data->promiscuous && !dev->data->all_multicast)
@@ -124,8 +122,6 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
        int ret = 0;
 
        (void)vmdq;
-       if (mlx5_is_secondary())
-               return 0;
        assert(index < MLX5_MAX_MAC_ADDRESSES);
        /* First, make sure this address isn't already configured. */
        for (i = 0; (i != MLX5_MAX_MAC_ADDRESSES); ++i) {
@@ -154,8 +150,6 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
 void
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-       if (mlx5_is_secondary())
-               return;
        DEBUG("%p: setting primary MAC address", (void *)dev);
        mlx5_mac_addr_add(dev, mac_addr, 0, 0);
 }
index 6b29eed..2776dc7 100644 (file)
@@ -291,6 +291,9 @@ priv_mr_new(struct priv *priv, struct rte_mempool *mp)
        DEBUG("mempool %p area start=%p end=%p size=%zu",
              (void *)mp, (void *)start, (void *)end,
              (size_t)(end - start));
+       /* Save original addresses for exact MR lookup. */
+       mr->start = start;
+       mr->end = end;
        /* Round start and end to page boundary if found in memory segments. */
        for (i = 0; (i < RTE_MAX_MEMSEG) && (ms[i].addr != NULL); ++i) {
                uintptr_t addr = (uintptr_t)ms[i].addr;
@@ -309,8 +312,6 @@ priv_mr_new(struct priv *priv, struct rte_mempool *mp)
                            IBV_ACCESS_LOCAL_WRITE);
        mr->mp = mp;
        mr->lkey = rte_cpu_to_be_32(mr->mr->lkey);
-       mr->start = start;
-       mr->end = (uintptr_t)mr->mr->addr + mr->mr->length;
        rte_atomic32_inc(&mr->refcnt);
        DEBUG("%p: new Memory Region %p refcnt: %d", (void *)priv,
              (void *)mr, rte_atomic32_read(&mr->refcnt));
index f3de46d..f47bda6 100644 (file)
@@ -51,6 +51,7 @@
 #include <rte_ethdev.h>
 
 #include "mlx5.h"
+#include "mlx5_defs.h"
 #include "mlx5_rxtx.h"
 
 /**
@@ -72,6 +73,10 @@ mlx5_rss_hash_update(struct rte_eth_dev *dev,
        int ret = 0;
 
        priv_lock(priv);
+       if (rss_conf->rss_hf & MLX5_RSS_HF_MASK) {
+               ret = -EINVAL;
+               goto out;
+       }
        if (rss_conf->rss_key && rss_conf->rss_key_len) {
                priv->rss_conf.rss_key = rte_realloc(priv->rss_conf.rss_key,
                                                     rss_conf->rss_key_len, 0);
@@ -274,7 +279,6 @@ mlx5_dev_rss_reta_update(struct rte_eth_dev *dev,
        int ret;
        struct priv *priv = dev->data->dev_private;
 
-       assert(!mlx5_is_secondary());
        priv_lock(priv);
        ret = priv_dev_rss_reta_update(priv, reta_conf, reta_size);
        priv_unlock(priv);
index 0ef2cdf..6fb245b 100644 (file)
@@ -60,8 +60,6 @@
 void
 mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 {
-       if (mlx5_is_secondary())
-               return;
        dev->data->promiscuous = 1;
        mlx5_traffic_restart(dev);
 }
@@ -75,8 +73,6 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 void
 mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 {
-       if (mlx5_is_secondary())
-               return;
        dev->data->promiscuous = 0;
        mlx5_traffic_restart(dev);
 }
@@ -90,8 +86,6 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 void
 mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 {
-       if (mlx5_is_secondary())
-               return;
        dev->data->all_multicast = 1;
        mlx5_traffic_restart(dev);
 }
@@ -105,8 +99,6 @@ mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 void
 mlx5_allmulticast_disable(struct rte_eth_dev *dev)
 {
-       if (mlx5_is_secondary())
-               return;
        dev->data->all_multicast = 0;
        mlx5_traffic_restart(dev);
 }
index 85399ef..20f3ec6 100644 (file)
@@ -242,8 +242,6 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
        int ret = 0;
 
        (void)conf;
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
        priv_lock(priv);
        if (!rte_is_power_of_2(desc)) {
                desc = 1 << log2above(desc);
@@ -294,9 +292,6 @@ mlx5_rx_queue_release(void *dpdk_rxq)
        struct mlx5_rxq_ctrl *rxq_ctrl;
        struct priv *priv;
 
-       if (mlx5_is_secondary())
-               return;
-
        if (rxq == NULL)
                return;
        rxq_ctrl = container_of(rxq, struct mlx5_rxq_ctrl, rxq);
@@ -327,7 +322,6 @@ priv_rx_intr_vec_enable(struct priv *priv)
        unsigned int count = 0;
        struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
 
-       assert(!mlx5_is_secondary());
        if (!priv->dev->data->dev_conf.intr_conf.rxq)
                return 0;
        priv_rx_intr_vec_disable(priv);
index 2d30c50..32bfa30 100644 (file)
@@ -374,7 +374,7 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                uint16_t pkt_inline_sz = MLX5_WQE_DWORD_SIZE + 2;
                uint16_t tso_header_sz = 0;
                uint16_t ehdr;
-               uint8_t cs_flags = 0;
+               uint8_t cs_flags;
                uint64_t tso = 0;
                uint16_t tso_segsz = 0;
 #ifdef MLX5_PMD_SOFT_COUNTERS
@@ -417,23 +417,7 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                if (pkts_n - i > 1)
                        rte_prefetch0(
                            rte_pktmbuf_mtod(*(pkts + 1), volatile void *));
-               /* Should we enable HW CKSUM offload */
-               if (buf->ol_flags &
-                   (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
-                       const uint64_t is_tunneled = buf->ol_flags &
-                                                    (PKT_TX_TUNNEL_GRE |
-                                                     PKT_TX_TUNNEL_VXLAN);
-
-                       if (is_tunneled && txq->tunnel_en) {
-                               cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM |
-                                          MLX5_ETH_WQE_L4_INNER_CSUM;
-                               if (buf->ol_flags & PKT_TX_OUTER_IP_CKSUM)
-                                       cs_flags |= MLX5_ETH_WQE_L3_CSUM;
-                       } else {
-                               cs_flags = MLX5_ETH_WQE_L3_CSUM |
-                                          MLX5_ETH_WQE_L4_CSUM;
-                       }
-               }
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                raw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;
                /* Replace the Ethernet type by the VLAN if necessary. */
                if (buf->ol_flags & PKT_TX_VLAN_PKT) {
@@ -847,7 +831,7 @@ mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                struct rte_mbuf *buf = *(pkts++);
                uint32_t length;
                unsigned int segs_n = buf->nb_segs;
-               uint32_t cs_flags = 0;
+               uint32_t cs_flags;
 
                /*
                 * Make sure there is enough room to store this packet and
@@ -863,10 +847,7 @@ mlx5_tx_burst_mpw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                }
                max_elts -= segs_n;
                --pkts_n;
-               /* Should we enable HW CKSUM offload */
-               if (buf->ol_flags &
-                   (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM))
-                       cs_flags = MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                /* Retrieve packet information. */
                length = PKT_LEN(buf);
                assert(length);
@@ -1072,7 +1053,7 @@ mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
                uintptr_t addr;
                uint32_t length;
                unsigned int segs_n = buf->nb_segs;
-               uint32_t cs_flags = 0;
+               uint8_t cs_flags;
 
                /*
                 * Make sure there is enough room to store this packet and
@@ -1093,10 +1074,7 @@ mlx5_tx_burst_mpw_inline(void *dpdk_txq, struct rte_mbuf **pkts,
                 * iteration.
                 */
                max_wqe = (1u << txq->wqe_n) - (txq->wqe_ci - txq->wqe_pi);
-               /* Should we enable HW CKSUM offload */
-               if (buf->ol_flags &
-                   (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM))
-                       cs_flags = MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                /* Retrieve packet information. */
                length = PKT_LEN(buf);
                /* Start new session if packet differs. */
@@ -1366,7 +1344,7 @@ mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                unsigned int do_inline = 0; /* Whether inline is possible. */
                uint32_t length;
                unsigned int segs_n = buf->nb_segs;
-               uint32_t cs_flags = 0;
+               uint8_t cs_flags;
 
                /*
                 * Make sure there is enough room to store this packet and
@@ -1380,10 +1358,7 @@ mlx5_tx_burst_empw(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                        txq->stats.oerrors++;
                        break;
                }
-               /* Should we enable HW CKSUM offload. */
-               if (buf->ol_flags &
-                   (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM))
-                       cs_flags = MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                /* Retrieve packet information. */
                length = PKT_LEN(buf);
                /* Start new session if:
index d34f3cc..de5b769 100644 (file)
@@ -114,8 +114,7 @@ struct mlx5_rxq_data {
        unsigned int elts_n:4; /* Log 2 of Mbufs. */
        unsigned int rss_hash:1; /* RSS hash result is enabled. */
        unsigned int mark:1; /* Marked flow available on the queue. */
-       unsigned int pending_err:1; /* CQE error needs to be handled. */
-       unsigned int :14; /* Remaining bits. */
+       unsigned int :15; /* Remaining bits. */
        volatile uint32_t *rq_db;
        volatile uint32_t *cq_db;
        uint16_t port_id;
@@ -548,15 +547,16 @@ mlx5_tx_mb2mr(struct mlx5_txq_data *txq, struct rte_mbuf *mb)
        struct mlx5_mr *mr;
 
        assert(i < RTE_DIM(txq->mp2mr));
-       if (likely(txq->mp2mr[i]->start <= addr && txq->mp2mr[i]->end >= addr))
+       if (likely(txq->mp2mr[i]->start <= addr && txq->mp2mr[i]->end > addr))
                return txq->mp2mr[i]->lkey;
        for (i = 0; (i != RTE_DIM(txq->mp2mr)); ++i) {
-               if (unlikely(txq->mp2mr[i]->mr == NULL)) {
+               if (unlikely(txq->mp2mr[i] == NULL ||
+                   txq->mp2mr[i]->mr == NULL)) {
                        /* Unknown MP, add a new MR for it. */
                        break;
                }
                if (txq->mp2mr[i]->start <= addr &&
-                   txq->mp2mr[i]->end >= addr) {
+                   txq->mp2mr[i]->end > addr) {
                        assert(txq->mp2mr[i]->lkey != (uint32_t)-1);
                        assert(rte_cpu_to_be_32(txq->mp2mr[i]->mr->lkey) ==
                               txq->mp2mr[i]->lkey);
@@ -564,7 +564,6 @@ mlx5_tx_mb2mr(struct mlx5_txq_data *txq, struct rte_mbuf *mb)
                        return txq->mp2mr[i]->lkey;
                }
        }
-       txq->mr_cache_idx = 0;
        mr = mlx5_txq_mp2mr_reg(txq, mlx5_tx_mb2mp(mb), i);
        /*
         * Request the reference to use in this queue, the original one is
@@ -572,6 +571,7 @@ mlx5_tx_mb2mr(struct mlx5_txq_data *txq, struct rte_mbuf *mb)
         */
        if (mr) {
                rte_atomic32_inc(&mr->refcnt);
+               txq->mr_cache_idx = i >= RTE_DIM(txq->mp2mr) ? i - 1 : i;
                return mr->lkey;
        }
        return (uint32_t)-1;
@@ -617,4 +617,39 @@ mlx5_tx_dbrec(struct mlx5_txq_data *txq, volatile struct mlx5_wqe *wqe)
        mlx5_tx_dbrec_cond_wmb(txq, wqe, 1);
 }
 
+/**
+ * Convert the Checksum offloads to Verbs.
+ *
+ * @param txq_data
+ *   Pointer to the Tx queue.
+ * @param buf
+ *   Pointer to the mbuf.
+ *
+ * @return
+ *   the converted cs_flags.
+ */
+static __rte_always_inline uint8_t
+txq_ol_cksum_to_cs(struct mlx5_txq_data *txq_data, struct rte_mbuf *buf)
+{
+       uint8_t cs_flags = 0;
+
+       /* Should we enable HW CKSUM offload */
+       if (buf->ol_flags &
+           (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM |
+            PKT_TX_OUTER_IP_CKSUM)) {
+               if (txq_data->tunnel_en &&
+                   (buf->ol_flags &
+                    (PKT_TX_TUNNEL_GRE | PKT_TX_TUNNEL_VXLAN))) {
+                       cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM |
+                                  MLX5_ETH_WQE_L4_INNER_CSUM;
+                       if (buf->ol_flags & PKT_TX_OUTER_IP_CKSUM)
+                               cs_flags |= MLX5_ETH_WQE_L3_CSUM;
+               } else {
+                       cs_flags = MLX5_ETH_WQE_L3_CSUM |
+                                  MLX5_ETH_WQE_L4_CSUM;
+               }
+       }
+       return cs_flags;
+}
+
 #endif /* RTE_PMD_MLX5_RXTX_H_ */
index ba6c8ce..101aa15 100644 (file)
@@ -123,24 +123,7 @@ txq_calc_offload(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
        for (pos = 1; pos < pkts_n; ++pos)
                if ((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask)
                        break;
-       /* Should open another MPW session for the rest. */
-       if (pkts[0]->ol_flags &
-           (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
-               const uint64_t is_tunneled =
-                       pkts[0]->ol_flags &
-                       (PKT_TX_TUNNEL_GRE |
-                        PKT_TX_TUNNEL_VXLAN);
-
-               if (is_tunneled && txq->tunnel_en) {
-                       *cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM |
-                                   MLX5_ETH_WQE_L4_INNER_CSUM;
-                       if (pkts[0]->ol_flags & PKT_TX_OUTER_IP_CKSUM)
-                               *cs_flags |= MLX5_ETH_WQE_L3_CSUM;
-               } else {
-                       *cs_flags = MLX5_ETH_WQE_L3_CSUM |
-                                   MLX5_ETH_WQE_L4_CSUM;
-               }
-       }
+       *cs_flags = txq_ol_cksum_to_cs(txq, pkts[0]);
        return pos;
 }
 
@@ -261,7 +244,6 @@ rxq_handle_pending_error(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts,
        rxq->stats.ipackets -= (pkts_n - n);
        rxq->stats.ibytes -= err_bytes;
 #endif
-       rxq->pending_err = 0;
        return n;
 }
 
@@ -283,9 +265,10 @@ mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 {
        struct mlx5_rxq_data *rxq = dpdk_rxq;
        uint16_t nb_rx;
+       uint64_t err = 0;
 
-       nb_rx = rxq_burst_v(rxq, pkts, pkts_n);
-       if (unlikely(rxq->pending_err))
+       nb_rx = rxq_burst_v(rxq, pkts, pkts_n, &err);
+       if (unlikely(err))
                nb_rx = rxq_handle_pending_error(rxq, pkts, nb_rx);
        return nb_rx;
 }
index c721d80..06f83ef 100644 (file)
@@ -149,7 +149,7 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
                        11, 10,  9,  8, /* bswap32 */
                        12, 13, 14, 15
                };
-               uint8_t cs_flags = 0;
+               uint8_t cs_flags;
                uint16_t max_elts;
                uint16_t max_wqe;
                uint8x16_t *t_wqe;
@@ -168,22 +168,7 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
                        break;
                wqe = &((volatile struct mlx5_wqe64 *)
                         txq->wqes)[wqe_ci & wq_mask].hdr;
-               if (buf->ol_flags &
-                    (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
-                       const uint64_t is_tunneled =
-                               buf->ol_flags & (PKT_TX_TUNNEL_GRE |
-                                                PKT_TX_TUNNEL_VXLAN);
-
-                       if (is_tunneled && txq->tunnel_en) {
-                               cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM |
-                                          MLX5_ETH_WQE_L4_INNER_CSUM;
-                               if (buf->ol_flags & PKT_TX_OUTER_IP_CKSUM)
-                                       cs_flags |= MLX5_ETH_WQE_L3_CSUM;
-                       } else {
-                               cs_flags = MLX5_ETH_WQE_L3_CSUM |
-                                          MLX5_ETH_WQE_L4_CSUM;
-                       }
-               }
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                /* Title WQEBB pointer. */
                t_wqe = (uint8x16_t *)wqe;
                dseg = (uint8_t *)(wqe + 1);
@@ -590,11 +575,15 @@ rxq_cq_to_ptype_oflags_v(struct mlx5_rxq_data *rxq,
        if (rxq->mark) {
                const uint32x4_t ft_def = vdupq_n_u32(MLX5_FLOW_MARK_DEFAULT);
                const uint32x4_t fdir_flags = vdupq_n_u32(PKT_RX_FDIR);
-               const uint32x4_t fdir_id_flags = vdupq_n_u32(PKT_RX_FDIR_ID);
+               uint32x4_t fdir_id_flags = vdupq_n_u32(PKT_RX_FDIR_ID);
+               uint32x4_t invalid_mask;
 
                /* Check if flow tag is non-zero then set PKT_RX_FDIR. */
-               ol_flags = vorrq_u32(ol_flags, vbicq_u32(fdir_flags,
-                                                        vceqzq_u32(flow_tag)));
+               invalid_mask = vceqzq_u32(flow_tag);
+               ol_flags = vorrq_u32(ol_flags,
+                                    vbicq_u32(fdir_flags, invalid_mask));
+               /* Mask out invalid entries. */
+               fdir_id_flags = vbicq_u32(fdir_id_flags, invalid_mask);
                /* Check if flow tag MLX5_FLOW_MARK_DEFAULT. */
                ol_flags = vorrq_u32(ol_flags,
                                     vbicq_u32(fdir_id_flags,
@@ -665,12 +654,16 @@ rxq_cq_to_ptype_oflags_v(struct mlx5_rxq_data *rxq,
  *   Array to store received packets.
  * @param pkts_n
  *   Maximum number of packets in array.
+ * @param[out] err
+ *   Pointer to a flag. Set non-zero value if pkts array has at least one error
+ *   packet to handle.
  *
  * @return
  *   Number of packets received including errors (<= pkts_n).
  */
 static inline uint16_t
-rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
+rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
+           uint64_t *err)
 {
        const uint16_t q_n = 1 << rxq->cqe_n;
        const uint16_t q_mask = q_n - 1;
@@ -970,8 +963,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                opcode = vceq_u16(resp_err_check, opcode);
                opcode = vbic_u16(opcode, invalid_mask);
                /* D.4 mark if any error is set */
-               rxq->pending_err |=
-                       !!vget_lane_u64(vreinterpret_u64_u16(opcode), 0);
+               *err |= vget_lane_u64(vreinterpret_u64_u16(opcode), 0);
                /* C.4 fill in mbuf - rearm_data and packet_type. */
                rxq_cq_to_ptype_oflags_v(rxq, ptype_info, flow_tag,
                                         opcode, &elts[pos]);
index 2b9f160..7ef2c59 100644 (file)
@@ -148,7 +148,7 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
                                      8,  9, 10, 11, /* bswap32 */
                                      4,  5,  6,  7, /* bswap32 */
                                      0,  1,  2,  3  /* bswap32 */);
-               uint8_t cs_flags = 0;
+               uint8_t cs_flags;
                uint16_t max_elts;
                uint16_t max_wqe;
                __m128i *t_wqe, *dseg;
@@ -170,22 +170,7 @@ txq_scatter_v(struct mlx5_txq_data *txq, struct rte_mbuf **pkts,
                }
                wqe = &((volatile struct mlx5_wqe64 *)
                         txq->wqes)[wqe_ci & wq_mask].hdr;
-               if (buf->ol_flags &
-                    (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
-                       const uint64_t is_tunneled =
-                               buf->ol_flags & (PKT_TX_TUNNEL_GRE |
-                                                PKT_TX_TUNNEL_VXLAN);
-
-                       if (is_tunneled && txq->tunnel_en) {
-                               cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM |
-                                          MLX5_ETH_WQE_L4_INNER_CSUM;
-                               if (buf->ol_flags & PKT_TX_OUTER_IP_CKSUM)
-                                       cs_flags |= MLX5_ETH_WQE_L3_CSUM;
-                       } else {
-                               cs_flags = MLX5_ETH_WQE_L3_CSUM |
-                                          MLX5_ETH_WQE_L4_CSUM;
-                       }
-               }
+               cs_flags = txq_ol_cksum_to_cs(txq, buf);
                /* Title WQEBB pointer. */
                t_wqe = (__m128i *)wqe;
                dseg = (__m128i *)(wqe + 1);
@@ -591,7 +576,7 @@ rxq_cq_to_ptype_oflags_v(struct mlx5_rxq_data *rxq, __m128i cqes[4],
                        _mm_set_epi32(0xffffff00, 0xffffff00,
                                      0xffffff00, 0xffffff00);
                const __m128i fdir_flags = _mm_set1_epi32(PKT_RX_FDIR);
-               const __m128i fdir_id_flags = _mm_set1_epi32(PKT_RX_FDIR_ID);
+               __m128i fdir_id_flags = _mm_set1_epi32(PKT_RX_FDIR_ID);
                __m128i flow_tag, invalid_mask;
 
                flow_tag = _mm_and_si128(pinfo, pinfo_ft_mask);
@@ -601,7 +586,7 @@ rxq_cq_to_ptype_oflags_v(struct mlx5_rxq_data *rxq, __m128i cqes[4],
                                        _mm_andnot_si128(invalid_mask,
                                                         fdir_flags));
                /* Mask out invalid entries. */
-               flow_tag = _mm_andnot_si128(invalid_mask, flow_tag);
+               fdir_id_flags = _mm_andnot_si128(invalid_mask, fdir_id_flags);
                /* Check if flow tag MLX5_FLOW_MARK_DEFAULT. */
                ol_flags = _mm_or_si128(ol_flags,
                                        _mm_andnot_si128(
@@ -669,12 +654,16 @@ rxq_cq_to_ptype_oflags_v(struct mlx5_rxq_data *rxq, __m128i cqes[4],
  *   Array to store received packets.
  * @param pkts_n
  *   Maximum number of packets in array.
+ * @param[out] err
+ *   Pointer to a flag. Set non-zero value if pkts array has at least one error
+ *   packet to handle.
  *
  * @return
  *   Number of packets received including errors (<= pkts_n).
  */
 static inline uint16_t
-rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
+rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n,
+           uint64_t *err)
 {
        const uint16_t q_n = 1 << rxq->cqe_n;
        const uint16_t q_mask = q_n - 1;
@@ -936,7 +925,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                opcode = _mm_packs_epi32(opcode, zero);
                opcode = _mm_andnot_si128(invalid_mask, opcode);
                /* D.4 mark if any error is set */
-               rxq->pending_err |= !!_mm_cvtsi128_si64(opcode);
+               *err |= _mm_cvtsi128_si64(opcode);
                /* D.5 fill in mbuf - rearm_data and packet_type. */
                rxq_cq_to_ptype_oflags_v(rxq, cqes, opcode, &pkts[pos]);
                if (rxq->hw_timestamp) {
index 5e225d3..2427585 100644 (file)
@@ -143,11 +143,9 @@ priv_read_dev_counters(struct priv *priv, uint64_t *stats)
        struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
        unsigned int i;
        struct ifreq ifr;
-       unsigned int stats_sz = (xstats_ctrl->stats_n * sizeof(uint64_t)) +
-                                sizeof(struct ethtool_stats);
-       struct ethtool_stats et_stats[(stats_sz + (
-                                     sizeof(struct ethtool_stats) - 1)) /
-                                     sizeof(struct ethtool_stats)];
+       unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t);
+       unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz];
+       struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf;
 
        et_stats->cmd = ETHTOOL_GSTATS;
        et_stats->n_stats = xstats_ctrl->stats_n;
index 5de2d02..d682ea2 100644 (file)
@@ -64,8 +64,11 @@ priv_txq_start(struct priv *priv)
 
                if (!txq_ctrl)
                        continue;
-               LIST_FOREACH(mr, &priv->mr, next)
+               LIST_FOREACH(mr, &priv->mr, next) {
                        priv_txq_mp2mr_reg(priv, &txq_ctrl->txq, mr->mp, idx++);
+                       if (idx == MLX5_PMD_TX_MP_CACHE)
+                               break;
+               }
                txq_alloc_elts(txq_ctrl);
                txq_ctrl->ibv = mlx5_priv_txq_ibv_new(priv, i);
                if (!txq_ctrl->ibv) {
@@ -132,9 +135,6 @@ mlx5_dev_start(struct rte_eth_dev *dev)
        struct mlx5_mr *mr = NULL;
        int err;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        dev->data->dev_started = 1;
        priv_lock(priv);
        err = priv_flow_create_drop_queue(priv);
@@ -151,38 +151,29 @@ mlx5_dev_start(struct rte_eth_dev *dev)
                      (void *)dev, strerror(err));
                goto error;
        }
-       /* Update send callback. */
-       priv_dev_select_tx_function(priv, dev);
        err = priv_rxq_start(priv);
        if (err) {
                ERROR("%p: RXQ allocation failed: %s",
                      (void *)dev, strerror(err));
                goto error;
        }
-       /* Update receive callback. */
-       priv_dev_select_rx_function(priv, dev);
-       err = priv_dev_traffic_enable(priv, dev);
-       if (err) {
-               ERROR("%p: an error occurred while configuring control flows:"
-                     " %s",
-                     (void *)priv, strerror(err));
-               goto error;
-       }
-       err = priv_flow_start(priv, &priv->flows);
-       if (err) {
-               ERROR("%p: an error occurred while configuring flows:"
-                     " %s",
-                     (void *)priv, strerror(err));
-               goto error;
-       }
        err = priv_rx_intr_vec_enable(priv);
        if (err) {
                ERROR("%p: RX interrupt vector creation failed",
                      (void *)priv);
                goto error;
        }
-       priv_dev_interrupt_handler_install(priv, dev);
        priv_xstats_init(priv);
+       /* Update link status and Tx/Rx callbacks for the first time. */
+       memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
+       INFO("Forcing port %u link to be up", dev->data->port_id);
+       err = priv_force_link_status_change(priv, ETH_LINK_UP);
+       if (err) {
+               DEBUG("Failed to set port %u link to be up",
+                     dev->data->port_id);
+               goto error;
+       }
+       priv_dev_interrupt_handler_install(priv, dev);
        priv_unlock(priv);
        return 0;
 error:
@@ -196,7 +187,7 @@ error:
        priv_rxq_stop(priv);
        priv_flow_delete_drop_queue(priv);
        priv_unlock(priv);
-       return -err;
+       return err;
 }
 
 /**
@@ -213,9 +204,6 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
        struct priv *priv = dev->data->dev_private;
        struct mlx5_mr *mr;
 
-       if (mlx5_is_secondary())
-               return;
-
        priv_lock(priv);
        dev->data->dev_started = 0;
        /* Prevent crashes when queues are still in use. */
index 9c5860f..7ca99f5 100644 (file)
@@ -142,9 +142,6 @@ mlx5_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                container_of(txq, struct mlx5_txq_ctrl, txq);
        int ret = 0;
 
-       if (mlx5_is_secondary())
-               return -E_RTE_SECONDARY;
-
        priv_lock(priv);
        if (desc <= MLX5_TX_COMP_THRESH) {
                WARN("%p: number of descriptors requested for TX queue %u"
@@ -203,9 +200,6 @@ mlx5_tx_queue_release(void *dpdk_txq)
        struct priv *priv;
        unsigned int i;
 
-       if (mlx5_is_secondary())
-               return;
-
        if (txq == NULL)
                return;
        txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);
@@ -253,6 +247,8 @@ priv_tx_uar_remap(struct priv *priv, int fd)
         * Ref to libmlx5 function: mlx5_init_context()
         */
        for (i = 0; i != priv->txqs_n; ++i) {
+               if (!(*priv->txqs)[i])
+                       continue;
                txq = (*priv->txqs)[i];
                txq_ctrl = container_of(txq, struct mlx5_txq_ctrl, txq);
                uar_va = (uintptr_t)txq_ctrl->txq.bf_reg;
index 6fc315e..198a69e 100644 (file)
@@ -127,6 +127,11 @@ priv_vlan_strip_queue_set(struct priv *priv, uint16_t idx, int on)
 
        DEBUG("set VLAN offloads 0x%x for port %d queue %d",
              vlan_offloads, rxq->port_id, idx);
+       if (!rxq_ctrl->ibv) {
+               /* Update related bits in RX queue. */
+               rxq->vlan_strip = !!on;
+               return;
+       }
        mod = (struct ibv_wq_attr){
                .attr_mask = IBV_WQ_ATTR_FLAGS,
                .flags_mask = IBV_WQ_FLAGS_CVLAN_STRIPPING,
index 2936165..9a35819 100644 (file)
@@ -115,6 +115,11 @@ struct pp2_bpool *mrvl_port_to_bpool_lookup[RTE_MAX_ETHPORTS];
 int mrvl_port_bpool_size[PP2_NUM_PKT_PROC][PP2_BPOOL_NUM_POOLS][RTE_MAX_LCORE];
 uint64_t cookie_addr_high = MRVL_COOKIE_ADDR_INVALID;
 
+struct mrvl_ifnames {
+       const char *names[PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC];
+       int idx;
+};
+
 /*
  * To use buffer harvesting based on loopback port shadow queue structure
  * was introduced for buffers information bookkeeping.
@@ -149,21 +154,17 @@ struct mrvl_txq {
        int queue_id;
        int port_id;
        uint64_t bytes_sent;
+       struct mrvl_shadow_txq shadow_txqs[RTE_MAX_LCORE];
 };
 
-/*
- * Every tx queue should have dedicated shadow tx queue.
- *
- * Ports assigned by DPDK might not start at zero or be continuous so
- * as a workaround define shadow queues for each possible port so that
- * we eventually fit somewhere.
- */
-struct mrvl_shadow_txq shadow_txqs[RTE_MAX_ETHPORTS][RTE_MAX_LCORE];
-
-/** Number of ports configured. */
-int mrvl_ports_nb;
 static int mrvl_lcore_first;
 static int mrvl_lcore_last;
+static int mrvl_dev_num;
+
+static int mrvl_fill_bpool(struct mrvl_rxq *rxq, int num);
+static inline void mrvl_free_sent_buffers(struct pp2_ppio *ppio,
+                       struct pp2_hif *hif, unsigned int core_id,
+                       struct mrvl_shadow_txq *sq, int qid, int force);
 
 static inline int
 mrvl_get_bpool_size(int pp2_id, int pool_id)
@@ -190,6 +191,59 @@ mrvl_reserve_bit(int *bitmap, int max)
        return n;
 }
 
+static int
+mrvl_init_hif(int core_id)
+{
+       struct pp2_hif_params params;
+       char match[MRVL_MATCH_LEN];
+       int ret;
+
+       ret = mrvl_reserve_bit(&used_hifs, MRVL_MUSDK_HIFS_MAX);
+       if (ret < 0) {
+               RTE_LOG(ERR, PMD, "Failed to allocate hif %d\n", core_id);
+               return ret;
+       }
+
+       snprintf(match, sizeof(match), "hif-%d", ret);
+       memset(&params, 0, sizeof(params));
+       params.match = match;
+       params.out_size = MRVL_PP2_AGGR_TXQD_MAX;
+       ret = pp2_hif_init(&params, &hifs[core_id]);
+       if (ret) {
+               RTE_LOG(ERR, PMD, "Failed to initialize hif %d\n", core_id);
+               return ret;
+       }
+
+       return 0;
+}
+
+static inline struct pp2_hif*
+mrvl_get_hif(struct mrvl_priv *priv, int core_id)
+{
+       int ret;
+
+       if (likely(hifs[core_id] != NULL))
+               return hifs[core_id];
+
+       rte_spinlock_lock(&priv->lock);
+
+       ret = mrvl_init_hif(core_id);
+       if (ret < 0) {
+               RTE_LOG(ERR, PMD, "Failed to allocate hif %d\n", core_id);
+               goto out;
+       }
+
+       if (core_id < mrvl_lcore_first)
+               mrvl_lcore_first = core_id;
+
+       if (core_id > mrvl_lcore_last)
+               mrvl_lcore_last = core_id;
+out:
+       rte_spinlock_unlock(&priv->lock);
+
+       return hifs[core_id];
+}
+
 /**
  * Configure rss based on dpdk rss configuration.
  *
@@ -408,19 +462,12 @@ mrvl_dev_start(struct rte_eth_dev *dev)
 {
        struct mrvl_priv *priv = dev->data->dev_private;
        char match[MRVL_MATCH_LEN];
-       int ret;
+       int ret = 0, def_init_size;
 
        snprintf(match, sizeof(match), "ppio-%d:%d",
                 priv->pp_id, priv->ppio_id);
        priv->ppio_params.match = match;
 
-       /*
-        * Calculate the maximum bpool size for refill feature to 1.5 of the
-        * configured size. In case the bpool size will exceed this value,
-        * superfluous buffers will be removed
-        */
-       priv->bpool_max_size = priv->bpool_init_size +
-                             (priv->bpool_init_size >> 1);
        /*
         * Calculate the minimum bpool size for refill feature as follows:
         * 2 default burst sizes multiply by number of rx queues.
@@ -429,6 +476,29 @@ mrvl_dev_start(struct rte_eth_dev *dev)
         */
        priv->bpool_min_size = priv->nb_rx_queues * MRVL_BURST_SIZE * 2;
 
+       /* In case initial bpool size configured in queues setup is
+        * smaller than minimum size add more buffers
+        */
+       def_init_size = priv->bpool_min_size + MRVL_BURST_SIZE * 2;
+       if (priv->bpool_init_size < def_init_size) {
+               int buffs_to_add = def_init_size - priv->bpool_init_size;
+
+               priv->bpool_init_size += buffs_to_add;
+               ret = mrvl_fill_bpool(dev->data->rx_queues[0], buffs_to_add);
+               if (ret)
+                       RTE_LOG(ERR, PMD, "Failed to add buffers to bpool\n");
+       }
+
+       /*
+        * Calculate the maximum bpool size for refill feature as follows:
+        * maximum number of descriptors in rx queue multiply by number
+        * of rx queues plus minimum bpool size.
+        * In case the bpool size will exceed this value, superfluous buffers
+        * will be removed
+        */
+       priv->bpool_max_size = (priv->nb_rx_queues * MRVL_PP2_RXD_MAX) +
+                               priv->bpool_min_size;
+
        ret = pp2_ppio_init(&priv->ppio_params, &priv->ppio);
        if (ret)
                return ret;
@@ -518,21 +588,32 @@ mrvl_flush_rx_queues(struct rte_eth_dev *dev)
 static void
 mrvl_flush_tx_shadow_queues(struct rte_eth_dev *dev)
 {
-       int i;
+       int i, j;
+       struct mrvl_txq *txq;
 
        RTE_LOG(INFO, PMD, "Flushing tx shadow queues\n");
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               struct mrvl_shadow_txq *sq =
-                       &shadow_txqs[dev->data->port_id][i];
+       for (i = 0; i < dev->data->nb_tx_queues; i++) {
+               txq = (struct mrvl_txq *)dev->data->tx_queues[i];
+
+               for (j = 0; j < RTE_MAX_LCORE; j++) {
+                       struct mrvl_shadow_txq *sq;
 
-               while (sq->tail != sq->head) {
-                       uint64_t addr = cookie_addr_high |
+                       if (!hifs[j])
+                               continue;
+
+                       sq = &txq->shadow_txqs[j];
+                       mrvl_free_sent_buffers(txq->priv->ppio,
+                               hifs[j], j, sq, txq->queue_id, 1);
+                       while (sq->tail != sq->head) {
+                               uint64_t addr = cookie_addr_high |
                                        sq->ent[sq->tail].buff.cookie;
-                       rte_pktmbuf_free((struct rte_mbuf *)addr);
-                       sq->tail = (sq->tail + 1) & MRVL_PP2_TX_SHADOWQ_MASK;
+                               rte_pktmbuf_free(
+                                       (struct rte_mbuf *)addr);
+                               sq->tail = (sq->tail + 1) &
+                                           MRVL_PP2_TX_SHADOWQ_MASK;
+                       }
+                       memset(sq, 0, sizeof(*sq));
                }
-
-               memset(sq, 0, sizeof(*sq));
        }
 }
 
@@ -546,8 +627,15 @@ static void
 mrvl_flush_bpool(struct rte_eth_dev *dev)
 {
        struct mrvl_priv *priv = dev->data->dev_private;
+       struct pp2_hif *hif;
        uint32_t num;
        int ret;
+       unsigned int core_id = rte_lcore_id();
+
+       if (core_id == LCORE_ID_ANY)
+               core_id = 0;
+
+       hif = mrvl_get_hif(priv, core_id);
 
        ret = pp2_bpool_get_num_buffs(priv->bpool, &num);
        if (ret) {
@@ -559,8 +647,7 @@ mrvl_flush_bpool(struct rte_eth_dev *dev)
                struct pp2_buff_inf inf;
                uint64_t addr;
 
-               ret = pp2_bpool_get_buff(hifs[rte_lcore_id()], priv->bpool,
-                                        &inf);
+               ret = pp2_bpool_get_buff(hif, priv->bpool, &inf);
                if (ret)
                        break;
 
@@ -583,8 +670,10 @@ mrvl_dev_stop(struct rte_eth_dev *dev)
        mrvl_dev_set_link_down(dev);
        mrvl_flush_rx_queues(dev);
        mrvl_flush_tx_shadow_queues(dev);
-       if (priv->qos_tbl)
+       if (priv->qos_tbl) {
                pp2_cls_qos_tbl_deinit(priv->qos_tbl);
+               priv->qos_tbl = NULL;
+       }
        pp2_ppio_deinit(priv->ppio);
        priv->ppio = NULL;
 }
@@ -1131,9 +1220,19 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num)
        struct buff_release_entry entries[MRVL_PP2_TXD_MAX];
        struct rte_mbuf *mbufs[MRVL_PP2_TXD_MAX];
        int i, ret;
-       unsigned int core_id = rte_lcore_id();
-       struct pp2_hif *hif = hifs[core_id];
-       struct pp2_bpool *bpool = rxq->priv->bpool;
+       unsigned int core_id;
+       struct pp2_hif *hif;
+       struct pp2_bpool *bpool;
+
+       core_id = rte_lcore_id();
+       if (core_id == LCORE_ID_ANY)
+               core_id = 0;
+
+       hif = mrvl_get_hif(rxq->priv, core_id);
+       if (!hif)
+               return -1;
+
+       bpool = rxq->priv->bpool;
 
        ret = rte_pktmbuf_alloc_bulk(rxq->mp, mbufs, num);
        if (ret)
@@ -1269,8 +1368,15 @@ mrvl_rx_queue_release(void *rxq)
        struct mrvl_rxq *q = rxq;
        struct pp2_ppio_tc_params *tc_params;
        int i, num, tc, inq;
+       struct pp2_hif *hif;
+       unsigned int core_id = rte_lcore_id();
 
-       if (!q)
+       if (core_id == LCORE_ID_ANY)
+               core_id = 0;
+
+       hif = mrvl_get_hif(q->priv, core_id);
+
+       if (!q || !hif)
                return;
 
        tc = q->priv->rxq_map[q->queue_id].tc;
@@ -1281,7 +1387,7 @@ mrvl_rx_queue_release(void *rxq)
                struct pp2_buff_inf inf;
                uint64_t addr;
 
-               pp2_bpool_get_buff(hifs[rte_lcore_id()], q->priv->bpool, &inf);
+               pp2_bpool_get_buff(hif, q->priv->bpool, &inf);
                addr = cookie_addr_high | inf.cookie;
                rte_pktmbuf_free((struct rte_mbuf *)addr);
        }
@@ -1557,9 +1663,12 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
        struct pp2_bpool *bpool;
        int i, ret, rx_done = 0;
        int num;
+       struct pp2_hif *hif;
        unsigned int core_id = rte_lcore_id();
 
-       if (unlikely(!q->priv->ppio))
+       hif = mrvl_get_hif(q->priv, core_id);
+
+       if (unlikely(!q->priv->ppio || !hif))
                return 0;
 
        bpool = q->priv->bpool;
@@ -1602,7 +1711,7 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                                .cookie = (pp2_cookie_t)(uint64_t)mbuf,
                        };
 
-                       pp2_bpool_put_buff(hifs[core_id], bpool, &binf);
+                       pp2_bpool_put_buff(hif, bpool, &binf);
                        mrvl_port_bpool_size
                                [bpool->pp2_id][bpool->id][core_id]++;
                        q->drop_mac++;
@@ -1648,14 +1757,15 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                                q->priv->bpool_init_size);
 
                        for (i = 0; i < pkt_to_remove; i++) {
-                               pp2_bpool_get_buff(hifs[core_id], bpool, &buff);
+                               ret = pp2_bpool_get_buff(hif, bpool, &buff);
+                               if (ret)
+                                       break;
                                mbuf = (struct rte_mbuf *)
                                        (cookie_addr_high | buff.cookie);
                                rte_pktmbuf_free(mbuf);
                        }
                        mrvl_port_bpool_size
-                               [bpool->pp2_id][bpool->id][core_id] -=
-                                                               pkt_to_remove;
+                               [bpool->pp2_id][bpool->id][core_id] -= i;
                }
                rte_spinlock_unlock(&q->priv->lock);
        }
@@ -1740,11 +1850,12 @@ mrvl_prepare_proto_info(uint64_t ol_flags, uint32_t packet_type,
  */
 static inline void
 mrvl_free_sent_buffers(struct pp2_ppio *ppio, struct pp2_hif *hif,
-                      struct mrvl_shadow_txq *sq, int qid, int force)
+                      unsigned int core_id, struct mrvl_shadow_txq *sq,
+                      int qid, int force)
 {
        struct buff_release_entry *entry;
        uint16_t nb_done = 0, num = 0, skip_bufs = 0;
-       int i, core_id = rte_lcore_id();
+       int i;
 
        pp2_ppio_get_num_outq_done(ppio, hif, qid, &nb_done);
 
@@ -1791,6 +1902,7 @@ skip:
                sq->tail = (sq->tail + num) & MRVL_PP2_TX_SHADOWQ_MASK;
                sq->size -= num;
                num = 0;
+               skip_bufs = 0;
        }
 
        if (likely(num)) {
@@ -1817,18 +1929,23 @@ static uint16_t
 mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
        struct mrvl_txq *q = txq;
-       struct mrvl_shadow_txq *sq = &shadow_txqs[q->port_id][rte_lcore_id()];
-       struct pp2_hif *hif = hifs[rte_lcore_id()];
+       struct mrvl_shadow_txq *sq;
+       struct pp2_hif *hif;
        struct pp2_ppio_desc descs[nb_pkts];
+       unsigned int core_id = rte_lcore_id();
        int i, ret, bytes_sent = 0;
        uint16_t num, sq_free_size;
        uint64_t addr;
 
-       if (unlikely(!q->priv->ppio))
+       hif = mrvl_get_hif(q->priv, core_id);
+       sq = &q->shadow_txqs[core_id];
+
+       if (unlikely(!q->priv->ppio || !hif))
                return 0;
 
        if (sq->size)
-               mrvl_free_sent_buffers(q->priv->ppio, hif, sq, q->queue_id, 0);
+               mrvl_free_sent_buffers(q->priv->ppio, hif, core_id,
+                                      sq, q->queue_id, 0);
 
        sq_free_size = MRVL_PP2_TX_SHADOWQ_SIZE - sq->size - 1;
        if (unlikely(nb_pkts > sq_free_size)) {
@@ -2034,6 +2151,7 @@ mrvl_eth_dev_create(struct rte_vdev_device *vdev, const char *name)
 
        eth_dev->rx_pkt_burst = mrvl_rx_pkt_burst;
        eth_dev->tx_pkt_burst = mrvl_tx_pkt_burst;
+       eth_dev->data->kdrv = RTE_KDRV_NONE;
        eth_dev->data->dev_private = priv;
        eth_dev->device = &vdev->device;
        eth_dev->dev_ops = &mrvl_ops;
@@ -2067,6 +2185,7 @@ mrvl_eth_dev_destroy(const char *name)
 
        priv = eth_dev->data->dev_private;
        pp2_bpool_deinit(priv->bpool);
+       used_bpools[priv->pp_id] &= ~(1 << priv->bpool_bit);
        rte_free(priv);
        rte_free(eth_dev->data->mac_addrs);
        rte_eth_dev_release_port(eth_dev);
@@ -2090,41 +2209,9 @@ static int
 mrvl_get_ifnames(const char *key __rte_unused, const char *value,
                 void *extra_args)
 {
-       const char **ifnames = extra_args;
-
-       ifnames[mrvl_ports_nb++] = value;
-
-       return 0;
-}
-
-/**
- * Initialize per-lcore MUSDK hardware interfaces (hifs).
- *
- * @return
- *   0 on success, negative error value otherwise.
- */
-static int
-mrvl_init_hifs(void)
-{
-       struct pp2_hif_params params;
-       char match[MRVL_MATCH_LEN];
-       int i, ret;
-
-       RTE_LCORE_FOREACH(i) {
-               ret = mrvl_reserve_bit(&used_hifs, MRVL_MUSDK_HIFS_MAX);
-               if (ret < 0)
-                       return ret;
+       struct mrvl_ifnames *ifnames = extra_args;
 
-               snprintf(match, sizeof(match), "hif-%d", ret);
-               memset(&params, 0, sizeof(params));
-               params.match = match;
-               params.out_size = MRVL_PP2_AGGR_TXQD_MAX;
-               ret = pp2_hif_init(&params, &hifs[i]);
-               if (ret) {
-                       RTE_LOG(ERR, PMD, "Failed to initialize hif %d\n", i);
-                       return ret;
-               }
-       }
+       ifnames->names[ifnames->idx++] = value;
 
        return 0;
 }
@@ -2137,19 +2224,12 @@ mrvl_deinit_hifs(void)
 {
        int i;
 
-       RTE_LCORE_FOREACH(i) {
+       for (i = mrvl_lcore_first; i <= mrvl_lcore_last; i++) {
                if (hifs[i])
                        pp2_hif_deinit(hifs[i]);
        }
-}
-
-static void mrvl_set_first_last_cores(int core_id)
-{
-       if (core_id < mrvl_lcore_first)
-               mrvl_lcore_first = core_id;
-
-       if (core_id > mrvl_lcore_last)
-               mrvl_lcore_last = core_id;
+       used_hifs = MRVL_MUSDK_HIFS_RESERVED;
+       memset(hifs, 0, sizeof(hifs));
 }
 
 /**
@@ -2165,9 +2245,9 @@ static int
 rte_pmd_mrvl_probe(struct rte_vdev_device *vdev)
 {
        struct rte_kvargs *kvlist;
-       const char *ifnames[PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC];
+       struct mrvl_ifnames ifnames;
        int ret = -EINVAL;
-       uint32_t i, ifnum, cfgnum, core_id;
+       uint32_t i, ifnum, cfgnum;
        const char *params;
 
        params = rte_vdev_device_args(vdev);
@@ -2179,21 +2259,34 @@ rte_pmd_mrvl_probe(struct rte_vdev_device *vdev)
                return -EINVAL;
 
        ifnum = rte_kvargs_count(kvlist, MRVL_IFACE_NAME_ARG);
-       if (ifnum > RTE_DIM(ifnames))
+       if (ifnum > RTE_DIM(ifnames.names))
                goto out_free_kvlist;
 
+       ifnames.idx = 0;
        rte_kvargs_process(kvlist, MRVL_IFACE_NAME_ARG,
                           mrvl_get_ifnames, &ifnames);
 
-       cfgnum = rte_kvargs_count(kvlist, MRVL_CFG_ARG);
-       if (cfgnum > 1) {
-               RTE_LOG(ERR, PMD, "Cannot handle more than one config file!\n");
-               goto out_free_kvlist;
-       } else if (cfgnum == 1) {
-               rte_kvargs_process(kvlist, MRVL_CFG_ARG,
-                                  mrvl_get_qoscfg, &mrvl_qos_cfg);
+
+       /*
+        * The below system initialization should be done only once,
+        * on the first provided configuration file
+        */
+       if (!mrvl_qos_cfg) {
+               cfgnum = rte_kvargs_count(kvlist, MRVL_CFG_ARG);
+               RTE_LOG(INFO, PMD, "Parsing config file!\n");
+               if (cfgnum > 1) {
+                       RTE_LOG(ERR, PMD, "Cannot handle more than one config file!\n");
+                       goto out_free_kvlist;
+               } else if (cfgnum == 1) {
+                       rte_kvargs_process(kvlist, MRVL_CFG_ARG,
+                                          mrvl_get_qoscfg, &mrvl_qos_cfg);
+               }
        }
 
+       if (mrvl_dev_num)
+               goto init_devices;
+
+       RTE_LOG(INFO, PMD, "Perform MUSDK initializations\n");
        /*
         * ret == -EEXIST is correct, it means DMA
         * has been already initialized (by another PMD).
@@ -2213,37 +2306,32 @@ rte_pmd_mrvl_probe(struct rte_vdev_device *vdev)
                goto out_deinit_dma;
        }
 
-       ret = mrvl_init_hifs();
-       if (ret)
-               goto out_deinit_hifs;
+       memset(mrvl_port_bpool_size, 0, sizeof(mrvl_port_bpool_size));
 
+       mrvl_lcore_first = RTE_MAX_LCORE;
+       mrvl_lcore_last = 0;
+
+init_devices:
        for (i = 0; i < ifnum; i++) {
-               RTE_LOG(INFO, PMD, "Creating %s\n", ifnames[i]);
-               ret = mrvl_eth_dev_create(vdev, ifnames[i]);
+               RTE_LOG(INFO, PMD, "Creating %s\n", ifnames.names[i]);
+               ret = mrvl_eth_dev_create(vdev, ifnames.names[i]);
                if (ret)
                        goto out_cleanup;
        }
+       mrvl_dev_num += ifnum;
 
        rte_kvargs_free(kvlist);
 
-       memset(mrvl_port_bpool_size, 0, sizeof(mrvl_port_bpool_size));
-
-       mrvl_lcore_first = RTE_MAX_LCORE;
-       mrvl_lcore_last = 0;
-
-       RTE_LCORE_FOREACH(core_id) {
-               mrvl_set_first_last_cores(core_id);
-       }
-
        return 0;
 out_cleanup:
        for (; i > 0; i--)
-               mrvl_eth_dev_destroy(ifnames[i]);
-out_deinit_hifs:
-       mrvl_deinit_hifs();
-       mrvl_deinit_pp2();
+               mrvl_eth_dev_destroy(ifnames.names[i]);
+
+       if (mrvl_dev_num == 0)
+               mrvl_deinit_pp2();
 out_deinit_dma:
-       mv_sys_dma_mem_destroy();
+       if (mrvl_dev_num == 0)
+               mv_sys_dma_mem_destroy();
 out_free_kvlist:
        rte_kvargs_free(kvlist);
 
@@ -2276,11 +2364,15 @@ rte_pmd_mrvl_remove(struct rte_vdev_device *vdev)
 
                rte_eth_dev_get_name_by_port(i, ifname);
                mrvl_eth_dev_destroy(ifname);
+               mrvl_dev_num--;
        }
 
-       mrvl_deinit_hifs();
-       mrvl_deinit_pp2();
-       mv_sys_dma_mem_destroy();
+       if (mrvl_dev_num == 0) {
+               RTE_LOG(INFO, PMD, "Perform MUSDK deinit\n");
+               mrvl_deinit_hifs();
+               mrvl_deinit_pp2();
+               mv_sys_dma_mem_destroy();
+       }
 
        return 0;
 }
index 2a4ab5a..7764da1 100644 (file)
@@ -110,7 +110,4 @@ struct mrvl_priv {
        uint16_t nb_rx_queues;
 };
 
-/** Number of ports configured. */
-extern int mrvl_ports_nb;
-
 #endif /* _MRVL_ETHDEV_H_ */
index 7c9943a..fbb3681 100644 (file)
@@ -369,7 +369,7 @@ mrvl_get_qoscfg(const char *key __rte_unused, const char *path,
        }
 
        /* Use the number of ports given as vdev parameters. */
-       for (n = 0; n < mrvl_ports_nb; ++n) {
+       for (n = 0; n < (PP2_NUM_ETH_PPIO * PP2_NUM_PKT_PROC); ++n) {
                snprintf(sec_name, sizeof(sec_name), "%s %d %s",
                        MRVL_TOK_PORT, n, MRVL_TOK_DEFAULT);
 
index 0501156..fa8ff3c 100644 (file)
@@ -489,12 +489,10 @@ nfp_net_configure(struct rte_eth_dev *dev)
        }
 
        if (rxmode->jumbo_frame)
-               /* this is handled in rte_eth_dev_configure */
+               hw->mtu = rxmode->max_rx_pkt_len;
 
-       if (rxmode->hw_strip_crc) {
-               PMD_INIT_LOG(INFO, "strip CRC not supported");
-               return -EINVAL;
-       }
+       if (!rxmode->hw_strip_crc)
+               PMD_INIT_LOG(INFO, "HW does strip CRC and it is not configurable");
 
        if (rxmode->enable_scatter) {
                PMD_INIT_LOG(INFO, "Scatter not supported");
@@ -1196,7 +1194,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
        dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
        dev_info->min_rx_bufsize = ETHER_MIN_MTU;
-       dev_info->max_rx_pktlen = hw->mtu;
+       dev_info->max_rx_pktlen = hw->max_mtu;
        /* Next should change when PF support is implemented */
        dev_info->max_mac_addrs = 1;
 
@@ -1469,6 +1467,13 @@ nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        if ((mtu < ETHER_MIN_MTU) || ((uint32_t)mtu > hw->max_mtu))
                return -EINVAL;
 
+       /* mtu setting is forbidden if port is started */
+       if (dev->data->dev_started) {
+               PMD_DRV_LOG(ERR, "port %d must be stopped before configuration",
+                           dev->data->port_id);
+               return -EBUSY;
+       }
+
        /* switch to jumbo mode if needed */
        if ((uint32_t)mtu > ETHER_MAX_LEN)
                dev->data->dev_conf.rxmode.jumbo_frame = 1;
@@ -2774,7 +2779,7 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
        hw->ver = nn_cfg_readl(hw, NFP_NET_CFG_VERSION);
        hw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP);
        hw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU);
-       hw->mtu = hw->max_mtu;
+       hw->mtu = ETHER_MTU;
 
        if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2)
                hw->rx_offset = NFP_NET_RX_OFFSET;
index 032c30e..726a5c5 100644 (file)
@@ -91,7 +91,7 @@ static struct rte_eth_link pmd_link = {
        .link_speed = ETH_SPEED_NUM_10G,
        .link_duplex = ETH_LINK_FULL_DUPLEX,
        .link_status = ETH_LINK_DOWN,
-       .link_autoneg = ETH_LINK_SPEED_AUTONEG,
+       .link_autoneg = ETH_LINK_AUTONEG,
 };
 
 static uint16_t
index bd24ec3..eca3a39 100644 (file)
@@ -54,6 +54,9 @@ struct octeontx_vdev_init_params {
        uint8_t nr_port;
 };
 
+uint16_t
+rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX];
+
 enum octeontx_link_speed {
        OCTEONTX_LINK_SPEED_SGMII,
        OCTEONTX_LINK_SPEED_XAUI,
@@ -572,8 +575,8 @@ octeontx_dev_link_update(struct rte_eth_dev *dev,
                break;
        }
 
-       link.link_duplex = ETH_LINK_AUTONEG;
-       link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
+       link.link_duplex = ETH_LINK_FULL_DUPLEX;
+       link.link_autoneg = ETH_LINK_AUTONEG;
 
        return octeontx_atomic_write_link_status(dev, &link);
 }
@@ -1133,6 +1136,9 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
                                nic->num_tx_queues);
        PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu);
 
+       rte_octeontx_pchan_map[(nic->base_ochan >> 8) & 0x7]
+               [(nic->base_ochan >> 4) & 0xF] = data->port_id;
+
        return data->port_id;
 
 err:
index c47d4c6..d37bb8a 100644 (file)
 #define OCTEONTX_VDEV_NR_PORT_ARG              ("nr_port")
 #define OCTEONTX_MAX_NAME_LEN                  32
 
+#define OCTEONTX_MAX_BGX_PORTS                 4
+#define OCTEONTX_MAX_LMAC_PER_BGX              4
+
 static inline struct octeontx_nic *
 octeontx_pmd_priv(struct rte_eth_dev *dev)
 {
        return dev->data->dev_private;
 }
 
+extern uint16_t
+rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX];
+
 /* Octeontx ethdev nic */
 struct octeontx_nic {
        struct rte_eth_dev *dev;
index a70bd19..40d68c7 100644 (file)
@@ -1,4 +1,7 @@
 DPDK_17.11 {
+       global:
+
+       rte_octeontx_pchan_map;
 
        local: *;
 };
index 5a86752..3385d04 100644 (file)
@@ -124,7 +124,7 @@ static struct rte_eth_link pmd_link = {
                .link_speed = ETH_SPEED_NUM_10G,
                .link_duplex = ETH_LINK_FULL_DUPLEX,
                .link_status = ETH_LINK_DOWN,
-               .link_autoneg = ETH_LINK_SPEED_FIXED,
+               .link_autoneg = ETH_LINK_AUTONEG,
 };
 
 static int
@@ -806,7 +806,7 @@ pmd_init_internals(struct rte_vdev_device *vdev,
        const char *name;
 
        name = rte_vdev_device_name(vdev);
-       RTE_LOG(INFO, PMD, "Creating pcap-backed ethdev on numa socket %u\n",
+       RTE_LOG(INFO, PMD, "Creating pcap-backed ethdev on numa socket %d\n",
                numa_node);
 
        /* now do all data allocation - for eth_dev structure
@@ -1036,7 +1036,7 @@ pmd_pcap_remove(struct rte_vdev_device *dev)
 {
        struct rte_eth_dev *eth_dev = NULL;
 
-       RTE_LOG(INFO, PMD, "Closing pcap ethdev on numa socket %u\n",
+       RTE_LOG(INFO, PMD, "Closing pcap ethdev on numa socket %d\n",
                        rte_socket_id());
 
        if (!dev)
index 632297a..21ddda9 100644 (file)
@@ -216,10 +216,9 @@ ecore_dcbx_get_app_protocol_type(struct ecore_hwfn *p_hwfn,
                *type = DCBX_PROTOCOL_ETH;
        } else {
                *type = DCBX_MAX_PROTOCOL_TYPE;
-               DP_ERR(p_hwfn,
-                      "No action required, App TLV id = 0x%x"
-                      " app_prio_bitmap = 0x%x\n",
-                      id, app_prio_bitmap);
+               DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
+                           "No action required, App TLV entry = 0x%x\n",
+                          app_prio_bitmap);
                return false;
        }
 
index 25109db..e0f2dd5 100644 (file)
@@ -1385,6 +1385,12 @@ ecore_vf_pf_vport_update(struct ecore_hwfn *p_hwfn,
                if (sge_tpa_params->tpa_gro_consistent_flg)
                        p_sge_tpa_tlv->sge_tpa_flags |=
                            VFPF_TPA_GRO_CONSIST_FLAG;
+               if (sge_tpa_params->tpa_ipv4_tunn_en_flg)
+                       p_sge_tpa_tlv->sge_tpa_flags |=
+                           VFPF_TPA_TUNN_IPV4_EN_FLAG;
+               if (sge_tpa_params->tpa_ipv6_tunn_en_flg)
+                       p_sge_tpa_tlv->sge_tpa_flags |=
+                           VFPF_TPA_TUNN_IPV6_EN_FLAG;
 
                p_sge_tpa_tlv->tpa_max_aggs_num =
                    sge_tpa_params->tpa_max_aggs_num;
index 3ccc766..ecb0064 100644 (file)
@@ -424,6 +424,8 @@ struct vfpf_vport_update_sge_tpa_tlv {
        #define VFPF_TPA_PKT_SPLIT_FLAG      (1 << 2)
        #define VFPF_TPA_HDR_DATA_SPLIT_FLAG (1 << 3)
        #define VFPF_TPA_GRO_CONSIST_FLAG    (1 << 4)
+       #define VFPF_TPA_TUNN_IPV4_EN_FLAG   (1 << 5)
+       #define VFPF_TPA_TUNN_IPV6_EN_FLAG   (1 << 6)
 
        u8                      update_sge_tpa_flags;
        #define VFPF_UPDATE_SGE_DEPRECATED_FLAG    (1 << 0)
index 6f5ba2a..73764e9 100644 (file)
@@ -9,6 +9,7 @@
 #include "qede_ethdev.h"
 #include <rte_alarm.h>
 #include <rte_version.h>
+#include <rte_kvargs.h>
 
 /* Globals */
 static const struct qed_eth_ops *qed_ops;
@@ -385,6 +386,62 @@ static void qede_print_adapter_info(struct qede_dev *qdev)
 }
 #endif
 
+static void qede_reset_queue_stats(struct qede_dev *qdev, bool xstats)
+{
+#ifdef RTE_LIBRTE_QEDE_DEBUG_DRIVER
+       struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+#endif
+       unsigned int i = 0, j = 0, qid;
+       unsigned int rxq_stat_cntrs, txq_stat_cntrs;
+       struct qede_tx_queue *txq;
+
+       DP_VERBOSE(edev, ECORE_MSG_DEBUG, "Clearing queue stats\n");
+
+       rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(qdev),
+                              RTE_ETHDEV_QUEUE_STAT_CNTRS);
+       txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(qdev),
+                              RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+       for_each_rss(qid) {
+               OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) +
+                            offsetof(struct qede_rx_queue, rcv_pkts), 0,
+                           sizeof(uint64_t));
+               OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) +
+                            offsetof(struct qede_rx_queue, rx_hw_errors), 0,
+                           sizeof(uint64_t));
+               OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) +
+                            offsetof(struct qede_rx_queue, rx_alloc_errors), 0,
+                           sizeof(uint64_t));
+
+               if (xstats)
+                       for (j = 0; j < RTE_DIM(qede_rxq_xstats_strings); j++)
+                               OSAL_MEMSET((((char *)
+                                             (qdev->fp_array[qid].rxq)) +
+                                            qede_rxq_xstats_strings[j].offset),
+                                           0,
+                                           sizeof(uint64_t));
+
+               i++;
+               if (i == rxq_stat_cntrs)
+                       break;
+       }
+
+       i = 0;
+
+       for_each_tss(qid) {
+               txq = qdev->fp_array[qid].txq;
+
+               OSAL_MEMSET((uint64_t *)(uintptr_t)
+                               (((uint64_t)(uintptr_t)(txq)) +
+                                offsetof(struct qede_tx_queue, xmit_pkts)), 0,
+                           sizeof(uint64_t));
+
+               i++;
+               if (i == txq_stat_cntrs)
+                       break;
+       }
+}
+
 static int
 qede_start_vport(struct qede_dev *qdev, uint16_t mtu)
 {
@@ -410,6 +467,8 @@ qede_start_vport(struct qede_dev *qdev, uint16_t mtu)
                }
        }
        ecore_reset_vport_stats(edev);
+       if (IS_PF(edev))
+               qede_reset_queue_stats(qdev, true);
        DP_INFO(edev, "VPORT started with MTU = %u\n", mtu);
 
        return 0;
@@ -453,13 +512,13 @@ 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;
-#ifndef RTE_LIBRTE_QEDE_VF_TX_SWITCH
-       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) {
+               if (IS_VF(edev)) {
+                       params.update_tx_switching_flg = 1;
+                       params.tx_switching_flg = !flg;
+                       DP_INFO(edev, "VF tx-switching is disabled\n");
+               }
        }
-#endif
        for_each_hwfn(edev, i) {
                p_hwfn = &edev->hwfns[i];
                params.opaque_fid = p_hwfn->hw_info.opaque_fid;
@@ -482,8 +541,8 @@ qede_update_sge_tpa_params(struct ecore_sge_tpa_params *sge_tpa_params,
        /* Enable LRO in split mode */
        sge_tpa_params->tpa_ipv4_en_flg = enable;
        sge_tpa_params->tpa_ipv6_en_flg = enable;
-       sge_tpa_params->tpa_ipv4_tunn_en_flg = false;
-       sge_tpa_params->tpa_ipv6_tunn_en_flg = false;
+       sge_tpa_params->tpa_ipv4_tunn_en_flg = enable;
+       sge_tpa_params->tpa_ipv6_tunn_en_flg = enable;
        /* set if tpa enable changes */
        sge_tpa_params->update_tpa_en_flg = 1;
        /* set if tpa parameters should be handled */
@@ -1208,6 +1267,68 @@ static void qede_dev_stop(struct rte_eth_dev *eth_dev)
        DP_INFO(edev, "Device is stopped\n");
 }
 
+#define QEDE_TX_SWITCHING              "vf_txswitch"
+
+const char *valid_args[] = {
+       QEDE_TX_SWITCHING,
+       NULL,
+};
+
+static int qede_args_check(const char *key, const char *val, void *opaque)
+{
+       unsigned long tmp;
+       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);
+#endif
+
+       errno = 0;
+       tmp = strtoul(val, NULL, 0);
+       if (errno) {
+               DP_INFO(edev, "%s: \"%s\" is not a valid integer", key, val);
+               return errno;
+       }
+
+       if (strcmp(QEDE_TX_SWITCHING, key) == 0)
+               qdev->enable_tx_switching = !!tmp;
+
+       return ret;
+}
+
+static int qede_args(struct rte_eth_dev *eth_dev)
+{
+       struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+       struct rte_kvargs *kvlist;
+       struct rte_devargs *devargs;
+       int ret;
+       int i;
+
+       devargs = pci_dev->device.devargs;
+       if (!devargs)
+               return 0; /* return success */
+
+       kvlist = rte_kvargs_parse(devargs->args, valid_args);
+       if (kvlist == NULL)
+               return -EINVAL;
+
+        /* Process parameters. */
+       for (i = 0; (valid_args[i] != NULL); ++i) {
+               if (rte_kvargs_count(kvlist, valid_args[i])) {
+                       ret = rte_kvargs_process(kvlist, valid_args[i],
+                                                qede_args_check, eth_dev);
+                       if (ret != ECORE_SUCCESS) {
+                               rte_kvargs_free(kvlist);
+                               return ret;
+                       }
+               }
+       }
+       rte_kvargs_free(kvlist);
+
+       return 0;
+}
+
 static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 {
        struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1233,6 +1354,21 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
                }
        }
 
+       /* We need to have min 1 RX queue.There is no min check in
+        * rte_eth_dev_configure(), so we are checking it here.
+        */
+       if (eth_dev->data->nb_rx_queues == 0) {
+               DP_ERR(edev, "Minimum one RX queue is required\n");
+               return -EINVAL;
+       }
+
+       /* Enable Tx switching by default */
+       qdev->enable_tx_switching = 1;
+
+       /* Parse devargs and fix up rxmode */
+       if (qede_args(eth_dev))
+               return -ENOTSUP;
+
        /* Sanity checks and throw warnings */
        if (rxmode->enable_scatter)
                eth_dev->data->scattered_rx = 1;
@@ -1269,18 +1405,24 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
                        return -ENOMEM;
        }
 
+       /* If jumbo enabled adjust MTU */
+       if (eth_dev->data->dev_conf.rxmode.jumbo_frame)
+               eth_dev->data->mtu =
+                               eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
+                               ETHER_HDR_LEN - ETHER_CRC_LEN;
+
        /* VF's MTU has to be set using vport-start where as
         * PF's MTU can be updated via vport-update.
         */
        if (IS_VF(edev)) {
-               if (qede_start_vport(qdev, rxmode->max_rx_pkt_len))
+               if (qede_start_vport(qdev, eth_dev->data->mtu))
                        return -1;
        } else {
-               if (qede_update_mtu(eth_dev, rxmode->max_rx_pkt_len))
+               if (qede_update_mtu(eth_dev, eth_dev->data->mtu))
                        return -1;
        }
 
-       qdev->mtu = rxmode->max_rx_pkt_len;
+       qdev->mtu = eth_dev->data->mtu;
        qdev->new_mtu = qdev->mtu;
 
        /* Enable VLAN offloads by default */
@@ -1733,6 +1875,7 @@ qede_reset_xstats(struct rte_eth_dev *dev)
        struct ecore_dev *edev = &qdev->edev;
 
        ecore_reset_vport_stats(edev);
+       qede_reset_queue_stats(qdev, true);
 }
 
 int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up)
@@ -1768,6 +1911,7 @@ static void qede_reset_stats(struct rte_eth_dev *eth_dev)
        struct ecore_dev *edev = &qdev->edev;
 
        ecore_reset_vport_stats(edev);
+       qede_reset_queue_stats(qdev, false);
 }
 
 static void qede_allmulticast_enable(struct rte_eth_dev *eth_dev)
@@ -2159,16 +2303,23 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
        struct rte_eth_dev_info dev_info = {0};
        struct qede_fastpath *fp;
+       uint32_t max_rx_pkt_len;
        uint32_t frame_size;
        uint16_t rx_buf_size;
        uint16_t bufsz;
+       bool restart = false;
        int i;
 
        PMD_INIT_FUNC_TRACE(edev);
+       if (IS_VF(edev))
+               return -ENOTSUP;
        qede_dev_info_get(dev, &dev_info);
-       frame_size = mtu + QEDE_ETH_OVERHEAD;
+       max_rx_pkt_len = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+       frame_size = max_rx_pkt_len + QEDE_ETH_OVERHEAD;
        if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) {
-               DP_ERR(edev, "MTU %u out of range\n", mtu);
+               DP_ERR(edev, "MTU %u out of range, %u is maximum allowable\n",
+                      mtu, dev_info.max_rx_pktlen - ETHER_HDR_LEN -
+                       ETHER_CRC_LEN - QEDE_ETH_OVERHEAD);
                return -EINVAL;
        }
        if (!dev->data->scattered_rx &&
@@ -2182,29 +2333,39 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
         */
        dev->rx_pkt_burst = qede_rxtx_pkts_dummy;
        dev->tx_pkt_burst = qede_rxtx_pkts_dummy;
-       qede_dev_stop(dev);
+       if (dev->data->dev_started) {
+               dev->data->dev_started = 0;
+               qede_dev_stop(dev);
+               restart = true;
+       }
        rte_delay_ms(1000);
-       qdev->mtu = mtu;
+       qdev->new_mtu = mtu;
        /* Fix up RX buf size for all queues of the port */
        for_each_rss(i) {
                fp = &qdev->fp_array[i];
-               bufsz = (uint16_t)rte_pktmbuf_data_room_size(
-                       fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
-               if (dev->data->scattered_rx)
-                       rx_buf_size = bufsz + QEDE_ETH_OVERHEAD;
-               else
-                       rx_buf_size = mtu + QEDE_ETH_OVERHEAD;
-               rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
-               fp->rxq->rx_buf_size = rx_buf_size;
-               DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size);
+               if (fp->rxq != NULL) {
+                       bufsz = (uint16_t)rte_pktmbuf_data_room_size(
+                               fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+                       if (dev->data->scattered_rx)
+                               rx_buf_size = bufsz + ETHER_HDR_LEN +
+                                             ETHER_CRC_LEN + QEDE_ETH_OVERHEAD;
+                       else
+                               rx_buf_size = frame_size;
+                       rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
+                       fp->rxq->rx_buf_size = rx_buf_size;
+                       DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size);
+               }
        }
-       qede_dev_start(dev);
-       if (frame_size > ETHER_MAX_LEN)
+       if (max_rx_pkt_len > ETHER_MAX_LEN)
                dev->data->dev_conf.rxmode.jumbo_frame = 1;
        else
                dev->data->dev_conf.rxmode.jumbo_frame = 0;
+       if (!dev->data->dev_started && restart) {
+               qede_dev_start(dev);
+               dev->data->dev_started = 1;
+       }
        /* update max frame size */
-       dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+       dev->data->dev_conf.rxmode.max_rx_pkt_len = max_rx_pkt_len;
        /* Reassign back */
        dev->rx_pkt_burst = qede_recv_pkts;
        dev->tx_pkt_burst = qede_xmit_pkts;
index 021de5c..8f21b33 100644 (file)
@@ -185,6 +185,7 @@ struct qede_dev {
        struct qede_fastpath *fp_array;
        uint16_t mtu;
        uint16_t new_mtu;
+       bool enable_tx_switching;
        bool rss_enable;
        struct rte_eth_rss_conf rss_conf;
        uint16_t rss_ind_table[ECORE_RSS_IND_TABLE_SIZE];
index 01a24e5..31132ce 100644 (file)
@@ -84,7 +84,6 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
        rxq->port_id = dev->data->port_id;
 
        max_rx_pkt_len = (uint16_t)rxmode->max_rx_pkt_len;
-       qdev->mtu = max_rx_pkt_len;
 
        /* Fix up RX buffer size */
        bufsz = (uint16_t)rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM;
@@ -97,9 +96,10 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
        }
 
        if (dev->data->scattered_rx)
-               rxq->rx_buf_size = bufsz + QEDE_ETH_OVERHEAD;
+               rxq->rx_buf_size = bufsz + ETHER_HDR_LEN +
+                                  ETHER_CRC_LEN + QEDE_ETH_OVERHEAD;
        else
-               rxq->rx_buf_size = qdev->mtu + QEDE_ETH_OVERHEAD;
+               rxq->rx_buf_size = max_rx_pkt_len + QEDE_ETH_OVERHEAD;
        /* Align to cache-line size if needed */
        rxq->rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rxq->rx_buf_size);
 
@@ -158,7 +158,7 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
        qdev->fp_array[queue_idx].rxq = rxq;
 
        DP_INFO(edev, "rxq %d num_desc %u rx_buf_size=%u socket %u\n",
-                 queue_idx, nb_desc, qdev->mtu, socket_id);
+                 queue_idx, nb_desc, rxq->rx_buf_size, socket_id);
 
        return 0;
 }
@@ -812,12 +812,18 @@ void qede_stop_queues(struct rte_eth_dev *eth_dev)
        }
 }
 
-static bool qede_tunn_exist(uint16_t flag)
+static inline bool qede_tunn_exist(uint16_t flag)
 {
        return !!((PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
                    PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT) & flag);
 }
 
+static inline uint8_t qede_check_tunn_csum_l3(uint16_t flag)
+{
+       return !!((PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_MASK <<
+               PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_SHIFT) & flag);
+}
+
 /*
  * qede_check_tunn_csum_l4:
  * Returns:
@@ -844,33 +850,51 @@ static inline uint8_t qede_check_notunn_csum_l4(uint16_t flag)
        return 0;
 }
 
-/* Returns outer L3 and L4 packet_type for tunneled packets */
+/* Returns outer L2, L3 and L4 packet_type for tunneled packets */
 static inline uint32_t qede_rx_cqe_to_pkt_type_outer(struct rte_mbuf *m)
 {
        uint32_t packet_type = RTE_PTYPE_UNKNOWN;
        struct ether_hdr *eth_hdr;
        struct ipv4_hdr *ipv4_hdr;
        struct ipv6_hdr *ipv6_hdr;
+       struct vlan_hdr *vlan_hdr;
+       uint16_t ethertype;
+       bool vlan_tagged = 0;
+       uint16_t len;
 
        eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
-       if (eth_hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
+       len = sizeof(struct ether_hdr);
+       ethertype = rte_cpu_to_be_16(eth_hdr->ether_type);
+
+        /* Note: Valid only if VLAN stripping is disabled */
+       if (ethertype == ETHER_TYPE_VLAN) {
+               vlan_tagged = 1;
+               vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+               len += sizeof(struct vlan_hdr);
+               ethertype = rte_cpu_to_be_16(vlan_hdr->eth_proto);
+       }
+
+       if (ethertype == ETHER_TYPE_IPv4) {
                packet_type |= RTE_PTYPE_L3_IPV4;
-               ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
-                                                  sizeof(struct ether_hdr));
+               ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, len);
                if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
                        packet_type |= RTE_PTYPE_L4_TCP;
                else if (ipv4_hdr->next_proto_id == IPPROTO_UDP)
                        packet_type |= RTE_PTYPE_L4_UDP;
-       } else if (eth_hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6)) {
+       } else if (ethertype == ETHER_TYPE_IPv6) {
                packet_type |= RTE_PTYPE_L3_IPV6;
-               ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
-                                                  sizeof(struct ether_hdr));
+               ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, len);
                if (ipv6_hdr->proto == IPPROTO_TCP)
                        packet_type |= RTE_PTYPE_L4_TCP;
                else if (ipv6_hdr->proto == IPPROTO_UDP)
                        packet_type |= RTE_PTYPE_L4_UDP;
        }
 
+       if (vlan_tagged)
+               packet_type |= RTE_PTYPE_L2_ETHER_VLAN;
+       else
+               packet_type |= RTE_PTYPE_L2_ETHER;
+
        return packet_type;
 }
 
@@ -1163,17 +1187,17 @@ static inline uint32_t qede_rx_cqe_to_tunn_pkt_type(uint16_t flags)
                [QEDE_PKT_TYPE_TUNN_GRE] = RTE_PTYPE_TUNNEL_GRE,
                [QEDE_PKT_TYPE_TUNN_VXLAN] = RTE_PTYPE_TUNNEL_VXLAN,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GENEVE] =
-                               RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_GENEVE,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_GRE] =
-                               RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_GRE,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_NOEXIST_VXLAN] =
-                               RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_VXLAN,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GENEVE] =
-                               RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_GENEVE,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_GRE] =
-                               RTE_PTYPE_TUNNEL_GRE | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_GRE,
                [QEDE_PKT_TYPE_TUNN_L2_TENID_EXIST_VXLAN] =
-                               RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L2_ETHER,
+                               RTE_PTYPE_TUNNEL_VXLAN,
                [QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GENEVE] =
                                RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L3_IPV4,
                [QEDE_PKT_TYPE_TUNN_IPV4_TENID_NOEXIST_GRE] =
@@ -1253,7 +1277,7 @@ print_rx_bd_info(struct rte_mbuf *m, struct qede_rx_queue *rxq,
                 uint8_t bitfield)
 {
        PMD_RX_LOG(INFO, rxq,
-               "len 0x%x bf 0x%x hash_val 0x%x"
+               "len 0x%04x bf 0x%04x hash_val 0x%x"
                " ol_flags 0x%04lx l2=%s l3=%s l4=%s tunn=%s"
                " inner_l2=%s inner_l3=%s inner_l4=%s\n",
                m->data_len, bitfield, m->hash.rss,
@@ -1402,49 +1426,64 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
                                            parse_flag);
                                rxq->rx_hw_errors++;
                                ol_flags |= PKT_RX_L4_CKSUM_BAD;
-                       } else {
-                               ol_flags |= PKT_RX_L4_CKSUM_GOOD;
-                               if (tpa_start_flg)
-                                       flags =
-                                        cqe_start_tpa->tunnel_pars_flags.flags;
-                               else
-                                       flags = fp_cqe->tunnel_pars_flags.flags;
-                               tunn_parse_flag = flags;
-                               /* Tunnel_type */
-                               packet_type =
-                               qede_rx_cqe_to_tunn_pkt_type(tunn_parse_flag);
-
-                               /* Inner header */
-                               packet_type |=
-                                     qede_rx_cqe_to_pkt_type_inner(parse_flag);
-
-                               /* Outer L3/L4 types is not available in CQE */
-                               packet_type |=
-                                     qede_rx_cqe_to_pkt_type_outer(rx_mb);
-                       }
-               } else {
-                       PMD_RX_LOG(INFO, rxq, "Rx non-tunneled packet\n");
-                       if (unlikely(qede_check_notunn_csum_l4(parse_flag))) {
-                               PMD_RX_LOG(ERR, rxq,
-                                           "L4 csum failed, flags = 0x%x\n",
-                                           parse_flag);
-                               rxq->rx_hw_errors++;
-                               ol_flags |= PKT_RX_L4_CKSUM_BAD;
                        } else {
                                ol_flags |= PKT_RX_L4_CKSUM_GOOD;
                        }
-                       if (unlikely(qede_check_notunn_csum_l3(rx_mb,
-                                                       parse_flag))) {
+
+                       if (unlikely(qede_check_tunn_csum_l3(parse_flag))) {
                                PMD_RX_LOG(ERR, rxq,
-                                          "IP csum failed, flags = 0x%x\n",
-                                          parse_flag);
-                               rxq->rx_hw_errors++;
-                               ol_flags |= PKT_RX_IP_CKSUM_BAD;
+                                       "Outer L3 csum failed, flags = 0x%x\n",
+                                       parse_flag);
+                                 rxq->rx_hw_errors++;
+                                 ol_flags |= PKT_RX_EIP_CKSUM_BAD;
                        } else {
-                               ol_flags |= PKT_RX_IP_CKSUM_GOOD;
-                               packet_type =
-                                       qede_rx_cqe_to_pkt_type(parse_flag);
+                                 ol_flags |= PKT_RX_IP_CKSUM_GOOD;
                        }
+
+                       if (tpa_start_flg)
+                               flags = cqe_start_tpa->tunnel_pars_flags.flags;
+                       else
+                               flags = fp_cqe->tunnel_pars_flags.flags;
+                       tunn_parse_flag = flags;
+
+                       /* Tunnel_type */
+                       packet_type =
+                               qede_rx_cqe_to_tunn_pkt_type(tunn_parse_flag);
+
+                       /* Inner header */
+                       packet_type |=
+                             qede_rx_cqe_to_pkt_type_inner(parse_flag);
+
+                       /* Outer L3/L4 types is not available in CQE */
+                       packet_type |= qede_rx_cqe_to_pkt_type_outer(rx_mb);
+
+                       /* Outer L3/L4 types is not available in CQE.
+                        * Need to add offset to parse correctly,
+                        */
+                       rx_mb->data_off = offset + RTE_PKTMBUF_HEADROOM;
+                       packet_type |= qede_rx_cqe_to_pkt_type_outer(rx_mb);
+               }
+
+               /* Common handling for non-tunnel packets and for inner
+                * headers in the case of tunnel.
+                */
+               if (unlikely(qede_check_notunn_csum_l4(parse_flag))) {
+                       PMD_RX_LOG(ERR, rxq,
+                                   "L4 csum failed, flags = 0x%x\n",
+                                   parse_flag);
+                       rxq->rx_hw_errors++;
+                       ol_flags |= PKT_RX_L4_CKSUM_BAD;
+               } else {
+                       ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+               }
+               if (unlikely(qede_check_notunn_csum_l3(rx_mb, parse_flag))) {
+                       PMD_RX_LOG(ERR, rxq, "IP csum failed, flags = 0x%x\n",
+                                  parse_flag);
+                       rxq->rx_hw_errors++;
+                       ol_flags |= PKT_RX_IP_CKSUM_BAD;
+               } else {
+                       ol_flags |= PKT_RX_IP_CKSUM_GOOD;
+                       packet_type |= qede_rx_cqe_to_pkt_type(parse_flag);
                }
 
                if (CQE_HAS_VLAN(parse_flag) ||
@@ -1549,7 +1588,8 @@ next_cqe:
 /* Populate scatter gather buffer descriptor fields */
 static inline uint16_t
 qede_encode_sg_bd(struct qede_tx_queue *p_txq, struct rte_mbuf *m_seg,
-                 struct eth_tx_2nd_bd **bd2, struct eth_tx_3rd_bd **bd3)
+                 struct eth_tx_2nd_bd **bd2, struct eth_tx_3rd_bd **bd3,
+                 uint16_t start_seg)
 {
        struct qede_tx_queue *txq = p_txq;
        struct eth_tx_bd *tx_bd = NULL;
@@ -1558,7 +1598,7 @@ qede_encode_sg_bd(struct qede_tx_queue *p_txq, struct rte_mbuf *m_seg,
 
        /* Check for scattered buffers */
        while (m_seg) {
-               if (nb_segs == 0) {
+               if (start_seg == 0) {
                        if (!*bd2) {
                                *bd2 = (struct eth_tx_2nd_bd *)
                                        ecore_chain_produce(&txq->tx_pbl);
@@ -1568,7 +1608,7 @@ qede_encode_sg_bd(struct qede_tx_queue *p_txq, struct rte_mbuf *m_seg,
                        mapping = rte_mbuf_data_iova(m_seg);
                        QEDE_BD_SET_ADDR_LEN(*bd2, mapping, m_seg->data_len);
                        PMD_TX_LOG(DEBUG, txq, "BD2 len %04x", m_seg->data_len);
-               } else if (nb_segs == 1) {
+               } else if (start_seg == 1) {
                        if (!*bd3) {
                                *bd3 = (struct eth_tx_3rd_bd *)
                                        ecore_chain_produce(&txq->tx_pbl);
@@ -1606,20 +1646,24 @@ print_tx_bd_info(struct qede_tx_queue *txq,
 
        if (bd1)
                PMD_TX_LOG(INFO, txq,
-                          "BD1: nbytes=%u nbds=%u bd_flags=%04x bf=%04x",
-                          rte_cpu_to_le_16(bd1->nbytes), bd1->data.nbds,
-                          bd1->data.bd_flags.bitfields,
-                          rte_cpu_to_le_16(bd1->data.bitfields));
+                  "BD1: nbytes=0x%04x nbds=0x%04x bd_flags=0x%04x bf=0x%04x",
+                  rte_cpu_to_le_16(bd1->nbytes), bd1->data.nbds,
+                  bd1->data.bd_flags.bitfields,
+                  rte_cpu_to_le_16(bd1->data.bitfields));
        if (bd2)
                PMD_TX_LOG(INFO, txq,
-                          "BD2: nbytes=%u bf=%04x\n",
-                          rte_cpu_to_le_16(bd2->nbytes), bd2->data.bitfields1);
+                  "BD2: nbytes=0x%04x bf1=0x%04x bf2=0x%04x tunn_ip=0x%04x\n",
+                  rte_cpu_to_le_16(bd2->nbytes), bd2->data.bitfields1,
+                  bd2->data.bitfields2, bd2->data.tunn_ip_size);
        if (bd3)
                PMD_TX_LOG(INFO, txq,
-                          "BD3: nbytes=%u bf=%04x mss=%u\n",
-                          rte_cpu_to_le_16(bd3->nbytes),
-                          rte_cpu_to_le_16(bd3->data.bitfields),
-                          rte_cpu_to_le_16(bd3->data.lso_mss));
+                  "BD3: nbytes=0x%04x bf=0x%04x MSS=0x%04x "
+                  "tunn_l4_hdr_start_offset_w=0x%04x tunn_hdr_size=0x%04x\n",
+                  rte_cpu_to_le_16(bd3->nbytes),
+                  rte_cpu_to_le_16(bd3->data.bitfields),
+                  rte_cpu_to_le_16(bd3->data.lso_mss),
+                  bd3->data.tunn_l4_hdr_start_offset_w,
+                  bd3->data.tunn_hdr_size_w);
 
        rte_get_tx_ol_flag_list(tx_ol_flags, ol_buf, sizeof(ol_buf));
        PMD_TX_LOG(INFO, txq, "TX offloads = %s\n", ol_buf);
@@ -1897,6 +1941,10 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                         * and BD2 onwards for data.
                         */
                        hdr_size = mbuf->l2_len + mbuf->l3_len + mbuf->l4_len;
+                       if (tunn_flg)
+                               hdr_size += mbuf->outer_l2_len +
+                                           mbuf->outer_l3_len;
+
                        bd1_bd_flags_bf |= 1 << ETH_TX_1ST_BD_FLAGS_LSO_SHIFT;
                        bd1_bd_flags_bf |=
                                        1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT;
@@ -2013,9 +2061,11 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
                /* Handle fragmented MBUF */
                m_seg = mbuf->next;
+
                /* Encode scatter gather buffer descriptors if required */
-               nb_frags = qede_encode_sg_bd(txq, m_seg, &bd2, &bd3);
+               nb_frags = qede_encode_sg_bd(txq, m_seg, &bd2, &bd3, nbds - 1);
                bd1->data.nbds = nbds + nb_frags;
+
                txq->nb_tx_avail -= bd1->data.nbds;
                txq->sw_tx_prod++;
                rte_prefetch0(txq->sw_tx_ring[TX_PROD(txq)].mbuf);
@@ -2023,7 +2073,6 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
                    rte_cpu_to_le_16(ecore_chain_get_prod_idx(&txq->tx_pbl));
 #ifdef RTE_LIBRTE_QEDE_DEBUG_TX
                print_tx_bd_info(txq, bd1, bd2, bd3, tx_ol_flags);
-               PMD_TX_LOG(INFO, txq, "lso=%d tunn=%d", lso_flg, tunn_flg);
 #endif
                nb_pkt_sent++;
                txq->xmit_pkts++;
index acf9e47..ae88206 100644 (file)
@@ -64,7 +64,7 @@
 #define QEDE_CEIL_TO_CACHE_LINE_SIZE(n) (((n) + (QEDE_FW_RX_ALIGN_END - 1)) & \
                                        ~(QEDE_FW_RX_ALIGN_END - 1))
 /* Note: QEDE_LLC_SNAP_HDR_LEN is optional */
-#define QEDE_ETH_OVERHEAD      ((ETHER_HDR_LEN) + ((2 * QEDE_VLAN_TAG_SIZE)) \
+#define QEDE_ETH_OVERHEAD      (((2 * QEDE_VLAN_TAG_SIZE)) - (ETHER_CRC_LEN) \
                                + (QEDE_LLC_SNAP_HDR_LEN))
 
 #define QEDE_RSS_OFFLOAD_ALL    (ETH_RSS_IPV4                  |\
index a73c631..8583a67 100644 (file)
@@ -89,7 +89,7 @@ static struct rte_eth_link pmd_link = {
                .link_speed = ETH_SPEED_NUM_10G,
                .link_duplex = ETH_LINK_FULL_DUPLEX,
                .link_status = ETH_LINK_DOWN,
-               .link_autoneg = ETH_LINK_SPEED_AUTONEG
+               .link_autoneg = ETH_LINK_AUTONEG
 };
 
 static uint16_t
index 7f11bf2..ef980a4 100644 (file)
@@ -158,6 +158,8 @@ struct sfc_port {
        boolean_t                       promisc;
        boolean_t                       allmulti;
 
+       struct ether_addr               default_mac_addr;
+
        unsigned int                    max_mcast_addrs;
        unsigned int                    nb_mcast_addrs;
        uint8_t                         *mcast_addrs;
@@ -210,7 +212,29 @@ struct sfc_adapter {
        unsigned int                    evq_count;
 
        unsigned int                    mgmt_evq_index;
+       /*
+        * The lock is used to serialise management event queue polling
+        * which can be done from different context. Also the lock
+        * guarantees that mgmt_evq_running is preserved while the lock
+        * is held. It is used to serialise polling and start/stop
+        * operations.
+        *
+        * Locks which may be held when the lock is acquired:
+        *  - adapter lock, when:
+        *    - device start/stop to change mgmt_evq_running
+        *    - any control operations in client side MCDI proxy handling to
+        *      poll management event queue waiting for proxy response
+        *  - MCDI lock, when:
+        *    - any control operations in client side MCDI proxy handling to
+        *      poll management event queue waiting for proxy response
+        *
+        * Locks which are acquired with the lock held:
+        *  - nic_lock, when:
+        *    - MC event processing on management event queue polling
+        *      (e.g. MC REBOOT or BADASSERT events)
+        */
        rte_spinlock_t                  mgmt_evq_lock;
+       bool                            mgmt_evq_running;
        struct sfc_evq                  *mgmt_evq;
 
        unsigned int                    rxq_count;
index 18d60c6..4c76f74 100644 (file)
@@ -286,10 +286,10 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
                         PKT_RX_IP_CKSUM_BAD : PKT_RX_IP_CKSUM_GOOD);
                break;
        case ESE_DZ_L3_CLASS_IP6_FRAG:
-               l4_ptype |= RTE_PTYPE_L4_FRAG;
+               l4_ptype = RTE_PTYPE_L4_FRAG;
                /* FALLTHROUGH */
        case ESE_DZ_L3_CLASS_IP6:
-               l3_ptype |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+               l3_ptype = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
                ol_flags |= PKT_RX_RSS_HASH;
                break;
        case ESE_DZ_L3_CLASS_ARP:
index 2f5f86f..fabcc32 100644 (file)
@@ -926,6 +926,12 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 
        sfc_adapter_lock(sa);
 
+       /*
+        * Copy the address to the device private data so that
+        * it could be recalled in the case of adapter restart.
+        */
+       ether_addr_copy(mac_addr, &port->default_mac_addr);
+
        if (port->isolated) {
                sfc_err(sa, "isolated mode is active on the port");
                sfc_err(sa, "will not set MAC address");
@@ -961,9 +967,9 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 
                /*
                 * Since setting MAC address with filters installed is not
-                * allowed on the adapter, one needs to simply restart adapter
-                * so that the new MAC address will be taken from an outer
-                * storage and set flawlessly by means of sfc_start() call
+                * allowed on the adapter, the new MAC address will be set
+                * by means of adapter restart. sfc_start() shall retrieve
+                * the new address from the device private data and set it.
                 */
                sfc_stop(sa);
                rc = sfc_start(sa);
@@ -972,6 +978,13 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
        }
 
 unlock:
+       /*
+        * In the case of failure sa->port->default_mac_addr does not
+        * need rollback since no error code is returned, and the upper
+        * API will anyway update the external MAC address storage.
+        * To be consistent with that new value it is better to keep
+        * the device private value the same.
+        */
        sfc_adapter_unlock(sa);
 }
 
index a16dc27..5fbebbf 100644 (file)
@@ -565,10 +565,8 @@ void
 sfc_ev_mgmt_qpoll(struct sfc_adapter *sa)
 {
        if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) {
-               struct sfc_evq *mgmt_evq = sa->mgmt_evq;
-
-               if (mgmt_evq->init_state == SFC_EVQ_STARTED)
-                       sfc_ev_qpoll(mgmt_evq);
+               if (sa->mgmt_evq_running)
+                       sfc_ev_qpoll(sa->mgmt_evq);
 
                rte_spinlock_unlock(&sa->mgmt_evq_lock);
        }
@@ -734,20 +732,26 @@ sfc_ev_start(struct sfc_adapter *sa)
                goto fail_ev_init;
 
        /* Start management EVQ used for global events */
-       rte_spinlock_lock(&sa->mgmt_evq_lock);
 
+       /*
+        * Management event queue start polls the queue, but it cannot
+        * interfere with other polling contexts since mgmt_evq_running
+        * is false yet.
+        */
        rc = sfc_ev_qstart(sa->mgmt_evq, sa->mgmt_evq_index);
        if (rc != 0)
                goto fail_mgmt_evq_start;
 
+       rte_spinlock_lock(&sa->mgmt_evq_lock);
+       sa->mgmt_evq_running = true;
+       rte_spinlock_unlock(&sa->mgmt_evq_lock);
+
        if (sa->intr.lsc_intr) {
                rc = sfc_ev_qprime(sa->mgmt_evq);
                if (rc != 0)
-                       goto fail_evq0_prime;
+                       goto fail_mgmt_evq_prime;
        }
 
-       rte_spinlock_unlock(&sa->mgmt_evq_lock);
-
        /*
         * Start management EVQ polling. If interrupts are disabled
         * (not used), it is required to process link status change
@@ -763,11 +767,10 @@ sfc_ev_start(struct sfc_adapter *sa)
 
        return 0;
 
-fail_evq0_prime:
+fail_mgmt_evq_prime:
        sfc_ev_qstop(sa->mgmt_evq);
 
 fail_mgmt_evq_start:
-       rte_spinlock_unlock(&sa->mgmt_evq_lock);
        efx_ev_fini(sa->nic);
 
 fail_ev_init:
@@ -783,9 +786,11 @@ sfc_ev_stop(struct sfc_adapter *sa)
        sfc_ev_mgmt_periodic_qpoll_stop(sa);
 
        rte_spinlock_lock(&sa->mgmt_evq_lock);
-       sfc_ev_qstop(sa->mgmt_evq);
+       sa->mgmt_evq_running = false;
        rte_spinlock_unlock(&sa->mgmt_evq_lock);
 
+       sfc_ev_qstop(sa->mgmt_evq);
+
        efx_ev_fini(sa->nic);
 }
 
index f2050f6..e770b98 100644 (file)
@@ -1021,7 +1021,7 @@ fail_scale_tbl_set:
 fail_filter_insert:
 fail_scale_key_set:
 fail_scale_mode_set:
-       if (rss != NULL)
+       if (flow->rss)
                efx_rx_scale_context_free(sa->nic, spec->efs_rss_context);
 
 fail_scale_context_alloc:
@@ -1126,8 +1126,6 @@ sfc_flow_parse(struct rte_eth_dev *dev,
        struct sfc_adapter *sa = dev->data->dev_private;
        int rc;
 
-       memset(&flow->spec, 0, sizeof(flow->spec));
-
        rc = sfc_flow_parse_attr(attr, flow, error);
        if (rc != 0)
                goto fail_bad_value;
@@ -1160,6 +1158,8 @@ sfc_flow_validate(struct rte_eth_dev *dev,
 {
        struct rte_flow flow;
 
+       memset(&flow, 0, sizeof(flow));
+
        return sfc_flow_parse(dev, attr, pattern, actions, &flow, error);
 }
 
index ee59cb1..de65f8c 100644 (file)
@@ -57,8 +57,9 @@ sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
 
        evq = sa->mgmt_evq;
 
-       if (evq->init_state != SFC_EVQ_STARTED) {
-               sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
+       if (!sa->mgmt_evq_running) {
+               sfc_log_init(sa, "interrupt on not running management EVQ %u",
+                            evq->evq_index);
        } else {
                sfc_ev_qpoll(evq);
 
index c1466a7..5254394 100644 (file)
@@ -188,10 +188,10 @@ sfc_port_start(struct sfc_adapter *sa)
                goto fail_mac_pdu_set;
 
        if (!port->isolated) {
-               struct ether_addr *mac_addrs = sa->eth_dev->data->mac_addrs;
+               struct ether_addr *addr = &port->default_mac_addr;
 
                sfc_log_init(sa, "set MAC address");
-               rc = efx_mac_addr_set(sa->nic, mac_addrs[0].addr_bytes);
+               rc = efx_mac_addr_set(sa->nic, addr->addr_bytes);
                if (rc != 0)
                        goto fail_mac_addr_set;
 
@@ -279,10 +279,10 @@ fail_port_init_dev_link:
        (void)efx_mac_drain(sa->nic, B_TRUE);
 
 fail_mac_drain:
+fail_mac_stats_upload:
        (void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
                                     0, B_FALSE);
 
-fail_mac_stats_upload:
 fail_mac_stats_periodic:
 fail_mcast_address_list_set:
 fail_mac_filter_set:
@@ -342,6 +342,8 @@ int
 sfc_port_attach(struct sfc_adapter *sa)
 {
        struct sfc_port *port = &sa->port;
+       const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+       const struct ether_addr *from;
        long kvarg_stats_update_period_ms;
        int rc;
 
@@ -353,6 +355,10 @@ sfc_port_attach(struct sfc_adapter *sa)
        port->flow_ctrl = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
        port->flow_ctrl_autoneg = B_TRUE;
 
+       RTE_BUILD_BUG_ON(sizeof(encp->enc_mac_addr) != sizeof(*from));
+       from = (const struct ether_addr *)(encp->enc_mac_addr);
+       ether_addr_copy(from, &port->default_mac_addr);
+
        port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX;
        port->nb_mcast_addrs = 0;
        port->mcast_addrs = rte_calloc_socket("mcast_addr_list_buf",
@@ -404,9 +410,14 @@ sfc_port_attach(struct sfc_adapter *sa)
        return 0;
 
 fail_kvarg_stats_update_period_ms:
+       sfc_dma_free(sa, &port->mac_stats_dma_mem);
+
 fail_mac_stats_dma_alloc:
        rte_free(port->mac_stats_buf);
+
 fail_mac_stats_buf_alloc:
+       rte_free(port->mcast_addrs);
+
 fail_mcast_addr_list_buf_alloc:
        sfc_log_init(sa, "failed %d", rc);
        return rc;
@@ -422,6 +433,8 @@ sfc_port_detach(struct sfc_adapter *sa)
        sfc_dma_free(sa, &port->mac_stats_dma_mem);
        rte_free(port->mac_stats_buf);
 
+       rte_free(port->mcast_addrs);
+
        sfc_log_init(sa, "done");
 }
 
index 3e47c2f..c8f918d 100644 (file)
@@ -551,7 +551,7 @@ pmd_ethdev_register(struct rte_vdev_device *vdev,
        soft_dev->data->dev_private = dev_private;
        soft_dev->data->dev_link.link_speed = hard_speed;
        soft_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-       soft_dev->data->dev_link.link_autoneg = ETH_LINK_SPEED_FIXED;
+       soft_dev->data->dev_link.link_autoneg = ETH_LINK_AUTONEG;
        soft_dev->data->dev_link.link_status = ETH_LINK_DOWN;
        soft_dev->data->mac_addrs = &eth_addr;
        soft_dev->data->promiscuous = 1;
index 74f151c..45aebed 100644 (file)
@@ -1214,7 +1214,7 @@ eth_link_update(struct rte_eth_dev *dev,
 
        link.link_status = (link_is_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
-       link.link_autoneg = ETH_LINK_SPEED_FIXED;
+       link.link_autoneg = ETH_LINK_FIXED;
 
        rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
                        *(uint64_t *)link_ptr);
@@ -1553,7 +1553,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
                        pci_dev->mem_resource[PCI_RESOURCE_NUMBER].len,
                        PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        close(fd);
-       if (pci_resource_ptr == NULL) {
+       if (pci_resource_ptr == MAP_FAILED) {
                RTE_LOG(ERR, PMD, "Could not mmap file %s (fd = %d)\n",
                                rsc_filename, fd);
                return -EINVAL;
index 6b27679..b8187f9 100644 (file)
@@ -60,7 +60,6 @@
 #include <net/if.h>
 #include <linux/if_tun.h>
 #include <linux/if_ether.h>
-#include <linux/version.h>
 #include <fcntl.h>
 
 #include <rte_eth_tap.h>
@@ -78,9 +77,6 @@
 #define ETH_TAP_MAC_ARG         "mac"
 #define ETH_TAP_MAC_FIXED       "fixed"
 
-#define FLOWER_KERNEL_VERSION KERNEL_VERSION(4, 2, 0)
-#define FLOWER_VLAN_KERNEL_VERSION KERNEL_VERSION(4, 9, 0)
-
 static struct rte_vdev_driver pmd_tap_drv;
 
 static const char *valid_arguments[] = {
@@ -99,7 +95,7 @@ static struct rte_eth_link pmd_link = {
        .link_speed = ETH_SPEED_NUM_10G,
        .link_duplex = ETH_LINK_FULL_DUPLEX,
        .link_status = ETH_LINK_DOWN,
-       .link_autoneg = ETH_LINK_SPEED_AUTONEG
+       .link_autoneg = ETH_LINK_AUTONEG
 };
 
 static void
@@ -1244,13 +1240,13 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
        data = rte_zmalloc_socket(tap_name, sizeof(*data), 0, numa_node);
        if (!data) {
                RTE_LOG(ERR, PMD, "TAP Failed to allocate data\n");
-               goto error_exit;
+               goto error_exit_nodev;
        }
 
        dev = rte_eth_vdev_allocate(vdev, sizeof(*pmd));
        if (!dev) {
                RTE_LOG(ERR, PMD, "TAP Unable to allocate device struct\n");
-               goto error_exit;
+               goto error_exit_nodev;
        }
 
        pmd = dev->data->dev_private;
@@ -1420,6 +1416,11 @@ error_remote:
        tap_flow_implicit_flush(pmd, NULL);
 
 error_exit:
+       if (pmd->ioctl_sock > 0)
+               close(pmd->ioctl_sock);
+       rte_eth_dev_release_port(dev);
+
+error_exit_nodev:
        RTE_LOG(ERR, PMD, "TAP Unable to initialize %s\n",
                rte_vdev_device_name(vdev));
 
index d65d3ce..c62371c 100644 (file)
@@ -100,7 +100,7 @@ nicvf_set_eth_link_status(struct nicvf *nic, struct rte_eth_link *link)
        else if (nic->duplex == NICVF_FULL_DUPLEX)
                link->link_duplex = ETH_LINK_FULL_DUPLEX;
        link->link_speed = nic->speed;
-       link->link_autoneg = ETH_LINK_SPEED_AUTONEG;
+       link->link_autoneg = ETH_LINK_AUTONEG;
 }
 
 static void
index e27776e..9d69cf4 100644 (file)
@@ -252,7 +252,7 @@ nicvf_xmit_pkts_multiseg(void *tx_queue, struct rte_mbuf **tx_pkts,
 
        /* Inform HW to xmit the packets */
        nicvf_addr_write(sq->sq_door, used_desc);
-       return nb_pkts;
+       return i;
 }
 
 static const uint32_t ptype_table[16][16] __rte_cache_aligned = {
index e0328f6..4da1ba3 100644 (file)
@@ -294,17 +294,6 @@ virtio_dev_queue_release(void *queue __rte_unused)
        /* do nothing */
 }
 
-static int
-virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)
-{
-       if (vtpci_queue_idx == hw->max_queue_pairs * 2)
-               return VTNET_CQ;
-       else if (vtpci_queue_idx % 2 == 0)
-               return VTNET_RQ;
-       else
-               return VTNET_TQ;
-}
-
 static uint16_t
 virtio_get_nr_vq(struct virtio_hw *hw)
 {
@@ -893,7 +882,7 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev,
                /* Note: limit checked in rte_eth_xstats_names() */
 
                for (i = 0; i < dev->data->nb_rx_queues; i++) {
-                       struct virtqueue *rxvq = dev->data->rx_queues[i];
+                       struct virtnet_rx *rxvq = dev->data->rx_queues[i];
                        if (rxvq == NULL)
                                continue;
                        for (t = 0; t < VIRTIO_NB_RXQ_XSTATS; t++) {
@@ -906,7 +895,7 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev,
                }
 
                for (i = 0; i < dev->data->nb_tx_queues; i++) {
-                       struct virtqueue *txvq = dev->data->tx_queues[i];
+                       struct virtnet_tx *txvq = dev->data->tx_queues[i];
                        if (txvq == NULL)
                                continue;
                        for (t = 0; t < VIRTIO_NB_TXQ_XSTATS; t++) {
@@ -1405,6 +1394,11 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
        /* Reset the device although not necessary at startup */
        vtpci_reset(hw);
 
+       if (hw->vqs) {
+               virtio_dev_free_mbufs(eth_dev);
+               virtio_free_queues(hw);
+       }
+
        /* Tell the host we've noticed this device. */
        vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
 
@@ -1754,7 +1748,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 
        if (rxmode->enable_lro &&
                (!vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
-                       !vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4))) {
+                !vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6))) {
                PMD_DRV_LOG(ERR,
                        "Large Receive Offload not available on this host");
                return -ENOTSUP;
@@ -1784,7 +1778,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
        hw->use_simple_rx = 1;
        hw->use_simple_tx = 1;
 
-#if defined RTE_ARCH_ARM64 || defined CONFIG_RTE_ARCH_ARM
+#if defined RTE_ARCH_ARM64 || defined RTE_ARCH_ARM
        if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
                hw->use_simple_rx = 0;
                hw->use_simple_tx = 0;
@@ -1860,7 +1854,7 @@ virtio_dev_start(struct rte_eth_dev *dev)
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
                rxvq = dev->data->rx_queues[i];
                /* Flush the old packets */
-               virtqueue_flush(rxvq->vq);
+               virtqueue_rxvq_flush(rxvq->vq);
                virtqueue_notify(rxvq->vq);
        }
 
@@ -1898,6 +1892,9 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
                struct virtnet_rx *rxvq = dev->data->rx_queues[i];
 
+               if (rxvq == NULL || rxvq->vq == NULL)
+                       continue;
+
                PMD_INIT_LOG(DEBUG,
                             "Before freeing rxq[%d] used and unused buf", i);
                VIRTQUEUE_DUMP(rxvq->vq);
@@ -1917,6 +1914,9 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
        for (i = 0; i < dev->data->nb_tx_queues; i++) {
                struct virtnet_tx *txvq = dev->data->tx_queues[i];
 
+               if (txvq == NULL || txvq->vq == NULL)
+                       continue;
+
                PMD_INIT_LOG(DEBUG,
                             "Before freeing txq[%d] used and unused bufs",
                             i);
index 906d7a2..7ce512c 100644 (file)
@@ -171,6 +171,11 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
        for (i = 0; i < dev->max_queue_pairs; ++i)
                dev->ops->enable_qp(dev, i, 0);
 
+       if (dev->ops->send_request(dev, VHOST_USER_RESET_OWNER, NULL) < 0) {
+               PMD_DRV_LOG(INFO, "Failed to reset the device\n");
+               return -1;
+       }
+
        return 0;
 }
 
index c3a536f..7f5e996 100644 (file)
@@ -37,6 +37,7 @@
 #include "virtqueue.h"
 #include "virtio_logs.h"
 #include "virtio_pci.h"
+#include "virtio_rxtx_simple.h"
 
 /*
  * Two types of mbuf to be cleaned:
@@ -47,23 +48,47 @@ struct rte_mbuf *
 virtqueue_detatch_unused(struct virtqueue *vq)
 {
        struct rte_mbuf *cookie;
-       int idx;
+       struct virtio_hw *hw;
+       uint16_t start, end;
+       int type, idx;
 
-       if (vq != NULL)
-               for (idx = 0; idx < vq->vq_nentries; idx++) {
+       if (vq == NULL)
+               return NULL;
+
+       hw = vq->hw;
+       type = virtio_get_queue_type(hw, vq->vq_queue_index);
+       start = vq->vq_avail_idx & (vq->vq_nentries - 1);
+       end = (vq->vq_avail_idx + vq->vq_free_cnt) & (vq->vq_nentries - 1);
+
+       for (idx = 0; idx < vq->vq_nentries; idx++) {
+               if (hw->use_simple_rx && type == VTNET_RQ) {
+                       if (start <= end && idx >= start && idx < end)
+                               continue;
+                       if (start > end && (idx >= start || idx < end))
+                               continue;
+                       cookie = vq->sw_ring[idx];
+                       if (cookie != NULL) {
+                               vq->sw_ring[idx] = NULL;
+                               return cookie;
+                       }
+               } else {
                        cookie = vq->vq_descx[idx].cookie;
                        if (cookie != NULL) {
                                vq->vq_descx[idx].cookie = NULL;
                                return cookie;
                        }
                }
+       }
+
        return NULL;
 }
 
 /* Flush the elements in the used ring. */
 void
-virtqueue_flush(struct virtqueue *vq)
+virtqueue_rxvq_flush(struct virtqueue *vq)
 {
+       struct virtnet_rx *rxq = &vq->rxq;
+       struct virtio_hw *hw = vq->hw;
        struct vring_used_elem *uep;
        struct vq_desc_extra *dxp;
        uint16_t used_idx, desc_idx;
@@ -74,13 +99,27 @@ virtqueue_flush(struct virtqueue *vq)
        for (i = 0; i < nb_used; i++) {
                used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1);
                uep = &vq->vq_ring.used->ring[used_idx];
-               desc_idx = (uint16_t)uep->id;
-               dxp = &vq->vq_descx[desc_idx];
-               if (dxp->cookie != NULL) {
-                       rte_pktmbuf_free(dxp->cookie);
-                       dxp->cookie = NULL;
+               if (hw->use_simple_rx) {
+                       desc_idx = used_idx;
+                       rte_pktmbuf_free(vq->sw_ring[desc_idx]);
+                       vq->vq_free_cnt++;
+               } else {
+                       desc_idx = (uint16_t)uep->id;
+                       dxp = &vq->vq_descx[desc_idx];
+                       if (dxp->cookie != NULL) {
+                               rte_pktmbuf_free(dxp->cookie);
+                               dxp->cookie = NULL;
+                       }
+                       vq_ring_free_chain(vq, desc_idx);
                }
                vq->vq_used_cons_idx++;
-               vq_ring_free_chain(vq, desc_idx);
+       }
+
+       if (hw->use_simple_rx) {
+               while (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) {
+                       virtio_rxq_rearm_vec(rxq);
+                       if (virtqueue_kick_prepare(vq))
+                               virtqueue_notify(vq);
+               }
        }
 }
index 2305d91..788d04d 100644 (file)
@@ -304,7 +304,7 @@ void virtqueue_dump(struct virtqueue *vq);
 struct rte_mbuf *virtqueue_detatch_unused(struct virtqueue *vq);
 
 /* Flush the elements in the used ring. */
-void virtqueue_flush(struct virtqueue *vq);
+void virtqueue_rxvq_flush(struct virtqueue *vq);
 
 static inline int
 virtqueue_full(const struct virtqueue *vq)
@@ -312,6 +312,17 @@ virtqueue_full(const struct virtqueue *vq)
        return vq->vq_free_cnt == 0;
 }
 
+static inline int
+virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)
+{
+       if (vtpci_queue_idx == hw->max_queue_pairs * 2)
+               return VTNET_CQ;
+       else if (vtpci_queue_idx % 2 == 0)
+               return VTNET_RQ;
+       else
+               return VTNET_TQ;
+}
+
 #define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
 
 void vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx);
index 82d59ca..93d9649 100644 (file)
@@ -1172,7 +1172,7 @@ __vmxnet3_dev_link_update(struct rte_eth_dev *dev,
                link.link_status = ETH_LINK_UP;
                link.link_duplex = ETH_LINK_FULL_DUPLEX;
                link.link_speed = ETH_SPEED_NUM_10G;
-               link.link_autoneg = ETH_LINK_SPEED_FIXED;
+               link.link_autoneg = ETH_LINK_AUTONEG;
        }
 
        vmxnet3_dev_atomic_write_link_status(dev, &link);
index 8e3b1f3..4f533e2 100644 (file)
@@ -226,7 +226,7 @@ bond_port_init(struct rte_mempool *mbuf_pool)
        uint16_t nb_rxd = RTE_RX_DESC_DEFAULT;
        uint16_t nb_txd = RTE_TX_DESC_DEFAULT;
 
-       retval = rte_eth_bond_create("bond0", BONDING_MODE_ALB,
+       retval = rte_eth_bond_create("net_bonding0", BONDING_MODE_ALB,
                        0 /*SOCKET_ID_ANY*/);
        if (retval < 0)
                rte_exit(EXIT_FAILURE,
@@ -446,6 +446,11 @@ static void cmd_obj_send_parsed(void *parsed_result,
                                (BOND_IP_3 << 16) | (BOND_IP_4 << 24);
 
        created_pkt = rte_pktmbuf_alloc(mbuf_pool);
+       if (created_pkt == NULL) {
+               cmdline_printf(cl, "Failed to allocate mbuf\n");
+               return;
+       }
+
        pkt_size = sizeof(struct ether_hdr) + sizeof(struct arp_hdr);
        created_pkt->data_len = pkt_size;
        created_pkt->pkt_len = pkt_size;
index e56e404..ffd0fc2 100644 (file)
@@ -1726,7 +1726,7 @@ app_init_pipelines(struct app_params *app)
                data->ptype = ptype;
 
                data->timer_period = (rte_get_tsc_hz() *
-                       params->timer_period) / 100;
+                       params->timer_period) / 1000;
        }
 }
 
index c98454a..b5ec70a 100644 (file)
@@ -407,7 +407,8 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,
                }
                /* Only check SPI match for processed IPSec packets */
                sa_idx = ip->res[i] & PROTECT_MASK;
-               if (sa_idx == 0 || !inbound_sa_check(sa, m, sa_idx)) {
+               if (sa_idx >= IPSEC_SA_MAX_ENTRIES ||
+                               !inbound_sa_check(sa, m, sa_idx)) {
                        rte_pktmbuf_free(m);
                        continue;
                }
@@ -472,9 +473,9 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip,
        for (i = 0; i < ip->num; i++) {
                m = ip->pkts[i];
                sa_idx = ip->res[i] & PROTECT_MASK;
-               if ((ip->res[i] == 0) || (ip->res[i] & DISCARD))
+               if (ip->res[i] & DISCARD)
                        rte_pktmbuf_free(m);
-               else if (sa_idx != 0) {
+               else if (sa_idx < IPSEC_SA_MAX_ENTRIES) {
                        ipsec->res[ipsec->num] = sa_idx;
                        ipsec->pkts[ipsec->num++] = m;
                } else /* BYPASS */
@@ -585,31 +586,81 @@ process_pkts_outbound_nosp(struct ipsec_ctx *ipsec_ctx,
                traffic->ip6.num = nb_pkts_out;
 }
 
+static inline int32_t
+get_hop_for_offload_pkt(struct rte_mbuf *pkt, int is_ipv6)
+{
+       struct ipsec_mbuf_metadata *priv;
+       struct ipsec_sa *sa;
+
+       priv = get_priv(pkt);
+
+       sa = priv->sa;
+       if (unlikely(sa == NULL)) {
+               RTE_LOG(ERR, IPSEC, "SA not saved in private data\n");
+               goto fail;
+       }
+
+       if (is_ipv6)
+               return sa->portid;
+
+       /* else */
+       return (sa->portid | RTE_LPM_LOOKUP_SUCCESS);
+
+fail:
+       if (is_ipv6)
+               return -1;
+
+       /* else */
+       return 0;
+}
+
 static inline void
 route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts)
 {
        uint32_t hop[MAX_PKT_BURST * 2];
        uint32_t dst_ip[MAX_PKT_BURST * 2];
+       int32_t pkt_hop = 0;
        uint16_t i, offset;
+       uint16_t lpm_pkts = 0;
 
        if (nb_pkts == 0)
                return;
 
+       /* Need to do an LPM lookup for non-inline packets. Inline packets will
+        * have port ID in the SA
+        */
+
        for (i = 0; i < nb_pkts; i++) {
-               offset = offsetof(struct ip, ip_dst);
-               dst_ip[i] = *rte_pktmbuf_mtod_offset(pkts[i],
-                               uint32_t *, offset);
-               dst_ip[i] = rte_be_to_cpu_32(dst_ip[i]);
+               if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+                       /* Security offload not enabled. So an LPM lookup is
+                        * required to get the hop
+                        */
+                       offset = offsetof(struct ip, ip_dst);
+                       dst_ip[lpm_pkts] = *rte_pktmbuf_mtod_offset(pkts[i],
+                                       uint32_t *, offset);
+                       dst_ip[lpm_pkts] = rte_be_to_cpu_32(dst_ip[lpm_pkts]);
+                       lpm_pkts++;
+               }
        }
 
-       rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop, nb_pkts);
+       rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop, lpm_pkts);
+
+       lpm_pkts = 0;
 
        for (i = 0; i < nb_pkts; i++) {
-               if ((hop[i] & RTE_LPM_LOOKUP_SUCCESS) == 0) {
+               if (pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) {
+                       /* Read hop from the SA */
+                       pkt_hop = get_hop_for_offload_pkt(pkts[i], 0);
+               } else {
+                       /* Need to use hop returned by lookup */
+                       pkt_hop = hop[lpm_pkts++];
+               }
+
+               if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0) {
                        rte_pktmbuf_free(pkts[i]);
                        continue;
                }
-               send_single_packet(pkts[i], hop[i] & 0xff);
+               send_single_packet(pkts[i], pkt_hop & 0xff);
        }
 }
 
@@ -619,26 +670,49 @@ route6_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts)
        int32_t hop[MAX_PKT_BURST * 2];
        uint8_t dst_ip[MAX_PKT_BURST * 2][16];
        uint8_t *ip6_dst;
+       int32_t pkt_hop = 0;
        uint16_t i, offset;
+       uint16_t lpm_pkts = 0;
 
        if (nb_pkts == 0)
                return;
 
+       /* Need to do an LPM lookup for non-inline packets. Inline packets will
+        * have port ID in the SA
+        */
+
        for (i = 0; i < nb_pkts; i++) {
-               offset = offsetof(struct ip6_hdr, ip6_dst);
-               ip6_dst = rte_pktmbuf_mtod_offset(pkts[i], uint8_t *, offset);
-               memcpy(&dst_ip[i][0], ip6_dst, 16);
+               if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
+                       /* Security offload not enabled. So an LPM lookup is
+                        * required to get the hop
+                        */
+                       offset = offsetof(struct ip6_hdr, ip6_dst);
+                       ip6_dst = rte_pktmbuf_mtod_offset(pkts[i], uint8_t *,
+                                       offset);
+                       memcpy(&dst_ip[lpm_pkts][0], ip6_dst, 16);
+                       lpm_pkts++;
+               }
        }
 
-       rte_lpm6_lookup_bulk_func((struct rte_lpm6 *)rt_ctx, dst_ip,
-                       hop, nb_pkts);
+       rte_lpm6_lookup_bulk_func((struct rte_lpm6 *)rt_ctx, dst_ip, hop,
+                       lpm_pkts);
+
+       lpm_pkts = 0;
 
        for (i = 0; i < nb_pkts; i++) {
-               if (hop[i] == -1) {
+               if (pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) {
+                       /* Read hop from the SA */
+                       pkt_hop = get_hop_for_offload_pkt(pkts[i], 1);
+               } else {
+                       /* Need to use hop returned by lookup */
+                       pkt_hop = hop[lpm_pkts++];
+               }
+
+               if (pkt_hop == -1) {
                        rte_pktmbuf_free(pkts[i]);
                        continue;
                }
-               send_single_packet(pkts[i], hop[i] & 0xff);
+               send_single_packet(pkts[i], pkt_hop & 0xff);
        }
 }
 
index 70ed227..c850c7b 100644 (file)
@@ -187,7 +187,7 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
                        sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP;
                        sa->pattern[2].spec = &sa->esp_spec;
                        sa->pattern[2].mask = &rte_flow_item_esp_mask;
-                       sa->esp_spec.hdr.spi = sa->spi;
+                       sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi);
 
                        sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
 
@@ -198,6 +198,8 @@ create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)
 
                        sa->attr.egress = (sa->direction ==
                                        RTE_SECURITY_IPSEC_SA_DIR_EGRESS);
+                       sa->attr.ingress = (sa->direction ==
+                                       RTE_SECURITY_IPSEC_SA_DIR_INGRESS);
                        sa->flow = rte_flow_create(sa->portid,
                                &sa->attr, sa->pattern, sa->action, &err);
                        if (sa->flow == NULL) {
index 4c448e5..b9f4a21 100644 (file)
@@ -269,6 +269,8 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
        APP_CHECK_TOKEN_IS_NUM(tokens, 1, status);
        if (status->status < 0)
                return;
+       if (atoi(tokens[1]) == INVALID_SPI)
+               return;
        rule->spi = atoi(tokens[1]);
 
        for (ti = 2; ti < n_tokens; ti++) {
index 0a4ed14..50c3702 100644 (file)
@@ -79,8 +79,6 @@
 
 #define MIN_ZERO_POLL_COUNT 10
 
-/* around 100ms at 2 Ghz */
-#define TIMER_RESOLUTION_CYCLES           200000000ULL
 /* 100 ms interval */
 #define TIMER_NUMBER_PER_SECOND           10
 /* 100000 us */
@@ -875,7 +873,7 @@ main_loop(__attribute__((unused)) void *dummy)
 {
        struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
        unsigned lcore_id;
-       uint64_t prev_tsc, diff_tsc, cur_tsc;
+       uint64_t prev_tsc, diff_tsc, cur_tsc, tim_res_tsc, hz;
        uint64_t prev_tsc_power = 0, cur_tsc_power, diff_tsc_power;
        int i, j, nb_rx;
        uint8_t queueid;
@@ -890,6 +888,8 @@ main_loop(__attribute__((unused)) void *dummy)
        const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
 
        prev_tsc = 0;
+       hz = rte_get_timer_hz();
+       tim_res_tsc = hz/TIMER_NUMBER_PER_SECOND;
 
        lcore_id = rte_lcore_id();
        qconf = &lcore_conf[lcore_id];
@@ -935,7 +935,7 @@ main_loop(__attribute__((unused)) void *dummy)
                }
 
                diff_tsc_power = cur_tsc_power - prev_tsc_power;
-               if (diff_tsc_power > TIMER_RESOLUTION_CYCLES) {
+               if (diff_tsc_power > tim_res_tsc) {
                        rte_timer_manage();
                        prev_tsc_power = cur_tsc_power;
                }
@@ -1051,9 +1051,11 @@ start_rx:
                                        turn_on_intr(qconf);
                                        sleep_until_rx_interrupt(
                                                qconf->n_rx_queue);
+                                       /**
+                                        * start receiving packets immediately
+                                        */
+                                       goto start_rx;
                                }
-                               /* start receiving packets immediately */
-                               goto start_rx;
                        }
                        stats[lcore_id].sleep_time += lcore_idle_hint;
                }
index 89a61f0..1f532fe 100644 (file)
@@ -279,12 +279,6 @@ port_init(uint16_t port)
        /* The max pool number from dev_info will be used to validate the pool number specified in cmd line */
        rte_eth_dev_info_get (port, &dev_info);
 
-       if (dev_info.max_rx_queues > MAX_QUEUES) {
-               rte_exit(EXIT_FAILURE,
-                       "please define MAX_QUEUES no less than %u in %s\n",
-                       dev_info.max_rx_queues, __FILE__);
-       }
-
        rxconf = &dev_info.default_rxconf;
        txconf = &dev_info.default_txconf;
        rxconf->rx_drop_en = 1;
@@ -964,7 +958,8 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
                struct vhost_dev *vdev2;
 
                TAILQ_FOREACH(vdev2, &vhost_dev_list, global_vdev_entry) {
-                       virtio_xmit(vdev2, vdev, m);
+                       if (vdev2 != vdev)
+                               virtio_xmit(vdev2, vdev, m);
                }
                goto queue2nic;
        }
index dc4e8df..26113cd 100644 (file)
@@ -125,5 +125,6 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
 endif
 DEPDIRS-librte_kni := librte_eal librte_mempool librte_mbuf librte_ether
+DEPDIRS-librte_kni += librte_pci
 
 include $(RTE_SDK)/mk/rte.subdir.mk
index 6321dec..87407ef 100644 (file)
@@ -61,6 +61,8 @@
 #ifndef _CIRBUF_H_
 #define _CIRBUF_H_
 
+#include <rte_config.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index 3e12ee5..7f799f9 100644 (file)
@@ -168,6 +168,8 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf,
        int n = 0;
        struct cmdline_token_hdr token_hdr;
 
+       if (resbuf != NULL)
+               memset(resbuf, 0, resbuf_size);
        /* check if we match all tokens of inst */
        while (!nb_match_token || i < nb_match_token) {
                token_p = get_token(inst, i);
@@ -263,6 +265,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
 #ifdef RTE_LIBRTE_CMDLINE_DEBUG
        char debug_buf[BUFSIZ];
 #endif
+       char *result_buf = result.buf;
 
        if (!cl || !buf)
                return CMDLINE_PARSE_BAD_ARGS;
@@ -312,16 +315,14 @@ cmdline_parse(struct cmdline *cl, const char * buf)
                debug_printf("INST %d\n", inst_num);
 
                /* fully parsed */
-               tok = match_inst(inst, buf, 0, tmp_result.buf,
-                                sizeof(tmp_result.buf));
+               tok = match_inst(inst, buf, 0, result_buf,
+                                CMDLINE_PARSE_RESULT_BUFSIZE);
 
                if (tok > 0) /* we matched at least one token */
                        err = CMDLINE_PARSE_BAD_ARGS;
 
                else if (!tok) {
                        debug_printf("INST fully parsed\n");
-                       memcpy(&result, &tmp_result,
-                              sizeof(result));
                        /* skip spaces */
                        while (isblank2(*curbuf)) {
                                curbuf++;
@@ -332,6 +333,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
                                if (!f) {
                                        memcpy(&f, &inst->f, sizeof(f));
                                        memcpy(&data, &inst->data, sizeof(data));
+                                       result_buf = tmp_result.buf;
                                }
                                else {
                                        /* more than 1 inst matches */
index 3d672fe..6f0b297 100644 (file)
@@ -121,7 +121,7 @@ struct rte_crypto_op {
        rte_iova_t phys_addr;
        /**< physical address of crypto operation */
 
-       RTE_STD_C11
+       __extension__
        union {
                struct rte_crypto_sym_op sym[0];
                /**< Symmetric operation parameters */
index b40c028..9fe0d9d 100644 (file)
@@ -362,6 +362,8 @@ rte_cryptodev_get_feature_name(uint64_t flag)
                return "CPU_AVX";
        case RTE_CRYPTODEV_FF_CPU_AVX2:
                return "CPU_AVX2";
+       case RTE_CRYPTODEV_FF_CPU_AVX512:
+               return "CPU_AVX512";
        case RTE_CRYPTODEV_FF_CPU_AESNI:
                return "CPU_AESNI";
        case RTE_CRYPTODEV_FF_HW_ACCELERATED:
@@ -1120,7 +1122,7 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
        struct rte_cryptodev_sym_session *sess;
 
        /* Allocate a session structure from the session pool */
-       if (rte_mempool_get(mp, (void *)&sess)) {
+       if (rte_mempool_get(mp, (void **)&sess)) {
                CDEV_LOG_ERR("couldn't get object from session mempool");
                return NULL;
        }
index dade554..ed92f98 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 #include "rte_crypto.h"
 #include "rte_dev.h"
 #include <rte_common.h>
+#include <rte_config.h>
 
 extern const char **rte_cyptodev_names;
 
index 744405e..089848e 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
 
 #include <string.h>
 
+#include <rte_config.h>
 #include <rte_dev.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
@@ -389,7 +390,7 @@ struct rte_cryptodev_ops {
        /**< Clear a Crypto sessions private data. */
        cryptodev_sym_queue_pair_attach_session_t qp_attach_session;
        /**< Attach session to queue pair. */
-       cryptodev_sym_queue_pair_attach_session_t qp_detach_session;
+       cryptodev_sym_queue_pair_detach_session_t qp_detach_session;
        /**< Detach session from queue pair. */
 };
 
index 69a9f74..851fd02 100644 (file)
@@ -1,52 +1,7 @@
-/*
- *   BSD LICENSE
- *
- *   Copyright (C) IBM Corporation 2014.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of IBM Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <rte_lcore.h>
-#include <rte_log.h>
-#include "eal_filesystem.h"
 #include "eal_private.h"
 
-static const char sys_cpu_dir[] = "/sys/devices/system/cpu";
-
 uint64_t
 get_tsc_freq_arch(void)
 {
-       unsigned long cpu_hz;
-       char path[PATH_MAX];
-
-       snprintf(path, sizeof(path), "%s/cpu%d/cpufreq/cpuinfo_cur_freq",
-                       sys_cpu_dir, rte_get_master_lcore());
-       if (eal_parse_sysfs_value(path, &cpu_hz) < 0)
-               RTE_LOG(WARNING, EAL, "Unable to parse %s\n", path);
-
-       return cpu_hz*1000;
+       return 0;
 }
index e894b75..4b2409a 100644 (file)
@@ -139,6 +139,8 @@ rte_log_set_level_regexp(const char *pattern, uint32_t level)
                        rte_logs.dynamic_types[i].loglevel = level;
        }
 
+       regfree(&r);
+
        return 0;
 }
 
index ea072a2..b682b00 100644 (file)
@@ -237,7 +237,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
                return NULL;
        }
 
-       const struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
+       struct malloc_elem *elem = malloc_elem_from_data(mz_addr);
 
        /* fill the zone in config */
        mz = get_next_free_memzone();
@@ -245,6 +245,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len,
        if (mz == NULL) {
                RTE_LOG(ERR, EAL, "%s(): Cannot find free memzone but there is room "
                                "in config!\n", __func__);
+               malloc_elem_free(elem);
                rte_errno = ENOSPC;
                return NULL;
        }
index 0b70d62..71da29c 100644 (file)
@@ -43,8 +43,8 @@ extern "C" {
 
 #include "generic/rte_atomic.h"
 
-#define dsb(opt)  { asm volatile("dsb " #opt : : : "memory"); }
-#define dmb(opt)  { asm volatile("dmb " #opt : : : "memory"); }
+#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
+#define dmb(opt) asm volatile("dmb " #opt : : : "memory")
 
 #define rte_mb() dsb(sy)
 
index 150810c..6993dd2 100644 (file)
@@ -64,9 +64,9 @@ extern "C" {
  * occur before the STORE operations generated after.
  */
 #ifdef RTE_ARCH_64
-#define        rte_wmb() {asm volatile("lwsync" : : : "memory"); }
+#define        rte_wmb() asm volatile("lwsync" : : : "memory")
 #else
-#define        rte_wmb() {asm volatile("sync" : : : "memory"); }
+#define        rte_wmb() asm volatile("sync" : : : "memory")
 #endif
 
 /**
@@ -76,9 +76,9 @@ extern "C" {
  * occur before the LOAD operations generated after.
  */
 #ifdef RTE_ARCH_64
-#define        rte_rmb() {asm volatile("lwsync" : : : "memory"); }
+#define        rte_rmb() asm volatile("lwsync" : : : "memory")
 #else
-#define        rte_rmb() {asm volatile("sync" : : : "memory"); }
+#define        rte_rmb() asm volatile("sync" : : : "memory")
 #endif
 
 #define rte_smp_mb() rte_mb()
index 4eac666..ea665d5 100644 (file)
@@ -40,6 +40,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <emmintrin.h>
 #include "generic/rte_atomic.h"
 
index 251f11b..126f29e 100644 (file)
@@ -40,6 +40,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include "generic/rte_byteorder.h"
 
 #ifndef RTE_BYTE_ORDER
index 1bb3e1d..b95bece 100644 (file)
@@ -47,6 +47,7 @@ extern int rte_cycles_vmware_tsc_map;
 #include <rte_branch_prediction.h>
 #endif
 #include <rte_common.h>
+#include <rte_config.h>
 
 static inline uint64_t
 rte_rdtsc(void)
index 74c280c..596d777 100644 (file)
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <rte_vect.h>
 #include <rte_common.h>
+#include <rte_config.h>
 
 #ifdef __cplusplus
 extern "C" {
index 03fc991..893b812 100644 (file)
@@ -41,6 +41,7 @@
  */
 
 #include <stdint.h>
+#include <rte_config.h>
 #include "generic/rte_vect.h"
 
 #if (defined(__ICC) || (__GNUC__ == 4 &&  __GNUC_MINOR__ < 4))
index e5e820d..29e70c9 100644 (file)
@@ -51,6 +51,7 @@
 #endif
 
 #include <rte_common.h>
+#include <rte_config.h>
 
 /*
  * Compile-time endianness detection
index 010d752..b9067e6 100644 (file)
@@ -66,6 +66,7 @@ extern "C" {
 
 #include <string.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_debug.h>
 #include <rte_memory.h>
 #include <rte_branch_prediction.h>
index de853e1..f1d24b8 100644 (file)
@@ -51,6 +51,8 @@ extern "C" {
 #include <errno.h>
 #include <limits.h>
 
+#include <rte_config.h>
+
 #ifndef typeof
 #define typeof __typeof__
 #endif
index 9342e0c..8088dcc 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 #include <stdio.h>
 #include <sys/queue.h>
 
+#include <rte_config.h>
 #include <rte_log.h>
 
 __attribute__((format(printf, 2, 0)))
index 8e4e71c..78b0e00 100644 (file)
@@ -43,6 +43,7 @@
 #include <stdint.h>
 #include <sched.h>
 
+#include <rte_config.h>
 #include <rte_per_lcore.h>
 #include <rte_bus.h>
 
index b9eee70..c963b45 100644 (file)
@@ -34,6 +34,7 @@
 #ifndef _RTE_EAL_MEMCONFIG_H_
 #define _RTE_EAL_MEMCONFIG_H_
 
+#include <rte_config.h>
 #include <rte_tailq.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
index 88ad8e4..e9f8f08 100644 (file)
@@ -39,6 +39,7 @@
 #ifndef _KEEPALIVE_H_
 #define _KEEPALIVE_H_
 
+#include <rte_config.h>
 #include <rte_memory.h>
 
 #ifndef RTE_KEEPALIVE_MAXCORES
index c89e6ba..3735da0 100644 (file)
@@ -40,6 +40,7 @@
  * API for lcore and socket manipulation
  *
  */
+#include <rte_config.h>
 #include <rte_per_lcore.h>
 #include <rte_eal.h>
 #include <rte_launch.h>
index 6c2d356..0bb1068 100644 (file)
@@ -51,6 +51,7 @@ extern "C" {
 #include <stdarg.h>
 
 #include <rte_common.h>
+#include <rte_config.h>
 
 struct rte_log_dynamic_type;
 
index 14aacea..80a8fc0 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 #endif
 
 #include <rte_common.h>
+#include <rte_config.h>
 
 __extension__
 enum rte_page_sizes {
index 9272440..80b90fa 100644 (file)
@@ -59,6 +59,7 @@ extern "C" {
 #include <stdint.h>
 #include <sys/queue.h>
 
+#include <rte_config.h>
 #include <rte_lcore.h>
 
 #define RTE_SERVICE_NAME_MAX 32
@@ -274,7 +275,9 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id,
  * Start a service core.
  *
  * Starting a core makes the core begin polling. Any services assigned to it
- * will be run as fast as possible.
+ * will be run as fast as possible. The application must ensure that the lcore
+ * is in a launchable state: e.g. call *rte_eal_lcore_wait* on the lcore_id
+ * before calling this function.
  *
  * @retval 0 Success
  * @retval -EINVAL Failed to start core. The *lcore_id* passed in is not
index b176f65..a0611f3 100644 (file)
@@ -66,7 +66,7 @@ extern "C" {
 /**
  * Patch level number i.e. the z in yy.mm.z
  */
-#define RTE_VER_MINOR 0
+#define RTE_VER_MINOR 1
 
 /**
  * Extra string to be appended to version number
index 98bcd37..f6cbc42 100644 (file)
@@ -98,6 +98,7 @@ elem_start_pt(struct malloc_elem *elem, size_t size, unsigned align,
        if ((new_data_start & bmask) != ((end_pt - 1) & bmask)) {
                end_pt = RTE_ALIGN_FLOOR(end_pt, bound);
                new_data_start = RTE_ALIGN_FLOOR((end_pt - size), align);
+               end_pt = new_data_start + size;
                if (((end_pt - 1) & bmask) != (new_data_start & bmask))
                        return NULL;
        }
index 267a4c6..c731f1c 100644 (file)
@@ -178,12 +178,14 @@ malloc_heap_alloc(struct malloc_heap *heap,
  * Function to retrieve data for heap on given socket
  */
 int
-malloc_heap_get_stats(const struct malloc_heap *heap,
+malloc_heap_get_stats(struct malloc_heap *heap,
                struct rte_malloc_socket_stats *socket_stats)
 {
        size_t idx;
        struct malloc_elem *elem;
 
+       rte_spinlock_lock(&heap->lock);
+
        /* Initialise variables for heap */
        socket_stats->free_count = 0;
        socket_stats->heap_freesz_bytes = 0;
@@ -205,6 +207,8 @@ malloc_heap_get_stats(const struct malloc_heap *heap,
        socket_stats->heap_allocsz_bytes = (socket_stats->heap_totalsz_bytes -
                        socket_stats->heap_freesz_bytes);
        socket_stats->alloc_count = heap->alloc_count;
+
+       rte_spinlock_unlock(&heap->lock);
        return 0;
 }
 
index 3ccbef0..3b1166f 100644 (file)
@@ -57,7 +57,7 @@ malloc_heap_alloc(struct malloc_heap *heap,   const char *type, size_t size,
                unsigned flags, size_t align, size_t bound);
 
 int
-malloc_heap_get_stats(const struct malloc_heap *heap,
+malloc_heap_get_stats(struct malloc_heap *heap,
                struct rte_malloc_socket_stats *socket_stats);
 
 int
index cdd6956..0c7ecba 100644 (file)
 
 struct rte_keepalive {
        /** Core Liveness. */
-       enum rte_keepalive_state __rte_cache_aligned state_flags[
-               RTE_KEEPALIVE_MAXCORES];
+       struct {
+               /*
+                * Each element must be cache aligned to prevent false sharing.
+                */
+               enum rte_keepalive_state core_state __rte_cache_aligned;
+       } live_data[RTE_KEEPALIVE_MAXCORES];
 
        /** Last-seen-alive timestamps */
        uint64_t last_alive[RTE_KEEPALIVE_MAXCORES];
@@ -95,19 +99,22 @@ rte_keepalive_dispatch_pings(__rte_unused void *ptr_timer,
                if (keepcfg->active_cores[idx_core] == 0)
                        continue;
 
-               switch (keepcfg->state_flags[idx_core]) {
+               switch (keepcfg->live_data[idx_core].core_state) {
                case RTE_KA_STATE_UNUSED:
                        break;
                case RTE_KA_STATE_ALIVE: /* Alive */
-                       keepcfg->state_flags[idx_core] = RTE_KA_STATE_MISSING;
+                       keepcfg->live_data[idx_core].core_state =
+                           RTE_KA_STATE_MISSING;
                        keepcfg->last_alive[idx_core] = rte_rdtsc();
                        break;
                case RTE_KA_STATE_MISSING: /* MIA */
                        print_trace("Core MIA. ", keepcfg, idx_core);
-                       keepcfg->state_flags[idx_core] = RTE_KA_STATE_DEAD;
+                       keepcfg->live_data[idx_core].core_state =
+                           RTE_KA_STATE_DEAD;
                        break;
                case RTE_KA_STATE_DEAD: /* Dead */
-                       keepcfg->state_flags[idx_core] = RTE_KA_STATE_GONE;
+                       keepcfg->live_data[idx_core].core_state =
+                           RTE_KA_STATE_GONE;
                        print_trace("Core died. ", keepcfg, idx_core);
                        if (keepcfg->callback)
                                keepcfg->callback(
@@ -118,7 +125,8 @@ rte_keepalive_dispatch_pings(__rte_unused void *ptr_timer,
                case RTE_KA_STATE_GONE: /* Buried */
                        break;
                case RTE_KA_STATE_DOZING: /* Core going idle */
-                       keepcfg->state_flags[idx_core] = RTE_KA_STATE_SLEEP;
+                       keepcfg->live_data[idx_core].core_state =
+                           RTE_KA_STATE_SLEEP;
                        keepcfg->last_alive[idx_core] = rte_rdtsc();
                        break;
                case RTE_KA_STATE_SLEEP: /* Idled core */
@@ -128,7 +136,7 @@ rte_keepalive_dispatch_pings(__rte_unused void *ptr_timer,
                        keepcfg->relay_callback(
                                keepcfg->relay_callback_data,
                                idx_core,
-                               keepcfg->state_flags[idx_core],
+                               keepcfg->live_data[idx_core].core_state,
                                keepcfg->last_alive[idx_core]
                                );
        }
@@ -172,11 +180,11 @@ rte_keepalive_register_core(struct rte_keepalive *keepcfg, const int id_core)
 void
 rte_keepalive_mark_alive(struct rte_keepalive *keepcfg)
 {
-       keepcfg->state_flags[rte_lcore_id()] = RTE_KA_STATE_ALIVE;
+       keepcfg->live_data[rte_lcore_id()].core_state = RTE_KA_STATE_ALIVE;
 }
 
 void
 rte_keepalive_mark_sleep(struct rte_keepalive *keepcfg)
 {
-       keepcfg->state_flags[rte_lcore_id()] = RTE_KA_STATE_DOZING;
+       keepcfg->live_data[rte_lcore_id()].core_state = RTE_KA_STATE_DOZING;
 }
index ae97e6b..1f92294 100644 (file)
@@ -111,14 +111,14 @@ int32_t rte_service_init(void)
                        RTE_CACHE_LINE_SIZE);
        if (!rte_services) {
                printf("error allocating rte services array\n");
-               return -ENOMEM;
+               goto fail_mem;
        }
 
        lcore_states = rte_calloc("rte_service_core_states", RTE_MAX_LCORE,
                        sizeof(struct core_state), RTE_CACHE_LINE_SIZE);
        if (!lcore_states) {
                printf("error allocating core states array\n");
-               return -ENOMEM;
+               goto fail_mem;
        }
 
        int i;
@@ -135,6 +135,12 @@ int32_t rte_service_init(void)
 
        rte_service_library_initialized = 1;
        return 0;
+fail_mem:
+       if (rte_services)
+               rte_free(rte_services);
+       if (lcore_states)
+               rte_free(lcore_states);
+       return -ENOMEM;
 }
 
 /* returns 1 if service is registered and has not been unregistered
@@ -545,10 +551,14 @@ service_update(struct rte_service_spec *service, uint32_t lcore,
 
        uint64_t sid_mask = UINT64_C(1) << sid;
        if (set) {
-               if (*set) {
+               uint64_t lcore_mapped = lcore_states[lcore].service_mask &
+                       sid_mask;
+
+               if (*set && !lcore_mapped) {
                        lcore_states[lcore].service_mask |= sid_mask;
                        rte_atomic32_inc(&rte_services[sid].num_mapped_cores);
-               } else {
+               }
+               if (!*set && lcore_mapped) {
                        lcore_states[lcore].service_mask &= ~(sid_mask);
                        rte_atomic32_dec(&rte_services[sid].num_mapped_cores);
                }
@@ -583,23 +593,6 @@ rte_service_map_lcore_get(uint32_t id, uint32_t lcore)
        return ret;
 }
 
-int32_t rte_service_lcore_reset_all(void)
-{
-       /* loop over cores, reset all to mask 0 */
-       uint32_t i;
-       for (i = 0; i < RTE_MAX_LCORE; i++) {
-               lcore_states[i].service_mask = 0;
-               lcore_states[i].is_service_core = 0;
-               lcore_states[i].runstate = RUNSTATE_STOPPED;
-       }
-       for (i = 0; i < RTE_SERVICE_NUM_MAX; i++)
-               rte_atomic32_set(&rte_services[i].num_mapped_cores, 0);
-
-       rte_smp_wmb();
-
-       return 0;
-}
-
 static void
 set_lcore_state(uint32_t lcore, int32_t state)
 {
@@ -614,6 +607,25 @@ set_lcore_state(uint32_t lcore, int32_t state)
        lcore_states[lcore].is_service_core = (state == ROLE_SERVICE);
 }
 
+int32_t rte_service_lcore_reset_all(void)
+{
+       /* loop over cores, reset all to mask 0 */
+       uint32_t i;
+       for (i = 0; i < RTE_MAX_LCORE; i++) {
+               if (lcore_states[i].is_service_core) {
+                       lcore_states[i].service_mask = 0;
+                       set_lcore_state(i, ROLE_RTE);
+                       lcore_states[i].runstate = RUNSTATE_STOPPED;
+               }
+       }
+       for (i = 0; i < RTE_SERVICE_NUM_MAX; i++)
+               rte_atomic32_set(&rte_services[i].num_mapped_cores, 0);
+
+       rte_smp_wmb();
+
+       return 0;
+}
+
 int32_t
 rte_service_lcore_add(uint32_t lcore)
 {
index 58f0123..fb1a622 100644 (file)
@@ -525,7 +525,7 @@ rte_vfio_enable(const char *modname)
 int
 rte_vfio_is_enabled(const char *modname)
 {
-       const int mod_available = rte_eal_check_module(modname);
+       const int mod_available = rte_eal_check_module(modname) > 0;
        return vfio_cfg.vfio_enabled && mod_available;
 }
 
index a3a98c1..1826adb 100644 (file)
@@ -45,6 +45,8 @@ struct rte_uio_pci_dev {
        struct uio_info info;
        struct pci_dev *pdev;
        enum rte_intr_mode mode;
+       struct mutex lock;
+       int refcnt;
 };
 
 static char *intr_mode;
@@ -336,11 +338,18 @@ igbuio_pci_open(struct uio_info *info, struct inode *inode)
        struct pci_dev *dev = udev->pdev;
        int err;
 
+       mutex_lock(&udev->lock);
+       if (++udev->refcnt > 1) {
+               mutex_unlock(&udev->lock);
+               return 0;
+       }
+
        /* set bus master, which was cleared by the reset function */
        pci_set_master(dev);
 
        /* enable interrupts */
        err = igbuio_pci_enable_interrupts(udev);
+       mutex_unlock(&udev->lock);
        if (err) {
                dev_err(&dev->dev, "Enable interrupt fails\n");
                return err;
@@ -354,12 +363,19 @@ igbuio_pci_release(struct uio_info *info, struct inode *inode)
        struct rte_uio_pci_dev *udev = info->priv;
        struct pci_dev *dev = udev->pdev;
 
+       mutex_lock(&udev->lock);
+       if (--udev->refcnt > 0) {
+               mutex_unlock(&udev->lock);
+               return 0;
+       }
+
        /* disable interrupts */
        igbuio_pci_disable_interrupts(udev);
 
        /* stop the device from further DMA */
        pci_clear_master(dev);
 
+       mutex_unlock(&udev->lock);
        return 0;
 }
 
@@ -480,6 +496,7 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (!udev)
                return -ENOMEM;
 
+       mutex_init(&udev->lock);
        /*
         * enable device: ask low-level code to enable I/O and
         * memory
@@ -570,6 +587,7 @@ igbuio_pci_remove(struct pci_dev *dev)
 {
        struct rte_uio_pci_dev *udev = pci_get_drvdata(dev);
 
+       mutex_destroy(&udev->lock);
        sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
        uio_unregister_device(&udev->info);
        igbuio_pci_release_iomem(&udev->info);
index 99338c5..e0f427a 100644 (file)
@@ -137,11 +137,20 @@ static void igb_clean_all_tx_rings(struct igb_adapter *);
 static void igb_clean_all_rx_rings(struct igb_adapter *);
 static void igb_clean_tx_ring(struct igb_ring *);
 static void igb_set_rx_mode(struct net_device *);
+#ifdef HAVE_TIMER_SETUP
+static void igb_update_phy_info(struct timer_list *);
+static void igb_watchdog(struct timer_list *);
+#else
 static void igb_update_phy_info(unsigned long);
 static void igb_watchdog(unsigned long);
+#endif
 static void igb_watchdog_task(struct work_struct *);
 static void igb_dma_err_task(struct work_struct *);
+#ifdef HAVE_TIMER_SETUP
+static void igb_dma_err_timer(struct timer_list *);
+#else
 static void igb_dma_err_timer(unsigned long data);
+#endif
 static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
 static struct net_device_stats *igb_get_stats(struct net_device *);
 static int igb_change_mtu(struct net_device *, int);
@@ -2806,6 +2815,12 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        /* Check if Media Autosense is enabled */
        if (hw->mac.type == e1000_82580)
                igb_init_mas(adapter);
+#ifdef HAVE_TIMER_SETUP
+       timer_setup(&adapter->watchdog_timer, &igb_watchdog, 0);
+       if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
+               timer_setup(&adapter->dma_err_timer, &igb_dma_err_timer, 0);
+       timer_setup(&adapter->phy_info_timer, &igb_update_phy_info, 0);
+#else
        setup_timer(&adapter->watchdog_timer, &igb_watchdog,
                    (unsigned long) adapter);
        if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
@@ -2813,6 +2828,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                            (unsigned long) adapter);
        setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
                    (unsigned long) adapter);
+#endif
 
        INIT_WORK(&adapter->reset_task, igb_reset_task);
        INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
@@ -4543,9 +4559,15 @@ static void igb_spoof_check(struct igb_adapter *adapter)
 
 /* Need to wait a few seconds after link up to get diagnostic information from
  * the phy */
+#ifdef HAVE_TIMER_SETUP
+static void igb_update_phy_info(struct timer_list *t)
+{
+       struct igb_adapter *adapter = from_timer(adapter, t, phy_info_timer);
+#else
 static void igb_update_phy_info(unsigned long data)
 {
        struct igb_adapter *adapter = (struct igb_adapter *) data;
+#endif
        e1000_get_phy_info(&adapter->hw);
 }
 
@@ -4594,9 +4616,15 @@ bool igb_has_link(struct igb_adapter *adapter)
  * igb_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
  **/
+#ifdef HAVE_TIMER_SETUP
+static void igb_watchdog(struct timer_list *t)
+{
+       struct igb_adapter *adapter = from_timer(adapter, t, watchdog_timer);
+#else
 static void igb_watchdog(unsigned long data)
 {
        struct igb_adapter *adapter = (struct igb_adapter *)data;
+#endif
        /* Do the rest outside of interrupt context */
        schedule_work(&adapter->watchdog_task);
 }
@@ -4854,9 +4882,15 @@ dma_timer_reset:
  * igb_dma_err_timer - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
  **/
+#ifdef HAVE_TIMER_SETUP
+static void igb_dma_err_timer(struct timer_list *t)
+{
+       struct igb_adapter *adapter = from_timer(adapter, t, dma_err_timer);
+#else
 static void igb_dma_err_timer(unsigned long data)
 {
        struct igb_adapter *adapter = (struct igb_adapter *)data;
+#endif
        /* Do the rest outside of interrupt context */
        schedule_work(&adapter->dma_err_task);
 }
@@ -10051,6 +10085,12 @@ int igb_kni_probe(struct pci_dev *pdev,
                igb_init_mas(adapter);
 
 #ifdef NO_KNI
+#ifdef HAVE_TIMER_SETUP
+       timer_setup(&adapter->watchdog_timer, &igb_watchdog, 0);
+       if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
+               timer_setup(&adapter->dma_err_timer, &igb_dma_err_timer, 0);
+       timer_setup(&adapter->phy_info_timer, &igb_update_phy_info, 0);
+#else
        setup_timer(&adapter->watchdog_timer, &igb_watchdog,
                    (unsigned long) adapter);
        if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA)
@@ -10058,6 +10098,7 @@ int igb_kni_probe(struct pci_dev *pdev,
                            (unsigned long) adapter);
        setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
                    (unsigned long) adapter);
+#endif
 
        INIT_WORK(&adapter->reset_task, igb_reset_task);
        INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
index e38a756..443a3f2 100644 (file)
@@ -3941,4 +3941,8 @@ skb_set_hash(struct sk_buff *skb, __u32 hash, __always_unused int type)
 #define HAVE_PCI_ENABLE_MSIX
 #endif
 
+#if defined(timer_setup) && defined(from_timer)
+#define HAVE_TIMER_SETUP
+#endif
+
 #endif /* _KCOMPAT_H_ */
index 318af28..4d23bc1 100644 (file)
@@ -93,6 +93,7 @@ static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
        {"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
        {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
        {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
+       {"rx_missed_errors", offsetof(struct rte_eth_stats, imissed)},
        {"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
        {"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
        {"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
@@ -191,8 +192,12 @@ rte_eth_dev_find_free_port(void)
        unsigned i;
 
        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-               if (rte_eth_devices[i].state == RTE_ETH_DEV_UNUSED)
+               /* Using shared name field to find a free port. */
+               if (rte_eth_dev_data[i].name[0] == '\0') {
+                       RTE_ASSERT(rte_eth_devices[i].state ==
+                                  RTE_ETH_DEV_UNUSED);
                        return i;
+               }
        }
        return RTE_MAX_ETHPORTS;
 }
@@ -217,22 +222,21 @@ rte_eth_dev_allocate(const char *name)
        uint16_t port_id;
        struct rte_eth_dev *eth_dev;
 
+       if (rte_eth_dev_data == NULL)
+               rte_eth_dev_data_alloc();
+
        port_id = rte_eth_dev_find_free_port();
        if (port_id == RTE_MAX_ETHPORTS) {
                RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
                return NULL;
        }
 
-       if (rte_eth_dev_data == NULL)
-               rte_eth_dev_data_alloc();
-
        if (rte_eth_dev_allocated(name) != NULL) {
                RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n",
                                name);
                return NULL;
        }
 
-       memset(&rte_eth_dev_data[port_id], 0, sizeof(struct rte_eth_dev_data));
        eth_dev = eth_dev_get(port_id);
        snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
        eth_dev->data->port_id = port_id;
@@ -278,6 +282,7 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
        if (eth_dev == NULL)
                return -EINVAL;
 
+       memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
        eth_dev->state = RTE_ETH_DEV_UNUSED;
        return 0;
 }
index 341c2d6..2cc2eed 100644 (file)
@@ -181,6 +181,7 @@ extern "C" {
 #include <rte_devargs.h>
 #include <rte_errno.h>
 #include <rte_common.h>
+#include <rte_config.h>
 
 #include "rte_ether.h"
 #include "rte_eth_ctrl.h"
@@ -262,17 +263,17 @@ __extension__
 struct rte_eth_link {
        uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
        uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
-       uint16_t link_autoneg : 1;  /**< ETH_LINK_SPEED_[AUTONEG/FIXED] */
+       uint16_t link_autoneg : 1;  /**< ETH_LINK_[AUTONEG/FIXED] */
        uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
 } __attribute__((aligned(8)));      /**< aligned for atomic64 read/write */
 
 /* Utility constants */
-#define ETH_LINK_HALF_DUPLEX    0 /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX    1 /**< Full-duplex connection. */
-#define ETH_LINK_DOWN           0 /**< Link is down. */
-#define ETH_LINK_UP             1 /**< Link is up. */
-#define ETH_LINK_FIXED          0 /**< No autonegotiation. */
-#define ETH_LINK_AUTONEG        1 /**< Autonegotiated. */
+#define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection (see link_duplex). */
+#define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection (see link_duplex). */
+#define ETH_LINK_DOWN        0 /**< Link is down (see link_status). */
+#define ETH_LINK_UP          1 /**< Link is up (see link_status). */
+#define ETH_LINK_FIXED       0 /**< No autonegotiation (see link_autoneg). */
+#define ETH_LINK_AUTONEG     1 /**< Autonegotiated (see link_autoneg). */
 
 /**
  * A structure used to configure the ring threshold registers of an RX/TX
index 722075e..ad64a16 100644 (file)
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
+#include <rte_config.h>
 #include <rte_ethdev.h>
 
 /**
index ff92e6e..feb5a3e 100644 (file)
@@ -34,6 +34,7 @@
 #ifndef _RTE_ETHDEV_VDEV_H_
 #define _RTE_ETHDEV_VDEV_H_
 
+#include <rte_config.h>
 #include <rte_malloc.h>
 #include <rte_bus_vdev.h>
 #include <rte_ethdev.h>
index ce6a5dc..e0c2a78 100644 (file)
@@ -832,13 +832,19 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,
        uint16_t *links_map;
        int i, diag;
 
-       RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+       RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, -EINVAL, 0);
        dev = &rte_eventdevs[dev_id];
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_link, -ENOTSUP);
+
+       if (*dev->dev_ops->port_link == NULL) {
+               RTE_PMD_DEBUG_TRACE("Function not supported\n");
+               rte_errno = -ENOTSUP;
+               return 0;
+       }
 
        if (!is_valid_port(dev, port_id)) {
                RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
-               return -EINVAL;
+               rte_errno = -EINVAL;
+               return 0;
        }
 
        if (queues == NULL) {
@@ -857,8 +863,10 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,
        }
 
        for (i = 0; i < nb_links; i++)
-               if (queues[i] >= dev->data->nb_queues)
-                       return -EINVAL;
+               if (queues[i] >= dev->data->nb_queues) {
+                       rte_errno = -EINVAL;
+                       return 0;
+               }
 
        diag = (*dev->dev_ops->port_link)(dev, dev->data->ports[port_id],
                                                queues, priorities, nb_links);
@@ -883,13 +891,19 @@ rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
        int i, diag;
        uint16_t *links_map;
 
-       RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
+       RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, -EINVAL, 0);
        dev = &rte_eventdevs[dev_id];
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_unlink, -ENOTSUP);
+
+       if (*dev->dev_ops->port_unlink == NULL) {
+               RTE_PMD_DEBUG_TRACE("Function not supported\n");
+               rte_errno = -ENOTSUP;
+               return 0;
+       }
 
        if (!is_valid_port(dev, port_id)) {
                RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
-               return -EINVAL;
+               rte_errno = -EINVAL;
+               return 0;
        }
 
        if (queues == NULL) {
@@ -900,8 +914,10 @@ rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
        }
 
        for (i = 0; i < nb_unlinks; i++)
-               if (queues[i] >= dev->data->nb_queues)
-                       return -EINVAL;
+               if (queues[i] >= dev->data->nb_queues) {
+                       rte_errno = -EINVAL;
+                       return 0;
+               }
 
        diag = (*dev->dev_ops->port_unlink)(dev, dev->data->ports[port_id],
                                        queues, nb_unlinks);
index f1949ff..eb1024d 100644 (file)
@@ -239,6 +239,7 @@ extern "C" {
 #endif
 
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_memory.h>
 #include <rte_errno.h>
 
@@ -420,9 +421,9 @@ rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info);
  * @param[out] attr_value A pointer that will be filled in with the attribute
  *             value if successful.
  *
- * @retval 0 Successfully retrieved attribute value
- *         -EINVAL Invalid device or  *attr_id* provided, or *attr_value*
- *         is NULL
+ * @return
+ *   - 0: Successfully retrieved attribute value
+ *   - -EINVAL: Invalid device or  *attr_id* provided, or *attr_value* is NULL
  */
 int
 rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id,
@@ -640,18 +641,22 @@ rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
 /**
  * Get an attribute from a queue.
  *
- * @param dev_id Eventdev id
- * @param queue_id Eventdev queue id
- * @param attr_id The attribute ID to retrieve
- * @param[out] attr_value A pointer that will be filled in with the attribute
- *             value if successful
+ * @param dev_id
+ *   Eventdev id
+ * @param queue_id
+ *   Eventdev queue id
+ * @param attr_id
+ *   The attribute ID to retrieve
+ * @param[out] attr_value
+ *   A pointer that will be filled in with the attribute value if successful
  *
- * @retval 0 Successfully returned value
- *         -EINVAL invalid device, queue or attr_id provided, or attr_value
- *         was NULL
- *         -EOVERFLOW returned when attr_id is set to
- *         RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE and event_queue_cfg is set to
- *         RTE_EVENT_QUEUE_CFG_ALL_TYPES
+ * @return
+ *   - 0: Successfully returned value
+ *   - -EINVAL: invalid device, queue or attr_id provided, or attr_value was
+ *             NULL
+ *   - -EOVERFLOW: returned when attr_id is set to
+ *   RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE and event_queue_cfg is set to
+ *   RTE_EVENT_QUEUE_CFG_ALL_TYPES
  */
 int
 rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
@@ -754,14 +759,18 @@ rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
 /**
  * Get an attribute from a port.
  *
- * @param dev_id Eventdev id
- * @param port_id Eventdev port id
- * @param attr_id The attribute ID to retrieve
- * @param[out] attr_value A pointer that will be filled in with the attribute
- *             value if successful
+ * @param dev_id
+ *   Eventdev id
+ * @param port_id
+ *   Eventdev port id
+ * @param attr_id
+ *   The attribute ID to retrieve
+ * @param[out] attr_value
+ *   A pointer that will be filled in with the attribute value if successful
  *
- * @retval 0 Successfully returned value
- *         -EINVAL Invalid device, port or attr_id, or attr_value was NULL
+ * @return
+ *   - 0: Successfully returned value
+ *   - (-EINVAL) Invalid device, port or attr_id, or attr_value was NULL
  */
 int
 rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,
index 7a206c5..64535f2 100644 (file)
@@ -47,6 +47,7 @@ extern "C" {
 #include <string.h>
 
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_dev.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
@@ -76,6 +77,14 @@ extern "C" {
        } \
 } while (0)
 
+#define RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, errno, retval) do { \
+       if (!rte_event_pmd_is_valid_dev((dev_id))) { \
+               RTE_EDEV_LOG_ERR("Invalid dev_id=%d\n", dev_id); \
+               rte_errno = errno; \
+               return retval; \
+       } \
+} while (0)
+
 #define RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id) do { \
        if (!rte_event_pmd_is_valid_dev((dev_id))) { \
                RTE_EDEV_LOG_ERR("Invalid dev_id=%d\n", dev_id); \
index ade32b5..8da40be 100644 (file)
@@ -47,6 +47,7 @@ extern "C" {
 
 #include <string.h>
 
+#include <rte_config.h>
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
index 56232de..f77d59b 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
 
 #include <string.h>
 
+#include <rte_config.h>
 #include <rte_debug.h>
 #include <rte_eal.h>
 #include <rte_bus_vdev.h>
index 1211873..e14bc78 100644 (file)
@@ -70,6 +70,7 @@
  *    with rte_flow_classifier_free()
  */
 
+#include <rte_common.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
 #include <rte_flow.h>
@@ -82,9 +83,12 @@ extern "C" {
 
 extern int librte_flow_classify_logtype;
 
-#define RTE_FLOW_CLASSIFY_LOG(level, fmt, args...) \
-rte_log(RTE_LOG_ ## level, librte_flow_classify_logtype, "%s(): " fmt, \
-       __func__, ## args)
+#define RTE_FLOW_CLASSIFY_LOG(level, ...) \
+       rte_log(RTE_LOG_ ## level, \
+               librte_flow_classify_logtype, \
+               RTE_FMT("%s(): " RTE_FMT_HEAD(__VA_ARGS__,), \
+                       __func__, \
+                       RTE_FMT_TAIL(__VA_ARGS__,)))
 
 /** Opaque data type for flow classifier */
 struct rte_flow_classifier;
index c39c097..e0d42b4 100644 (file)
@@ -54,6 +54,7 @@ extern "C" {
 
 #include <string.h>
 
+#include <rte_config.h>
 #ifndef RTE_FBK_HASH_FUNC_DEFAULT
 #if defined(RTE_ARCH_X86) || defined(RTE_MACHINE_CPUFLAG_CRC32)
 #include <rte_hash_crc.h>
index 4f815ae..93188c2 100644 (file)
@@ -45,6 +45,7 @@ extern "C" {
 #endif
 
 #include <stdint.h>
+#include <rte_config.h>
 #include <rte_cpuflags.h>
 #include <rte_branch_prediction.h>
 #include <rte_common.h>
index 3eca138..42c4568 100644 (file)
@@ -48,6 +48,7 @@ extern "C" {
 #include <string.h>
 #include <limits.h>
 
+#include <rte_config.h>
 #include <rte_log.h>
 #include <rte_byteorder.h>
 
index 4fa5e07..a6ddb7b 100644 (file)
@@ -53,6 +53,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <rte_byteorder.h>
+#include <rte_config.h>
 #include <rte_ip.h>
 #include <rte_common.h>
 
index 9f8cede..0144164 100644 (file)
@@ -48,6 +48,7 @@ extern "C" {
 #include <stdint.h>
 #include <stdio.h>
 
+#include <rte_config.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
 #include <rte_ip.h>
index e1f1fad..dda74a9 100644 (file)
@@ -912,7 +912,7 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
                 */
 
                struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
-                       { .group_idx = (uint8_t)tbl8_group_index, },
+                       .group_idx = (uint8_t)tbl8_group_index,
                        .valid = VALID,
                        .valid_group = 1,
                        .depth = 0,
@@ -958,7 +958,7 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
                 */
 
                struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
-                               { .group_idx = (uint8_t)tbl8_group_index, },
+                               .group_idx = (uint8_t)tbl8_group_index,
                                .valid = VALID,
                                .valid_group = 1,
                                .depth = 0,
@@ -1365,7 +1365,7 @@ delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
                 */
 
                struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
-                       {.next_hop = lpm->rules_tbl[sub_rule_index].next_hop,},
+                       .next_hop = lpm->rules_tbl[sub_rule_index].next_hop,
                        .valid = VALID,
                        .valid_group = 0,
                        .depth = sub_rule_depth,
@@ -1668,7 +1668,7 @@ delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
        } else if (tbl8_recycle_index > -1) {
                /* Update tbl24 entry. */
                struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
-                       { .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop, },
+                       .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop,
                        .valid = VALID,
                        .valid_group = 0,
                        .depth = lpm->tbl8[tbl8_recycle_index].depth,
index 682865e..650c51d 100644 (file)
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <rte_branch_prediction.h>
 #include <rte_byteorder.h>
+#include <rte_config.h>
 #include <rte_memory.h>
 #include <rte_common.h>
 #include <rte_vect.h>
index ce8a05d..16a6048 100644 (file)
@@ -62,6 +62,7 @@
 
 #include <stdint.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_mempool.h>
 #include <rte_memory.h>
 #include <rte_atomic.h>
@@ -764,6 +765,13 @@ rte_mbuf_refcnt_set(struct rte_mbuf *m, uint16_t new_value)
        rte_atomic16_set(&m->refcnt_atomic, new_value);
 }
 
+/* internal */
+static inline uint16_t
+__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
+{
+       return (uint16_t)(rte_atomic16_add_return(&m->refcnt_atomic, value));
+}
+
 /**
  * Adds given value to an mbuf's refcnt and returns its new value.
  * @param m
@@ -788,19 +796,26 @@ rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
                return 1 + value;
        }
 
-       return (uint16_t)(rte_atomic16_add_return(&m->refcnt_atomic, value));
+       return __rte_mbuf_refcnt_update(m, value);
 }
 
 #else /* ! RTE_MBUF_REFCNT_ATOMIC */
 
+/* internal */
+static inline uint16_t
+__rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
+{
+       m->refcnt = (uint16_t)(m->refcnt + value);
+       return m->refcnt;
+}
+
 /**
  * Adds given value to an mbuf's refcnt and returns its new value.
  */
 static inline uint16_t
 rte_mbuf_refcnt_update(struct rte_mbuf *m, int16_t value)
 {
-       m->refcnt = (uint16_t)(m->refcnt + value);
-       return m->refcnt;
+       return __rte_mbuf_refcnt_update(m, value);
 }
 
 /**
@@ -1364,8 +1379,7 @@ rte_pktmbuf_prefree_seg(struct rte_mbuf *m)
 
                return m;
 
-       } else if (rte_atomic16_add_return(&m->refcnt_atomic, -1) == 0) {
-
+       } else if (__rte_mbuf_refcnt_update(m, -1) == 0) {
 
                if (RTE_MBUF_INDIRECT(m))
                        rte_pktmbuf_detach(m);
@@ -1413,13 +1427,14 @@ rte_pktmbuf_free_seg(struct rte_mbuf *m)
  * segment is added back into its original mempool.
  *
  * @param m
- *   The packet mbuf to be freed.
+ *   The packet mbuf to be freed. If NULL, the function does nothing.
  */
 static inline void rte_pktmbuf_free(struct rte_mbuf *m)
 {
        struct rte_mbuf *m_next;
 
-       __rte_mbuf_sanity_check(m, 1);
+       if (m != NULL)
+               __rte_mbuf_sanity_check(m, 1);
 
        while (m != NULL) {
                m_next = m->next;
index cc9ea84..c3a238b 100644 (file)
@@ -191,8 +191,9 @@ rte_member_create(const struct rte_member_parameters *params)
        return setsum;
 
 error_unlock_exit:
+       rte_free(te);
+       rte_free(setsum);
        rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
-       rte_member_free(setsum);
        return NULL;
 }
 
index 9b0c8f9..56dd3b3 100644 (file)
@@ -80,6 +80,9 @@ extern "C" {
 
 #include <stdint.h>
 
+#include <rte_common.h>
+#include <rte_config.h>
+
 /** The set ID type that stored internally in hash table based set summary. */
 typedef uint16_t member_set_t;
 /** Invalid set ID used to mean no match found. */
@@ -104,9 +107,12 @@ typedef uint16_t member_set_t;
 
 extern int librte_member_logtype;
 
-#define RTE_MEMBER_LOG(level, fmt, args...) \
-rte_log(RTE_LOG_ ## level, librte_member_logtype, "%s(): " fmt, \
-       __func__, ## args)
+#define RTE_MEMBER_LOG(level, ...) \
+       rte_log(RTE_LOG_ ## level, \
+               librte_member_logtype, \
+               RTE_FMT("%s(): " RTE_FMT_HEAD(__VA_ARGS__,), \
+                       __func__, \
+                       RTE_FMT_TAIL(__VA_ARGS__,)))
 
 /** @internal setsummary structure. */
 struct rte_member_setsum;
index d50dba4..5bd74ea 100644 (file)
@@ -362,16 +362,12 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
        void *opaque)
 {
        unsigned total_elt_sz;
+       unsigned int mp_capa_flags;
        unsigned i = 0;
        size_t off;
        struct rte_mempool_memhdr *memhdr;
        int ret;
 
-       /* Notify memory area to mempool */
-       ret = rte_mempool_ops_register_memory_area(mp, vaddr, iova, len);
-       if (ret != -ENOTSUP && ret < 0)
-               return ret;
-
        /* create the internal ring if not already done */
        if ((mp->flags & MEMPOOL_F_POOL_CREATED) == 0) {
                ret = rte_mempool_ops_alloc(mp);
@@ -380,14 +376,28 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
                mp->flags |= MEMPOOL_F_POOL_CREATED;
        }
 
+       /* Notify memory area to mempool */
+       ret = rte_mempool_ops_register_memory_area(mp, vaddr, iova, len);
+       if (ret != -ENOTSUP && ret < 0)
+               return ret;
+
        /* mempool is already populated */
        if (mp->populated_size >= mp->size)
                return -ENOSPC;
 
        total_elt_sz = mp->header_size + mp->elt_size + mp->trailer_size;
 
+       /* Get mempool capabilities */
+       mp_capa_flags = 0;
+       ret = rte_mempool_ops_get_capabilities(mp, &mp_capa_flags);
+       if ((ret < 0) && (ret != -ENOTSUP))
+               return ret;
+
+       /* update mempool capabilities */
+       mp->flags |= mp_capa_flags;
+
        /* Detect pool area has sufficient space for elements */
-       if (mp->flags & MEMPOOL_F_CAPA_PHYS_CONTIG) {
+       if (mp_capa_flags & MEMPOOL_F_CAPA_PHYS_CONTIG) {
                if (len < total_elt_sz * mp->size) {
                        RTE_LOG(ERR, MEMPOOL,
                                "pool area %" PRIx64 " not enough\n",
@@ -407,7 +417,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
        memhdr->free_cb = free_cb;
        memhdr->opaque = opaque;
 
-       if (mp->flags & MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS)
+       if (mp_capa_flags & MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS)
                /* align object start address to a multiple of total_elt_sz */
                off = total_elt_sz - ((uintptr_t)vaddr % total_elt_sz);
        else if (mp->flags & MEMPOOL_F_NO_CACHE_ALIGN)
index 721227f..e21026a 100644 (file)
@@ -69,6 +69,7 @@
 #include <inttypes.h>
 #include <sys/queue.h>
 
+#include <rte_config.h>
 #include <rte_spinlock.h>
 #include <rte_log.h>
 #include <rte_debug.h>
index e228af0..148c06e 100644 (file)
@@ -49,8 +49,8 @@ extern "C" {
  * ESP Header
  */
 struct esp_hdr {
-       uint32_t spi;  /**< Security Parameters Index */
-       uint32_t seq;  /**< packet sequence number */
+       rte_be32_t spi;  /**< Security Parameters Index */
+       rte_be32_t seq;  /**< packet sequence number */
 } __attribute__((__packed__));
 
 #ifdef __cplusplus
index bc18f81..44dcc95 100644 (file)
@@ -581,7 +581,7 @@ rte_pdump_init(const char *path)
        if (ret != 0) {
                RTE_LOG(ERR, PDUMP,
                        "Failed to create the pdump thread:%s, %s:%d\n",
-                       strerror(errno), __func__, __LINE__);
+                       strerror(ret), __func__, __LINE__);
                return -1;
        }
        /* Set thread_name for aid in debugging. */
@@ -604,7 +604,7 @@ rte_pdump_uninit(void)
        if (ret != 0) {
                RTE_LOG(ERR, PDUMP,
                        "Failed to cancel the pdump thread:%s, %s:%d\n",
-                       strerror(errno), __func__, __LINE__);
+                       strerror(ret), __func__, __LINE__);
                return -1;
        }
 
index e924438..7069d52 100644 (file)
@@ -96,6 +96,7 @@ extern "C" {
 #include <sys/queue.h>
 #include <errno.h>
 #include <rte_common.h>
+#include <rte_config.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
 #include <rte_atomic.h>
index 1227fca..685729f 100644 (file)
@@ -49,7 +49,7 @@ rte_security_session_create(struct rte_security_ctx *instance,
 
        RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->session_create, NULL);
 
-       if (rte_mempool_get(mp, (void *)&sess))
+       if (rte_mempool_get(mp, (void **)&sess))
                return NULL;
 
        if (instance->ops->session_create(instance->device, conf, sess, mp)) {
index 653929b..2b609cb 100644 (file)
@@ -60,7 +60,7 @@ extern "C" {
 
 /** IPSec protocol mode */
 enum rte_security_ipsec_sa_mode {
-       RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+       RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT = 1,
        /**< IPSec Transport mode */
        RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
        /**< IPSec Tunnel mode */
@@ -68,7 +68,7 @@ enum rte_security_ipsec_sa_mode {
 
 /** IPSec Protocol */
 enum rte_security_ipsec_sa_protocol {
-       RTE_SECURITY_IPSEC_SA_PROTO_AH,
+       RTE_SECURITY_IPSEC_SA_PROTO_AH = 1,
        /**< AH protocol */
        RTE_SECURITY_IPSEC_SA_PROTO_ESP,
        /**< ESP protocol */
@@ -76,7 +76,7 @@ enum rte_security_ipsec_sa_protocol {
 
 /** IPSEC tunnel type */
 enum rte_security_ipsec_tunnel_type {
-       RTE_SECURITY_IPSEC_TUNNEL_IPV4,
+       RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 1,
        /**< Outer header is IPv4 */
        RTE_SECURITY_IPSEC_TUNNEL_IPV6,
        /**< Outer header is IPv6 */
@@ -94,7 +94,7 @@ enum rte_security_ipsec_tunnel_type {
 struct rte_security_ctx {
        void *device;
        /**< Crypto/ethernet device attached */
-       struct rte_security_ops *ops;
+       const struct rte_security_ops *ops;
        /**< Pointer to security ops for the device */
        uint16_t sess_cnt;
        /**< Number of sessions attached to this context */
@@ -228,6 +228,7 @@ struct rte_security_ipsec_xform {
  */
 struct rte_security_macsec_xform {
        /** To be Filled */
+       int dummy;
 };
 
 /**
@@ -252,7 +253,7 @@ enum rte_security_session_action_type {
 
 /** Security session protocol definition */
 enum rte_security_session_protocol {
-       RTE_SECURITY_PROTOCOL_IPSEC,
+       RTE_SECURITY_PROTOCOL_IPSEC = 1,
        /**< IPsec Protocol */
        RTE_SECURITY_PROTOCOL_MACSEC,
        /**< MACSec Protocol */
@@ -452,6 +453,7 @@ struct rte_security_capability {
                /**< IPsec capability */
                struct {
                        /* To be Filled */
+                       int dummy;
                } macsec;
                /**< MACsec capability */
        };
index 93258ef..a73b2ff 100644 (file)
@@ -38,6 +38,7 @@
 extern "C" {
 #endif
 
+#include <rte_config.h>
 #ifdef RTE_ARCH_X86_64
 #include "rte_lru_x86.h"
 #elif defined(RTE_ARCH_ARM64)
index 10f513c..b4f6052 100644 (file)
@@ -40,6 +40,8 @@ extern "C" {
 
 #include <stdint.h>
 
+#include <rte_config.h>
+
 #ifndef RTE_TABLE_HASH_LRU_STRATEGY
 #define RTE_TABLE_HASH_LRU_STRATEGY                        2
 #endif
index 88826f5..ba436cd 100644 (file)
@@ -432,7 +432,7 @@ rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
 
        if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
                        !(rte_lcore_is_enabled(tim_lcore) ||
-                               rte_lcore_has_role(tim_lcore, ROLE_SERVICE))))
+                         rte_lcore_has_role(tim_lcore, ROLE_SERVICE) == 0)))
                return -1;
 
        if (type == PERIODICAL)
index a276a73..3b50155 100644 (file)
@@ -67,6 +67,7 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <rte_common.h>
+#include <rte_config.h>
 
 #ifdef __cplusplus
 extern "C" {
index b74cc6a..c11ebca 100644 (file)
@@ -50,6 +50,9 @@ struct vhost_iotlb_entry {
 
 #define IOTLB_CACHE_SIZE 2048
 
+static void
+vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq);
+
 static void
 vhost_user_iotlb_pending_remove_all(struct vhost_virtqueue *vq)
 {
@@ -95,9 +98,11 @@ vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq,
 
        ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
        if (ret) {
-               RTE_LOG(INFO, VHOST_CONFIG,
-                               "IOTLB pool empty, clear pending misses\n");
-               vhost_user_iotlb_pending_remove_all(vq);
+               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+               if (!TAILQ_EMPTY(&vq->iotlb_pending_list))
+                       vhost_user_iotlb_pending_remove_all(vq);
+               else
+                       vhost_user_iotlb_cache_random_evict(vq);
                ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
                if (ret) {
                        RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
@@ -115,7 +120,7 @@ vhost_user_iotlb_pending_insert(struct vhost_virtqueue *vq,
        rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
 }
 
-static void
+void
 vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq,
                                uint64_t iova, uint64_t size, uint8_t perm)
 {
@@ -186,8 +191,11 @@ vhost_user_iotlb_cache_insert(struct vhost_virtqueue *vq, uint64_t iova,
 
        ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
        if (ret) {
-               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, evict one entry\n");
-               vhost_user_iotlb_cache_random_evict(vq);
+               RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+               if (!TAILQ_EMPTY(&vq->iotlb_list))
+                       vhost_user_iotlb_cache_random_evict(vq);
+               else
+                       vhost_user_iotlb_pending_remove_all(vq);
                ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
                if (ret) {
                        RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
index f1a050e..e7083e3 100644 (file)
@@ -71,6 +71,9 @@ bool vhost_user_iotlb_pending_miss(struct vhost_virtqueue *vq, uint64_t iova,
                                                uint8_t perm);
 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);
+
 int vhost_user_iotlb_init(struct virtio_net *dev, int vq_index);
 
 #endif /* _VHOST_IOTLB_H_ */
index 422da00..811e6bf 100644 (file)
@@ -472,7 +472,7 @@ vhost_user_reconnect_init(void)
 
        ret = pthread_create(&reconn_tid, NULL,
                             vhost_user_client_reconnect, NULL);
-       if (ret < 0) {
+       if (ret != 0) {
                RTE_LOG(ERR, VHOST_CONFIG, "failed to create reconnect thread");
                if (pthread_mutex_destroy(&reconn_list.mutex)) {
                        RTE_LOG(ERR, VHOST_CONFIG,
@@ -678,9 +678,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
        if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
                vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);
                if (vsocket->reconnect && reconn_tid == 0) {
-                       if (vhost_user_reconnect_init() < 0) {
+                       if (vhost_user_reconnect_init() != 0)
                                goto out_mutex;
-                       }
                }
        } else {
                vsocket->is_server = true;
@@ -837,7 +836,7 @@ rte_vhost_driver_start(const char *path)
        if (fdset_tid == 0) {
                int ret = pthread_create(&fdset_tid, NULL, fdset_event_dispatch,
                                     &vhost_user.fdset);
-               if (ret < 0)
+               if (ret != 0)
                        RTE_LOG(ERR, VHOST_CONFIG,
                                "failed to create fdset handling thread");
        }
index 4f8b73a..51ea720 100644 (file)
@@ -71,7 +71,9 @@ __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
        if (tmp_size == size)
                return vva;
 
-       if (!vhost_user_iotlb_pending_miss(vq, iova + tmp_size, perm)) {
+       iova += tmp_size;
+
+       if (!vhost_user_iotlb_pending_miss(vq, iova, perm)) {
                /*
                 * iotlb_lock is read-locked for a full burst,
                 * but it only protects the iotlb cache.
@@ -81,8 +83,13 @@ __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
                 */
                vhost_user_iotlb_rd_unlock(vq);
 
-               vhost_user_iotlb_pending_insert(vq, iova + tmp_size, perm);
-               vhost_user_iotlb_miss(dev, iova + tmp_size, perm);
+               vhost_user_iotlb_pending_insert(vq, iova, perm);
+               if (vhost_user_iotlb_miss(dev, iova, perm)) {
+                       RTE_LOG(ERR, VHOST_CONFIG,
+                               "IOTLB miss req failed for IOVA 0x%" PRIx64 "\n",
+                               iova);
+                       vhost_user_iotlb_pending_remove(vq, iova, 1, perm);
+               }
 
                vhost_user_iotlb_rd_lock(vq);
        }
@@ -259,6 +266,7 @@ alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
 
        dev->virtqueue[vring_idx] = vq;
        init_vring_queue(dev, vring_idx);
+       rte_spinlock_init(&vq->access_lock);
 
        dev->nr_vring += 1;
 
index 1cc81c1..c8f2a81 100644 (file)
@@ -108,12 +108,14 @@ struct vhost_virtqueue {
 
        /* Backend value to determine if device should started/stopped */
        int                     backend;
+       int                     enabled;
+       int                     access_ok;
+       rte_spinlock_t          access_lock;
+
        /* Used to notify the guest (trigger interrupt) */
        int                     callfd;
        /* Currently unused as polling mode is enabled */
        int                     kickfd;
-       int                     enabled;
-       int                     access_ok;
 
        /* Physical address of used ring, for logging */
        uint64_t                log_guest_addr;
index f4c7ce4..3acaacf 100644 (file)
@@ -573,6 +573,30 @@ dump_guest_pages(struct virtio_net *dev)
 #define dump_guest_pages(dev)
 #endif
 
+static bool
+vhost_memory_changed(struct VhostUserMemory *new,
+                    struct rte_vhost_memory *old)
+{
+       uint32_t i;
+
+       if (new->nregions != old->nregions)
+               return true;
+
+       for (i = 0; i < new->nregions; ++i) {
+               VhostUserMemoryRegion *new_r = &new->regions[i];
+               struct rte_vhost_mem_region *old_r = &old->regions[i];
+
+               if (new_r->guest_phys_addr != old_r->guest_phys_addr)
+                       return true;
+               if (new_r->memory_size != old_r->size)
+                       return true;
+               if (new_r->userspace_addr != old_r->guest_user_addr)
+                       return true;
+       }
+
+       return false;
+}
+
 static int
 vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
 {
@@ -585,6 +609,16 @@ vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
        uint32_t i;
        int fd;
 
+       if (dev->mem && !vhost_memory_changed(&memory, dev->mem)) {
+               RTE_LOG(INFO, VHOST_CONFIG,
+                       "(%d) memory regions not changed\n", dev->vid);
+
+               for (i = 0; i < memory.nregions; i++)
+                       close(pmsg->fds[i]);
+
+               return 0;
+       }
+
        if (dev->mem) {
                free_mem_region(dev);
                rte_free(dev->mem);
@@ -1190,12 +1224,47 @@ vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, VhostUserMsg *msg)
        return alloc_vring_queue(dev, vring_idx);
 }
 
+static void
+vhost_user_lock_all_queue_pairs(struct virtio_net *dev)
+{
+       unsigned int i = 0;
+       unsigned int vq_num = 0;
+
+       while (vq_num < dev->nr_vring) {
+               struct vhost_virtqueue *vq = dev->virtqueue[i];
+
+               if (vq) {
+                       rte_spinlock_lock(&vq->access_lock);
+                       vq_num++;
+               }
+               i++;
+       }
+}
+
+static void
+vhost_user_unlock_all_queue_pairs(struct virtio_net *dev)
+{
+       unsigned int i = 0;
+       unsigned int vq_num = 0;
+
+       while (vq_num < dev->nr_vring) {
+               struct vhost_virtqueue *vq = dev->virtqueue[i];
+
+               if (vq) {
+                       rte_spinlock_unlock(&vq->access_lock);
+                       vq_num++;
+               }
+               i++;
+       }
+}
+
 int
 vhost_user_msg_handler(int vid, int fd)
 {
        struct virtio_net *dev;
        struct VhostUserMsg msg;
        int ret;
+       int unlock_required = 0;
 
        dev = get_device(vid);
        if (dev == NULL)
@@ -1241,6 +1310,38 @@ vhost_user_msg_handler(int vid, int fd)
                return -1;
        }
 
+       /*
+        * Note: we don't lock all queues on VHOST_USER_GET_VRING_BASE,
+        * since it is sent when virtio stops and device is destroyed.
+        * destroy_device waits for queues to be inactive, so it is safe.
+        * Otherwise taking the access_lock would cause a dead lock.
+        */
+       switch (msg.request.master) {
+       case VHOST_USER_SET_FEATURES:
+       case VHOST_USER_SET_PROTOCOL_FEATURES:
+       case VHOST_USER_SET_OWNER:
+       case VHOST_USER_RESET_OWNER:
+       case VHOST_USER_SET_MEM_TABLE:
+       case VHOST_USER_SET_LOG_BASE:
+       case VHOST_USER_SET_LOG_FD:
+       case VHOST_USER_SET_VRING_NUM:
+       case VHOST_USER_SET_VRING_ADDR:
+       case VHOST_USER_SET_VRING_BASE:
+       case VHOST_USER_SET_VRING_KICK:
+       case VHOST_USER_SET_VRING_CALL:
+       case VHOST_USER_SET_VRING_ERR:
+       case VHOST_USER_SET_VRING_ENABLE:
+       case VHOST_USER_SEND_RARP:
+       case VHOST_USER_NET_SET_MTU:
+       case VHOST_USER_SET_SLAVE_REQ_FD:
+               vhost_user_lock_all_queue_pairs(dev);
+               unlock_required = 1;
+               break;
+       default:
+               break;
+
+       }
+
        switch (msg.request.master) {
        case VHOST_USER_GET_FEATURES:
                msg.payload.u64 = vhost_user_get_features(dev);
@@ -1342,6 +1443,9 @@ vhost_user_msg_handler(int vid, int fd)
 
        }
 
+       if (unlock_required)
+               vhost_user_unlock_all_queue_pairs(dev);
+
        if (msg.flags & VHOST_USER_NEED_REPLY) {
                msg.payload.u64 = !!ret;
                msg.size = sizeof(msg.payload.u64);
index 6fee16e..d347030 100644 (file)
@@ -44,6 +44,7 @@
 #include <rte_udp.h>
 #include <rte_sctp.h>
 #include <rte_arp.h>
+#include <rte_spinlock.h>
 
 #include "iotlb.h"
 #include "vhost.h"
@@ -326,8 +327,11 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
        }
 
        vq = dev->virtqueue[queue_id];
+
+       rte_spinlock_lock(&vq->access_lock);
+
        if (unlikely(vq->enabled == 0))
-               return 0;
+               goto out_access_unlock;
 
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
                vhost_user_iotlb_rd_lock(vq);
@@ -419,6 +423,9 @@ out:
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
                vhost_user_iotlb_rd_unlock(vq);
 
+out_access_unlock:
+       rte_spinlock_unlock(&vq->access_lock);
+
        return count;
 }
 
@@ -651,8 +658,11 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
        }
 
        vq = dev->virtqueue[queue_id];
+
+       rte_spinlock_lock(&vq->access_lock);
+
        if (unlikely(vq->enabled == 0))
-               return 0;
+               goto out_access_unlock;
 
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
                vhost_user_iotlb_rd_lock(vq);
@@ -715,6 +725,9 @@ out:
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
                vhost_user_iotlb_rd_unlock(vq);
 
+out_access_unlock:
+       rte_spinlock_unlock(&vq->access_lock);
+
        return pkt_idx;
 }
 
@@ -977,7 +990,8 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
                                        desc->addr + desc_offset, cpy_len)))) {
                        cur->data_len = cpy_len;
                        cur->data_off = 0;
-                       cur->buf_addr = (void *)(uintptr_t)desc_addr;
+                       cur->buf_addr = (void *)(uintptr_t)(desc_addr
+                               + desc_offset);
                        cur->buf_iova = hpa;
 
                        /*
@@ -1156,6 +1170,22 @@ mbuf_is_consumed(struct rte_mbuf *m)
        return true;
 }
 
+static __rte_always_inline void
+restore_mbuf(struct rte_mbuf *m)
+{
+       uint32_t mbuf_size, priv_size;
+
+       while (m) {
+               priv_size = rte_pktmbuf_priv_size(m->pool);
+               mbuf_size = sizeof(struct rte_mbuf) + priv_size;
+               /* start of buffer is after mbuf structure and priv data */
+
+               m->buf_addr = (char *)m + mbuf_size;
+               m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size;
+               m = m->next;
+       }
+}
+
 uint16_t
 rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
        struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -1180,9 +1210,13 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
        }
 
        vq = dev->virtqueue[queue_id];
-       if (unlikely(vq->enabled == 0))
+
+       if (unlikely(rte_spinlock_trylock(&vq->access_lock) == 0))
                return 0;
 
+       if (unlikely(vq->enabled == 0))
+               goto out_access_unlock;
+
        vq->batch_copy_nb_elems = 0;
 
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
@@ -1207,6 +1241,7 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
                                nr_updated += 1;
 
                                TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next);
+                               restore_mbuf(zmbuf->mbuf);
                                rte_pktmbuf_free(zmbuf->mbuf);
                                put_zmbuf(zmbuf);
                                vq->nr_zmbuf -= 1;
@@ -1356,6 +1391,9 @@ out:
        if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
                vhost_user_iotlb_rd_unlock(vq);
 
+out_access_unlock:
+       rte_spinlock_unlock(&vq->access_lock);
+
        if (unlikely(rarp_mbuf != NULL)) {
                /*
                 * Inject it to the head of "pkts" array, so that switch's mac
index e2462fd..ea41ebf 100644 (file)
@@ -48,7 +48,7 @@ ifeq ("$(origin M)", "command line")
 RTE_EXTMK := $(abspath $(M))
 endif
 endif
-RTE_EXTMK ?= $(RTE_SRCDIR)/Makefile
+RTE_EXTMK ?= $(RTE_SRCDIR)/$(notdir $(firstword $(MAKEFILE_LIST)))
 export RTE_EXTMK
 
 # RTE_SDK_BIN must point to .config, include/ and lib/.
diff --git a/mk/machine/tilegx/rte.vars.mk b/mk/machine/tilegx/rte.vars.mk
deleted file mode 100644 (file)
index c8256f1..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright (C) EZchip Semiconductor Ltd. 2015.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of EZchip Semiconductor nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#
-# machine:
-#
-#   - can define ARCH variable (overridden by cmdline value)
-#   - can define CROSS variable (overridden by cmdline value)
-#   - define MACHINE_CFLAGS variable (overridden by cmdline value)
-#   - define MACHINE_LDFLAGS variable (overridden by cmdline value)
-#   - define MACHINE_ASFLAGS variable (overridden by cmdline value)
-#   - can define CPU_CFLAGS variable (overridden by cmdline value) that
-#     overrides the one defined in arch.
-#   - can define CPU_LDFLAGS variable (overridden by cmdline value) that
-#     overrides the one defined in arch.
-#   - can define CPU_ASFLAGS variable (overridden by cmdline value) that
-#     overrides the one defined in arch.
-#   - may override any previously defined variable
-#
-
-# ARCH =
-# CROSS =
-# MACHINE_CFLAGS =
-# MACHINE_LDFLAGS =
-# MACHINE_ASFLAGS =
-# CPU_CFLAGS =
-# CPU_LDFLAGS =
-# CPU_ASFLAGS =
-
-MACHINE_CFLAGS =
index 6a41fc7..bbb16f1 100644 (file)
@@ -30,7 +30,7 @@
 # OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Name: dpdk
-Version: 17.11
+Version: 17.11.1
 Release: 1
 Packager: packaging@6wind.com
 URL: http://dpdk.org
index 0e6ff7c..fe41d40 100644 (file)
@@ -162,8 +162,20 @@ unit_test_suite_runner(struct unit_test_suite *suite)
        }
 
        if (suite->setup)
-               if (suite->setup() != 0)
+               if (suite->setup() != 0) {
+                       /*
+                        * setup failed, so count all enabled tests and mark
+                        * them as failed
+                        */
+                       while (suite->unit_test_cases[total].testcase) {
+                               if (!suite->unit_test_cases[total].enabled)
+                                       skipped++;
+                               else
+                                       failed++;
+                               total++;
+                       }
                        goto suite_summary;
+               }
 
        printf(" + ------------------------------------------------------- +\n");
 
index 5c9eee9..7045d33 100644 (file)
@@ -186,6 +186,9 @@ test_bitmap(void)
        if (test_bitmap_scan_operations(bmp) < 0)
                return TEST_FAILED;
 
+       rte_bitmap_free(bmp);
+       rte_free(mem);
+
        return TEST_SUCCESS;
 }
 
index 1bed65d..7997b48 100644 (file)
@@ -30,6 +30,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <time.h>
+
 #include <rte_common.h>
 #include <rte_hexdump.h>
 #include <rte_mbuf.h>
index ba39cba..1ed2a1d 100644 (file)
@@ -839,6 +839,9 @@ test_eventdev_unlink(void)
        for (i = 0; i < nb_queues; i++)
                queues[i] = i;
 
+       ret = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0);
+       TEST_ASSERT(ret >= 0, "Failed to link with NULL device%d",
+                                TEST_DEV_ID);
 
        ret = rte_event_port_unlink(TEST_DEV_ID, 0, queues, nb_queues);
        TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d",
@@ -899,9 +902,9 @@ test_eventdev_link_get(void)
        ret = rte_event_port_links_get(TEST_DEV_ID, 0, queues, priorities);
        TEST_ASSERT(ret == 1, "(%d)Wrong link get ret=%d expected=%d",
                                        TEST_DEV_ID, ret, 1);
-       /* unlink all*/
+       /* unlink the queue */
        ret = rte_event_port_unlink(TEST_DEV_ID, 0, NULL, 0);
-       TEST_ASSERT(ret == nb_queues, "Failed to unlink(device%d) ret=%d",
+       TEST_ASSERT(ret == 1, "Failed to unlink(device%d) ret=%d",
                                 TEST_DEV_ID, ret);
 
        /* 4links and 2 unlinks */
index dbc36d9..8fddb4f 100644 (file)
@@ -355,7 +355,7 @@ generate_random_events(const unsigned int total_events)
        for (i = 0; i < total_events; i++) {
                ret = inject_events(
                        rte_rand() % info.max_event_queue_flows /*flow_id */,
-                       rte_rand() % (RTE_EVENT_TYPE_CPU + 1) /* event_type */,
+                       RTE_EVENT_TYPE_CPU /* event_type */,
                        rte_rand() % 256 /* sub_event_type */,
                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
                        rte_rand() % queue_count /* queue */,
@@ -745,7 +745,7 @@ test_queue_to_port_single_link(void)
 
                ret = inject_events(
                        0x100 /*flow_id */,
-                       rte_rand() % (RTE_EVENT_TYPE_CPU + 1) /* event_type */,
+                       RTE_EVENT_TYPE_CPU /* event_type */,
                        rte_rand() % 256 /* sub_event_type */,
                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
                        queue /* queue */,
@@ -824,7 +824,7 @@ test_queue_to_port_multi_link(void)
 
                ret = inject_events(
                        0x100 /*flow_id */,
-                       rte_rand() % (RTE_EVENT_TYPE_CPU + 1) /* event_type */,
+                       RTE_EVENT_TYPE_CPU /* event_type */,
                        rte_rand() % 256 /* sub_event_type */,
                        rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
                        queue /* queue */,
index 1cf235a..1115ee0 100644 (file)
@@ -280,19 +280,24 @@ test_memzone_reserve_flags(void)
                                printf("MEMZONE FLAG 2MB\n");
                                return -1;
                        }
-                       if (rte_memzone_free(mz)) {
-                               printf("Fail memzone free\n");
-                               return -1;
-                       }
                }
 
                if (hugepage_2MB_avail && hugepage_1GB_avail) {
                        mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
                                                                RTE_MEMZONE_2MB|RTE_MEMZONE_1GB);
-                       if (mz != NULL) {
+                       if (mz == NULL) {
                                printf("BOTH SIZES SET\n");
                                return -1;
                        }
+                       if (mz->hugepage_sz != RTE_PGSIZE_1G &&
+                                       mz->hugepage_sz != RTE_PGSIZE_2M) {
+                               printf("Wrong size when both sizes set\n");
+                               return -1;
+                       }
+                       if (rte_memzone_free(mz)) {
+                               printf("Fail memzone free\n");
+                               return -1;
+                       }
                }
        }
        /*
@@ -424,10 +429,19 @@ test_memzone_reserve_flags(void)
                        mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
                                SOCKET_ID_ANY,
                                RTE_MEMZONE_16MB|RTE_MEMZONE_16GB);
-                       if (mz != NULL) {
+                       if (mz == NULL) {
                                printf("BOTH SIZES SET\n");
                                return -1;
                        }
+                       if (mz->hugepage_sz != RTE_PGSIZE_16G &&
+                                       mz->hugepage_sz != RTE_PGSIZE_16M) {
+                               printf("Wrong size when both sizes set\n");
+                               return -1;
+                       }
+                       if (rte_memzone_free(mz)) {
+                               printf("Fail memzone free\n");
+                               return -1;
+                       }
                }
        }
        return 0;
@@ -775,7 +789,7 @@ test_memzone_bounded(void)
 static int
 test_memzone_free(void)
 {
-       const struct rte_memzone *mz[RTE_MAX_MEMZONE];
+       const struct rte_memzone *mz[RTE_MAX_MEMZONE + 1];
        int i;
        char name[20];
 
index 4ec22ac..429f6eb 100644 (file)
@@ -360,9 +360,20 @@ test_setup(void)
        return 0;
 }
 
+static void
+test_teardown(void)
+{
+       rte_reorder_free(test_params->b);
+       test_params->b = NULL;
+       rte_mempool_free(test_params->p);
+       test_params->p = NULL;
+}
+
+
 static struct unit_test_suite reorder_test_suite  = {
 
        .setup = test_setup,
+       .teardown = test_teardown,
        .suite_name = "Reorder Unit Test Suite",
        .unit_test_cases = {
                TEST_CASE(test_reorder_create),
index 5eb40a0..d225e82 100644 (file)
@@ -86,8 +86,6 @@
 
 static rte_atomic32_t synchro;
 
-static struct rte_ring *r;
-
 #define        TEST_RING_VERIFY(exp)                                           \
        if (!(exp)) {                                                   \
                printf("error at %s:%d\tcondition " #exp " failed\n",   \
@@ -102,7 +100,7 @@ static struct rte_ring *r;
  * helper routine for test_ring_basic
  */
 static int
-test_ring_basic_full_empty(void * const src[], void *dst[])
+test_ring_basic_full_empty(struct rte_ring *r, void * const src[], void *dst[])
 {
        unsigned i, rand;
        const unsigned rsz = RING_SIZE - 1;
@@ -143,7 +141,7 @@ test_ring_basic_full_empty(void * const src[], void *dst[])
 }
 
 static int
-test_ring_basic(void)
+test_ring_basic(struct rte_ring *r)
 {
        void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
        int ret;
@@ -279,7 +277,7 @@ test_ring_basic(void)
                goto fail;
        }
 
-       if (test_ring_basic_full_empty(src, dst) != 0)
+       if (test_ring_basic_full_empty(r, src, dst) != 0)
                goto fail;
 
        cur_src = src;
@@ -346,7 +344,7 @@ test_ring_basic(void)
 }
 
 static int
-test_ring_burst_basic(void)
+test_ring_burst_basic(struct rte_ring *r)
 {
        void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
        int ret;
@@ -700,7 +698,7 @@ test_ring_basic_ex(void)
 {
        int ret = -1;
        unsigned i;
-       struct rte_ring * rp;
+       struct rte_ring *rp = NULL;
        void **obj = NULL;
 
        obj = rte_calloc("test_ring_basic_ex_malloc", RING_SIZE, sizeof(void *), 0);
@@ -760,6 +758,7 @@ test_ring_basic_ex(void)
 
        ret = 0;
 fail_test:
+       rte_ring_free(rp);
        if (obj != NULL)
                rte_free(obj);
 
@@ -840,61 +839,67 @@ end:
 static int
 test_ring(void)
 {
+       struct rte_ring *r = NULL;
+
        /* some more basic operations */
        if (test_ring_basic_ex() < 0)
-               return -1;
+               goto test_fail;
 
        rte_atomic32_init(&synchro);
 
+       r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
        if (r == NULL)
-               r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
-       if (r == NULL)
-               return -1;
+               goto test_fail;
 
        /* retrieve the ring from its name */
        if (rte_ring_lookup("test") != r) {
                printf("Cannot lookup ring from its name\n");
-               return -1;
+               goto test_fail;
        }
 
        /* burst operations */
-       if (test_ring_burst_basic() < 0)
-               return -1;
+       if (test_ring_burst_basic(r) < 0)
+               goto test_fail;
 
        /* basic operations */
-       if (test_ring_basic() < 0)
-               return -1;
+       if (test_ring_basic(r) < 0)
+               goto test_fail;
 
        /* basic operations */
        if ( test_create_count_odd() < 0){
-                       printf ("Test failed to detect odd count\n");
-                       return -1;
-               }
-               else
-                       printf ( "Test detected odd count\n");
+               printf("Test failed to detect odd count\n");
+               goto test_fail;
+       } else
+               printf("Test detected odd count\n");
 
        if ( test_lookup_null() < 0){
-                               printf ("Test failed to detect NULL ring lookup\n");
-                               return -1;
-                       }
-                       else
-                               printf ( "Test detected NULL ring lookup \n");
+               printf("Test failed to detect NULL ring lookup\n");
+               goto test_fail;
+       } else
+               printf("Test detected NULL ring lookup\n");
 
        /* test of creating ring with wrong size */
        if (test_ring_creation_with_wrong_size() < 0)
-               return -1;
+               goto test_fail;
 
        /* test of creation ring with an used name */
        if (test_ring_creation_with_an_used_name() < 0)
-               return -1;
+               goto test_fail;
 
        if (test_ring_with_exact_size() < 0)
-               return -1;
+               goto test_fail;
 
        /* dump the ring status */
        rte_ring_list_dump(stdout);
 
+       rte_ring_free(r);
+
        return 0;
+
+test_fail:
+       rte_ring_free(r);
+
+       return -1;
 }
 
 REGISTER_TEST_COMMAND(ring_autotest, test_ring);
index 84d2003..66aa51a 100644 (file)
@@ -61,9 +61,6 @@
  */
 static const volatile unsigned bulk_sizes[] = { 8, 32 };
 
-/* The ring structure used for tests */
-static struct rte_ring *r;
-
 struct lcore_pair {
        unsigned c1, c2;
 };
@@ -144,7 +141,7 @@ get_two_sockets(struct lcore_pair *lcp)
 
 /* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */
 static void
-test_empty_dequeue(void)
+test_empty_dequeue(struct rte_ring *r)
 {
        const unsigned iter_shift = 26;
        const unsigned iterations = 1<<iter_shift;
@@ -172,6 +169,7 @@ test_empty_dequeue(void)
  * and return two. Input = burst size, output = cycle average for sp/sc & mp/mc
  */
 struct thread_params {
+       struct rte_ring *r;
        unsigned size;        /* input value, the burst size */
        double spsc, mpmc;    /* output value, the single or multi timings */
 };
@@ -186,6 +184,7 @@ enqueue_bulk(void *p)
        const unsigned iter_shift = 23;
        const unsigned iterations = 1<<iter_shift;
        struct thread_params *params = p;
+       struct rte_ring *r = params->r;
        const unsigned size = params->size;
        unsigned i;
        void *burst[MAX_BURST] = {0};
@@ -221,6 +220,7 @@ dequeue_bulk(void *p)
        const unsigned iter_shift = 23;
        const unsigned iterations = 1<<iter_shift;
        struct thread_params *params = p;
+       struct rte_ring *r = params->r;
        const unsigned size = params->size;
        unsigned i;
        void *burst[MAX_BURST] = {0};
@@ -251,7 +251,7 @@ dequeue_bulk(void *p)
  * used to measure ring perf between hyperthreads, cores and sockets.
  */
 static void
-run_on_core_pair(struct lcore_pair *cores,
+run_on_core_pair(struct lcore_pair *cores, struct rte_ring *r,
                lcore_function_t f1, lcore_function_t f2)
 {
        struct thread_params param1 = {0}, param2 = {0};
@@ -259,6 +259,7 @@ run_on_core_pair(struct lcore_pair *cores,
        for (i = 0; i < sizeof(bulk_sizes)/sizeof(bulk_sizes[0]); i++) {
                lcore_count = 0;
                param1.size = param2.size = bulk_sizes[i];
+               param1.r = param2.r = r;
                if (cores->c1 == rte_get_master_lcore()) {
                        rte_eal_remote_launch(f2, &param2, cores->c2);
                        f1(&param1);
@@ -281,7 +282,7 @@ run_on_core_pair(struct lcore_pair *cores,
  * takes on a single lcore. Result is for comparison with the bulk enq+deq.
  */
 static void
-test_single_enqueue_dequeue(void)
+test_single_enqueue_dequeue(struct rte_ring *r)
 {
        const unsigned iter_shift = 24;
        const unsigned iterations = 1<<iter_shift;
@@ -314,7 +315,7 @@ test_single_enqueue_dequeue(void)
  * as for the bulk function called on a single lcore.
  */
 static void
-test_burst_enqueue_dequeue(void)
+test_burst_enqueue_dequeue(struct rte_ring *r)
 {
        const unsigned iter_shift = 23;
        const unsigned iterations = 1<<iter_shift;
@@ -352,7 +353,7 @@ test_burst_enqueue_dequeue(void)
 
 /* Times enqueue and dequeue on a single lcore */
 static void
-test_bulk_enqueue_dequeue(void)
+test_bulk_enqueue_dequeue(struct rte_ring *r)
 {
        const unsigned iter_shift = 23;
        const unsigned iterations = 1<<iter_shift;
@@ -394,32 +395,35 @@ static int
 test_ring_perf(void)
 {
        struct lcore_pair cores;
+       struct rte_ring *r = NULL;
+
        r = rte_ring_create(RING_NAME, RING_SIZE, rte_socket_id(), 0);
-       if (r == NULL && (r = rte_ring_lookup(RING_NAME)) == NULL)
+       if (r == NULL)
                return -1;
 
        printf("### Testing single element and burst enq/deq ###\n");
-       test_single_enqueue_dequeue();
-       test_burst_enqueue_dequeue();
+       test_single_enqueue_dequeue(r);
+       test_burst_enqueue_dequeue(r);
 
        printf("\n### Testing empty dequeue ###\n");
-       test_empty_dequeue();
+       test_empty_dequeue(r);
 
        printf("\n### Testing using a single lcore ###\n");
-       test_bulk_enqueue_dequeue();
+       test_bulk_enqueue_dequeue(r);
 
        if (get_two_hyperthreads(&cores) == 0) {
                printf("\n### Testing using two hyperthreads ###\n");
-               run_on_core_pair(&cores, enqueue_bulk, dequeue_bulk);
+               run_on_core_pair(&cores, r, enqueue_bulk, dequeue_bulk);
        }
        if (get_two_cores(&cores) == 0) {
                printf("\n### Testing using two physical cores ###\n");
-               run_on_core_pair(&cores, enqueue_bulk, dequeue_bulk);
+               run_on_core_pair(&cores, r, enqueue_bulk, dequeue_bulk);
        }
        if (get_two_sockets(&cores) == 0) {
                printf("\n### Testing using two NUMA nodes ###\n");
-               run_on_core_pair(&cores, enqueue_bulk, dequeue_bulk);
+               run_on_core_pair(&cores, r, enqueue_bulk, dequeue_bulk);
        }
+       rte_ring_free(r);
        return 0;
 }
 
index 311c704..ebff8b0 100644 (file)
@@ -348,6 +348,7 @@ service_lcore_en_dis_able(void)
 
        /* call remote_launch to verify that app can launch ex-service lcore */
        service_remote_launch_flag = 0;
+       rte_eal_wait_lcore(slcore_id);
        int ret = rte_eal_remote_launch(service_remote_launch_func, NULL,
                                        slcore_id);
        TEST_ASSERT_EQUAL(0, ret, "Ex-service core remote launch failed.");
@@ -362,7 +363,7 @@ static int
 service_lcore_running_check(void)
 {
        uint64_t tick = service_tick;
-       rte_delay_ms(SERVICE_DELAY * 10);
+       rte_delay_ms(SERVICE_DELAY * 100);
        /* if (tick != service_tick) we know the lcore as polled the service */
        return tick != service_tick;
 }
@@ -505,6 +506,10 @@ service_threaded_test(int mt_safe)
        if (!mt_safe)
                test_params[1] = 1;
 
+       /* wait for lcores before start() */
+       rte_eal_wait_lcore(slcore_1);
+       rte_eal_wait_lcore(slcore_2);
+
        rte_service_lcore_start(slcore_1);
        rte_service_lcore_start(slcore_2);
 
@@ -518,6 +523,8 @@ service_threaded_test(int mt_safe)
        TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
                        "Failed to stop MT Safe service");
 
+       rte_eal_wait_lcore(slcore_1);
+       rte_eal_wait_lcore(slcore_2);
        unregister_all();
 
        /* return the value of the callback pass_test variable to caller */
@@ -611,6 +618,7 @@ service_app_lcore_poll_impl(const int mt_safe)
        rte_service_runstate_set(id, 1);
 
        uint32_t app_core2 = rte_get_next_lcore(slcore_id, 1, 1);
+       rte_eal_wait_lcore(app_core2);
        int app_core2_ret = rte_eal_remote_launch(service_run_on_app_core_func,
                                                  &id, app_core2);
 
index db7d4e6..c5a6e00 100644 (file)
@@ -83,6 +83,14 @@ uint64_t pipeline_test_hash(void *key,
        return signature;
 }
 
+static void
+app_free_resources(void) {
+       int i;
+       for (i = 0; i < N_PORTS; i++)
+               rte_ring_free(rings_rx[i]);
+       rte_mempool_free(pool);
+}
+
 static void
 app_init_mbuf_pools(void)
 {
@@ -142,18 +150,20 @@ app_init_rings(void)
 static int
 test_table(void)
 {
-       int status, failures;
+       int status, ret;
        unsigned i;
 
-       failures = 0;
+       ret = TEST_SUCCESS;
 
        app_init_rings();
        app_init_mbuf_pools();
 
        printf("\n\n\n\n************Pipeline tests************\n");
 
-       if (test_table_pipeline() < 0)
-               return -1;
+       if (test_table_pipeline() < 0) {
+               ret = TEST_FAILED;
+               goto end;
+       }
 
        printf("\n\n\n\n************Port tests************\n");
        for (i = 0; i < n_port_tests; i++) {
@@ -161,8 +171,8 @@ test_table(void)
                if (status < 0) {
                        printf("\nPort test number %d failed (%d).\n", i,
                                status);
-                       failures++;
-                       return -1;
+                       ret = TEST_FAILED;
+                       goto end;
                }
        }
 
@@ -172,8 +182,8 @@ test_table(void)
                if (status < 0) {
                        printf("\nTable test number %d failed (%d).\n", i,
                                status);
-                       failures++;
-                       return -1;
+                       ret = TEST_FAILED;
+                       goto end;
                }
        }
 
@@ -183,21 +193,23 @@ test_table(void)
                if (status < 0) {
                        printf("\nCombined table test number %d failed with "
                                "reason number %d.\n", i, status);
-                       failures++;
-                       return -1;
+                       ret = TEST_FAILED;
+                       goto end;
                }
        }
 
-       if (failures)
-               return -1;
-
 #ifdef RTE_LIBRTE_ACL
        printf("\n\n\n\n************ACL tests************\n");
-       if (test_table_acl() < 0)
-               return -1;
+       if (test_table_acl() < 0) {
+               ret = TEST_FAILED;
+               goto end;
+       }
 #endif
 
-       return 0;
+end:
+       app_free_resources();
+
+       return ret;
 }
 
 REGISTER_TEST_COMMAND(table_autotest, test_table);
index 08c100f..6fcf4cc 100644 (file)
@@ -532,6 +532,8 @@ setup_acl_pipeline(void)
                struct rte_pipeline_table_entry *table_entries[5];
                int key_found[5];
 
+               memset(table_entries, 0, sizeof(table_entries));
+
                for (n = 0; n < 5; n++) {
                        memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
                        key_array[n] = &keys[n];
index 467ae13..9804133 100644 (file)
@@ -156,6 +156,7 @@ test_timer_perf(void)
        printf("Time per rte_timer_manage with zero callbacks: %"PRIu64" cycles\n",
                        (end_tsc - start_tsc + iterations/2) / iterations);
 
+       rte_free(tms);
        return 0;
 }
 
index f9f7aee..df9b21a 100755 (executable)
@@ -278,6 +278,8 @@ def get_device_details(devices_type):
                 # of dictionary key names
                 if "Driver" in dev.keys():
                     dev["Driver_str"] = dev.pop("Driver")
+                if "Module" in dev.keys():
+                    dev["Module_str"] = dev.pop("Module")
                 # use dict to make copy of dev
                 devices[dev["Slot"]] = dict(dev)
             # Clear previous device's data