From f9ca1b020ac0d42ec2d288352aa0447b4548fc18 Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Sep 20 2022 00:56:51 +0000 Subject: Import openvswitch2.13-2.13.0-201 from Fast DataPath --- diff --git a/SOURCES/arm64-armv8a-linuxapp-gcc-config b/SOURCES/arm64-armv8a-linuxapp-gcc-config index 3db2efb..4e69105 100644 --- a/SOURCES/arm64-armv8a-linuxapp-gcc-config +++ b/SOURCES/arm64-armv8a-linuxapp-gcc-config @@ -1,4 +1,4 @@ -# -*- cfg-sha: b96dcc8ca3ed08c34a442991fd5e08c64629dfcf8cc5833bd9c311dd0b7e0f77 +# -*- cfg-sha: 97a6783bf749f70521899958d4d929ef96ba593380f5e495709a146e7f88578f # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2015 Cavium, Inc # SPDX-License-Identifier: BSD-3-Clause @@ -12,7 +12,7 @@ CONFIG_RTE_VER_PREFIX="DPDK" # Version information completed when this file is processed for a build CONFIG_RTE_VER_YEAR=19 CONFIG_RTE_VER_MONTH=11 -CONFIG_RTE_VER_MINOR=7 +CONFIG_RTE_VER_MINOR=13 CONFIG_RTE_VER_SUFFIX="" CONFIG_RTE_VER_RELEASE=99 # RTE_EXEC_ENV values are the directories in mk/exec-env/ diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index 9c8f911..a994ce0 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -341,7 +341,7 @@ index 0000000000..b6447aba1b +set -ev +pip3 install --user --upgrade docutils diff --git a/.cirrus.yml b/.cirrus.yml -index 1b32f55d65..79271ff147 100644 +index 1b32f55d65..b4ce3cde16 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,21 +2,23 @@ freebsd_build_task: @@ -351,7 +351,7 @@ index 1b32f55d65..79271ff147 100644 - image_family: freebsd-12-1-snap - image_family: freebsd-11-3-snap + image_family: freebsd-12-3-snap -+ image_family: freebsd-13-0-snap ++ image_family: freebsd-13-1-snap cpu: 4 - memory: 8G + memory: 4G @@ -2954,7 +2954,7 @@ index 8f90d06f28..77ac26dd85 100644 - env: DEF_LIB="static" BUILD_32BIT=1 compiler: gcc diff --git a/dpdk/MAINTAINERS b/dpdk/MAINTAINERS -index 4395d8df14..952ded7b00 100644 +index 4395d8df14..b207fbce03 100644 --- a/dpdk/MAINTAINERS +++ b/dpdk/MAINTAINERS @@ -46,7 +46,7 @@ M: Jerin Jacob @@ -2966,18 +2966,23 @@ index 4395d8df14..952ded7b00 100644 T: git://dpdk.org/next/dpdk-next-net-mlx Next-virtio Tree -@@ -128,8 +128,11 @@ F: meson.build +@@ -73,6 +73,8 @@ T: git://dpdk.org/next/dpdk-next-pipeline + Stable Branches + M: Luca Boccassi + M: Kevin Traynor ++M: Christian Ehrhardt ++M: Xueming Li + T: git://dpdk.org/dpdk-stable + + Security Issues +@@ -128,6 +130,7 @@ F: meson.build F: lib/librte_eal/freebsd/BSDmakefile.meson F: meson_options.txt F: config/rte_config.h +F: buildtools/call-sphinx-build.py F: buildtools/gen-pmdinfo-cfile.sh F: buildtools/map_to_def.py -+F: buildtools/list-dir-globs.py -+F: buildtools/pkg-config/ F: buildtools/symlink-drivers-solibs.sh - - Public CI @@ -370,7 +373,7 @@ F: devtools/test-null.sh F: doc/guides/prog_guide/switch_representation.rst @@ -3066,18 +3071,22 @@ index 4395d8df14..952ded7b00 100644 F: doc/guides/sample_app_ug/flow_filtering.rst diff --git a/dpdk/VERSION b/dpdk/VERSION -index 22131b00aa..8bda73742f 100644 +index 22131b00aa..0698e5a376 100644 --- a/dpdk/VERSION +++ b/dpdk/VERSION @@ -1 +1 @@ -19.11.0 -+19.11.7 ++19.11.13 diff --git a/dpdk/app/meson.build b/dpdk/app/meson.build -index 71109cc422..c7f689eb79 100644 +index 71109cc422..4bdfaf4787 100644 --- a/dpdk/app/meson.build +++ b/dpdk/app/meson.build -@@ -22,6 +22,10 @@ apps = [ - lib_execinfo = cc.find_library('execinfo', required: false) +@@ -18,10 +18,12 @@ apps = [ + 'test-pmd', + 'test-sad'] + +-# for BSD only +-lib_execinfo = cc.find_library('execinfo', required: false) default_cflags = machine_args +default_ldflags = [] @@ -3087,7 +3096,7 @@ index 71109cc422..c7f689eb79 100644 foreach app:apps build = true -@@ -30,6 +34,7 @@ foreach app:apps +@@ -30,6 +32,7 @@ foreach app:apps sources = [] includes = [] cflags = default_cflags @@ -3095,7 +3104,15 @@ index 71109cc422..c7f689eb79 100644 objs = [] # other object files to link against, used e.g. for # instruction-set optimized versions of code -@@ -60,8 +65,10 @@ foreach app:apps +@@ -46,7 +49,6 @@ foreach app:apps + dep_objs += get_variable(get_option('default_library') + + '_rte_' + d) + endforeach +- dep_objs += lib_execinfo + + link_libs = [] + if get_option('default_library') == 'static' +@@ -60,8 +62,10 @@ foreach app:apps executable('dpdk-' + name, sources, c_args: cflags, @@ -3107,7 +3124,7 @@ index 71109cc422..c7f689eb79 100644 driver_install_path), install: true) diff --git a/dpdk/app/pdump/main.c b/dpdk/app/pdump/main.c -index 903d02f482..c38c53719e 100644 +index 903d02f482..99ef010d13 100644 --- a/dpdk/app/pdump/main.c +++ b/dpdk/app/pdump/main.c @@ -151,7 +151,7 @@ static uint8_t multiple_core_capture; @@ -3128,6 +3145,44 @@ index 903d02f482..c38c53719e 100644 ret = rte_eth_tx_queue_setup(port_id, q, TX_DESC_PER_QUEUE, rte_eth_dev_socket_id(port_id), NULL); if (ret < 0) +@@ -906,11 +906,21 @@ dump_packets_core(void *arg) + return 0; + } + ++static unsigned int ++get_next_core(unsigned int lcore) ++{ ++ lcore = rte_get_next_lcore(lcore, 1, 0); ++ if (lcore == RTE_MAX_LCORE) ++ rte_exit(EXIT_FAILURE, ++ "Max core limit %u reached for packet capture", lcore); ++ return lcore; ++} ++ + static inline void + dump_packets(void) + { + int i; +- uint32_t lcore_id = 0; ++ unsigned int lcore_id = 0; + + if (!multiple_core_capture) { + printf(" core (%u), capture for (%d) tuples\n", +@@ -936,12 +946,12 @@ dump_packets(void) + return; + } + +- lcore_id = rte_get_next_lcore(lcore_id, 1, 0); ++ lcore_id = get_next_core(lcore_id); + + for (i = 0; i < num_tuples; i++) { + rte_eal_remote_launch(dump_packets_core, + &pdump_t[i], lcore_id); +- lcore_id = rte_get_next_lcore(lcore_id, 1, 0); ++ lcore_id = get_next_core(lcore_id); + + if (rte_eal_wait_lcore(lcore_id) < 0) + rte_exit(EXIT_FAILURE, "failed to wait\n"); diff --git a/dpdk/app/proc-info/main.c b/dpdk/app/proc-info/main.c index abeca4aab4..f6d19cdac2 100644 --- a/dpdk/app/proc-info/main.c @@ -3193,8 +3248,63 @@ index 371cbc692d..52d51ae330 120000 \ No newline at end of file +test_vectors/ldpc_enc_v2342.data \ No newline at end of file +diff --git a/dpdk/app/test-bbdev/test_bbdev_perf.c b/dpdk/app/test-bbdev/test_bbdev_perf.c +index d8db58ea00..d6da21ca48 100644 +--- a/dpdk/app/test-bbdev/test_bbdev_perf.c ++++ b/dpdk/app/test-bbdev/test_bbdev_perf.c +@@ -327,14 +327,14 @@ check_dev_cap(const struct rte_bbdev_info *dev_info) + if (nb_harq_inputs > cap->num_buffers_hard_out) { + printf( + "Too many HARQ inputs defined: %u, max: %u\n", +- nb_hard_outputs, ++ nb_harq_inputs, + cap->num_buffers_hard_out); + return TEST_FAILED; + } + if (nb_harq_outputs > cap->num_buffers_hard_out) { + printf( + "Too many HARQ outputs defined: %u, max: %u\n", +- nb_hard_outputs, ++ nb_harq_outputs, + cap->num_buffers_hard_out); + return TEST_FAILED; + } +diff --git a/dpdk/app/test-compress-perf/comp_perf_options_parse.c b/dpdk/app/test-compress-perf/comp_perf_options_parse.c +index 12d0a6caf0..898dd310dd 100644 +--- a/dpdk/app/test-compress-perf/comp_perf_options_parse.c ++++ b/dpdk/app/test-compress-perf/comp_perf_options_parse.c +@@ -598,7 +598,7 @@ comp_perf_options_parse(struct comp_test_data *test_data, int argc, char **argv) + switch (opt) { + case 'h': + usage(argv[0]); +- rte_exit(EXIT_SUCCESS, "Displayed help\n"); ++ exit(EXIT_SUCCESS); + break; + /* long options */ + case 0: +diff --git a/dpdk/app/test-compress-perf/main.c b/dpdk/app/test-compress-perf/main.c +index 6b56dd6809..3138bbcadb 100644 +--- a/dpdk/app/test-compress-perf/main.c ++++ b/dpdk/app/test-compress-perf/main.c +@@ -158,7 +158,7 @@ comp_perf_initialize_compressdev(struct comp_test_data *test_data, + cdev_id = enabled_cdevs[i]; + + struct rte_compressdev_info cdev_info; +- uint8_t socket_id = rte_compressdev_socket_id(cdev_id); ++ int socket_id = rte_compressdev_socket_id(cdev_id); + + rte_compressdev_info_get(cdev_id, &cdev_info); + if (cdev_info.max_nb_queue_pairs && +@@ -184,6 +184,7 @@ comp_perf_initialize_compressdev(struct comp_test_data *test_data, + .max_nb_priv_xforms = NUM_MAX_XFORMS, + .max_nb_streams = 0 + }; ++ test_data->nb_qps = config.nb_queue_pairs; + + if (rte_compressdev_configure(cdev_id, &config) < 0) { + RTE_LOG(ERR, USER1, "Device configuration failed\n"); diff --git a/dpdk/app/test-crypto-perf/cperf_options_parsing.c b/dpdk/app/test-crypto-perf/cperf_options_parsing.c -index f43c5bede7..49b469781c 100644 +index f43c5bede7..e16e8eca9c 100644 --- a/dpdk/app/test-crypto-perf/cperf_options_parsing.c +++ b/dpdk/app/test-crypto-perf/cperf_options_parsing.c @@ -23,7 +23,7 @@ usage(char *progname) @@ -3206,6 +3316,41 @@ index f43c5bede7..49b469781c 100644 " set test type\n" " --pool_sz N: set the number of crypto ops/mbufs allocated\n" " --total-ops N: set the number of total operations performed\n" +@@ -495,6 +495,12 @@ parse_test_name(struct cperf_options *opts, + { + char *test_name = (char *) rte_zmalloc(NULL, + sizeof(char) * (strlen(arg) + 3), 0); ++ if (test_name == NULL) { ++ RTE_LOG(ERR, USER1, "Failed to rte zmalloc with size: %zu\n", ++ strlen(arg) + 3); ++ return -1; ++ } ++ + snprintf(test_name, strlen(arg) + 3, "[%s]", arg); + opts->test_name = test_name; + +@@ -953,7 +959,7 @@ cperf_options_parse(struct cperf_options *options, int argc, char **argv) + switch (opt) { + case 'h': + usage(argv[0]); +- rte_exit(EXIT_SUCCESS, "Displayed help\n"); ++ exit(EXIT_SUCCESS); + break; + /* long options */ + case 0: +diff --git a/dpdk/app/test-crypto-perf/cperf_test_common.c b/dpdk/app/test-crypto-perf/cperf_test_common.c +index 85603eed5b..b7347ad499 100644 +--- a/dpdk/app/test-crypto-perf/cperf_test_common.c ++++ b/dpdk/app/test-crypto-perf/cperf_test_common.c +@@ -194,7 +194,7 @@ cperf_alloc_common_memory(const struct cperf_options *options, + (mbuf_size * segments_nb); + params.dst_buf_offset = *dst_buf_offset; + /* Destination buffer will be one segment only */ +- obj_size += max_size; ++ obj_size += max_size + sizeof(struct rte_mbuf); + } + + *pool = rte_mempool_create_empty(pool_name, diff --git a/dpdk/app/test-crypto-perf/cperf_test_latency.c b/dpdk/app/test-crypto-perf/cperf_test_latency.c index 62478a2df5..951b4d10ac 100644 --- a/dpdk/app/test-crypto-perf/cperf_test_latency.c @@ -3252,6 +3397,21 @@ index 35c51026fe..2528f39571 100644 ctx->lcore_id, ctx->options->test_buffer_size, test_burst_size, +diff --git a/dpdk/app/test-crypto-perf/cperf_test_vectors.c b/dpdk/app/test-crypto-perf/cperf_test_vectors.c +index 41641650c8..1bd46d848e 100644 +--- a/dpdk/app/test-crypto-perf/cperf_test_vectors.c ++++ b/dpdk/app/test-crypto-perf/cperf_test_vectors.c +@@ -553,6 +553,10 @@ cperf_test_vector_get_dummy(struct cperf_options *options) + rte_free(t_vec); + return NULL; + } ++ ++ if (options->aead_aad_sz > sizeof(aad)) ++ options->aead_aad_sz = sizeof(aad); ++ + memcpy(t_vec->aad.data, aad, options->aead_aad_sz); + t_vec->aad.phys_addr = rte_malloc_virt2iova(t_vec->aad.data); + t_vec->aad.length = options->aead_aad_sz; diff --git a/dpdk/app/test-crypto-perf/cperf_test_verify.c b/dpdk/app/test-crypto-perf/cperf_test_verify.c index 833bc9a552..2939aeaa93 100644 --- a/dpdk/app/test-crypto-perf/cperf_test_verify.c @@ -3326,7 +3486,7 @@ index 0674396da8..dcc4bf9cbc 100644 + deps += 'pmd_crypto_scheduler' +endif diff --git a/dpdk/app/test-eventdev/evt_options.c b/dpdk/app/test-eventdev/evt_options.c -index c60b61a904..4f4800d99d 100644 +index c60b61a904..3c80c1a489 100644 --- a/dpdk/app/test-eventdev/evt_options.c +++ b/dpdk/app/test-eventdev/evt_options.c @@ -197,6 +197,10 @@ evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg) @@ -3340,6 +3500,24 @@ index c60b61a904..4f4800d99d 100644 return ret; } +@@ -214,7 +218,7 @@ evt_parse_plcores(struct evt_options *opt, const char *corelist) + { + int ret; + +- ret = parse_lcores_list(opt->plcores, corelist); ++ ret = parse_lcores_list(opt->plcores, RTE_MAX_LCORE, corelist); + if (ret == -E2BIG) + evt_err("duplicate lcores in plcores"); + +@@ -226,7 +230,7 @@ evt_parse_work_lcores(struct evt_options *opt, const char *corelist) + { + int ret; + +- ret = parse_lcores_list(opt->wlcores, corelist); ++ ret = parse_lcores_list(opt->wlcores, RTE_MAX_LCORE, corelist); + if (ret == -E2BIG) + evt_err("duplicate lcores in wlcores"); + diff --git a/dpdk/app/test-eventdev/meson.build b/dpdk/app/test-eventdev/meson.build index 7ff2b786cf..9e588d9ec7 100644 --- a/dpdk/app/test-eventdev/meson.build @@ -3354,6 +3532,52 @@ index 7ff2b786cf..9e588d9ec7 100644 + 'test_pipeline_atq.c', + 'test_pipeline_queue.c') deps += 'eventdev' +diff --git a/dpdk/app/test-eventdev/parser.c b/dpdk/app/test-eventdev/parser.c +index 24f1855e9a..8818c37ff8 100644 +--- a/dpdk/app/test-eventdev/parser.c ++++ b/dpdk/app/test-eventdev/parser.c +@@ -310,7 +310,7 @@ parse_hex_string(char *src, uint8_t *dst, uint32_t *size) + } + + int +-parse_lcores_list(bool lcores[], const char *corelist) ++parse_lcores_list(bool lcores[], int lcores_num, const char *corelist) + { + int i, idx = 0; + int min, max; +@@ -332,6 +332,8 @@ parse_lcores_list(bool lcores[], const char *corelist) + if (*corelist == '\0') + return -1; + idx = strtoul(corelist, &end, 10); ++ if (idx < 0 || idx > lcores_num) ++ return -1; + + if (end == NULL) + return -1; +diff --git a/dpdk/app/test-eventdev/parser.h b/dpdk/app/test-eventdev/parser.h +index 673ff22d78..696b40a3e2 100644 +--- a/dpdk/app/test-eventdev/parser.h ++++ b/dpdk/app/test-eventdev/parser.h +@@ -46,5 +46,5 @@ int parse_hex_string(char *src, uint8_t *dst, uint32_t *size); + + int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens); + +-int parse_lcores_list(bool lcores[], const char *corelist); ++int parse_lcores_list(bool lcores[], int lcores_num, const char *corelist); + #endif +diff --git a/dpdk/app/test-eventdev/test_perf_common.c b/dpdk/app/test-eventdev/test_perf_common.c +index b3af4bfeca..958845c26b 100644 +--- a/dpdk/app/test-eventdev/test_perf_common.c ++++ b/dpdk/app/test-eventdev/test_perf_common.c +@@ -17,7 +17,7 @@ perf_test_result(struct evt_test *test, struct evt_options *opt) + total += t->worker[i].processed_pkts; + for (i = 0; i < t->nb_workers; i++) + printf("Worker %d packets: "CLGRN"%"PRIx64" "CLNRM"percentage:" +- CLGRN" %3.2f\n"CLNRM, i, ++ CLGRN" %3.2f"CLNRM"\n", i, + t->worker[i].processed_pkts, + (((double)t->worker[i].processed_pkts)/total) + * 100); diff --git a/dpdk/app/test-eventdev/test_perf_common.h b/dpdk/app/test-eventdev/test_perf_common.h index d8fbee6d89..e095da9a47 100644 --- a/dpdk/app/test-eventdev/test_perf_common.h @@ -3528,9 +3752,18 @@ index 28ac9fcc0e..33f3f1c827 100644 void diff --git a/dpdk/app/test-pmd/bpf_cmd.c b/dpdk/app/test-pmd/bpf_cmd.c -index 830bfc13a5..d2deadd4e6 100644 +index 830bfc13a5..3899d9f724 100644 --- a/dpdk/app/test-pmd/bpf_cmd.c +++ b/dpdk/app/test-pmd/bpf_cmd.c +@@ -20,7 +20,7 @@ static const struct rte_bpf_xsym bpf_xsym[] = { + .name = RTE_STR(stdout), + .type = RTE_BPF_XTYPE_VAR, + .var = { +- .val = &stdout, ++ .val = (void *)(uintptr_t)&stdout, + .desc = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(stdout), @@ -55,7 +55,7 @@ static const struct rte_bpf_xsym bpf_xsym[] = { struct cmd_bpf_ld_result { cmdline_fixed_string_t bpf; @@ -3550,7 +3783,7 @@ index 830bfc13a5..d2deadd4e6 100644 }; diff --git a/dpdk/app/test-pmd/cmdline.c b/dpdk/app/test-pmd/cmdline.c -index 9f3e0b251b..9a9da744a1 100644 +index 9f3e0b251b..599a9c5743 100644 --- a/dpdk/app/test-pmd/cmdline.c +++ b/dpdk/app/test-pmd/cmdline.c @@ -94,7 +94,7 @@ static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result, @@ -3571,6 +3804,24 @@ index 9f3e0b251b..9a9da744a1 100644 " Set the transmit balance policy for bonded device running in balance mode.\n\n" "set bonding mon_period (port_id) (value)\n" +@@ -1324,7 +1324,7 @@ cmdline_parse_token_string_t cmd_operate_port_all_all = + cmdline_parse_inst_t cmd_operate_port = { + .f = cmd_operate_port_parsed, + .data = NULL, +- .help_str = "port start|stop|close all: Start/Stop/Close/Reset all ports", ++ .help_str = "port start|stop|close|reset all: Start/Stop/Close/Reset all ports", + .tokens = { + (void *)&cmd_operate_port_all_cmd, + (void *)&cmd_operate_port_all_port, +@@ -1371,7 +1371,7 @@ cmdline_parse_token_num_t cmd_operate_specific_port_id = + cmdline_parse_inst_t cmd_operate_specific_port = { + .f = cmd_operate_specific_port_parsed, + .data = NULL, +- .help_str = "port start|stop|close : Start/Stop/Close/Reset port_id", ++ .help_str = "port start|stop|close|reset : Start/Stop/Close/Reset port_id", + .tokens = { + (void *)&cmd_operate_specific_port_cmd, + (void *)&cmd_operate_specific_port_port, @@ -1437,7 +1437,7 @@ cmdline_parse_inst_t cmd_set_port_setup_on = { struct cmd_operate_attach_port_result { cmdline_fixed_string_t port; @@ -3613,7 +3864,35 @@ index 9f3e0b251b..9a9da744a1 100644 else printf("Unknown parameter\n"); } -@@ -1911,18 +1913,13 @@ cmd_config_rx_tx_parsed(void *parsed_result, +@@ -1616,6 +1618,9 @@ parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed) + } + } + ++ if (*speed != ETH_LINK_SPEED_AUTONEG) ++ *speed |= ETH_LINK_SPEED_FIXED; ++ + return 0; + } + +@@ -1699,13 +1704,13 @@ cmd_config_speed_specific_parsed(void *parsed_result, + struct cmd_config_speed_specific *res = parsed_result; + uint32_t link_speed; + +- if (!all_ports_stopped()) { +- printf("Please stop all ports first\n"); ++ if (port_id_is_invalid(res->id, ENABLED_WARN)) + return; +- } + +- if (port_id_is_invalid(res->id, ENABLED_WARN)) ++ if (!port_is_stopped(res->id)) { ++ printf("Please stop port %d first\n", res->id); + return; ++ } + + if (parse_and_check_speed_duplex(res->value1, res->value2, + &link_speed) < 0) +@@ -1911,18 +1916,13 @@ cmd_config_rx_tx_parsed(void *parsed_result, nb_txq = res->value; } else if (!strcmp(res->name, "rxd")) { @@ -3635,7 +3914,7 @@ index 9f3e0b251b..9a9da744a1 100644 nb_txd = res->value; } else { printf("Unknown parameter\n"); -@@ -1977,7 +1974,9 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, +@@ -1977,7 +1977,9 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_config_max_pkt_len_result *res = parsed_result; @@ -3645,7 +3924,7 @@ index 9f3e0b251b..9a9da744a1 100644 if (!all_ports_stopped()) { printf("Please stop all ports first\n"); -@@ -1986,7 +1985,6 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, +@@ -1986,7 +1988,6 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, RTE_ETH_FOREACH_DEV(pid) { struct rte_port *port = &ports[pid]; @@ -3653,7 +3932,7 @@ index 9f3e0b251b..9a9da744a1 100644 if (!strcmp(res->name, "max-pkt-len")) { if (res->value < RTE_ETHER_MIN_LEN) { -@@ -1997,12 +1995,18 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, +@@ -1997,12 +1998,18 @@ cmd_config_max_pkt_len_parsed(void *parsed_result, if (res->value == port->dev_conf.rxmode.max_rx_pkt_len) return; @@ -3677,7 +3956,45 @@ index 9f3e0b251b..9a9da744a1 100644 } else { printf("Unknown parameter\n"); return; -@@ -4171,6 +4175,9 @@ cmd_tx_vlan_set_parsed(void *parsed_result, +@@ -2641,7 +2648,7 @@ cmd_config_rxtx_queue_parsed(void *parsed_result, + ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid); + + if (ret == -ENOTSUP) +- printf("Function not supported in PMD driver\n"); ++ printf("Function not supported in PMD\n"); + } + + cmdline_parse_token_string_t cmd_config_rxtx_queue_port = +@@ -2842,6 +2849,10 @@ cmd_setup_rxtx_queue_parsed( + if (!numa_support || socket_id == NUMA_NO_CONFIG) + socket_id = port->socket_id; + ++ if (port->nb_tx_desc[res->qid] < tx_pkt_nb_segs) { ++ printf("Failed to setup TX queue: not enough descriptors\n"); ++ return; ++ } + ret = rte_eth_tx_queue_setup(res->portid, + res->qid, + port->nb_tx_desc[res->qid], +@@ -3051,7 +3062,7 @@ showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf, + return -1; + } + for (i = 0; i < ret; i++) +- conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0); ++ conf[i].mask = (uint64_t)strtoull(str_fld[i], &end, 0); + + return 0; + } +@@ -3580,7 +3591,7 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items, + return nb_item; + + /* +- * Then, check that all values in the list are differents. ++ * Then, check that all values in the list are different. + * No optimization here... + */ + for (i = 0; i < nb_item; i++) { +@@ -4171,6 +4182,9 @@ cmd_tx_vlan_set_parsed(void *parsed_result, { struct cmd_tx_vlan_set_result *res = parsed_result; @@ -3687,7 +4004,7 @@ index 9f3e0b251b..9a9da744a1 100644 if (!port_is_stopped(res->port_id)) { printf("Please stop port %d first\n", res->port_id); return; -@@ -4225,6 +4232,9 @@ cmd_tx_vlan_set_qinq_parsed(void *parsed_result, +@@ -4225,6 +4239,9 @@ cmd_tx_vlan_set_qinq_parsed(void *parsed_result, { struct cmd_tx_vlan_set_qinq_result *res = parsed_result; @@ -3697,7 +4014,7 @@ index 9f3e0b251b..9a9da744a1 100644 if (!port_is_stopped(res->port_id)) { printf("Please stop port %d first\n", res->port_id); return; -@@ -4338,6 +4348,9 @@ cmd_tx_vlan_reset_parsed(void *parsed_result, +@@ -4338,6 +4355,9 @@ cmd_tx_vlan_reset_parsed(void *parsed_result, { struct cmd_tx_vlan_reset_result *res = parsed_result; @@ -3707,7 +4024,16 @@ index 9f3e0b251b..9a9da744a1 100644 if (!port_is_stopped(res->port_id)) { printf("Please stop port %d first\n", res->port_id); return; -@@ -5120,7 +5133,7 @@ cmd_gso_size_parsed(void *parsed_result, +@@ -4448,7 +4468,7 @@ cmd_config_queue_tx_offloads(struct rte_port *port) + int k; + + /* Apply queue tx offloads configuration */ +- for (k = 0; k < port->dev_info.max_rx_queues; k++) ++ for (k = 0; k < port->dev_info.max_tx_queues; k++) + port->tx_conf[k].offloads = + port->dev_conf.txmode.offloads; + } +@@ -5120,7 +5140,7 @@ cmd_gso_size_parsed(void *parsed_result, if (test_done == 0) { printf("Before setting GSO segsz, please first" @@ -3716,7 +4042,35 @@ index 9f3e0b251b..9a9da744a1 100644 return; } -@@ -7078,9 +7091,10 @@ cmd_priority_flow_ctrl_set_parsed(void *parsed_result, +@@ -5652,6 +5672,19 @@ static void cmd_set_bonding_mode_parsed(void *parsed_result, + { + struct cmd_set_bonding_mode_result *res = parsed_result; + portid_t port_id = res->port_id; ++ struct rte_port *port = &ports[port_id]; ++ ++ /* ++ * Bonding mode changed means resources of device changed, like whether ++ * started rte timer or not. Device should be restarted when resources ++ * of device changed. ++ */ ++ if (port->port_status != RTE_PORT_STOPPED) { ++ fprintf(stderr, ++ "\t Error: Can't set bonding mode when port %d is not stopped\n", ++ port_id); ++ return; ++ } + + /* Set the bonding mode for the relevant port. */ + if (0 != rte_eth_bond_mode_set(port_id, res->value)) +@@ -6196,6 +6229,7 @@ static void cmd_create_bonded_device_parsed(void *parsed_result, + printf("Failed to enable promiscuous mode for port %u: %s - ignore\n", + port_id, rte_strerror(-ret)); + ++ ports[port_id].bond_flag = 1; + ports[port_id].need_setup = 0; + ports[port_id].port_status = RTE_PORT_STOPPED; + } +@@ -7078,9 +7112,10 @@ cmd_priority_flow_ctrl_set_parsed(void *parsed_result, * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side. */ static enum rte_eth_fc_mode rx_tx_onoff_2_pfc_mode[2][2] = { @@ -3728,7 +4082,73 @@ index 9f3e0b251b..9a9da744a1 100644 rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on",2)) ? 1 : 0; tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on",2)) ? 1 : 0; pfc_conf.fc.mode = rx_tx_onoff_2_pfc_mode[rx_fc_enable][tx_fc_enable]; -@@ -16802,8 +16816,10 @@ cmd_ddp_get_list_parsed( +@@ -8023,6 +8058,7 @@ static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, + __attribute__((unused)) void *data) + { + cmdline_quit(cl); ++ cl_quit = 1; + } + + cmdline_parse_token_string_t cmd_quit_quit = +@@ -8558,6 +8594,7 @@ cmd_set_vf_rxmode_parsed(void *parsed_result, + } + + RTE_SET_USED(is_on); ++ RTE_SET_USED(vf_rxmode); + + #ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) +@@ -9086,7 +9123,7 @@ cmdline_parse_inst_t cmd_tunnel_filter = { + + /* *** CONFIGURE TUNNEL UDP PORT *** */ + struct cmd_tunnel_udp_config { +- cmdline_fixed_string_t cmd; ++ cmdline_fixed_string_t rx_vxlan_port; + cmdline_fixed_string_t what; + uint16_t udp_port; + portid_t port_id; +@@ -9102,9 +9139,7 @@ cmd_tunnel_udp_config_parsed(void *parsed_result, + int ret; + + tunnel_udp.udp_port = res->udp_port; +- +- if (!strcmp(res->cmd, "rx_vxlan_port")) +- tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN; ++ tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN; + + if (!strcmp(res->what, "add")) + ret = rte_eth_dev_udp_tunnel_port_add(res->port_id, +@@ -9117,9 +9152,9 @@ cmd_tunnel_udp_config_parsed(void *parsed_result, + printf("udp tunneling add error: (%s)\n", strerror(-ret)); + } + +-cmdline_parse_token_string_t cmd_tunnel_udp_config_cmd = ++cmdline_parse_token_string_t cmd_tunnel_udp_config_rx_vxlan_port = + TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config, +- cmd, "rx_vxlan_port"); ++ rx_vxlan_port, "rx_vxlan_port"); + cmdline_parse_token_string_t cmd_tunnel_udp_config_what = + TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config, + what, "add#rm"); +@@ -9136,7 +9171,7 @@ cmdline_parse_inst_t cmd_tunnel_udp_config = { + .help_str = "rx_vxlan_port add|rm : " + "Add/Remove a tunneling UDP port filter", + .tokens = { +- (void *)&cmd_tunnel_udp_config_cmd, ++ (void *)&cmd_tunnel_udp_config_rx_vxlan_port, + (void *)&cmd_tunnel_udp_config_what, + (void *)&cmd_tunnel_udp_config_udp_port, + (void *)&cmd_tunnel_udp_config_port_id, +@@ -16746,7 +16781,7 @@ cmd_ddp_info_parsed( + free(proto); + #endif + if (ret == -ENOTSUP) +- printf("Function not supported in PMD driver\n"); ++ printf("Function not supported in PMD\n"); + close_file(pkg); + } + +@@ -16802,8 +16837,10 @@ cmd_ddp_get_list_parsed( #ifdef RTE_LIBRTE_I40E_PMD size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4; p_list = (struct rte_pmd_i40e_profile_list *)malloc(size); @@ -3740,7 +4160,35 @@ index 9f3e0b251b..9a9da744a1 100644 if (ret == -ENOTSUP) ret = rte_pmd_i40e_get_ddp_list(res->port_id, -@@ -19494,6 +19510,7 @@ cmdline_read_from_file(const char *filename) +@@ -19022,7 +19059,8 @@ cmd_show_rx_tx_desc_status_parsed(void *parsed_result, + rc = rte_eth_rx_descriptor_status(res->cmd_pid, res->cmd_qid, + res->cmd_did); + if (rc < 0) { +- printf("Invalid queueid = %d\n", res->cmd_qid); ++ printf("Invalid input: queue id = %d, desc id = %d\n", ++ res->cmd_qid, res->cmd_did); + return; + } + if (rc == RTE_ETH_RX_DESC_AVAIL) +@@ -19035,7 +19073,8 @@ cmd_show_rx_tx_desc_status_parsed(void *parsed_result, + rc = rte_eth_tx_descriptor_status(res->cmd_pid, res->cmd_qid, + res->cmd_did); + if (rc < 0) { +- printf("Invalid queueid = %d\n", res->cmd_qid); ++ printf("Invalid input: queue id = %d, desc id = %d\n", ++ res->cmd_qid, res->cmd_did); + return; + } + if (rc == RTE_ETH_TX_DESC_FULL) +@@ -19336,6 +19375,7 @@ cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_show_port_meter_cap, + (cmdline_parse_inst_t *)&cmd_add_port_meter_profile_srtcm, + (cmdline_parse_inst_t *)&cmd_add_port_meter_profile_trtcm, ++ (cmdline_parse_inst_t *)&cmd_add_port_meter_profile_trtcm_rfc4115, + (cmdline_parse_inst_t *)&cmd_del_port_meter_profile, + (cmdline_parse_inst_t *)&cmd_create_port_meter, + (cmdline_parse_inst_t *)&cmd_enable_port_meter, +@@ -19494,6 +19534,7 @@ cmdline_read_from_file(const char *filename) void prompt(void) { @@ -3748,7 +4196,7 @@ index 9f3e0b251b..9a9da744a1 100644 /* initialize non-constant commands */ cmd_set_fwd_mode_init(); cmd_set_fwd_retry_mode_init(); -@@ -19501,15 +19518,23 @@ prompt(void) +@@ -19501,15 +19542,23 @@ prompt(void) testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); if (testpmd_cl == NULL) return; @@ -3775,7 +4223,7 @@ index 9f3e0b251b..9a9da744a1 100644 static void diff --git a/dpdk/app/test-pmd/cmdline_flow.c b/dpdk/app/test-pmd/cmdline_flow.c -index 99dade7d8c..da3533c557 100644 +index 99dade7d8c..7ad4d29536 100644 --- a/dpdk/app/test-pmd/cmdline_flow.c +++ b/dpdk/app/test-pmd/cmdline_flow.c @@ -1005,7 +1005,6 @@ static const enum index item_pppoes[] = { @@ -3848,7 +4296,20 @@ index 99dade7d8c..da3533c557 100644 action->conf = &action_rss_data->conf; return ret; } -@@ -4534,7 +4524,9 @@ parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, +@@ -4260,7 +4250,11 @@ parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, + .src_addr = nvgre_encap_conf.ipv4_src, + .dst_addr = nvgre_encap_conf.ipv4_dst, + }, +- .item_nvgre.flow_id = 0, ++ .item_nvgre = { ++ .c_k_s_rsvd0_ver = RTE_BE16(0x2000), ++ .protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), ++ .flow_id = 0, ++ }, + }; + memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes, + nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); +@@ -4534,7 +4528,9 @@ parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, struct rte_flow_item_gre gre = { .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), }; @@ -3859,7 +4320,74 @@ index 99dade7d8c..da3533c557 100644 uint8_t *header; int ret; -@@ -6236,6 +6228,9 @@ flow_item_default_mask(const struct rte_flow_item *item) +@@ -5297,31 +5293,32 @@ parse_string(struct context *ctx, const struct token *token, + static int + parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) + { +- char *c = NULL; +- uint32_t i, len; +- char tmp[3]; +- +- /* Check input parameters */ +- if ((src == NULL) || +- (dst == NULL) || +- (size == NULL) || +- (*size == 0)) ++ const uint8_t *head = dst; ++ uint32_t left; ++ ++ if (*size == 0) + return -1; + ++ left = *size; ++ + /* Convert chars to bytes */ +- for (i = 0, len = 0; i < *size; i += 2) { +- snprintf(tmp, 3, "%s", src + i); +- dst[len++] = strtoul(tmp, &c, 16); +- if (*c != 0) { +- len--; +- dst[len] = 0; +- *size = len; ++ while (left) { ++ char tmp[3], *end = tmp; ++ uint32_t read_lim = left & 1 ? 1 : 2; ++ ++ snprintf(tmp, read_lim + 1, "%s", src); ++ *dst = strtoul(tmp, &end, 16); ++ if (*end) { ++ *dst = 0; ++ *size = (uint32_t)(dst - head); + return -1; + } ++ left -= read_lim; ++ src += read_lim; ++ dst++; + } +- dst[len] = 0; +- *size = len; +- ++ *dst = 0; ++ *size = (uint32_t)(dst - head); + return 0; + } + +@@ -5365,10 +5362,13 @@ parse_hex(struct context *ctx, const struct token *token, + hexlen -= 2; + } + if (hexlen > length) +- return -1; ++ goto error; + ret = parse_hex_string(str, hex_tmp, &hexlen); + if (ret < 0) + goto error; ++ /* Check the converted binary fits into data buffer. */ ++ if (hexlen > size) ++ goto error; + /* Let parse_int() fill length information first. */ + ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); + if (ret < 0) +@@ -6236,6 +6236,9 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_GTP_PSC: mask = &rte_flow_item_gtp_psc_mask; break; @@ -3870,9 +4398,26 @@ index 99dade7d8c..da3533c557 100644 mask = &rte_flow_item_pppoe_proto_id_mask; default: diff --git a/dpdk/app/test-pmd/cmdline_mtr.c b/dpdk/app/test-pmd/cmdline_mtr.c -index ab5c8642db..c6e7529b3d 100644 +index ab5c8642db..9f13de0ccd 100644 --- a/dpdk/app/test-pmd/cmdline_mtr.c +++ b/dpdk/app/test-pmd/cmdline_mtr.c +@@ -92,13 +92,13 @@ parse_dscp_table_entries(char *str, enum rte_color **dscp_table) + while (1) { + if (strcmp(token, "G") == 0 || + strcmp(token, "g") == 0) +- *dscp_table[i++] = RTE_COLOR_GREEN; ++ (*dscp_table)[i++] = RTE_COLOR_GREEN; + else if (strcmp(token, "Y") == 0 || + strcmp(token, "y") == 0) +- *dscp_table[i++] = RTE_COLOR_YELLOW; ++ (*dscp_table)[i++] = RTE_COLOR_YELLOW; + else if (strcmp(token, "R") == 0 || + strcmp(token, "r") == 0) +- *dscp_table[i++] = RTE_COLOR_RED; ++ (*dscp_table)[i++] = RTE_COLOR_RED; + else { + free(*dscp_table); + return -1; @@ -312,7 +312,7 @@ static void cmd_show_port_meter_cap_parsed(void *parsed_result, cmdline_parse_inst_t cmd_show_port_meter_cap = { .f = cmd_show_port_meter_cap_parsed, @@ -4013,13 +4558,14 @@ index ab5c8642db..c6e7529b3d 100644 (void *)&cmd_show_port_meter_stats_show, (void *)&cmd_show_port_meter_stats_port, diff --git a/dpdk/app/test-pmd/config.c b/dpdk/app/test-pmd/config.c -index d599682788..e14ff42745 100644 +index d599682788..9f96e77ba3 100644 --- a/dpdk/app/test-pmd/config.c +++ b/dpdk/app/test-pmd/config.c -@@ -53,6 +53,14 @@ +@@ -53,7 +53,13 @@ #include "testpmd.h" +-static char *flowtype_to_str(uint16_t flow_type); +#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */ +#define CLOCK_TYPE_ID CLOCK_MONOTONIC_RAW +#else @@ -4027,11 +4573,10 @@ index d599682788..e14ff42745 100644 +#endif + +#define NS_PER_SEC 1E9 -+ - static char *flowtype_to_str(uint16_t flow_type); static const struct { -@@ -125,9 +133,10 @@ nic_stats_display(portid_t port_id) + enum tx_pkt_split split; +@@ -125,21 +131,28 @@ nic_stats_display(portid_t port_id) static uint64_t prev_pkts_tx[RTE_MAX_ETHPORTS]; static uint64_t prev_bytes_rx[RTE_MAX_ETHPORTS]; static uint64_t prev_bytes_tx[RTE_MAX_ETHPORTS]; @@ -4044,7 +4589,27 @@ index d599682788..e14ff42745 100644 uint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx; struct rte_eth_stats stats; struct rte_port *port = &ports[port_id]; -@@ -184,10 +193,17 @@ nic_stats_display(portid_t port_id) + uint8_t i; +- + static const char *nic_stats_border = "########################"; ++ int ret; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) { + print_valid_ports(); + return; + } +- rte_eth_stats_get(port_id, &stats); ++ ret = rte_eth_stats_get(port_id, &stats); ++ if (ret != 0) { ++ fprintf(stderr, ++ "%s: Error: failed to get stats (port %u): %d", ++ __func__, port_id, ret); ++ return; ++ } + printf("\n %s NIC statistics for port %-2d %s\n", + nic_stats_border, port_id, nic_stats_border); + +@@ -184,10 +197,17 @@ nic_stats_display(portid_t port_id) } } @@ -4066,7 +4631,7 @@ index d599682788..e14ff42745 100644 diff_pkts_rx = (stats.ipackets > prev_pkts_rx[port_id]) ? (stats.ipackets - prev_pkts_rx[port_id]) : 0; -@@ -195,10 +211,10 @@ nic_stats_display(portid_t port_id) +@@ -195,10 +215,10 @@ nic_stats_display(portid_t port_id) (stats.opackets - prev_pkts_tx[port_id]) : 0; prev_pkts_rx[port_id] = stats.ipackets; prev_pkts_tx[port_id] = stats.opackets; @@ -4081,7 +4646,7 @@ index d599682788..e14ff42745 100644 diff_bytes_rx = (stats.ibytes > prev_bytes_rx[port_id]) ? (stats.ibytes - prev_bytes_rx[port_id]) : 0; -@@ -206,10 +222,10 @@ nic_stats_display(portid_t port_id) +@@ -206,10 +226,10 @@ nic_stats_display(portid_t port_id) (stats.obytes - prev_bytes_tx[port_id]) : 0; prev_bytes_rx[port_id] = stats.ibytes; prev_bytes_tx[port_id] = stats.obytes; @@ -4096,7 +4661,7 @@ index d599682788..e14ff42745 100644 printf("\n Throughput (since last show)\n"); printf(" Rx-pps: %12"PRIu64" Rx-bps: %12"PRIu64"\n Tx-pps: %12" -@@ -223,11 +239,28 @@ nic_stats_display(portid_t port_id) +@@ -223,11 +243,28 @@ nic_stats_display(portid_t port_id) void nic_stats_clear(portid_t port_id) { @@ -4126,7 +4691,7 @@ index d599682788..e14ff42745 100644 printf("\n NIC statistics for port %d cleared\n", port_id); } -@@ -303,10 +336,21 @@ nic_xstats_clear(portid_t port_id) +@@ -303,10 +340,21 @@ nic_xstats_clear(portid_t port_id) print_valid_ports(); return; } @@ -4148,7 +4713,59 @@ index d599682788..e14ff42745 100644 } } -@@ -1216,7 +1260,9 @@ void +@@ -511,6 +559,19 @@ device_infos_display(const char *identifier) + }; + } + ++const char * ++rsstypes_to_str(uint64_t rss_type) ++{ ++ uint16_t i; ++ ++ for (i = 0; rss_type_table[i].str != NULL; i++) { ++ if (rss_type_table[i].rss_type == rss_type) ++ return rss_type_table[i].str; ++ } ++ ++ return NULL; ++} ++ + void + port_infos_display(portid_t port_id) + { +@@ -605,19 +666,21 @@ port_infos_display(portid_t port_id) + if (!dev_info.flow_type_rss_offloads) + printf("No RSS offload flow type is supported.\n"); + else { ++ uint64_t rss_offload_types = dev_info.flow_type_rss_offloads; + uint16_t i; +- char *p; + + printf("Supported RSS offload flow types:\n"); +- for (i = RTE_ETH_FLOW_UNKNOWN + 1; +- i < sizeof(dev_info.flow_type_rss_offloads) * CHAR_BIT; i++) { +- if (!(dev_info.flow_type_rss_offloads & (1ULL << i))) +- continue; +- p = flowtype_to_str(i); +- if (p) +- printf(" %s\n", p); +- else +- printf(" user defined %d\n", i); ++ for (i = 0; i < sizeof(rss_offload_types) * CHAR_BIT; i++) { ++ uint64_t rss_offload = 1ULL << i; ++ ++ if ((rss_offload_types & rss_offload) != 0) { ++ const char *p = rsstypes_to_str(rss_offload); ++ if (p) ++ printf(" %s\n", p); ++ else ++ printf(" user defined %u\n", ++ i); ++ } + } + } + +@@ -1216,7 +1279,9 @@ void port_mtu_set(portid_t port_id, uint16_t mtu) { int diag; @@ -4158,7 +4775,7 @@ index d599682788..e14ff42745 100644 int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) -@@ -1232,9 +1278,24 @@ port_mtu_set(portid_t port_id, uint16_t mtu) +@@ -1232,9 +1297,24 @@ port_mtu_set(portid_t port_id, uint16_t mtu) return; } diag = rte_eth_dev_set_mtu(port_id, mtu); @@ -4186,7 +4803,7 @@ index d599682788..e14ff42745 100644 } /* Generic flow management functions. */ -@@ -1507,7 +1568,7 @@ port_flow_query(portid_t port_id, uint32_t rule, +@@ -1507,7 +1587,7 @@ port_flow_query(portid_t port_id, uint32_t rule, /** List flow rules. */ void @@ -4195,14 +4812,13 @@ index d599682788..e14ff42745 100644 { struct rte_port *port; struct port_flow *pf; -@@ -1624,22 +1685,102 @@ tx_queue_id_is_invalid(queueid_t txq_id) +@@ -1624,22 +1704,102 @@ tx_queue_id_is_invalid(queueid_t txq_id) } static int -rx_desc_id_is_invalid(uint16_t rxdesc_id) +get_rx_ring_size(portid_t port_id, queueid_t rxq_id, uint16_t *ring_size) - { -- if (rxdesc_id < nb_rxd) ++{ + struct rte_port *port = &ports[port_id]; + struct rte_eth_rxq_info rx_qinfo; + int ret; @@ -4266,7 +4882,8 @@ index d599682788..e14ff42745 100644 + +static int +rx_desc_id_is_invalid(portid_t port_id, queueid_t rxq_id, uint16_t rxdesc_id) -+{ + { +- if (rxdesc_id < nb_rxd) + uint16_t ring_size; + int ret; + @@ -4306,7 +4923,7 @@ index d599682788..e14ff42745 100644 return 1; } -@@ -1760,11 +1901,7 @@ rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id) +@@ -1760,11 +1920,7 @@ rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id) { const struct rte_memzone *rx_mz; @@ -4319,7 +4936,7 @@ index d599682788..e14ff42745 100644 return; rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id); if (rx_mz == NULL) -@@ -1777,11 +1914,7 @@ tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id) +@@ -1777,11 +1933,7 @@ tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id) { const struct rte_memzone *tx_mz; @@ -4332,7 +4949,7 @@ index d599682788..e14ff42745 100644 return; tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id); if (tx_mz == NULL) -@@ -1822,10 +1955,17 @@ rxtx_config_display(void) +@@ -1822,10 +1974,17 @@ rxtx_config_display(void) struct rte_eth_txconf *tx_conf = &ports[pid].tx_conf[0]; uint16_t *nb_rx_desc = &ports[pid].nb_rx_desc[0]; uint16_t *nb_tx_desc = &ports[pid].nb_tx_desc[0]; @@ -4352,7 +4969,7 @@ index d599682788..e14ff42745 100644 int32_t rc; /* per port config */ -@@ -1839,41 +1979,64 @@ rxtx_config_display(void) +@@ -1839,41 +1998,64 @@ rxtx_config_display(void) /* per rx queue config only for first queue to be less verbose */ for (qid = 0; qid < 1; qid++) { rc = rte_eth_rx_queue_info_get(pid, qid, &rx_qinfo); @@ -4432,7 +5049,117 @@ index d599682788..e14ff42745 100644 } } } -@@ -2518,6 +2681,10 @@ set_fwd_lcores_mask(uint64_t lcoremask) +@@ -1906,7 +2088,7 @@ port_rss_reta_info(portid_t port_id, + } + + /* +- * Displays the RSS hash functions of a port, and, optionaly, the RSS hash ++ * Displays the RSS hash functions of a port, and, optionally, the RSS hash + * key of the port. + */ + void +@@ -1961,7 +2143,9 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key) + } + printf("RSS functions:\n "); + for (i = 0; rss_type_table[i].str; i++) { +- if (rss_hf & rss_type_table[i].rss_type) ++ if (rss_type_table[i].rss_type == 0) ++ continue; ++ if ((rss_hf & rss_type_table[i].rss_type) == rss_type_table[i].rss_type) + printf("%s ", rss_type_table[i].str); + } + printf("\n"); +@@ -1975,14 +2159,14 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key) + + void + port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key, +- uint hash_key_len) ++ uint8_t hash_key_len) + { + struct rte_eth_rss_conf rss_conf; + int diag; + unsigned int i; + + rss_conf.rss_key = NULL; +- rss_conf.rss_key_len = hash_key_len; ++ rss_conf.rss_key_len = 0; + rss_conf.rss_hf = 0; + for (i = 0; rss_type_table[i].str; i++) { + if (!strcmp(rss_type_table[i].str, rss_type)) +@@ -1991,6 +2175,7 @@ port_rss_hash_key_update(portid_t port_id, char rss_type[], uint8_t *hash_key, + diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf); + if (diag == 0) { + rss_conf.rss_key = hash_key; ++ rss_conf.rss_key_len = hash_key_len; + diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf); + } + if (diag == 0) +@@ -2165,6 +2350,21 @@ rss_fwd_config_setup(void) + } + } + ++static uint16_t ++get_fwd_port_total_tc_num(void) ++{ ++ struct rte_eth_dcb_info dcb_info; ++ uint16_t total_tc_num = 0; ++ unsigned int i; ++ ++ for (i = 0; i < nb_fwd_ports; i++) { ++ (void)rte_eth_dev_get_dcb_info(fwd_ports_ids[i], &dcb_info); ++ total_tc_num += dcb_info.nb_tcs; ++ } ++ ++ return total_tc_num; ++} ++ + /** + * For the DCB forwarding test, each core is assigned on each traffic class. + * +@@ -2184,12 +2384,42 @@ dcb_fwd_config_setup(void) + lcoreid_t lc_id; + uint16_t nb_rx_queue, nb_tx_queue; + uint16_t i, j, k, sm_id = 0; ++ uint16_t total_tc_num; ++ struct rte_port *port; + uint8_t tc = 0; ++ portid_t pid; ++ int ret; ++ ++ /* ++ * The fwd_config_setup() is called when the port is RTE_PORT_STARTED ++ * or RTE_PORT_STOPPED. ++ * ++ * Re-configure ports to get updated mapping between tc and queue in ++ * case the queue number of the port is changed. Skip for started ports ++ * since modifying queue number and calling dev_configure need to stop ++ * ports first. ++ */ ++ for (pid = 0; pid < nb_fwd_ports; pid++) { ++ if (port_is_started(pid) == 1) ++ continue; ++ ++ port = &ports[pid]; ++ ret = rte_eth_dev_configure(pid, nb_rxq, nb_txq, ++ &port->dev_conf); ++ if (ret < 0) { ++ printf("Failed to re-configure port %d, ret = %d.\n", ++ pid, ret); ++ return; ++ } ++ } + + cur_fwd_config.nb_fwd_lcores = (lcoreid_t) nb_fwd_lcores; + cur_fwd_config.nb_fwd_ports = nb_fwd_ports; + cur_fwd_config.nb_fwd_streams = + (streamid_t) (nb_rxq * cur_fwd_config.nb_fwd_ports); ++ total_tc_num = get_fwd_port_total_tc_num(); ++ if (cur_fwd_config.nb_fwd_lcores > total_tc_num) ++ cur_fwd_config.nb_fwd_lcores = total_tc_num; + + /* reinitialize forwarding streams */ + init_fwd_streams(); +@@ -2518,6 +2748,10 @@ set_fwd_lcores_mask(uint64_t lcoremask) void set_fwd_lcores_number(uint16_t nb_lc) { @@ -4443,7 +5170,7 @@ index d599682788..e14ff42745 100644 if (nb_lc > nb_cfg_lcores) { printf("nb fwd cores %u > %u (max. number of configured " "lcores) - ignored\n", -@@ -2665,17 +2832,41 @@ show_tx_pkt_segments(void) +@@ -2665,21 +2899,61 @@ show_tx_pkt_segments(void) printf("Split packet: %s\n", split); } @@ -4458,13 +5185,15 @@ index d599682788..e14ff42745 100644 + RTE_ETH_FOREACH_DEV(port_id) { + for (queue_id = 0; queue_id < nb_txq; queue_id++) { + ret = get_tx_ring_size(port_id, queue_id, &ring_size); -+ -+ if (ret) -+ return true; -+ ++ if (ret) { ++ /* Port may not be initialized yet, can't say ++ * the port is invalid in this stage. ++ */ ++ continue; ++ } + if (ring_size < nb_segs) { -+ printf("nb segments per TX packets=%u >= " -+ "TX queue(%u) ring_size=%u - ignored\n", ++ printf("nb segments per TX packets=%u >= TX " ++ "queue(%u) ring_size=%u - txpkts ignored\n", + nb_segs, queue_id, ring_size); + return true; + } @@ -4483,13 +5212,31 @@ index d599682788..e14ff42745 100644 - if (nb_segs >= (unsigned) nb_txd) { - printf("nb segments per TX packets=%u >= nb_txd=%u - ignored\n", - nb_segs, (unsigned int) nb_txd); -+ if (nb_segs_is_invalid(nb_segs)) ++ /* ++ * For single segment settings failed check is ignored. ++ * It is a very basic capability to send the single segment ++ * packets, suppose it is always supported. ++ */ ++ if (nb_segs > 1 && nb_segs_is_invalid(nb_segs)) { ++ printf("Tx segment size(%u) is not supported - txpkts ignored\n", ++ nb_segs); ++ return; ++ } ++ ++ if (nb_segs > RTE_MAX_SEGS_PER_PKT) { ++ printf("Tx segment size(%u) is bigger than max number of segment(%u)\n", ++ nb_segs, RTE_MAX_SEGS_PER_PKT); return; -- } + } /* * Check that each segment length is greater or equal than -@@ -3019,9 +3210,11 @@ vlan_extend_set(portid_t port_id, int on) +- * the mbuf data sise. ++ * the mbuf data size. + * Check also that the total packet length is greater or equal than the + * size of an empty UDP/IP packet (sizeof(struct rte_ether_hdr) + + * 20 + 8). +@@ -3019,9 +3293,11 @@ vlan_extend_set(portid_t port_id, int on) } diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); @@ -4502,7 +5249,7 @@ index d599682788..e14ff42745 100644 ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; } -@@ -3046,9 +3239,11 @@ rx_vlan_strip_set(portid_t port_id, int on) +@@ -3046,9 +3322,11 @@ rx_vlan_strip_set(portid_t port_id, int on) } diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); @@ -4515,7 +5262,7 @@ index d599682788..e14ff42745 100644 ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; } -@@ -3087,9 +3282,11 @@ rx_vlan_filter_set(portid_t port_id, int on) +@@ -3087,9 +3365,11 @@ rx_vlan_filter_set(portid_t port_id, int on) } diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); @@ -4528,7 +5275,7 @@ index d599682788..e14ff42745 100644 ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; } -@@ -3114,9 +3311,11 @@ rx_vlan_qinq_strip_set(portid_t port_id, int on) +@@ -3114,9 +3394,11 @@ rx_vlan_qinq_strip_set(portid_t port_id, int on) } diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload); @@ -4541,7 +5288,7 @@ index d599682788..e14ff42745 100644 ports[port_id].dev_conf.rxmode.offloads = port_rx_offloads; } -@@ -3174,8 +3373,6 @@ tx_vlan_set(portid_t port_id, uint16_t vlan_id) +@@ -3174,8 +3456,6 @@ tx_vlan_set(portid_t port_id, uint16_t vlan_id) struct rte_eth_dev_info dev_info; int ret; @@ -4550,7 +5297,7 @@ index d599682788..e14ff42745 100644 if (vlan_id_is_invalid(vlan_id)) return; -@@ -3206,8 +3403,6 @@ tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) +@@ -3206,8 +3486,6 @@ tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) struct rte_eth_dev_info dev_info; int ret; @@ -4559,7 +5306,7 @@ index d599682788..e14ff42745 100644 if (vlan_id_is_invalid(vlan_id)) return; if (vlan_id_is_invalid(vlan_id_outer)) -@@ -3233,8 +3428,6 @@ tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) +@@ -3233,8 +3511,6 @@ tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer) void tx_vlan_reset(portid_t port_id) { @@ -4568,7 +5315,7 @@ index d599682788..e14ff42745 100644 ports[port_id].dev_conf.txmode.offloads &= ~(DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT); -@@ -3707,6 +3900,14 @@ mcast_addr_pool_extend(struct rte_port *port) +@@ -3707,12 +3983,20 @@ mcast_addr_pool_extend(struct rte_port *port) } @@ -4583,16 +5330,42 @@ index d599682788..e14ff42745 100644 static void mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) { -@@ -3725,7 +3926,7 @@ mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) + port->mc_addr_nb--; + if (addr_idx == port->mc_addr_nb) { +- /* No need to recompact the set of multicast addressses. */ ++ /* No need to recompact the set of multicast addresses. */ + if (port->mc_addr_nb == 0) { + /* free the pool of multicast addresses. */ + free(port->mc_addr_pool); +@@ -3725,7 +4009,26 @@ mcast_addr_pool_remove(struct rte_port *port, uint32_t addr_idx) sizeof(struct rte_ether_addr) * (port->mc_addr_nb - addr_idx)); } -static void ++int ++mcast_addr_pool_destroy(portid_t port_id) ++{ ++ struct rte_port *port; ++ ++ if (port_id_is_invalid(port_id, ENABLED_WARN) || ++ port_id == (portid_t)RTE_PORT_ALL) ++ return -EINVAL; ++ port = &ports[port_id]; ++ ++ if (port->mc_addr_nb != 0) { ++ /* free the pool of multicast addresses. */ ++ free(port->mc_addr_pool); ++ port->mc_addr_pool = NULL; ++ port->mc_addr_nb = 0; ++ } ++ return 0; ++} ++ +static int eth_port_multicast_addr_list_set(portid_t port_id) { struct rte_port *port; -@@ -3734,10 +3935,11 @@ eth_port_multicast_addr_list_set(portid_t port_id) +@@ -3734,10 +4037,11 @@ eth_port_multicast_addr_list_set(portid_t port_id) port = &ports[port_id]; diag = rte_eth_dev_set_mc_addr_list(port_id, port->mc_addr_pool, port->mc_addr_nb); @@ -4608,7 +5381,7 @@ index d599682788..e14ff42745 100644 } void -@@ -3762,10 +3964,10 @@ mcast_addr_add(portid_t port_id, struct rte_ether_addr *mc_addr) +@@ -3762,10 +4066,10 @@ mcast_addr_add(portid_t port_id, struct rte_ether_addr *mc_addr) } } @@ -4623,7 +5396,7 @@ index d599682788..e14ff42745 100644 } void -@@ -3792,7 +3994,9 @@ mcast_addr_remove(portid_t port_id, struct rte_ether_addr *mc_addr) +@@ -3792,7 +4096,9 @@ mcast_addr_remove(portid_t port_id, struct rte_ether_addr *mc_addr) } mcast_addr_pool_remove(port, i); @@ -4635,7 +5408,7 @@ index d599682788..e14ff42745 100644 void diff --git a/dpdk/app/test-pmd/csumonly.c b/dpdk/app/test-pmd/csumonly.c -index 25091de881..7b92ab1195 100644 +index 25091de881..50617c5f2a 100644 --- a/dpdk/app/test-pmd/csumonly.c +++ b/dpdk/app/test-pmd/csumonly.c @@ -139,22 +139,23 @@ parse_ipv6(struct rte_ipv6_hdr *ipv6_hdr, struct testpmd_offload_info *info) @@ -4668,8 +5441,141 @@ index 25091de881..7b92ab1195 100644 info->l2_len += sizeof(struct rte_vlan_hdr); info->ethertype = vlan_hdr->eth_proto; } +@@ -450,17 +451,18 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, + + if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV4)) { + ipv4_hdr = l3_hdr; +- ipv4_hdr->hdr_checksum = 0; + + ol_flags |= PKT_TX_IPV4; + if (info->l4_proto == IPPROTO_TCP && tso_segsz) { + ol_flags |= PKT_TX_IP_CKSUM; + } else { +- if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) ++ if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) { + ol_flags |= PKT_TX_IP_CKSUM; +- else ++ } else { ++ ipv4_hdr->hdr_checksum = 0; + ipv4_hdr->hdr_checksum = + rte_ipv4_cksum(ipv4_hdr); ++ } + } + } else if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV6)) + ol_flags |= PKT_TX_IPV6; +@@ -471,10 +473,10 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, + udp_hdr = (struct rte_udp_hdr *)((char *)l3_hdr + info->l3_len); + /* do not recalculate udp cksum if it was 0 */ + if (udp_hdr->dgram_cksum != 0) { +- udp_hdr->dgram_cksum = 0; +- if (tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM) ++ if (tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM) { + ol_flags |= PKT_TX_UDP_CKSUM; +- else { ++ } else { ++ udp_hdr->dgram_cksum = 0; + udp_hdr->dgram_cksum = + get_udptcp_checksum(l3_hdr, udp_hdr, + info->ethertype); +@@ -484,12 +486,12 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, + ol_flags |= PKT_TX_UDP_SEG; + } else if (info->l4_proto == IPPROTO_TCP) { + tcp_hdr = (struct rte_tcp_hdr *)((char *)l3_hdr + info->l3_len); +- tcp_hdr->cksum = 0; + if (tso_segsz) + ol_flags |= PKT_TX_TCP_SEG; +- else if (tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM) ++ else if (tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM) { + ol_flags |= PKT_TX_TCP_CKSUM; +- else { ++ } else { ++ tcp_hdr->cksum = 0; + tcp_hdr->cksum = + get_udptcp_checksum(l3_hdr, tcp_hdr, + info->ethertype); +@@ -499,13 +501,13 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, + } else if (info->l4_proto == IPPROTO_SCTP) { + sctp_hdr = (struct rte_sctp_hdr *) + ((char *)l3_hdr + info->l3_len); +- sctp_hdr->cksum = 0; + /* sctp payload must be a multiple of 4 to be + * offloaded */ + if ((tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) && + ((ipv4_hdr->total_length & 0x3) == 0)) { + ol_flags |= PKT_TX_SCTP_CKSUM; + } else { ++ sctp_hdr->cksum = 0; + /* XXX implement CRC32c, example available in + * RFC3309 */ + } +@@ -731,6 +733,26 @@ pkt_copy_split(const struct rte_mbuf *pkt) + return md[0]; + } + ++/* ++ * Re-calculate IP checksum for merged/fragmented packets. ++ */ ++static void ++pkts_ip_csum_recalc(struct rte_mbuf **pkts_burst, const uint16_t nb_pkts, uint64_t tx_offloads) ++{ ++ int i; ++ struct rte_ipv4_hdr *ipv4_hdr; ++ for (i = 0; i < nb_pkts; i++) { ++ if ((pkts_burst[i]->ol_flags & PKT_TX_IPV4) && ++ (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) { ++ ipv4_hdr = rte_pktmbuf_mtod_offset(pkts_burst[i], ++ struct rte_ipv4_hdr *, ++ pkts_burst[i]->l2_len); ++ ipv4_hdr->hdr_checksum = 0; ++ ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr); ++ } ++ } ++} ++ + /* + * Receive a burst of packets, and for each packet: + * - parse packet, and try to recognize a supported packet type (1) +@@ -844,10 +866,6 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + * and inner headers */ + + eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); +- rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr], +- ð_hdr->d_addr); +- rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, +- ð_hdr->s_addr); + parse_ethernet(eth_hdr, &info); + l3_hdr = (char *)eth_hdr + info.l2_len; + +@@ -925,8 +943,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + (tx_offloads & + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) || + (tx_offloads & +- DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) || +- (tx_ol_flags & PKT_TX_OUTER_IPV6)) { ++ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)) { + m->outer_l2_len = info.outer_l2_len; + m->outer_l3_len = info.outer_l3_len; + m->l2_len = info.l2_len; +@@ -1038,6 +1055,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + fs->gro_times = 0; + } + } ++ ++ pkts_ip_csum_recalc(pkts_burst, nb_rx, tx_offloads); + } + + if (gso_ports[fs->tx_port].enable == 0) +@@ -1059,6 +1078,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) + + tx_pkts_burst = gso_segments; + nb_rx = nb_segments; ++ ++ pkts_ip_csum_recalc(tx_pkts_burst, nb_rx, tx_offloads); + } + + nb_prep = rte_eth_tx_prepare(fs->tx_port, fs->tx_queue, diff --git a/dpdk/app/test-pmd/flowgen.c b/dpdk/app/test-pmd/flowgen.c -index 03b72aaa56..3e1335b627 100644 +index 03b72aaa56..ac00f61a92 100644 --- a/dpdk/app/test-pmd/flowgen.c +++ b/dpdk/app/test-pmd/flowgen.c @@ -1,35 +1,5 @@ @@ -4732,6 +5638,35 @@ index 03b72aaa56..3e1335b627 100644 sizeof(*ip_hdr)); /* Initialize UDP header. */ +@@ -213,12 +186,12 @@ pkt_burst_flow_gen(struct fwd_stream *fs) + /* + * Retry if necessary + */ +- if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { ++ if (unlikely(nb_tx < nb_pkt) && fs->retry_enabled) { + retry = 0; +- while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { ++ while (nb_tx < nb_pkt && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, +- &pkts_burst[nb_tx], nb_rx - nb_tx); ++ &pkts_burst[nb_tx], nb_pkt - nb_tx); + } + } + fs->tx_packets += nb_tx; +diff --git a/dpdk/app/test-pmd/icmpecho.c b/dpdk/app/test-pmd/icmpecho.c +index 2d359c9436..d4b942e186 100644 +--- a/dpdk/app/test-pmd/icmpecho.c ++++ b/dpdk/app/test-pmd/icmpecho.c +@@ -54,7 +54,7 @@ arp_op_name(uint16_t arp_op) + default: + break; + } +- return "Unkwown ARP op"; ++ return "Unknown ARP op"; + } + + static const char * diff --git a/dpdk/app/test-pmd/macswap.c b/dpdk/app/test-pmd/macswap.c index 71af916fc3..8428c26d85 100644 --- a/dpdk/app/test-pmd/macswap.c @@ -4797,10 +5732,20 @@ index 6006c60f99..b0249bdb3c 100644 deps += 'pmd_bnxt' endif diff --git a/dpdk/app/test-pmd/parameters.c b/dpdk/app/test-pmd/parameters.c -index 2e7a504415..a1c08a411a 100644 +index 2e7a504415..eff1cbb9a8 100644 --- a/dpdk/app/test-pmd/parameters.c +++ b/dpdk/app/test-pmd/parameters.c -@@ -49,7 +49,7 @@ +@@ -39,9 +39,6 @@ + #include + #include + #include +-#ifdef RTE_LIBRTE_PMD_BOND +-#include +-#endif + #include + + #include "testpmd.h" +@@ -49,7 +46,7 @@ static void usage(char* progname) { @@ -4809,7 +5754,27 @@ index 2e7a504415..a1c08a411a 100644 #ifdef RTE_LIBRTE_CMDLINE "[--interactive|-i] " "[--cmdline-file=FILENAME] " -@@ -884,12 +884,9 @@ launch_args_parse(int argc, char** argv) +@@ -694,7 +691,7 @@ launch_args_parse(int argc, char** argv) + case 0: /*long options */ + if (!strcmp(lgopts[opt_idx].name, "help")) { + usage(argv[0]); +- rte_exit(EXIT_SUCCESS, "Displayed help\n"); ++ exit(EXIT_SUCCESS); + } + #ifdef RTE_LIBRTE_CMDLINE + if (!strcmp(lgopts[opt_idx].name, "interactive")) { +@@ -876,20 +873,18 @@ launch_args_parse(int argc, char** argv) + } + if (!strcmp(lgopts[opt_idx].name, "total-num-mbufs")) { + n = atoi(optarg); +- if (n > 1024) ++ if (n > MIN_TOTAL_NUM_MBUFS) + param_total_num_mbufs = (unsigned)n; + else + rte_exit(EXIT_FAILURE, +- "total-num-mbufs should be > 1024\n"); ++ "total-num-mbufs should be > %d\n", ++ MIN_TOTAL_NUM_MBUFS); } if (!strcmp(lgopts[opt_idx].name, "max-pkt-len")) { n = atoi(optarg); @@ -4824,11 +5789,48 @@ index 2e7a504415..a1c08a411a 100644 rte_exit(EXIT_FAILURE, "Invalid max-pkt-len=%d - should be > %d\n", n, RTE_ETHER_MIN_LEN); +@@ -1359,7 +1354,7 @@ launch_args_parse(int argc, char** argv) + break; + case 'h': + usage(argv[0]); +- rte_exit(EXIT_SUCCESS, "Displayed help\n"); ++ exit(EXIT_SUCCESS); + break; + default: + usage(argv[0]); diff --git a/dpdk/app/test-pmd/testpmd.c b/dpdk/app/test-pmd/testpmd.c -index b374682236..0c3361e817 100644 +index b374682236..379f867caa 100644 --- a/dpdk/app/test-pmd/testpmd.c +++ b/dpdk/app/test-pmd/testpmd.c -@@ -421,8 +421,11 @@ lcoreid_t latencystats_lcore_id = -1; +@@ -60,6 +60,9 @@ + #ifdef RTE_LIBRTE_LATENCY_STATS + #include + #endif ++#ifdef RTE_LIBRTE_PMD_BOND ++#include ++#endif + + #include "testpmd.h" + +@@ -206,6 +209,7 @@ uint16_t stats_period; /**< Period to show statistics (disabled by default) */ + * option. Set flag to exit stats period loop after received SIGINT/SIGTERM. + */ + uint8_t f_quit; ++uint8_t cl_quit; /* Quit testpmd from cmdline. */ + + /* + * Configuration of packet segments used by the "txonly" processing engine. +@@ -228,9 +232,6 @@ uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ + /* current configuration is in DCB or not,0 means it is not in DCB mode */ + uint8_t dcb_config = 0; + +-/* Whether the dcb is in testing status */ +-uint8_t dcb_test = 0; +- + /* + * Configurable number of RX/TX queues. + */ +@@ -421,8 +422,11 @@ lcoreid_t latencystats_lcore_id = -1; * Ethernet device configuration. */ struct rte_eth_rxmode rx_mode = { @@ -4842,7 +5844,7 @@ index b374682236..0c3361e817 100644 }; struct rte_eth_txmode tx_mode = { -@@ -1071,6 +1074,177 @@ check_nb_txq(queueid_t txq) +@@ -1071,6 +1075,177 @@ check_nb_txq(queueid_t txq) return 0; } @@ -5020,19 +6022,198 @@ index b374682236..0c3361e817 100644 /* * Get the allowed maximum number of hairpin queues. * *pid return the port id which has minimal value of -@@ -1166,6 +1340,11 @@ init_config(void) - rte_exit(EXIT_FAILURE, - "rte_eth_dev_info_get() failed\n"); +@@ -1118,23 +1293,69 @@ check_nb_hairpinq(queueid_t hairpinq) + return 0; + } -+ ret = update_jumbo_frame_offload(pid); -+ if (ret != 0) -+ printf("Updating jumbo frame offload failed for port %u\n", -+ pid); ++static void ++init_config_port_offloads(portid_t pid, uint32_t socket_id) ++{ ++ struct rte_port *port = &ports[pid]; ++ uint16_t data_size; ++ int ret; ++ int i; ++ ++ port->dev_conf.txmode = tx_mode; ++ port->dev_conf.rxmode = rx_mode; ++ ++ ret = eth_dev_info_get_print_err(pid, &port->dev_info); ++ if (ret != 0) ++ rte_exit(EXIT_FAILURE, "rte_eth_dev_info_get() failed\n"); ++ ++ ret = update_jumbo_frame_offload(pid); ++ if (ret != 0) ++ printf("Updating jumbo frame offload failed for port %u\n", ++ pid); ++ ++ if (!(port->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)) ++ port->dev_conf.txmode.offloads &= ++ ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; ++ ++ /* Apply Rx offloads configuration */ ++ for (i = 0; i < port->dev_info.max_rx_queues; i++) ++ port->rx_conf[i].offloads = port->dev_conf.rxmode.offloads; ++ /* Apply Tx offloads configuration */ ++ for (i = 0; i < port->dev_info.max_tx_queues; i++) ++ port->tx_conf[i].offloads = port->dev_conf.txmode.offloads; ++ ++ /* set flag to initialize port/queue */ ++ port->need_reconfig = 1; ++ port->need_reconfig_queues = 1; ++ port->socket_id = socket_id; ++ port->tx_metadata = 0; ++ ++ /* ++ * Check for maximum number of segments per MTU. ++ * Accordingly update the mbuf data size. ++ */ ++ if (port->dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX && ++ port->dev_info.rx_desc_lim.nb_mtu_seg_max != 0) { ++ data_size = rx_mode.max_rx_pkt_len / ++ port->dev_info.rx_desc_lim.nb_mtu_seg_max; ++ ++ if ((data_size + RTE_PKTMBUF_HEADROOM) > mbuf_data_size) { ++ mbuf_data_size = data_size + RTE_PKTMBUF_HEADROOM; ++ TESTPMD_LOG(WARNING, "Configured mbuf size %hu\n", ++ mbuf_data_size); ++ } ++ } ++} + - if (!(port->dev_info.tx_offload_capa & - DEV_TX_OFFLOAD_MBUF_FAST_FREE)) - port->dev_conf.txmode.offloads &= -@@ -1430,9 +1609,9 @@ init_fwd_streams(void) + static void + init_config(void) + { + portid_t pid; +- struct rte_port *port; + struct rte_mempool *mbp; + unsigned int nb_mbuf_per_pool; + lcoreid_t lc_id; +- uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; + struct rte_gro_param gro_param; + uint32_t gso_types; +- uint16_t data_size; +- bool warning = 0; +- int k; +- int ret; +- +- memset(port_per_socket,0,RTE_MAX_NUMA_NODES); + + /* Configuration of logical cores. */ + fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", +@@ -1156,25 +1377,12 @@ init_config(void) + } + + RTE_ETH_FOREACH_DEV(pid) { +- port = &ports[pid]; +- /* Apply default TxRx configuration for all ports */ +- port->dev_conf.txmode = tx_mode; +- port->dev_conf.rxmode = rx_mode; ++ uint32_t socket_id; + +- ret = eth_dev_info_get_print_err(pid, &port->dev_info); +- if (ret != 0) +- rte_exit(EXIT_FAILURE, +- "rte_eth_dev_info_get() failed\n"); +- +- if (!(port->dev_info.tx_offload_capa & +- DEV_TX_OFFLOAD_MBUF_FAST_FREE)) +- port->dev_conf.txmode.offloads &= +- ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; + if (numa_support) { +- if (port_numa[pid] != NUMA_NO_CONFIG) +- port_per_socket[port_numa[pid]]++; +- else { +- uint32_t socket_id = rte_eth_dev_socket_id(pid); ++ socket_id = port_numa[pid]; ++ if (port_numa[pid] == NUMA_NO_CONFIG) { ++ socket_id = rte_eth_dev_socket_id(pid); + + /* + * if socket_id is invalid, +@@ -1182,45 +1390,15 @@ init_config(void) + */ + if (check_socket_id(socket_id) < 0) + socket_id = socket_ids[0]; +- port_per_socket[socket_id]++; +- } +- } +- +- /* Apply Rx offloads configuration */ +- for (k = 0; k < port->dev_info.max_rx_queues; k++) +- port->rx_conf[k].offloads = +- port->dev_conf.rxmode.offloads; +- /* Apply Tx offloads configuration */ +- for (k = 0; k < port->dev_info.max_tx_queues; k++) +- port->tx_conf[k].offloads = +- port->dev_conf.txmode.offloads; +- +- /* set flag to initialize port/queue */ +- port->need_reconfig = 1; +- port->need_reconfig_queues = 1; +- port->tx_metadata = 0; +- +- /* Check for maximum number of segments per MTU. Accordingly +- * update the mbuf data size. +- */ +- if (port->dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX && +- port->dev_info.rx_desc_lim.nb_mtu_seg_max != 0) { +- data_size = rx_mode.max_rx_pkt_len / +- port->dev_info.rx_desc_lim.nb_mtu_seg_max; +- +- if ((data_size + RTE_PKTMBUF_HEADROOM) > +- mbuf_data_size) { +- mbuf_data_size = data_size + +- RTE_PKTMBUF_HEADROOM; +- warning = 1; + } ++ } else { ++ socket_id = (socket_num == UMA_NO_CONFIG) ? ++ 0 : socket_num; + } ++ /* Apply default TxRx configuration for all ports */ ++ init_config_port_offloads(pid, socket_id); + } + +- if (warning) +- TESTPMD_LOG(WARNING, "Configured mbuf size %hu\n", +- mbuf_data_size); +- + /* + * Create pools of mbuf. + * If NUMA support is disabled, create a single pool of mbuf in +@@ -1303,7 +1481,7 @@ init_config(void) + #if defined RTE_LIBRTE_PMD_SOFTNIC + if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) { + RTE_ETH_FOREACH_DEV(pid) { +- port = &ports[pid]; ++ struct rte_port *port = &ports[pid]; + const char *driver = port->dev_info.driver_name; + + if (strcmp(driver, "net_softnic") == 0) +@@ -1318,21 +1496,8 @@ init_config(void) + void + reconfig(portid_t new_port_id, unsigned socket_id) + { +- struct rte_port *port; +- int ret; +- + /* Reconfiguration of Ethernet ports. */ +- port = &ports[new_port_id]; +- +- ret = eth_dev_info_get_print_err(new_port_id, &port->dev_info); +- if (ret != 0) +- return; +- +- /* set flag to initialize port/queue */ +- port->need_reconfig = 1; +- port->need_reconfig_queues = 1; +- port->socket_id = socket_id; +- ++ init_config_port_offloads(new_port_id, socket_id); + init_port_config(); + } + +@@ -1430,9 +1595,9 @@ init_fwd_streams(void) static void pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) { @@ -5045,7 +6226,16 @@ index b374682236..0c3361e817 100644 uint16_t pktnb_stats[3]; uint16_t nb_pkt; int burst_percent[3]; -@@ -1461,8 +1640,8 @@ pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) +@@ -1444,7 +1609,7 @@ pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) + total_burst = 0; + burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; + pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; +- for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { ++ for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST + 1; nb_pkt++) { + nb_burst = pbs->pkt_burst_spread[nb_pkt]; + if (nb_burst == 0) + continue; +@@ -1461,8 +1626,8 @@ pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) } if (total_burst == 0) return; @@ -5056,7 +6246,7 @@ index b374682236..0c3361e817 100644 burst_percent[0], (int) pktnb_stats[0]); if (burst_stats[0] == total_burst) { printf("]\n"); -@@ -1473,7 +1652,7 @@ pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) +@@ -1473,7 +1638,7 @@ pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 100 - burst_percent[0], pktnb_stats[1]); return; } @@ -5065,7 +6255,30 @@ index b374682236..0c3361e817 100644 burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { printf(" + %d%% of others]\n", 100 - burst_percent[0]); -@@ -1698,11 +1877,22 @@ fwd_stats_display(void) +@@ -1544,6 +1709,7 @@ fwd_stats_display(void) + struct rte_port *port; + streamid_t sm_id; + portid_t pt_id; ++ int ret; + int i; + + memset(ports_stats, 0, sizeof(ports_stats)); +@@ -1576,7 +1742,13 @@ fwd_stats_display(void) + pt_id = fwd_ports_ids[i]; + port = &ports[pt_id]; + +- rte_eth_stats_get(pt_id, &stats); ++ ret = rte_eth_stats_get(pt_id, &stats); ++ if (ret != 0) { ++ fprintf(stderr, ++ "%s: Error: failed to get stats (port %u): %d", ++ __func__, pt_id, ret); ++ continue; ++ } + stats.ipackets -= port->stats.ipackets; + stats.opackets -= port->stats.opackets; + stats.ibytes -= port->stats.ibytes; +@@ -1698,11 +1870,22 @@ fwd_stats_display(void) "%s\n", acc_stats_border, acc_stats_border); #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES @@ -5093,7 +6306,222 @@ index b374682236..0c3361e817 100644 #endif } -@@ -2549,32 +2739,17 @@ setup_attached_port(portid_t pi) +@@ -1711,11 +1894,16 @@ fwd_stats_reset(void) + { + streamid_t sm_id; + portid_t pt_id; ++ int ret; + int i; + + for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { + pt_id = fwd_ports_ids[i]; +- rte_eth_stats_get(pt_id, &ports[pt_id].stats); ++ ret = rte_eth_stats_get(pt_id, &ports[pt_id].stats); ++ if (ret != 0) ++ fprintf(stderr, ++ "%s: Error: failed to clear stats (port %u):%d", ++ __func__, pt_id, ret); + } + for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { + struct fwd_stream *fs = fwd_streams[sm_id]; +@@ -1915,8 +2103,7 @@ start_packet_forwarding(int with_tx_first) + return; + } + +- +- if(dcb_test) { ++ if (dcb_config) { + for (i = 0; i < nb_fwd_ports; i++) { + pt_id = fwd_ports_ids[i]; + port = &ports[pt_id]; +@@ -2124,6 +2311,38 @@ setup_hairpin_queues(portid_t pi) + return 0; + } + ++static int ++change_bonding_slave_port_status(portid_t bond_pid, bool is_stop) ++{ ++#ifdef RTE_LIBRTE_PMD_BOND ++ ++ portid_t slave_pids[RTE_MAX_ETHPORTS]; ++ struct rte_port *port; ++ int num_slaves; ++ portid_t slave_pid; ++ int i; ++ ++ num_slaves = rte_eth_bond_slaves_get(bond_pid, slave_pids, ++ RTE_MAX_ETHPORTS); ++ if (num_slaves < 0) { ++ fprintf(stderr, "Failed to get slave list for port = %u\n", ++ bond_pid); ++ return num_slaves; ++ } ++ ++ for (i = 0; i < num_slaves; i++) { ++ slave_pid = slave_pids[i]; ++ port = &ports[slave_pid]; ++ port->port_status = ++ is_stop ? RTE_PORT_STOPPED : RTE_PORT_STARTED; ++ } ++#else ++ RTE_SET_USED(bond_pid); ++ RTE_SET_USED(is_stop); ++#endif ++ return 0; ++} ++ + int + start_port(portid_t pid) + { +@@ -2131,18 +2350,22 @@ start_port(portid_t pid) + portid_t pi; + queueid_t qi; + struct rte_port *port; +- struct rte_ether_addr mac_addr; + struct rte_eth_hairpin_cap cap; + + if (port_id_is_invalid(pid, ENABLED_WARN)) + return 0; + +- if(dcb_config) +- dcb_test = 1; + RTE_ETH_FOREACH_DEV(pi) { + if (pid != pi && pid != (portid_t)RTE_PORT_ALL) + continue; + ++ if (port_is_bonding_slave(pi)) { ++ fprintf(stderr, ++ "Please remove port %d from bonded device.\n", ++ pi); ++ continue; ++ } ++ + need_check_link_status = 0; + port = &ports[pi]; + if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, +@@ -2292,16 +2515,28 @@ start_port(portid_t pid) + "stopped\n", pi); + continue; + } ++ /* ++ * Starting a bonded port also starts all slaves under the ++ * bonded device. So if this port is bond device, we need ++ * to modify the port status of these slaves. ++ */ ++ if (port->bond_flag == 1) { ++ if (change_bonding_slave_port_status(pi, false) != 0) ++ continue; ++ } + + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) + printf("Port %d can not be set into started\n", pi); + +- if (eth_macaddr_get_print_err(pi, &mac_addr) == 0) ++ if (eth_macaddr_get_print_err(pi, &port->eth_addr) == 0) + printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, +- mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], +- mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], +- mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); ++ port->eth_addr.addr_bytes[0], ++ port->eth_addr.addr_bytes[1], ++ port->eth_addr.addr_bytes[2], ++ port->eth_addr.addr_bytes[3], ++ port->eth_addr.addr_bytes[4], ++ port->eth_addr.addr_bytes[5]); + + /* at least one port started, need checking link status */ + need_check_link_status = 1; +@@ -2323,11 +2558,6 @@ stop_port(portid_t pid) + struct rte_port *port; + int need_check_link_status = 0; + +- if (dcb_test) { +- dcb_test = 0; +- dcb_config = 0; +- } +- + if (port_id_is_invalid(pid, ENABLED_WARN)) + return; + +@@ -2354,6 +2584,18 @@ stop_port(portid_t pid) + + rte_eth_dev_stop(pi); + ++ /* ++ * Stopping a bonded port also stops all slaves under the bonded ++ * device. So if this port is bond device, we need to modify the ++ * port status of these slaves. ++ */ ++ if (port->bond_flag == 1) { ++ if (change_bonding_slave_port_status(pi, true) != 0) { ++ RTE_LOG(ERR, EAL, "Fail to change bonding slave port status %u\n", ++ pi); ++ } ++ } ++ + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set into stopped\n", pi); +@@ -2387,11 +2629,36 @@ remove_invalid_ports(void) + nb_cfg_ports = nb_fwd_ports; + } + ++static void ++clear_bonding_slave_device(portid_t *slave_pids, uint16_t num_slaves) ++{ ++ struct rte_port *port; ++ portid_t slave_pid; ++ uint16_t i; ++ ++ for (i = 0; i < num_slaves; i++) { ++ slave_pid = slave_pids[i]; ++ if (port_is_started(slave_pid) == 1) { ++ rte_eth_dev_stop(slave_pid); ++ port = &ports[slave_pid]; ++ port->port_status = RTE_PORT_STOPPED; ++ } ++ ++ clear_port_slave_flag(slave_pid); ++ ++ /* Close slave device when testpmd quit or is killed. */ ++ if (cl_quit == 1 || f_quit == 1) ++ rte_eth_dev_close(slave_pid); ++ } ++} ++ + void + close_port(portid_t pid) + { + portid_t pi; + struct rte_port *port; ++ portid_t slave_pids[RTE_MAX_ETHPORTS]; ++ int num_slaves = 0; + + if (port_id_is_invalid(pid, ENABLED_WARN)) + return; +@@ -2427,7 +2694,20 @@ close_port(portid_t pid) + + if (port->flow_list) + port_flow_flush(pi); ++ ++#ifdef RTE_LIBRTE_PMD_BOND ++ if (port->bond_flag == 1) ++ num_slaves = rte_eth_bond_slaves_get(pi, ++ slave_pids, RTE_MAX_ETHPORTS); ++#endif ++ mcast_addr_pool_destroy(pi); + rte_eth_dev_close(pi); ++ /* ++ * If this port is bonded device, all slaves under the ++ * device need to be removed or closed. ++ */ ++ if (port->bond_flag == 1 && num_slaves > 0) ++ clear_bonding_slave_device(slave_pids, num_slaves); + + remove_invalid_ports(); + +@@ -2549,32 +2829,17 @@ setup_attached_port(portid_t pi) printf("Done\n"); } @@ -5129,7 +6557,7 @@ index b374682236..0c3361e817 100644 if (rte_dev_remove(dev) < 0) { TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name); -@@ -2592,14 +2767,33 @@ detach_port_device(portid_t port_id) +@@ -2592,14 +2857,33 @@ detach_port_device(portid_t port_id) remove_invalid_ports(); @@ -5165,7 +6593,7 @@ index b374682236..0c3361e817 100644 { struct rte_dev_iterator iterator; struct rte_devargs da; -@@ -2748,7 +2942,7 @@ check_all_ports_link_status(uint32_t port_mask) +@@ -2748,7 +3032,7 @@ check_all_ports_link_status(uint32_t port_mask) "Port%d Link Up. speed %u Mbps- %s\n", portid, link.link_speed, (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? @@ -5174,7 +6602,7 @@ index b374682236..0c3361e817 100644 else printf("Port %d Link Down\n", portid); continue; -@@ -2790,6 +2984,7 @@ rmv_port_callback(void *arg) +@@ -2790,6 +3074,7 @@ rmv_port_callback(void *arg) int need_to_start = 0; int org_no_link_check = no_link_check; portid_t port_id = (intptr_t)arg; @@ -5182,7 +6610,7 @@ index b374682236..0c3361e817 100644 RTE_ETH_VALID_PORTID_OR_RET(port_id); -@@ -2800,8 +2995,12 @@ rmv_port_callback(void *arg) +@@ -2800,8 +3085,12 @@ rmv_port_callback(void *arg) no_link_check = 1; stop_port(port_id); no_link_check = org_no_link_check; @@ -5196,7 +6624,7 @@ index b374682236..0c3361e817 100644 if (need_to_start) start_packet_forwarding(0); } -@@ -3049,6 +3248,80 @@ rxtx_port_config(struct rte_port *port) +@@ -3049,6 +3338,80 @@ rxtx_port_config(struct rte_port *port) } } @@ -5277,7 +6705,7 @@ index b374682236..0c3361e817 100644 void init_port_config(void) { -@@ -3184,6 +3457,8 @@ get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf, +@@ -3184,6 +3547,8 @@ get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf, struct rte_eth_dcb_tx_conf *tx_conf = ð_conf->tx_adv_conf.dcb_tx_conf; @@ -5286,7 +6714,45 @@ index b374682236..0c3361e817 100644 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf); if (rc != 0) return rc; -@@ -3570,5 +3845,10 @@ main(int argc, char** argv) +@@ -3223,18 +3588,21 @@ init_port_dcb_config(portid_t pid, + + rte_port = &ports[pid]; + +- memset(&port_conf, 0, sizeof(struct rte_eth_conf)); +- /* Enter DCB configuration status */ +- dcb_config = 1; +- +- port_conf.rxmode = rte_port->dev_conf.rxmode; +- port_conf.txmode = rte_port->dev_conf.txmode; ++ /* retain the original device configuration. */ ++ memcpy(&port_conf, &rte_port->dev_conf, sizeof(struct rte_eth_conf)); + + /*set configuration of DCB in vt mode and DCB in non-vt mode*/ + retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en); + if (retval < 0) + return retval; + port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; ++ /* remove RSS HASH offload for DCB in vt mode */ ++ if (port_conf.rxmode.mq_mode == ETH_MQ_RX_VMDQ_DCB) { ++ port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_RSS_HASH; ++ for (i = 0; i < nb_rxq; i++) ++ rte_port->rx_conf[i].offloads &= ++ ~DEV_RX_OFFLOAD_RSS_HASH; ++ } + + /* re-configure the device . */ + retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf); +@@ -3295,6 +3663,9 @@ init_port_dcb_config(portid_t pid, + + rte_port->dcb_flag = 1; + ++ /* Enter DCB configuration status */ ++ dcb_config = 1; ++ + return 0; + } + +@@ -3570,5 +3941,10 @@ main(int argc, char** argv) return 1; } @@ -5299,10 +6765,63 @@ index b374682236..0c3361e817 100644 + return EXIT_SUCCESS; } diff --git a/dpdk/app/test-pmd/testpmd.h b/dpdk/app/test-pmd/testpmd.h -index 217d577018..4dbcee3a62 100644 +index 217d577018..b34ad78949 100644 --- a/dpdk/app/test-pmd/testpmd.h +++ b/dpdk/app/test-pmd/testpmd.h -@@ -797,7 +797,7 @@ void stop_port(portid_t pid); +@@ -23,6 +23,8 @@ + #define RTE_PORT_CLOSED (uint16_t)2 + #define RTE_PORT_HANDLING (uint16_t)3 + ++extern uint8_t cl_quit; ++ + /* + * It is used to allocate the memory for hash key. + * The hash key size is NIC dependent. +@@ -53,6 +55,8 @@ + #define NUMA_NO_CONFIG 0xFF + #define UMA_NO_CONFIG 0xFF + ++#define MIN_TOTAL_NUM_MBUFS 1024 ++ + typedef uint8_t lcoreid_t; + typedef uint16_t portid_t; + typedef uint16_t queueid_t; +@@ -86,7 +90,7 @@ enum { + * that are recorded for each forwarding stream. + */ + struct pkt_burst_stats { +- unsigned int pkt_burst_spread[MAX_PKT_BURST]; ++ unsigned int pkt_burst_spread[MAX_PKT_BURST + 1]; + }; + #endif + +@@ -183,7 +187,8 @@ struct rte_port { + struct rte_eth_txconf tx_conf[RTE_MAX_QUEUES_PER_PORT+1]; /**< per queue tx configuration */ + struct rte_ether_addr *mc_addr_pool; /**< pool of multicast addrs */ + uint32_t mc_addr_nb; /**< nb. of addr. in mc_addr_pool */ +- uint8_t slave_flag; /**< bonding slave port */ ++ uint8_t slave_flag : 1, /**< bonding slave port */ ++ bond_flag : 1; /**< port is bond device */ + struct port_flow *flow_list; /**< Associated flows. */ + const struct rte_eth_rxtx_callback *rx_dump_cb[RTE_MAX_QUEUES_PER_PORT+1]; + const struct rte_eth_rxtx_callback *tx_dump_cb[RTE_MAX_QUEUES_PER_PORT+1]; +@@ -404,7 +409,6 @@ extern uint64_t noisy_lkup_num_reads; + extern uint64_t noisy_lkup_num_reads_writes; + + extern uint8_t dcb_config; +-extern uint8_t dcb_test; + + extern uint16_t mbuf_data_size; /**< Mbuf data space size. */ + extern uint32_t param_total_num_mbufs; +@@ -732,6 +736,7 @@ int port_flow_create(portid_t port_id, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action *actions); ++int mcast_addr_pool_destroy(portid_t port_id); + int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule); + int port_flow_flush(portid_t port_id); + int port_flow_query(portid_t port_id, uint32_t rule, +@@ -797,7 +802,7 @@ void stop_port(portid_t pid); void close_port(portid_t pid); void reset_port(portid_t pid); void attach_port(char *identifier); @@ -5311,7 +6830,18 @@ index 217d577018..4dbcee3a62 100644 void detach_port_device(portid_t port_id); int all_ports_stopped(void); int port_is_stopped(portid_t port_id); -@@ -859,6 +859,8 @@ queueid_t get_allowed_max_nb_rxq(portid_t *pid); +@@ -820,7 +825,9 @@ int set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, + + void port_rss_hash_conf_show(portid_t port_id, int show_rss_key); + void port_rss_hash_key_update(portid_t port_id, char rss_type[], +- uint8_t *hash_key, uint hash_key_len); ++ uint8_t *hash_key, uint8_t hash_key_len); ++const char *rsstypes_to_str(uint64_t rss_type); ++ + int rx_queue_id_is_invalid(queueid_t rxq_id); + int tx_queue_id_is_invalid(queueid_t txq_id); + void setup_gro(const char *onoff, portid_t port_id); +@@ -859,6 +866,8 @@ 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); @@ -5320,7 +6850,7 @@ index 217d577018..4dbcee3a62 100644 queueid_t get_allowed_max_nb_hairpinq(portid_t *pid); int check_nb_hairpinq(queueid_t hairpinq); -@@ -881,6 +883,8 @@ uint16_t tx_pkt_set_md(uint16_t port_id, __rte_unused uint16_t queue, +@@ -881,6 +890,8 @@ uint16_t tx_pkt_set_md(uint16_t port_id, __rte_unused uint16_t queue, void add_tx_md_callback(portid_t portid); void remove_tx_md_callback(portid_t portid); @@ -5420,7 +6950,7 @@ index 3caf281cb8..a1822c631d 100644 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/dpdk/app/test-pmd/util.c b/dpdk/app/test-pmd/util.c -index b514be5e16..487260d59d 100644 +index b514be5e16..416980cb2d 100644 --- a/dpdk/app/test-pmd/util.c +++ b/dpdk/app/test-pmd/util.c @@ -1,6 +1,6 @@ @@ -5593,7 +7123,7 @@ index b514be5e16..487260d59d 100644 if (is_encapsulation) { struct rte_ipv4_hdr *ipv4_hdr; struct rte_ipv6_hdr *ipv6_hdr; -@@ -146,18 +181,27 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], +@@ -146,18 +181,31 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], l2_len + l3_len + l4_len); udp_port = RTE_BE_TO_CPU_16(udp_hdr->dst_port); vx_vni = rte_be_to_cpu_32(vxlan_hdr->vx_vni); @@ -5609,12 +7139,17 @@ index b514be5e16..487260d59d 100644 - printf(" - %s queue=0x%x", is_rx ? "Receive" : "Send", - (unsigned int) queue); - printf("\n"); +- rte_get_rx_ol_flag_list(mb->ol_flags, buf, sizeof(buf)); +- printf(" ol_flags: %s\n", buf); + MKDUMPSTR(print_buf, buf_size, cur_len, + " - %s queue=0x%x", is_rx ? "Receive" : "Send", + (unsigned int) queue); + MKDUMPSTR(print_buf, buf_size, cur_len, "\n"); - rte_get_rx_ol_flag_list(mb->ol_flags, buf, sizeof(buf)); -- printf(" ol_flags: %s\n", buf); ++ if (is_rx) ++ rte_get_rx_ol_flag_list(mb->ol_flags, buf, sizeof(buf)); ++ else ++ rte_get_tx_ol_flag_list(mb->ol_flags, buf, sizeof(buf)); ++ + MKDUMPSTR(print_buf, buf_size, cur_len, + " ol_flags: %s\n", buf); if (rte_mbuf_check(mb, 1, &reason) < 0) @@ -5718,6 +7253,28 @@ index 6deb97bcc1..ca29b09f31 100644 "Func": default_autotest, "Report": None, }, +diff --git a/dpdk/app/test/autotest_test_funcs.py b/dpdk/app/test/autotest_test_funcs.py +index 26688b7132..016d99cc24 100644 +--- a/dpdk/app/test/autotest_test_funcs.py ++++ b/dpdk/app/test/autotest_test_funcs.py +@@ -12,13 +12,16 @@ + def default_autotest(child, test_name): + child.sendline(test_name) + result = child.expect(["Test OK", "Test Failed", +- "Command not found", pexpect.TIMEOUT], timeout=900) ++ "Command not found", pexpect.TIMEOUT, ++ "Test Skipped"], timeout=900) + if result == 1: + return -1, "Fail" + elif result == 2: + return -1, "Fail [Not found]" + elif result == 3: + return -1, "Fail [Timeout]" ++ elif result == 4: ++ return 0, "Skipped [Not Run]" + return 0, "Success" + + # autotest used to run dump commands diff --git a/dpdk/app/test/get-coremask.sh b/dpdk/app/test/get-coremask.sh new file mode 100755 index 0000000000..bb8cf404d2 @@ -5738,7 +7295,7 @@ index 0000000000..bb8cf404d2 + echo 0-3 +fi diff --git a/dpdk/app/test/meson.build b/dpdk/app/test/meson.build -index fb49d804ba..24fb59f74f 100644 +index fb49d804ba..8823f5a960 100644 --- a/dpdk/app/test/meson.build +++ b/dpdk/app/test/meson.build @@ -7,13 +7,11 @@ endif @@ -6016,7 +7573,7 @@ index fb49d804ba..24fb59f74f 100644 endif if dpdk_conf.has('RTE_LIBRTE_POWER') -@@ -359,19 +364,23 @@ endif +@@ -359,26 +364,29 @@ endif # specify -D_GNU_SOURCE unconditionally cflags += '-D_GNU_SOURCE' @@ -6043,16 +7600,14 @@ index fb49d804ba..24fb59f74f 100644 endif foreach d:test_deps -@@ -382,7 +391,7 @@ test_dep_objs += cc.find_library('execinfo', required: false) + def_lib = get_option('default_library') + test_dep_objs += get_variable(def_lib + '_rte_' + d) + endforeach +-test_dep_objs += cc.find_library('execinfo', required: false) link_libs = [] if get_option('default_library') == 'static' -- link_libs = dpdk_drivers -+ link_libs = dpdk_static_libraries + dpdk_drivers - endif - - dpdk_test = executable('dpdk-test', -@@ -390,53 +399,66 @@ dpdk_test = executable('dpdk-test', +@@ -390,53 +398,66 @@ dpdk_test = executable('dpdk-test', link_whole: link_libs, dependencies: test_dep_objs, c_args: [cflags, '-DALLOW_EXPERIMENTAL_API'], @@ -6064,7 +7619,7 @@ index fb49d804ba..24fb59f74f 100644 +has_hugepage = true +if is_linux + check_hugepage = run_command('cat', -+ '/proc/sys/vm/nr_hugepages') ++ '/proc/sys/vm/nr_hugepages', check: false) + if (check_hugepage.returncode() != 0 or + check_hugepage.stdout().strip() == '0') + has_hugepage = false @@ -6150,7 +7705,7 @@ index fb49d804ba..24fb59f74f 100644 timeout : timeout_seconds, is_parallel : false, suite : 'perf-tests') -@@ -445,7 +467,7 @@ endforeach +@@ -445,7 +466,7 @@ endforeach foreach arg : driver_test_names test(arg, dpdk_test, env : ['DPDK_TEST=' + arg], @@ -6159,7 +7714,7 @@ index fb49d804ba..24fb59f74f 100644 timeout : timeout_seconds, is_parallel : false, suite : 'driver-tests') -@@ -454,7 +476,7 @@ endforeach +@@ -454,7 +475,7 @@ endforeach foreach arg : dump_test_names test(arg, dpdk_test, env : ['DPDK_TEST=' + arg], @@ -6168,8 +7723,31 @@ index fb49d804ba..24fb59f74f 100644 timeout : timeout_seconds, is_parallel : false, suite : 'debug-tests') +diff --git a/dpdk/app/test/packet_burst_generator.c b/dpdk/app/test/packet_burst_generator.c +index f203f9d09e..0fd7290b0e 100644 +--- a/dpdk/app/test/packet_burst_generator.c ++++ b/dpdk/app/test/packet_burst_generator.c +@@ -117,6 +117,7 @@ initialize_tcp_header(struct rte_tcp_hdr *tcp_hdr, uint16_t src_port, + memset(tcp_hdr, 0, sizeof(struct rte_tcp_hdr)); + tcp_hdr->src_port = rte_cpu_to_be_16(src_port); + tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port); ++ tcp_hdr->data_off = (sizeof(struct rte_tcp_hdr) << 2) & 0xF0; + + return pkt_len; + } +@@ -141,8 +142,8 @@ uint16_t + initialize_ipv6_header(struct rte_ipv6_hdr *ip_hdr, uint8_t *src_addr, + uint8_t *dst_addr, uint16_t pkt_data_len) + { +- ip_hdr->vtc_flow = 0; +- ip_hdr->payload_len = pkt_data_len; ++ ip_hdr->vtc_flow = rte_cpu_to_be_32(0x60000000); /* Set version to 6. */ ++ ip_hdr->payload_len = rte_cpu_to_be_16(pkt_data_len); + ip_hdr->proto = IPPROTO_UDP; + ip_hdr->hop_limits = IP_DEFTTL; + diff --git a/dpdk/app/test/process.h b/dpdk/app/test/process.h -index 191d2796a9..c3b3780337 100644 +index 191d2796a9..20e8eedda8 100644 --- a/dpdk/app/test/process.h +++ b/dpdk/app/test/process.h @@ -25,10 +25,12 @@ @@ -6185,23 +7763,31 @@ index 191d2796a9..c3b3780337 100644 /* * launches a second copy of the test process using the given argv parameters, -@@ -44,7 +46,9 @@ process_dup(const char *const argv[], int numargs, const char *env_value) +@@ -44,7 +46,10 @@ process_dup(const char *const argv[], int numargs, const char *env_value) int i, status; char path[32]; #ifdef RTE_LIBRTE_PDUMP +#ifdef RTE_LIBRTE_RING_PMD pthread_t thread; ++ int rc; +#endif #endif pid_t pid = fork(); -@@ -121,17 +125,21 @@ process_dup(const char *const argv[], int numargs, const char *env_value) +@@ -121,17 +126,26 @@ process_dup(const char *const argv[], int numargs, const char *env_value) } /* parent process does a wait */ #ifdef RTE_LIBRTE_PDUMP +- if ((strcmp(env_value, "run_pdump_server_tests") == 0)) +- pthread_create(&thread, NULL, &send_pkts, NULL); +#ifdef RTE_LIBRTE_RING_PMD - if ((strcmp(env_value, "run_pdump_server_tests") == 0)) - pthread_create(&thread, NULL, &send_pkts, NULL); ++ if ((strcmp(env_value, "run_pdump_server_tests") == 0)) { ++ rc = pthread_create(&thread, NULL, &send_pkts, NULL); ++ if (rc != 0) { ++ rte_panic("Cannot start send pkts thread: %s\n", ++ strerror(rc)); ++ } ++ } +#endif #endif @@ -6217,8 +7803,62 @@ index 191d2796a9..c3b3780337 100644 #endif return status; } +diff --git a/dpdk/app/test/sample_packet_forward.c b/dpdk/app/test/sample_packet_forward.c +index 61384b3d9b..aa897274d8 100644 +--- a/dpdk/app/test/sample_packet_forward.c ++++ b/dpdk/app/test/sample_packet_forward.c +@@ -15,6 +15,35 @@ + + #include "sample_packet_forward.h" + ++/* ++ * heper function: configure and start test device ++ */ ++int ++test_dev_start(uint16_t port, struct rte_mempool *mp) ++{ ++ int32_t rc; ++ struct rte_eth_conf pconf; ++ ++ memset(&pconf, 0, sizeof(pconf)); ++ ++ rc = rte_eth_dev_configure(port, NUM_QUEUES, NUM_QUEUES, &pconf); ++ if (rc != 0) ++ return rc; ++ ++ rc = rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET_ID_ANY, ++ NULL, mp); ++ if (rc != 0) ++ return rc; ++ ++ rc = rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET_ID_ANY, ++ NULL); ++ if (rc != 0) ++ return rc; ++ ++ rc = rte_eth_dev_start(port); ++ return rc; ++} ++ + /* Sample test to create virtual rings and tx,rx portid from rings */ + int + test_ring_setup(struct rte_ring **ring, uint16_t *portid) +diff --git a/dpdk/app/test/sample_packet_forward.h b/dpdk/app/test/sample_packet_forward.h +index 6789217de3..af0b1d9924 100644 +--- a/dpdk/app/test/sample_packet_forward.h ++++ b/dpdk/app/test/sample_packet_forward.h +@@ -21,6 +21,9 @@ struct rte_ring; + /* Sample test to create virtual rings and tx,rx portid from rings */ + int test_ring_setup(struct rte_ring **ring, uint16_t *portid); + ++/* configure and start device created by test_ring_setup */ ++int test_dev_start(uint16_t port, struct rte_mempool *mp); ++ + /* Sample test to free the virtual rings */ + void test_ring_free(struct rte_ring *rxtx); + diff --git a/dpdk/app/test/test.c b/dpdk/app/test/test.c -index cd7aaf645f..4736a17ff3 100644 +index cd7aaf645f..3e063af333 100644 --- a/dpdk/app/test/test.c +++ b/dpdk/app/test/test.c @@ -53,7 +53,9 @@ do_recursive_call(void) @@ -6231,7 +7871,33 @@ index cd7aaf645f..4736a17ff3 100644 #endif { "test_missing_c_flag", no_action }, { "test_master_lcore_flag", no_action }, -@@ -162,29 +164,38 @@ main(int argc, char **argv) +@@ -132,8 +134,13 @@ main(int argc, char **argv) + goto out; + } + ++ argv += ret; ++ ++ prgname = argv[0]; ++ + #ifdef RTE_LIBRTE_TIMER +- if (rte_timer_subsystem_init() < 0) { ++ ret = rte_timer_subsystem_init(); ++ if (ret < 0 && ret != -EALREADY) { + ret = -1; + goto out; + } +@@ -144,10 +151,6 @@ main(int argc, char **argv) + goto out; + } + +- argv += ret; +- +- prgname = argv[0]; +- + recursive_call = getenv(RECURSIVE_ENV_VAR); + if (recursive_call != NULL) { + ret = do_recursive_call(); +@@ -162,29 +165,38 @@ main(int argc, char **argv) #ifdef RTE_LIBRTE_CMDLINE @@ -6327,11 +7993,171 @@ index 9cd9e37dbe..b78b67193a 100644 } /* NULL name */ +diff --git a/dpdk/app/test/test_atomic.c b/dpdk/app/test/test_atomic.c +index de3030d221..a8065f182a 100644 +--- a/dpdk/app/test/test_atomic.c ++++ b/dpdk/app/test/test_atomic.c +@@ -88,7 +88,7 @@ + * + * - Invoke ``test_atomic_exchange`` on each lcore. Before doing + * anything else, the cores wait for a synchronization event. +- * Each core then does the follwoing for N iterations: ++ * Each core then does the following for N iterations: + * + * Generate a new token with a data integrity check + * Exchange the new token for previously generated token +@@ -591,7 +591,7 @@ test_atomic(void) + rte_atomic32_clear(&synchro); + + iterations = count128.val[0] - count128.val[1]; +- if (iterations != 4*N*(rte_lcore_count()-1)) { ++ if (iterations != (uint64_t)4*N*(rte_lcore_count()-1)) { + printf("128-bit compare and swap failed\n"); + return -1; + } +diff --git a/dpdk/app/test/test_barrier.c b/dpdk/app/test/test_barrier.c +index 43b5f6232c..e54eca44fb 100644 +--- a/dpdk/app/test/test_barrier.c ++++ b/dpdk/app/test/test_barrier.c +@@ -6,7 +6,7 @@ + * This is a simple functional test for rte_smp_mb() implementation. + * I.E. make sure that LOAD and STORE operations that precede the + * rte_smp_mb() call are globally visible across the lcores +- * before the the LOAD and STORE operations that follows it. ++ * before the LOAD and STORE operations that follows it. + * The test uses simple implementation of Peterson's lock algorithm + * (https://en.wikipedia.org/wiki/Peterson%27s_algorithm) + * for two execution units to make sure that rte_smp_mb() prevents +@@ -66,7 +66,7 @@ struct plock_test { + struct lcore_plock_test { + struct plock_test *pt[2]; /* shared, lock-protected data */ + uint64_t sum[2]; /* local copy of the shared data */ +- uint64_t iter; /* number of iterations to perfom */ ++ uint64_t iter; /* number of iterations to perform */ + uint32_t lc; /* given lcore id */ + }; + +diff --git a/dpdk/app/test/test_bitratestats.c b/dpdk/app/test/test_bitratestats.c +index 3a7d9c037a..33b04c0369 100644 +--- a/dpdk/app/test/test_bitratestats.c ++++ b/dpdk/app/test/test_bitratestats.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include "sample_packet_forward.h" + #include "test.h" +@@ -145,12 +146,21 @@ test_bit_packet_forward(void) + printf("allocate mbuf pool Failed\n"); + return TEST_FAILED; + } ++ ret = test_dev_start(portid, mp); ++ if (ret < 0) { ++ printf("test_dev_start(%hu, %p) failed, error code: %d\n", ++ portid, mp, ret); ++ return TEST_FAILED; ++ } ++ + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); ++ ++ rte_eth_dev_stop(portid); + test_put_mbuf_to_pool(mp, pbuf); + +- return TEST_SUCCESS; ++ return (ret >= 0) ? TEST_SUCCESS : TEST_FAILED; + } + + static int diff --git a/dpdk/app/test/test_bpf.c b/dpdk/app/test/test_bpf.c -index ee534687a6..4a61a7d7cb 100644 +index ee534687a6..d60e639261 100644 --- a/dpdk/app/test/test_bpf.c +++ b/dpdk/app/test/test_bpf.c -@@ -1797,13 +1797,6 @@ test_call1_check(uint64_t rc, const void *arg) +@@ -51,6 +51,9 @@ struct dummy_net { + #define TEST_SHIFT_1 15 + #define TEST_SHIFT_2 33 + ++#define TEST_SHIFT32_MASK (CHAR_BIT * sizeof(uint32_t) - 1) ++#define TEST_SHIFT64_MASK (CHAR_BIT * sizeof(uint64_t) - 1) ++ + #define TEST_JCC_1 0 + #define TEST_JCC_2 -123 + #define TEST_JCC_3 5678 +@@ -540,15 +543,25 @@ static const struct ebpf_insn test_shift1_prog[] = { + .off = offsetof(struct dummy_vect8, out[1].u64), + }, + { +- .code = (BPF_ALU | BPF_RSH | BPF_X), +- .dst_reg = EBPF_REG_2, +- .src_reg = EBPF_REG_4, ++ .code = (BPF_ALU | BPF_AND | BPF_K), ++ .dst_reg = EBPF_REG_4, ++ .imm = TEST_SHIFT64_MASK, + }, + { + .code = (EBPF_ALU64 | BPF_LSH | BPF_X), + .dst_reg = EBPF_REG_3, + .src_reg = EBPF_REG_4, + }, ++ { ++ .code = (BPF_ALU | BPF_AND | BPF_K), ++ .dst_reg = EBPF_REG_4, ++ .imm = TEST_SHIFT32_MASK, ++ }, ++ { ++ .code = (BPF_ALU | BPF_RSH | BPF_X), ++ .dst_reg = EBPF_REG_2, ++ .src_reg = EBPF_REG_4, ++ }, + { + .code = (BPF_STX | BPF_MEM | EBPF_DW), + .dst_reg = EBPF_REG_1, +@@ -582,7 +595,7 @@ static const struct ebpf_insn test_shift1_prog[] = { + { + .code = (BPF_ALU | BPF_AND | BPF_K), + .dst_reg = EBPF_REG_2, +- .imm = sizeof(uint64_t) * CHAR_BIT - 1, ++ .imm = TEST_SHIFT64_MASK, + }, + { + .code = (EBPF_ALU64 | EBPF_ARSH | BPF_X), +@@ -592,7 +605,7 @@ static const struct ebpf_insn test_shift1_prog[] = { + { + .code = (BPF_ALU | BPF_AND | BPF_K), + .dst_reg = EBPF_REG_2, +- .imm = sizeof(uint32_t) * CHAR_BIT - 1, ++ .imm = TEST_SHIFT32_MASK, + }, + { + .code = (BPF_ALU | BPF_LSH | BPF_X), +@@ -658,8 +671,10 @@ test_shift1_check(uint64_t rc, const void *arg) + dve.out[0].u64 = r2; + dve.out[1].u64 = r3; + +- r2 = (uint32_t)r2 >> r4; ++ r4 &= TEST_SHIFT64_MASK; + r3 <<= r4; ++ r4 &= TEST_SHIFT32_MASK; ++ r2 = (uint32_t)r2 >> r4; + + dve.out[2].u64 = r2; + dve.out[3].u64 = r3; +@@ -668,9 +683,9 @@ test_shift1_check(uint64_t rc, const void *arg) + r3 = dvt->in[1].u64; + r4 = dvt->in[2].u32; + +- r2 &= sizeof(uint64_t) * CHAR_BIT - 1; ++ r2 &= TEST_SHIFT64_MASK; + r3 = (int64_t)r3 >> r2; +- r2 &= sizeof(uint32_t) * CHAR_BIT - 1; ++ r2 &= TEST_SHIFT32_MASK; + r4 = (uint32_t)r4 << r2; + + dve.out[4].u64 = r4; +@@ -1797,13 +1812,6 @@ test_call1_check(uint64_t rc, const void *arg) dummy_func1(arg, &v32, &v64); v64 += v32; @@ -6345,7 +8171,7 @@ index ee534687a6..4a61a7d7cb 100644 return cmp_res(__func__, v64, rc, dv, dv, sizeof(*dv)); } -@@ -1934,13 +1927,7 @@ test_call2_check(uint64_t rc, const void *arg) +@@ -1934,13 +1942,7 @@ test_call2_check(uint64_t rc, const void *arg) dummy_func2(&a, &b); v = a.u64 + a.u32 + b.u16 + b.u8; @@ -6360,7 +8186,16 @@ index ee534687a6..4a61a7d7cb 100644 } static const struct rte_bpf_xsym test_call2_xsym[] = { -@@ -2429,7 +2416,6 @@ test_call5_check(uint64_t rc, const void *arg) +@@ -2396,7 +2398,7 @@ static const struct ebpf_insn test_call5_prog[] = { + }, + }; + +-/* String comparision impelementation, return 0 if equal else difference */ ++/* String comparison implementation, return 0 if equal else difference */ + static uint32_t + dummy_func5(const char *s1, const char *s2) + { +@@ -2429,7 +2431,6 @@ test_call5_check(uint64_t rc, const void *arg) v = 0; fail: @@ -6368,7 +8203,7 @@ index ee534687a6..4a61a7d7cb 100644 return cmp_res(__func__, v, rc, &v, &rc, sizeof(v)); } -@@ -2458,6 +2444,7 @@ static const struct rte_bpf_xsym test_call5_xsym[] = { +@@ -2458,6 +2459,7 @@ static const struct rte_bpf_xsym test_call5_xsym[] = { }, }; @@ -6376,7 +8211,7 @@ index ee534687a6..4a61a7d7cb 100644 static const struct bpf_test tests[] = { { .name = "test_store1", -@@ -2738,7 +2725,6 @@ run_test(const struct bpf_test *tst) +@@ -2738,7 +2740,6 @@ run_test(const struct bpf_test *tst) } tst->prepare(tbuf); @@ -6384,7 +8219,7 @@ index ee534687a6..4a61a7d7cb 100644 rc = rte_bpf_exec(bpf, tbuf); ret = tst->check_result(rc, tbuf); if (ret != 0) { -@@ -2746,17 +2732,20 @@ run_test(const struct bpf_test *tst) +@@ -2746,17 +2747,20 @@ run_test(const struct bpf_test *tst) __func__, __LINE__, tst->name, ret, strerror(ret)); } @@ -6410,11 +8245,39 @@ index ee534687a6..4a61a7d7cb 100644 + printf("%s@%d: check_result(%s) failed, " + "error: %d(%s);\n", + __func__, __LINE__, tst->name, -+ rv, strerror(ret)); ++ rv, strerror(rv)); + } } rte_bpf_destroy(bpf); +diff --git a/dpdk/app/test/test_cmdline_ipaddr.c b/dpdk/app/test/test_cmdline_ipaddr.c +index 088cd5afc3..312ed79c49 100644 +--- a/dpdk/app/test/test_cmdline_ipaddr.c ++++ b/dpdk/app/test/test_cmdline_ipaddr.c +@@ -255,7 +255,7 @@ const char * ipaddr_invalid_strs[] = { + /** misc **/ + + /* too long */ +- "1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234" ++ "1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234", + "random invalid text", + "", + "\0", +diff --git a/dpdk/app/test/test_cmdline_num.c b/dpdk/app/test/test_cmdline_num.c +index 4c97caf3d0..481fc38295 100644 +--- a/dpdk/app/test/test_cmdline_num.c ++++ b/dpdk/app/test/test_cmdline_num.c +@@ -200,8 +200,8 @@ const char * num_invalid_strs[] = { + "-0x1234580A", + "-0b0111010101", + /* too long (128+ chars) */ +- "0b1111000011110000111100001111000011110000111100001111000011110000" +- "1111000011110000111100001111000011110000111100001111000011110000", ++ ("0b1111000011110000111100001111000011110000111100001111000011110000" ++ "1111000011110000111100001111000011110000111100001111000011110000"), + "1E3", + "0A", + "-B", diff --git a/dpdk/app/test/test_common.c b/dpdk/app/test/test_common.c index 2b856f8ba5..12bd1cad90 100644 --- a/dpdk/app/test/test_common.c @@ -6440,6 +8303,53 @@ index 2b856f8ba5..12bd1cad90 100644 uint64_t i64; /* extend range for 64-bit */ +diff --git a/dpdk/app/test/test_compressdev.c b/dpdk/app/test/test_compressdev.c +index 7549135c25..bb13d23838 100644 +--- a/dpdk/app/test/test_compressdev.c ++++ b/dpdk/app/test/test_compressdev.c +@@ -1359,7 +1359,6 @@ test_deflate_comp_finalize(const struct interim_data_params *int_data, + /* from int_data: */ + unsigned int num_xforms = int_data->num_xforms; + struct rte_comp_xform **compress_xforms = int_data->compress_xforms; +- uint16_t *buf_idx = int_data->buf_idx; + unsigned int num_bufs = int_data->num_bufs; + + /* from test_priv_data: */ +@@ -1390,7 +1389,7 @@ test_deflate_comp_finalize(const struct interim_data_params *int_data, + + RTE_LOG(DEBUG, USER1, "Buffer %u compressed by %s from %u to" + " %u bytes (level = %d, huffman = %s)\n", +- buf_idx[priv_data->orig_idx], engine, ++ i, engine, + ops_processed[i]->consumed, ops_processed[i]->produced, + compress_xform->level, + huffman_type_strings[huffman_type]); +@@ -1681,7 +1680,6 @@ test_deflate_decomp_finalize(const struct interim_data_params *int_data, + static unsigned int step; + + /* from int_data: */ +- uint16_t *buf_idx = int_data->buf_idx; + unsigned int num_bufs = int_data->num_bufs; + const char * const *test_bufs = int_data->test_bufs; + struct rte_comp_xform **compress_xforms = int_data->compress_xforms; +@@ -1713,7 +1711,7 @@ test_deflate_decomp_finalize(const struct interim_data_params *int_data, + strlcpy(engine, "pmd", sizeof(engine)); + RTE_LOG(DEBUG, USER1, + "Buffer %u decompressed by %s from %u to %u bytes\n", +- buf_idx[priv_data->orig_idx], engine, ++ i, engine, + ops_processed[i]->consumed, ops_processed[i]->produced); + ops[i] = NULL; + } +@@ -1978,7 +1976,7 @@ test_deflate_comp_decomp(const struct interim_data_params *int_data, + test_priv_data.all_decomp_data = &all_decomp_data; + test_priv_data.decomp_produced_data_size = &decomp_produced_data_size; + +- test_priv_data.num_priv_xforms = 0; /* it's used for deompression only */ ++ test_priv_data.num_priv_xforms = 0; /* it's used for decompression only */ + + capa = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE); + if (capa == NULL) { diff --git a/dpdk/app/test/test_compressdev_test_buffer.h b/dpdk/app/test/test_compressdev_test_buffer.h index c0492f89a2..d241602445 100644 --- a/dpdk/app/test/test_compressdev_test_buffer.h @@ -6653,11 +8563,38 @@ index c0492f89a2..d241602445 100644 }; #endif /* TEST_COMPRESSDEV_TEST_BUFFERS_H_ */ +diff --git a/dpdk/app/test/test_crc.c b/dpdk/app/test/test_crc.c +index f8a74e04ee..d8b513de32 100644 +--- a/dpdk/app/test/test_crc.c ++++ b/dpdk/app/test/test_crc.c +@@ -80,6 +80,8 @@ test_crc_calc(void) + + /* 32-bit ethernet CRC: Test 2 */ + test_data = rte_zmalloc(NULL, CRC32_VEC_LEN1, 0); ++ if (test_data == NULL) ++ return -7; + + for (i = 0; i < CRC32_VEC_LEN1; i += 12) + rte_memcpy(&test_data[i], crc32_vec1, 12); diff --git a/dpdk/app/test/test_cryptodev.c b/dpdk/app/test/test_cryptodev.c -index 1b561456d7..a852040ec2 100644 +index 1b561456d7..8ad2f251e5 100644 --- a/dpdk/app/test/test_cryptodev.c +++ b/dpdk/app/test/test_cryptodev.c -@@ -143,7 +143,7 @@ static struct rte_crypto_op * +@@ -112,10 +112,11 @@ setup_test_string(struct rte_mempool *mpool, + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + size_t t_len = len - (blocksize ? (len % blocksize) : 0); + +- memset(m->buf_addr, 0, m->buf_len); + if (m) { +- char *dst = rte_pktmbuf_append(m, t_len); ++ char *dst; + ++ memset(m->buf_addr, 0, m->buf_len); ++ dst = rte_pktmbuf_append(m, t_len); + if (!dst) { + rte_pktmbuf_free(m); + return NULL; +@@ -143,7 +144,7 @@ static struct rte_crypto_op * process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) { if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { @@ -6666,7 +8603,7 @@ index 1b561456d7..a852040ec2 100644 return NULL; } -@@ -152,6 +152,11 @@ process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) +@@ -152,6 +153,11 @@ process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op) while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0) rte_pause(); @@ -6678,7 +8615,24 @@ index 1b561456d7..a852040ec2 100644 return op; } -@@ -638,7 +643,7 @@ test_device_configure_invalid_dev_id(void) +@@ -575,7 +581,6 @@ ut_teardown(void) + { + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; +- struct rte_cryptodev_stats stats; + + /* free crypto session structure */ + #ifdef RTE_LIBRTE_SECURITY +@@ -622,8 +627,6 @@ ut_teardown(void) + RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n", + rte_mempool_avail_count(ts_params->mbuf_pool)); + +- rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); +- + /* Stop the device */ + rte_cryptodev_stop(ts_params->valid_devs[0]); + } +@@ -638,7 +641,7 @@ test_device_configure_invalid_dev_id(void) "Need at least %d devices for test", 1); /* valid dev_id values */ @@ -6687,7 +8641,7 @@ index 1b561456d7..a852040ec2 100644 /* Stop the device in case it's started so it can be configured */ rte_cryptodev_stop(dev_id); -@@ -2696,13 +2701,15 @@ create_wireless_algo_cipher_auth_session(uint8_t dev_id, +@@ -2696,13 +2699,15 @@ create_wireless_algo_cipher_auth_session(uint8_t dev_id, /* Create Crypto session*/ ut_params->sess = rte_cryptodev_sym_session_create( ts_params->session_mpool); @@ -6704,7 +8658,7 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -2822,12 +2829,24 @@ create_wireless_algo_auth_cipher_session(uint8_t dev_id, +@@ -2822,12 +2827,24 @@ create_wireless_algo_auth_cipher_session(uint8_t dev_id, /* Create Crypto session*/ ut_params->sess = rte_cryptodev_sym_session_create( ts_params->session_mpool); @@ -6733,7 +8687,7 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -2971,6 +2990,11 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, +@@ -2971,6 +2988,11 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, struct crypto_testsuite_params *ts_params = &testsuite_params; struct crypto_unittest_params *ut_params = &unittest_params; @@ -6745,7 +8699,7 @@ index 1b561456d7..a852040ec2 100644 /* Generate Crypto op data structure */ ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); -@@ -2991,8 +3015,22 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, +@@ -2991,8 +3013,22 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data, "no room to append auth tag"); ut_params->digest = sym_op->auth.digest.data; @@ -6770,7 +8724,7 @@ index 1b561456d7..a852040ec2 100644 if (op == RTE_CRYPTO_AUTH_OP_GENERATE) memset(sym_op->auth.digest.data, 0, auth_tag_len); else -@@ -3009,22 +3047,38 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, +@@ -3009,22 +3045,38 @@ create_wireless_algo_cipher_hash_operation(const uint8_t *auth_tag, iv_ptr += cipher_iv_len; rte_memcpy(iv_ptr, auth_iv, auth_iv_len); @@ -6815,7 +8769,7 @@ index 1b561456d7..a852040ec2 100644 { struct crypto_testsuite_params *ts_params = &testsuite_params; struct crypto_unittest_params *ut_params = &unittest_params; -@@ -3081,6 +3135,10 @@ create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len, +@@ -3081,6 +3133,10 @@ create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len, } } @@ -6826,7 +8780,31 @@ index 1b561456d7..a852040ec2 100644 /* Copy cipher and auth IVs at the end of the crypto operation */ uint8_t *iv_ptr = rte_crypto_op_ctod_offset( ut_params->op, uint8_t *, IV_OFFSET); -@@ -4643,7 +4701,7 @@ test_snow3g_auth_cipher(const struct snow3g_test_data *tdata, +@@ -3898,9 +3954,9 @@ test_kasumi_decryption(const struct kasumi_test_data *tdata) + + /* Create KASUMI operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, +- tdata->cipher_iv.len, +- tdata->ciphertext.len, +- tdata->validCipherOffsetInBits.len); ++ tdata->cipher_iv.len, ++ RTE_ALIGN_CEIL(tdata->validCipherLenInBits.len, 8), ++ tdata->validCipherOffsetInBits.len); + if (retval < 0) + return retval; + +@@ -4535,9 +4591,9 @@ test_snow3g_cipher_auth(const struct snow3g_test_data *tdata) + if (retval < 0) + return retval; + ++ TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + ut_params->op = process_crypto_request(ts_params->valid_devs[0], + ut_params->op); +- TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); + ut_params->obuf = ut_params->op->sym->m_src; + if (ut_params->obuf) + ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *); +@@ -4643,7 +4699,7 @@ test_snow3g_auth_cipher(const struct snow3g_test_data *tdata, /* Create SNOW 3G operation */ retval = create_wireless_algo_auth_cipher_operation( @@ -6835,7 +8813,7 @@ index 1b561456d7..a852040ec2 100644 tdata->cipher_iv.data, tdata->cipher_iv.len, tdata->auth_iv.data, tdata->auth_iv.len, (tdata->digest.offset_bytes == 0 ? -@@ -4653,7 +4711,7 @@ test_snow3g_auth_cipher(const struct snow3g_test_data *tdata, +@@ -4653,7 +4709,7 @@ test_snow3g_auth_cipher(const struct snow3g_test_data *tdata, tdata->cipher.offset_bits, tdata->validAuthLenInBits.len, tdata->auth.offset_bits, @@ -6844,7 +8822,32 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -4819,7 +4877,7 @@ test_snow3g_auth_cipher_sgl(const struct snow3g_test_data *tdata, +@@ -4703,16 +4759,20 @@ test_snow3g_auth_cipher(const struct snow3g_test_data *tdata, + + /* Validate obuf */ + if (verify) { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET( + plaintext, + tdata->plaintext.data, +- tdata->plaintext.len >> 3, ++ (tdata->plaintext.len - tdata->cipher.offset_bits - ++ (tdata->digest.len << 3)), ++ tdata->cipher.offset_bits, + "SNOW 3G Plaintext data not as expected"); + } else { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET( + ciphertext, + tdata->ciphertext.data, +- tdata->validDataLenInBits.len, ++ (tdata->validDataLenInBits.len - ++ tdata->cipher.offset_bits), ++ tdata->cipher.offset_bits, + "SNOW 3G Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( +@@ -4819,7 +4879,7 @@ test_snow3g_auth_cipher_sgl(const struct snow3g_test_data *tdata, /* Create SNOW 3G operation */ retval = create_wireless_algo_auth_cipher_operation( @@ -6853,7 +8856,7 @@ index 1b561456d7..a852040ec2 100644 tdata->cipher_iv.data, tdata->cipher_iv.len, tdata->auth_iv.data, tdata->auth_iv.len, (tdata->digest.offset_bytes == 0 ? -@@ -4829,7 +4887,7 @@ test_snow3g_auth_cipher_sgl(const struct snow3g_test_data *tdata, +@@ -4829,7 +4889,7 @@ test_snow3g_auth_cipher_sgl(const struct snow3g_test_data *tdata, tdata->cipher.offset_bits, tdata->validAuthLenInBits.len, tdata->auth.offset_bits, @@ -6862,7 +8865,32 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -4988,7 +5046,7 @@ test_kasumi_auth_cipher(const struct kasumi_test_data *tdata, +@@ -4887,16 +4947,20 @@ test_snow3g_auth_cipher_sgl(const struct snow3g_test_data *tdata, + + /* Validate obuf */ + if (verify) { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET( + plaintext, + tdata->plaintext.data, +- tdata->plaintext.len >> 3, ++ (tdata->plaintext.len - tdata->cipher.offset_bits - ++ (tdata->digest.len << 3)), ++ tdata->cipher.offset_bits, + "SNOW 3G Plaintext data not as expected"); + } else { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET( + ciphertext, + tdata->ciphertext.data, +- tdata->validDataLenInBits.len, ++ (tdata->validDataLenInBits.len - ++ tdata->cipher.offset_bits), ++ tdata->cipher.offset_bits, + "SNOW 3G Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( +@@ -4988,7 +5052,7 @@ test_kasumi_auth_cipher(const struct kasumi_test_data *tdata, /* Create KASUMI operation */ retval = create_wireless_algo_auth_cipher_operation( @@ -6871,7 +8899,7 @@ index 1b561456d7..a852040ec2 100644 tdata->cipher_iv.data, tdata->cipher_iv.len, NULL, 0, (tdata->digest.offset_bytes == 0 ? -@@ -4998,7 +5056,7 @@ test_kasumi_auth_cipher(const struct kasumi_test_data *tdata, +@@ -4998,7 +5062,7 @@ test_kasumi_auth_cipher(const struct kasumi_test_data *tdata, tdata->validCipherOffsetInBits.len, tdata->validAuthLenInBits.len, 0, @@ -6880,7 +8908,7 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -5165,7 +5223,7 @@ test_kasumi_auth_cipher_sgl(const struct kasumi_test_data *tdata, +@@ -5165,7 +5229,7 @@ test_kasumi_auth_cipher_sgl(const struct kasumi_test_data *tdata, /* Create KASUMI operation */ retval = create_wireless_algo_auth_cipher_operation( @@ -6889,7 +8917,7 @@ index 1b561456d7..a852040ec2 100644 tdata->cipher_iv.data, tdata->cipher_iv.len, NULL, 0, (tdata->digest.offset_bytes == 0 ? -@@ -5175,7 +5233,7 @@ test_kasumi_auth_cipher_sgl(const struct kasumi_test_data *tdata, +@@ -5175,7 +5239,7 @@ test_kasumi_auth_cipher_sgl(const struct kasumi_test_data *tdata, tdata->validCipherOffsetInBits.len, tdata->validAuthLenInBits.len, 0, @@ -6898,8 +8926,47 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -5666,7 +5724,7 @@ test_zuc_auth_cipher(const struct wireless_test_data *tdata, +@@ -5391,7 +5455,7 @@ test_zuc_encryption(const struct wireless_test_data *tdata) + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, + tdata->plaintext.len, +- 0); ++ tdata->validCipherOffsetInBits.len); + if (retval < 0) + return retval; + +@@ -5478,7 +5542,7 @@ test_zuc_encryption_sgl(const struct wireless_test_data *tdata) + /* Create ZUC operation */ + retval = create_wireless_algo_cipher_operation(tdata->cipher_iv.data, + tdata->cipher_iv.len, tdata->plaintext.len, +- 0); ++ tdata->validCipherOffsetInBits.len); + if (retval < 0) + return retval; +@@ -5650,23 +5714,23 @@ test_zuc_auth_cipher(const struct wireless_test_data *tdata, + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); +- if (op_mode == OUT_OF_PLACE) +- rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); + debug_hexdump(stdout, "ciphertext:", ciphertext, + ciphertext_len); + } else { ++ /* make sure enough space to cover partial digest verify case */ + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, +- plaintext_pad_len); ++ ciphertext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); +- if (op_mode == OUT_OF_PLACE) +- rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len); + debug_hexdump(stdout, "plaintext:", plaintext, + plaintext_len); + } + ++ if (op_mode == OUT_OF_PLACE) ++ rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); ++ /* Create ZUC operation */ retval = create_wireless_algo_auth_cipher_operation( - tdata->digest.len, @@ -6907,7 +8974,7 @@ index 1b561456d7..a852040ec2 100644 tdata->cipher_iv.data, tdata->cipher_iv.len, tdata->auth_iv.data, tdata->auth_iv.len, (tdata->digest.offset_bytes == 0 ? -@@ -5676,7 +5734,7 @@ test_zuc_auth_cipher(const struct wireless_test_data *tdata, +@@ -5676,7 +5740,7 @@ test_zuc_auth_cipher(const struct wireless_test_data *tdata, tdata->validCipherOffsetInBits.len, tdata->validAuthLenInBits.len, 0, @@ -6916,16 +8983,19 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -5852,7 +5910,7 @@ test_zuc_auth_cipher_sgl(const struct wireless_test_data *tdata, +@@ -5852,9 +5916,9 @@ test_zuc_auth_cipher_sgl(const struct wireless_test_data *tdata, /* Create ZUC operation */ retval = create_wireless_algo_auth_cipher_operation( - tdata->digest.len, + tdata->digest.data, tdata->digest.len, tdata->cipher_iv.data, tdata->cipher_iv.len, - NULL, 0, +- NULL, 0, ++ tdata->auth_iv.data, tdata->auth_iv.len, (tdata->digest.offset_bytes == 0 ? -@@ -5862,7 +5920,7 @@ test_zuc_auth_cipher_sgl(const struct wireless_test_data *tdata, + (verify ? ciphertext_pad_len : plaintext_pad_len) + : tdata->digest.offset_bytes), +@@ -5862,7 +5926,7 @@ test_zuc_auth_cipher_sgl(const struct wireless_test_data *tdata, tdata->validCipherOffsetInBits.len, tdata->validAuthLenInBits.len, 0, @@ -6934,7 +9004,7 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -6576,8 +6634,9 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, +@@ -6576,8 +6640,9 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, unsigned int ciphertext_len; struct rte_cryptodev_info dev_info; @@ -6945,7 +9015,7 @@ index 1b561456d7..a852040ec2 100644 if (test_mixed_check_if_unsupported(tdata)) return -ENOTSUP; -@@ -6593,18 +6652,26 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, +@@ -6593,18 +6658,26 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, } /* Create the session */ @@ -6984,8 +9054,28 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -6643,24 +6710,34 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, +@@ -6628,39 +6701,49 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, + ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + ciphertext_pad_len); + memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len); +- if (op_mode == OUT_OF_PLACE) +- rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); + debug_hexdump(stdout, "ciphertext:", ciphertext, + ciphertext_len); + } else { ++ /* make sure enough space to cover partial digest verify case */ + plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, +- plaintext_pad_len); ++ ciphertext_pad_len); + memcpy(plaintext, tdata->plaintext.data, plaintext_len); +- if (op_mode == OUT_OF_PLACE) +- rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len); + debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len); + } ++ if (op_mode == OUT_OF_PLACE) ++ rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len); ++ /* Create the operation */ retval = create_wireless_algo_auth_cipher_operation( - tdata->digest_enc.len, @@ -7023,7 +9113,7 @@ index 1b561456d7..a852040ec2 100644 TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); ut_params->obuf = (op_mode == IN_PLACE ? -@@ -6675,12 +6752,10 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, +@@ -6675,12 +6758,10 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, (tdata->cipher.offset_bits >> 3); debug_hexdump(stdout, "plaintext:", plaintext, @@ -7038,18 +9128,56 @@ index 1b561456d7..a852040ec2 100644 } else { if (ut_params->obuf) ciphertext = rte_pktmbuf_mtod(ut_params->obuf, -@@ -6725,6 +6800,10 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, - DIGEST_BYTE_LENGTH_SNOW3G_UIA2, +@@ -6705,26 +6786,33 @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata, + tdata->digest_enc.len); + } + +- /* Validate obuf */ +- if (verify) { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( +- plaintext, +- tdata->plaintext.data, +- tdata->plaintext.len_bits >> 3, +- "Plaintext data not as expected"); +- } else { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( +- ciphertext, +- tdata->ciphertext.data, +- tdata->validDataLen.len_bits, +- "Ciphertext data not as expected"); +- ++ if (!verify) { + TEST_ASSERT_BUFFERS_ARE_EQUAL( + ut_params->digest, + tdata->digest_enc.data, +- DIGEST_BYTE_LENGTH_SNOW3G_UIA2, ++ tdata->digest_enc.len, "Generated auth tag not as expected"); } + ++ if (tdata->cipher_algo != RTE_CRYPTO_CIPHER_NULL) { ++ if (verify) { ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ plaintext, ++ tdata->plaintext.data, ++ tdata->plaintext.len_bits >> 3, ++ "Plaintext data not as expected"); ++ } else { ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ ciphertext, ++ tdata->ciphertext.data, ++ tdata->validDataLen.len_bits, ++ "Ciphertext data not as expected"); ++ } ++ } ++ + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "crypto op processing failed"); + return 0; } -@@ -6748,6 +6827,7 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, +@@ -6748,6 +6836,7 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, uint8_t digest_buffer[10000]; struct rte_cryptodev_info dev_info; @@ -7057,7 +9185,7 @@ index 1b561456d7..a852040ec2 100644 /* Check if device supports particular algorithms */ if (test_mixed_check_if_unsupported(tdata)) -@@ -6776,18 +6856,26 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, +@@ -6776,18 +6865,26 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, } /* Create the session */ @@ -7096,7 +9224,7 @@ index 1b561456d7..a852040ec2 100644 if (retval < 0) return retval; -@@ -6797,7 +6885,7 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, +@@ -6797,7 +6894,7 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16); ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, @@ -7105,7 +9233,7 @@ index 1b561456d7..a852040ec2 100644 TEST_ASSERT_NOT_NULL(ut_params->ibuf, "Failed to allocate input buffer in mempool"); -@@ -6827,24 +6915,35 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, +@@ -6827,24 +6924,35 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, /* Create the operation */ retval = create_wireless_algo_auth_cipher_operation( @@ -7145,18 +9273,54 @@ index 1b561456d7..a852040ec2 100644 TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf"); ut_params->obuf = (op_mode == IN_PLACE ? -@@ -6917,6 +7016,10 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, +@@ -6898,25 +7006,33 @@ test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata, + tdata->digest_enc.data, tdata->digest_enc.len); + } + +- /* Validate obuf */ +- if (verify) { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( +- plaintext, +- tdata->plaintext.data, +- tdata->plaintext.len_bits >> 3, +- "Plaintext data not as expected"); +- } else { +- TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( +- ciphertext, +- tdata->ciphertext.data, +- tdata->validDataLen.len_bits, +- "Ciphertext data not as expected"); ++ if (!verify) { + TEST_ASSERT_BUFFERS_ARE_EQUAL( + digest, + tdata->digest_enc.data, tdata->digest_enc.len, "Generated auth tag not as expected"); } + ++ if (tdata->cipher_algo != RTE_CRYPTO_CIPHER_NULL) { ++ if (verify) { ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ plaintext, ++ tdata->plaintext.data, ++ tdata->plaintext.len_bits >> 3, ++ "Plaintext data not as expected"); ++ } else { ++ TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT( ++ ciphertext, ++ tdata->ciphertext.data, ++ tdata->validDataLen.len_bits, ++ "Ciphertext data not as expected"); ++ } ++ } ++ + TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS, + "crypto op processing failed"); + return 0; } -@@ -6978,6 +7081,176 @@ test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl(void) +@@ -6978,6 +7094,176 @@ test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl(void) &auth_aes_cmac_cipher_aes_ctr_test_case_1, OUT_OF_PLACE, 1); } @@ -7333,7 +9497,7 @@ index 1b561456d7..a852040ec2 100644 static int test_3DES_chain_qat_all(void) { -@@ -9139,8 +9412,10 @@ test_stats(void) +@@ -9139,8 +9425,10 @@ test_stats(void) { struct crypto_testsuite_params *ts_params = &testsuite_params; struct rte_cryptodev_stats stats; @@ -7346,7 +9510,7 @@ index 1b561456d7..a852040ec2 100644 rte_cryptodev_stats_reset(ts_params->valid_devs[0]); TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0] + 600, -@@ -9148,18 +9423,9 @@ test_stats(void) +@@ -9148,18 +9436,9 @@ test_stats(void) "rte_cryptodev_stats_get invalid dev failed"); TEST_ASSERT((rte_cryptodev_stats_get(ts_params->valid_devs[0], 0) != 0), "rte_cryptodev_stats_get invalid Param failed"); @@ -7365,7 +9529,26 @@ index 1b561456d7..a852040ec2 100644 TEST_ASSERT_SUCCESS(rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats), "rte_cryptodev_stats_get failed"); -@@ -10450,7 +10716,7 @@ aes128cbc_hmac_sha1_test_vector = { +@@ -9387,8 +9666,8 @@ test_multi_session(void) + rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info); + + sessions = rte_malloc(NULL, +- (sizeof(struct rte_cryptodev_sym_session *) * +- MAX_NB_SESSIONS) + 1, 0); ++ sizeof(struct rte_cryptodev_sym_session *) * ++ (MAX_NB_SESSIONS + 1), 0); + + /* Create multiple crypto sessions*/ + for (i = 0; i < MAX_NB_SESSIONS; i++) { +@@ -9433,6 +9712,7 @@ test_multi_session(void) + } + } + ++ sessions[i] = NULL; + /* Next session create should fail */ + rte_cryptodev_sym_session_init(ts_params->valid_devs[0], + sessions[i], &ut_params->auth_xform, +@@ -10450,7 +10730,7 @@ aes128cbc_hmac_sha1_test_vector = { static const struct test_crypto_vector aes128cbc_hmac_sha1_aad_test_vector = { .crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC, @@ -7374,7 +9557,7 @@ index 1b561456d7..a852040ec2 100644 .cipher_len = 496, .cipher_key = { .data = { -@@ -10486,9 +10752,9 @@ aes128cbc_hmac_sha1_aad_test_vector = { +@@ -10486,9 +10766,9 @@ aes128cbc_hmac_sha1_aad_test_vector = { }, .digest = { .data = { @@ -7387,7 +9570,7 @@ index 1b561456d7..a852040ec2 100644 }, .len = 20 } -@@ -10818,13 +11084,8 @@ test_authentication_verify_fail_when_data_corruption( +@@ -10818,13 +11098,8 @@ test_authentication_verify_fail_when_data_corruption( ut_params->op = process_crypto_request(ts_params->valid_devs[0], ut_params->op); @@ -7402,7 +9585,7 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -10879,13 +11140,8 @@ test_authentication_verify_GMAC_fail_when_corruption( +@@ -10879,13 +11154,8 @@ test_authentication_verify_GMAC_fail_when_corruption( ut_params->op = process_crypto_request(ts_params->valid_devs[0], ut_params->op); @@ -7417,7 +9600,7 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -10940,13 +11196,7 @@ test_authenticated_decryption_fail_when_corruption( +@@ -10940,19 +11210,13 @@ test_authenticated_decryption_fail_when_corruption( ut_params->op = process_crypto_request(ts_params->valid_devs[0], ut_params->op); @@ -7432,7 +9615,14 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -11149,6 +11399,7 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, + + static int +-test_authenticated_encryt_with_esn( ++test_authenticated_encrypt_with_esn( + struct crypto_testsuite_params *ts_params, + struct crypto_unittest_params *ut_params, + const struct test_crypto_vector *reference) +@@ -11149,6 +11413,7 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, const unsigned int auth_tag_len = tdata->auth_tag.len; const unsigned int iv_len = tdata->iv.len; unsigned int aad_len = tdata->aad.len; @@ -7440,7 +9630,7 @@ index 1b561456d7..a852040ec2 100644 /* Generate Crypto op data structure */ ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool, -@@ -11203,8 +11454,10 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, +@@ -11203,8 +11468,10 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, rte_memcpy(iv_ptr, tdata->iv.data, iv_len); @@ -7452,7 +9642,7 @@ index 1b561456d7..a852040ec2 100644 TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data, "no room to prepend aad"); sym_op->aead.aad.phys_addr = rte_pktmbuf_iova( -@@ -11219,7 +11472,7 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, +@@ -11219,7 +11486,7 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation op, } sym_op->aead.data.length = tdata->plaintext.len; @@ -7461,7 +9651,7 @@ index 1b561456d7..a852040ec2 100644 return 0; } -@@ -11252,7 +11505,7 @@ test_authenticated_encryption_SGL(const struct aead_test_data *tdata, +@@ -11252,7 +11519,7 @@ test_authenticated_encryption_SGL(const struct aead_test_data *tdata, int ecx = 0; void *digest_mem = NULL; @@ -7470,7 +9660,16 @@ index 1b561456d7..a852040ec2 100644 if (tdata->plaintext.len % fragsz != 0) { if (tdata->plaintext.len / fragsz + 1 > SGL_MAX_NO) -@@ -11915,6 +12168,8 @@ static struct unit_test_suite cryptodev_qat_testsuite = { +@@ -11614,7 +11881,7 @@ auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt(void) + static int + auth_encrypt_AES128CBC_HMAC_SHA1_esn_check(void) + { +- return test_authenticated_encryt_with_esn( ++ return test_authenticated_encrypt_with_esn( + &testsuite_params, + &unittest_params, + &aes128cbc_hmac_sha1_aad_test_vector); +@@ -11915,6 +12182,8 @@ static struct unit_test_suite cryptodev_qat_testsuite = { test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_400B), TEST_CASE_ST(ut_setup, ut_teardown, test_AES_GCM_auth_encrypt_SGL_out_of_place_1500B_2000B), @@ -7479,7 +9678,7 @@ index 1b561456d7..a852040ec2 100644 TEST_CASE_ST(ut_setup, ut_teardown, test_AES_GCM_authenticated_encryption_test_case_1), TEST_CASE_ST(ut_setup, ut_teardown, -@@ -12288,6 +12543,68 @@ static struct unit_test_suite cryptodev_qat_testsuite = { +@@ -12288,6 +12557,68 @@ static struct unit_test_suite cryptodev_qat_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl), @@ -7549,7 +9748,7 @@ index 1b561456d7..a852040ec2 100644 } }; diff --git a/dpdk/app/test/test_cryptodev_aes_test_vectors.h b/dpdk/app/test/test_cryptodev_aes_test_vectors.h -index 8307fcf9ae..66994b659a 100644 +index 8307fcf9ae..2b5d4175c3 100644 --- a/dpdk/app/test/test_cryptodev_aes_test_vectors.h +++ b/dpdk/app/test/test_cryptodev_aes_test_vectors.h @@ -358,69 +358,69 @@ static const struct blockcipher_test_data null_test_data_chain_x1_multiple = { @@ -7685,10 +9884,28 @@ index 8307fcf9ae..66994b659a 100644 }; /* AES128-CTR-SHA1 test vector */ +@@ -2212,7 +2212,7 @@ static const struct blockcipher_test_case aes_cipheronly_test_cases[] = { + BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2 + }, + { +- .test_descr = "AES-192-CBC Encryption Scater gather", ++ .test_descr = "AES-192-CBC Encryption Scatter gather", + .test_data = &aes_test_data_10, + .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT, + .feature_mask = BLOCKCIPHER_TEST_FEATURE_SG | diff --git a/dpdk/app/test/test_cryptodev_asym.c b/dpdk/app/test/test_cryptodev_asym.c -index 69df293041..a0802994fa 100644 +index 69df293041..9254c17183 100644 --- a/dpdk/app/test/test_cryptodev_asym.c +++ b/dpdk/app/test/test_cryptodev_asym.c +@@ -557,7 +557,7 @@ test_one_case(const void *test_case, int sessionless) + status = test_cryptodev_asym_op( + &testsuite_params, + &tc, test_msg, sessionless, i, +- RTE_RSA_KET_TYPE_QT); ++ RTE_RSA_KEY_TYPE_QT); + } + if (status) + break; @@ -933,8 +933,9 @@ testsuite_setup(void) } @@ -9135,6 +11352,404 @@ index bca47c05c8..f50dcb0457 100644 +}; + #endif /* TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_ */ +diff --git a/dpdk/app/test/test_cryptodev_rsa_test_vectors.h b/dpdk/app/test/test_cryptodev_rsa_test_vectors.h +index 48a72e1492..04539a1ecf 100644 +--- a/dpdk/app/test/test_cryptodev_rsa_test_vectors.h ++++ b/dpdk/app/test/test_cryptodev_rsa_test_vectors.h +@@ -378,7 +378,7 @@ struct rte_crypto_asym_xform rsa_xform_crt = { + .data = rsa_e, + .length = sizeof(rsa_e) + }, +- .key_type = RTE_RSA_KET_TYPE_QT, ++ .key_type = RTE_RSA_KEY_TYPE_QT, + .qt = { + .p = { + .data = rsa_p, +diff --git a/dpdk/app/test/test_cryptodev_snow3g_test_vectors.h b/dpdk/app/test/test_cryptodev_snow3g_test_vectors.h +index bbe05662be..b49a07bcf2 100644 +--- a/dpdk/app/test/test_cryptodev_snow3g_test_vectors.h ++++ b/dpdk/app/test/test_cryptodev_snow3g_test_vectors.h +@@ -138,11 +138,11 @@ struct snow3g_test_data snow3g_test_case_2 = { + .len = 16 + }, + .cipher_iv = { +- .data = { ++ .data = { + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00, + 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 + }, +- .len = 16 ++ .len = 16 + }, + .plaintext = { + .data = { +@@ -359,8 +359,8 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_1 = { + }, + .cipher_iv = { + .data = { +- 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, +- 0x94, 0x79, 0x3E, 0x41, 0x03, 0x97, 0x68, 0xFD ++ 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00, ++ 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00 + }, + .len = 16 + }, +@@ -383,13 +383,13 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_1 = { + .len = 384 + }, + .ciphertext = { +- .data = { +- 0x95, 0x2E, 0x5A, 0xE1, 0x50, 0xB8, 0x59, 0x2A, +- 0x9B, 0xA0, 0x38, 0xA9, 0x8E, 0x2F, 0xED, 0xAB, +- 0xFD, 0xC8, 0x3B, 0x47, 0x46, 0x0B, 0x50, 0x16, +- 0xEC, 0x88, 0x45, 0xB6, 0x05, 0xC7, 0x54, 0xF8, +- 0xBD, 0x91, 0xAA, 0xB6, 0xA4, 0xDC, 0x64, 0xB4, +- 0xCB, 0xEB, 0x97, 0x06, 0x4C, 0xF7, 0x02, 0x3D ++ .data = { ++ 0x86, 0x4F, 0x4D, 0xE8, 0x86, 0xE6, 0x3E, 0x66, ++ 0x52, 0x97, 0xC7, 0x62, 0xAE, 0x8E, 0xA2, 0xDB, ++ 0x01, 0xD6, 0x33, 0xA9, 0xA4, 0xCE, 0x02, 0xD5, ++ 0xC2, 0xC5, 0x5F, 0x90, 0xE0, 0x89, 0x48, 0xD4, ++ 0x92, 0xF4, 0xE5, 0x9A, 0xDA, 0x13, 0x76, 0xFF, ++ 0x6E, 0x76, 0x6B, 0x71, 0x62, 0x28, 0xB2, 0xEC + }, + .len = 384 + }, +@@ -428,15 +428,15 @@ struct snow3g_test_data snow3g_test_case_7 = { + }, + .cipher_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ++ 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00, ++ 0xE2, 0x8B, 0xCF, 0x7B, 0xC0, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A, ++ 0x36, 0xAF, 0x61, 0x44, 0x98, 0x38, 0xF0, 0x3A + }, + .len = 16 + }, +@@ -457,28 +457,28 @@ struct snow3g_test_data snow3g_test_case_7 = { + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, +- 0x5A, 0x5A, 0x5A, 0x5A, 0xF1, 0x9E, 0x2B, 0x6F, ++ 0x5A, 0x5A, 0x5A, 0x5A, 0xBB, 0x2B, 0x8B, 0x15, + }, + .len = 128 << 3 + }, + .ciphertext = { + .data = { +- 0x5A, 0x5A, 0xE4, 0xAD, 0x29, 0xA2, 0x6A, 0xA6, +- 0x20, 0x1D, 0xCD, 0x08, 0x50, 0xD6, 0xE6, 0x47, +- 0xBC, 0x88, 0x08, 0x01, 0x17, 0xFA, 0x47, 0x5B, +- 0x90, 0x40, 0xBA, 0x0C, 0xB5, 0x58, 0xF3, 0x0C, +- 0xA0, 0xD4, 0x98, 0x83, 0x1B, 0xCE, 0x54, 0xE3, +- 0x29, 0x00, 0x3C, 0xA4, 0xAD, 0x74, 0xEE, 0x05, +- 0xA3, 0x6C, 0xD4, 0xAC, 0xC6, 0x30, 0x33, 0xC9, +- 0x37, 0x57, 0x41, 0x9B, 0xD4, 0x73, 0xB9, 0x77, +- 0x70, 0x8B, 0x63, 0xDD, 0x22, 0xB8, 0xE1, 0x85, +- 0xB2, 0x92, 0x7C, 0x37, 0xD3, 0x2E, 0xD9, 0xF4, +- 0x4A, 0x69, 0x25, 0x30, 0xE3, 0x5B, 0x8B, 0xF6, +- 0x0F, 0xDE, 0x0B, 0x92, 0xD5, 0x25, 0x52, 0x6D, +- 0x26, 0xEB, 0x2F, 0x8A, 0x3B, 0x8B, 0x38, 0xE2, +- 0x48, 0xD3, 0x4A, 0x98, 0xF7, 0x3A, 0xC2, 0x46, +- 0x69, 0x8D, 0x73, 0x3E, 0x57, 0x88, 0x2C, 0x80, +- 0xF0, 0xF2, 0x75, 0xB8, 0x7D, 0x27, 0xC6, 0xDA, ++ 0x5A, 0x5A, 0x8A, 0x35, 0xF7, 0x36, 0xDA, 0xD7, ++ 0xC4, 0x2C, 0x10, 0xEA, 0x92, 0x9C, 0x00, 0xF0, ++ 0xAE, 0x35, 0x5E, 0x8D, 0xB6, 0x88, 0x30, 0x66, ++ 0x74, 0x8B, 0xA2, 0x82, 0x5C, 0xA7, 0xF3, 0x54, ++ 0x75, 0x02, 0xA9, 0x90, 0x6B, 0x4B, 0x6A, 0x63, ++ 0xFF, 0x4B, 0x08, 0xFE, 0x11, 0x3C, 0x5A, 0x53, ++ 0xEE, 0x68, 0x14, 0x41, 0x17, 0xCD, 0x7B, 0x27, ++ 0x88, 0xAF, 0x99, 0xE2, 0x9C, 0x86, 0x42, 0x12, ++ 0x97, 0x93, 0xF0, 0xE6, 0xE2, 0xB2, 0x2D, 0xDA, ++ 0x2C, 0x59, 0xB0, 0xA7, 0x09, 0xF6, 0x32, 0xC0, ++ 0x35, 0x9A, 0xD3, 0xBA, 0xDC, 0x8F, 0x2E, 0x18, ++ 0x97, 0x87, 0x44, 0xD6, 0x43, 0xFA, 0x86, 0x5A, ++ 0xB0, 0xA2, 0x5A, 0xB8, 0x5F, 0x57, 0xE3, 0x2F, ++ 0x73, 0x9C, 0x01, 0x3A, 0x02, 0x08, 0x8C, 0xEB, ++ 0xA0, 0x5D, 0x74, 0x58, 0x5A, 0xA1, 0x58, 0x17, ++ 0x5E, 0x86, 0x96, 0xE6, 0x9C, 0xEE, 0x8C, 0xA8 + + }, + .len = 128 << 3 +@@ -493,7 +493,7 @@ struct snow3g_test_data snow3g_test_case_7 = { + }, + .digest = { + .data = { +- 0x7D, 0x27, 0xC6, 0xDA ++ 0x9C, 0xEE, 0x8C, 0xA8 + }, + .len = 4, + .offset_bytes = 124 +@@ -520,15 +520,15 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_2 = { + }, + .cipher_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ++ 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, ++ 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2, ++ 0x3E, 0xDC, 0x87, 0xE2, 0xA4, 0xF2, 0xD8, 0xE2 + }, + .len = 16 + }, +@@ -556,22 +556,22 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_2 = { + }, + .ciphertext = { + .data = { +- 0x5A, 0x5A, 0xE4, 0xAD, 0x29, 0xA2, 0x6A, 0xA6, +- 0x20, 0x1D, 0xCD, 0x08, 0x50, 0xD6, 0xE6, 0x47, +- 0xBC, 0x88, 0x08, 0x01, 0x17, 0xFA, 0x47, 0x5B, +- 0x90, 0x40, 0xBA, 0x0C, 0xB5, 0x58, 0xF3, 0x0C, +- 0xA0, 0xD4, 0x98, 0x83, 0x1B, 0xCE, 0x54, 0xE3, +- 0x29, 0x00, 0x3C, 0xA4, 0xAD, 0x74, 0xEE, 0x05, +- 0xA3, 0x6C, 0xD4, 0xAC, 0xC6, 0x30, 0x33, 0xC9, +- 0x37, 0x57, 0x41, 0x9B, 0xD4, 0x73, 0xB9, 0x77, +- 0x70, 0x8B, 0x63, 0xDD, 0x22, 0xB8, 0xE1, 0x85, +- 0xB2, 0x92, 0x7C, 0x37, 0xD3, 0x2E, 0xD9, 0xF4, +- 0x4A, 0x69, 0x25, 0x30, 0xE3, 0x5B, 0x8B, 0xF6, +- 0x0F, 0xDE, 0x0B, 0x92, 0xD5, 0x25, 0x52, 0x6D, +- 0x26, 0xEB, 0x2F, 0x8A, 0x3B, 0x8B, 0x38, 0xE2, +- 0x48, 0xD3, 0x4A, 0x98, 0xF7, 0x3A, 0xC2, 0x46, +- 0x69, 0x8D, 0x73, 0x3E, 0x57, 0x88, 0x2C, 0x80, +- 0xF0, 0xF2, 0x75, 0xB8, 0x7D, 0x27, 0xC6, 0xDA, ++ 0x5A, 0x5A, 0xCF, 0xCF, 0x3D, 0x11, 0xBF, 0xD9, ++ 0xC3, 0x7F, 0x7C, 0xA8, 0x1A, 0x9F, 0x9F, 0x34, ++ 0xC5, 0x6E, 0x1B, 0x2C, 0xE0, 0x81, 0x4B, 0x66, ++ 0x87, 0xCB, 0xD5, 0x61, 0x04, 0xED, 0xBC, 0x69, ++ 0x79, 0x86, 0x73, 0x48, 0x69, 0x4A, 0xBA, 0x55, ++ 0x44, 0x6C, 0xEF, 0xD9, 0x34, 0x61, 0x59, 0x67, ++ 0x80, 0x4E, 0x03, 0x95, 0x0A, 0xA1, 0x6C, 0xBA, ++ 0x74, 0xBD, 0xAF, 0x11, 0x4B, 0xE6, 0x98, 0x61, ++ 0x4E, 0xD4, 0x3E, 0xE4, 0x99, 0x55, 0x5C, 0x3A, ++ 0x8C, 0x3E, 0xC0, 0x01, 0x6E, 0x15, 0xE1, 0x0E, ++ 0x71, 0x4C, 0x89, 0x43, 0x8A, 0x48, 0x69, 0x6D, ++ 0x02, 0x10, 0xC6, 0x54, 0x37, 0x18, 0xAA, 0x10, ++ 0x90, 0x80, 0x0B, 0x69, 0x08, 0xB4, 0xF9, 0x4D, ++ 0xD1, 0x2E, 0x43, 0xD9, 0x92, 0xAF, 0x06, 0x4A, ++ 0xAF, 0x26, 0x25, 0x77, 0x37, 0xD0, 0xFC, 0x3C, ++ 0xA0, 0xCB, 0xAF, 0x06, 0x95, 0x26, 0x30, 0x38, + + }, + .len = 128 << 3 +@@ -586,7 +586,7 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_2 = { + }, + .digest = { + .data = { +- 0x7D, 0x27, 0xC6, 0xDA ++ 0x95, 0x26, 0x30, 0x38 + }, + .len = 4, + .offset_bytes = 124 +@@ -613,15 +613,15 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_3 = { + }, + .cipher_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ++ 0x39, 0x8A, 0x59, 0xB4, 0x2C, 0x00, 0x00, 0x00, ++ 0x39, 0x8A, 0x59, 0xB4, 0x2C, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37, ++ 0x29, 0x6F, 0x39, 0x3C, 0x6B, 0x22, 0x77, 0x37 + }, + .len = 16 + }, +@@ -636,10 +636,10 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_3 = { + }, + .ciphertext = { + .data = { +- 0x5A, 0x5A, 0xE4, 0xAD, 0x29, 0xA2, 0x6A, 0xA6, +- 0x20, 0x1D, 0xCD, 0x08, 0x50, 0xD6, 0xE6, 0x47, +- 0xBC, 0x88, 0x08, 0x01, 0x17, 0xFA, 0x47, 0x5B, +- 0x90, 0x40, 0xBA, 0x0C, 0xBA, 0x6D, 0x6A, 0x5E, ++ 0x5A, 0x5A, 0x93, 0xB0, 0x3F, 0xA4, 0xEB, 0xD4, ++ 0x51, 0x12, 0x3B, 0x95, 0x93, 0x12, 0xBF, 0xBE, ++ 0xF2, 0xFE, 0xA5, 0xAE, 0xE7, 0xF4, 0x80, 0x3E, ++ 0xB2, 0xD1, 0xFF, 0x5F, 0xD9, 0x32, 0x72, 0xFE, + }, + .len = 32 << 3 + }, +@@ -653,7 +653,7 @@ struct snow3g_test_data snow3g_auth_cipher_test_case_3 = { + }, + .digest = { + .data = { +- 0xBA, 0x6D, 0x6A, 0x5E ++ 0xD9, 0x32, 0x72, 0xFE + }, + .len = 4, + .offset_bytes = 28 +@@ -680,15 +680,15 @@ struct snow3g_test_data snow3g_auth_cipher_partial_digest_encryption = { + }, + .cipher_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ++ 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00, ++ 0x72, 0xA4, 0xF2, 0x0F, 0x48, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD, ++ 0x14, 0x79, 0x3E, 0x41, 0x03, 0x97, 0xE8, 0xFD + }, + .len = 16 + }, +@@ -704,9 +704,9 @@ struct snow3g_test_data snow3g_auth_cipher_partial_digest_encryption = { + .ciphertext = { + .data = { + 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, +- 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0xE4, 0xAD, +- 0x29, 0xA2, 0x6A, 0xA6, 0x20, 0x1D, 0xCD, 0x08, +- 0x50, 0xD6, 0xE6, 0x47, 0xB3, 0xBD, 0xC3, 0x08 ++ 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0xA2, 0xB7, ++ 0xDF, 0xA7, 0x98, 0xA1, 0xD8, 0xD4, 0x9B, 0x6E, ++ 0x2C, 0x7A, 0x66, 0x15, 0xCC, 0x4C, 0xE5, 0xE0 + }, + .len = 32 << 3 + }, +@@ -720,7 +720,7 @@ struct snow3g_test_data snow3g_auth_cipher_partial_digest_encryption = { + }, + .digest = { + .data = { +- 0xB3, 0xBD, 0xC3, 0x08 ++ 0xCC, 0x4C, 0xE5, 0xE0 + }, + .len = 4, + .offset_bytes = 28 +diff --git a/dpdk/app/test/test_cryptodev_zuc_test_vectors.h b/dpdk/app/test/test_cryptodev_zuc_test_vectors.h +index cc2338e107..067fb5eb34 100644 +--- a/dpdk/app/test/test_cryptodev_zuc_test_vectors.h ++++ b/dpdk/app/test/test_cryptodev_zuc_test_vectors.h +@@ -558,13 +558,13 @@ static struct wireless_test_data zuc_test_case_cipher_200b_auth_200b = { + }, + .auth_iv = { + .data = { +- 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, +- 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00, ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { +- .data = {0x01, 0xFE, 0x5E, 0x38}, ++ .data = {0x2F, 0x45, 0x7D, 0x7B}, + .len = 4 + }, + .validAuthLenInBits = { +@@ -631,13 +631,13 @@ static struct wireless_test_data zuc_test_case_cipher_800b_auth_120b = { + }, + .auth_iv = { + .data = { +- 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00, +- 0xFA, 0x55, 0x6B, 0x26, 0x1C, 0x00, 0x00, 0x00 ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00, ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .digest = { +- .data = {0x9D, 0x42, 0x1C, 0xEA}, ++ .data = {0xCA, 0xBB, 0x8D, 0x94}, + .len = 4 + }, + .validAuthLenInBits = { +@@ -1056,15 +1056,15 @@ struct wireless_test_data zuc_auth_cipher_test_case_1 = { + }, + .cipher_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00, ++ 0x66, 0x03, 0x54, 0x92, 0x78, 0x00, 0x00, 0x00 + }, + .len = 16 + }, + .auth_iv = { + .data = { +- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00, ++ 0xFA, 0x55, 0x6B, 0x26, 0x18, 0x00, 0x00, 0x00 + }, + .len = 16 + }, +@@ -1091,22 +1091,22 @@ struct wireless_test_data zuc_auth_cipher_test_case_1 = { + }, + .ciphertext = { + .data = { +- 0x5A, 0x5A, 0xDB, 0x3D, 0xD5, 0xB7, 0xB9, 0x58, +- 0xA5, 0xD3, 0xE3, 0xF9, 0x18, 0x73, 0xB4, 0x74, +- 0x05, 0xF0, 0xE9, 0xB6, 0x5D, 0x9A, 0xE3, 0xFA, +- 0x5D, 0xFD, 0x24, 0x51, 0xAD, 0x73, 0xCA, 0x64, +- 0x91, 0xD5, 0xB3, 0x94, 0x10, 0x91, 0x89, 0xEA, +- 0x73, 0x6F, 0xB0, 0x2A, 0x0A, 0x63, 0x0F, 0x8D, +- 0x64, 0x87, 0xA3, 0x14, 0x6B, 0x93, 0x31, 0x0F, +- 0x14, 0xAD, 0xEA, 0x62, 0x80, 0x3F, 0x44, 0xDD, +- 0x4E, 0x30, 0xFA, 0xC8, 0x0E, 0x5F, 0x46, 0xE7, +- 0x60, 0xEC, 0xDF, 0x8B, 0x94, 0x7D, 0x2E, 0x63, +- 0x48, 0xD9, 0x69, 0x06, 0x13, 0xF2, 0x20, 0x49, +- 0x54, 0xA6, 0xD4, 0x98, 0xF4, 0xF6, 0x1D, 0x4A, +- 0xC9, 0xA5, 0xDA, 0x46, 0x3D, 0xD9, 0x02, 0x47, +- 0x1C, 0x20, 0x73, 0x35, 0x17, 0x1D, 0x81, 0x8D, +- 0x2E, 0xCD, 0x70, 0x37, 0x22, 0x55, 0x3C, 0xF3, +- 0xDA, 0x70, 0x42, 0x12, 0x0E, 0xAA, 0xC4, 0xAB ++ 0x5A, 0x5A, 0x94, 0xE7, 0xB8, 0xD7, 0x4E, 0xBB, ++ 0x4C, 0xC3, 0xD1, 0x16, 0xFC, 0x8C, 0xE4, 0x27, ++ 0x44, 0xEC, 0x04, 0x26, 0x60, 0x9C, 0xFF, 0x81, ++ 0xB6, 0x2B, 0x48, 0x1D, 0xEE, 0x26, 0xF7, 0x58, ++ 0x40, 0x38, 0x58, 0xEA, 0x22, 0x23, 0xE6, 0x34, ++ 0x9A, 0x69, 0x32, 0x68, 0xBD, 0xDD, 0x7D, 0xA3, ++ 0xC0, 0x04, 0x79, 0xF0, 0xF1, 0x58, 0x78, 0x5E, ++ 0xD0, 0xDF, 0x27, 0x9A, 0x53, 0x70, 0x5D, 0xFB, ++ 0x1B, 0xCA, 0xBA, 0x97, 0x12, 0x1F, 0x59, 0x6B, ++ 0x75, 0x7B, 0x94, 0xF6, 0xE7, 0xFA, 0x49, 0x6B, ++ 0x7D, 0x7F, 0x8F, 0x0F, 0x78, 0x56, 0x40, 0x52, ++ 0x84, 0x3E, 0xA9, 0xE8, 0x84, 0x6F, 0xEF, 0xFB, ++ 0x4A, 0x48, 0x3A, 0x4C, 0x81, 0x98, 0xDD, 0x17, ++ 0x89, 0x66, 0x3B, 0xC0, 0xEC, 0x71, 0xDB, 0xF6, ++ 0x44, 0xDF, 0xA7, 0x97, 0xB2, 0x9B, 0x84, 0xA7, ++ 0x2D, 0x2D, 0xC1, 0x93, 0x12, 0x37, 0xEA, 0xD2 + }, + .len = 128 << 3 + }, +@@ -1123,7 +1123,7 @@ struct wireless_test_data zuc_auth_cipher_test_case_1 = { + .len = 2 << 3 + }, + .digest = { +- .data = {0x0E, 0xAA, 0xC4, 0xAB}, ++ .data = {0x12, 0x37, 0xEA, 0xD2}, + .len = 4, + .offset_bytes = 124 + } diff --git a/dpdk/app/test/test_cycles.c b/dpdk/app/test/test_cycles.c index c78e6a5b12..97d42f3032 100644 --- a/dpdk/app/test/test_cycles.c @@ -9657,8 +12272,108 @@ index ba1f81cf8d..acfe728f0c 100644 } static int +diff --git a/dpdk/app/test/test_distributor_perf.c b/dpdk/app/test/test_distributor_perf.c +index f153bcf9bd..2441231e49 100644 +--- a/dpdk/app/test/test_distributor_perf.c ++++ b/dpdk/app/test/test_distributor_perf.c +@@ -108,7 +108,6 @@ static int + handle_work(void *arg) + { + struct rte_distributor *d = arg; +- unsigned int count = 0; + unsigned int num = 0; + int i; + unsigned int id = __atomic_fetch_add(&worker_idx, 1, __ATOMIC_RELAXED); +@@ -120,11 +119,9 @@ handle_work(void *arg) + num = rte_distributor_get_pkt(d, id, buf, buf, num); + while (!quit) { + worker_stats[id].handled_packets += num; +- count += num; + num = rte_distributor_get_pkt(d, id, buf, buf, num); + } + worker_stats[id].handled_packets += num; +- count += num; + rte_distributor_return_pkt(d, id, buf, num); + return 0; + } +@@ -188,13 +185,15 @@ quit_workers(struct rte_distributor *d, struct rte_mempool *p) + rte_mempool_get_bulk(p, (void *)bufs, num_workers); + + quit = 1; +- for (i = 0; i < num_workers; i++) ++ for (i = 0; i < num_workers; i++) { + bufs[i]->hash.usr = i << 1; +- rte_distributor_process(d, bufs, num_workers); ++ rte_distributor_process(d, &bufs[i], 1); ++ } + + rte_mempool_put_bulk(p, (void *)bufs, num_workers); + + rte_distributor_process(d, NULL, 0); ++ rte_distributor_flush(d); + rte_eal_mp_wait_lcore(); + quit = 0; + worker_idx = 0; +diff --git a/dpdk/app/test/test_eal_flags.c b/dpdk/app/test/test_eal_flags.c +index 5b2c0f5cdb..654bebff6f 100644 +--- a/dpdk/app/test/test_eal_flags.c ++++ b/dpdk/app/test/test_eal_flags.c +@@ -125,6 +125,7 @@ process_hugefiles(const char * prefix, enum hugepage_action action) + case HUGEPAGE_CHECK_EXISTS: + { + /* file exists, return */ ++ closedir(hugepage_dir); + result = 1; + goto end; + } +diff --git a/dpdk/app/test/test_efd.c b/dpdk/app/test/test_efd.c +index a779a71f2d..459ec44d0d 100644 +--- a/dpdk/app/test/test_efd.c ++++ b/dpdk/app/test/test_efd.c +@@ -96,14 +96,14 @@ static struct flow_key keys[5] = { + /* Array to store the data */ + static efd_value_t data[5]; + +-static inline uint8_t efd_get_all_sockets_bitmask(void) ++static inline uint64_t efd_get_all_sockets_bitmask(void) + { +- uint8_t all_cpu_sockets_bitmask = 0; ++ uint64_t all_cpu_sockets_bitmask = 0; + unsigned int i; + unsigned int next_lcore = rte_get_master_lcore(); + const int val_true = 1, val_false = 0; + for (i = 0; i < rte_lcore_count(); i++) { +- all_cpu_sockets_bitmask |= 1 << rte_lcore_to_socket_id(next_lcore); ++ all_cpu_sockets_bitmask |= 1ULL << rte_lcore_to_socket_id(next_lcore); + next_lcore = rte_get_next_lcore(next_lcore, val_false, val_true); + } + +@@ -448,6 +448,7 @@ static int test_efd_creation_with_bad_parameters(void) + static int + test_efd(void) + { ++ test_socket_id = rte_socket_id(); + + /* Unit tests */ + if (test_add_delete() < 0) +diff --git a/dpdk/app/test/test_efd_perf.c b/dpdk/app/test/test_efd_perf.c +index d47622d5ca..c7d6e1e426 100644 +--- a/dpdk/app/test/test_efd_perf.c ++++ b/dpdk/app/test/test_efd_perf.c +@@ -29,9 +29,9 @@ + #endif + static unsigned int test_socket_id; + +-static inline uint8_t efd_get_all_sockets_bitmask(void) ++static inline uint64_t efd_get_all_sockets_bitmask(void) + { +- uint8_t all_cpu_sockets_bitmask = 0; ++ uint64_t all_cpu_sockets_bitmask = 0; + unsigned int i; + unsigned int next_lcore = rte_get_master_lcore(); + const int val_true = 1, val_false = 0; diff --git a/dpdk/app/test/test_event_crypto_adapter.c b/dpdk/app/test/test_event_crypto_adapter.c -index 8d42462d87..1c0a0fa5e3 100644 +index 8d42462d87..fe016fec7b 100644 --- a/dpdk/app/test/test_event_crypto_adapter.c +++ b/dpdk/app/test/test_event_crypto_adapter.c @@ -171,7 +171,6 @@ test_op_forward_mode(uint8_t session_less) @@ -9686,7 +12401,7 @@ index 8d42462d87..1c0a0fa5e3 100644 op = rte_crypto_op_alloc(params.op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); TEST_ASSERT_NOT_NULL(op, -@@ -209,8 +202,8 @@ test_op_forward_mode(uint8_t session_less) +@@ -209,16 +202,16 @@ test_op_forward_mode(uint8_t session_less) &cipher_xform, params.session_priv_mpool); TEST_ASSERT_SUCCESS(ret, "Failed to init session\n"); @@ -9697,7 +12412,38 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { -@@ -296,7 +289,7 @@ test_sessionless_with_op_forward_mode(void) + /* Fill in private user data information */ +- rte_memcpy(&m_data.response_info, &response_info, +- sizeof(response_info)); +- rte_memcpy(&m_data.request_info, &request_info, +- sizeof(request_info)); ++ m_data.request_info.cdev_id = request_info.cdev_id; ++ m_data.request_info.queue_pair_id = ++ request_info.queue_pair_id; ++ m_data.response_info.event = response_info.event; + rte_cryptodev_sym_session_set_user_data(sess, + &m_data, sizeof(m_data)); + } +@@ -231,14 +224,12 @@ test_op_forward_mode(uint8_t session_less) + op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; + first_xform = &cipher_xform; + sym_op->xform = first_xform; +- uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + +- (sizeof(struct rte_crypto_sym_xform) * 2); ++ uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH; + op->private_data_offset = len; + /* Fill in private data information */ +- rte_memcpy(&m_data.response_info, &response_info, +- sizeof(response_info)); +- rte_memcpy(&m_data.request_info, &request_info, +- sizeof(request_info)); ++ m_data.request_info.cdev_id = request_info.cdev_id; ++ m_data.request_info.queue_pair_id = request_info.queue_pair_id; ++ m_data.response_info.event = response_info.event; + rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); + } + +@@ -296,7 +287,7 @@ test_sessionless_with_op_forward_mode(void) uint32_t cap; int ret; @@ -9706,7 +12452,7 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && -@@ -321,7 +314,7 @@ test_session_with_op_forward_mode(void) +@@ -321,7 +312,7 @@ test_session_with_op_forward_mode(void) uint32_t cap; int ret; @@ -9715,7 +12461,7 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && -@@ -378,7 +371,6 @@ test_op_new_mode(uint8_t session_less) +@@ -378,7 +369,6 @@ test_op_new_mode(uint8_t session_less) struct rte_mbuf *m; uint32_t cap; int ret; @@ -9723,7 +12469,7 @@ index 8d42462d87..1c0a0fa5e3 100644 memset(&m_data, 0, sizeof(m_data)); -@@ -390,15 +382,9 @@ test_op_new_mode(uint8_t session_less) +@@ -390,15 +380,9 @@ test_op_new_mode(uint8_t session_less) /* Setup Cipher Parameters */ cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; cipher_xform.next = NULL; @@ -9740,7 +12486,7 @@ index 8d42462d87..1c0a0fa5e3 100644 op = rte_crypto_op_alloc(params.op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); TEST_ASSERT_NOT_NULL(op, "Failed to allocate crypto_op!\n"); -@@ -410,8 +396,8 @@ test_op_new_mode(uint8_t session_less) +@@ -410,14 +394,13 @@ test_op_new_mode(uint8_t session_less) params.session_mpool); TEST_ASSERT_NOT_NULL(sess, "Session creation failed\n"); @@ -9751,7 +12497,29 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA) { -@@ -460,7 +446,7 @@ test_sessionless_with_op_new_mode(void) + /* Fill in private user data information */ +- rte_memcpy(&m_data.response_info, &response_info, +- sizeof(m_data)); ++ m_data.response_info.event = response_info.event; + rte_cryptodev_sym_session_set_user_data(sess, + &m_data, sizeof(m_data)); + } +@@ -433,12 +416,10 @@ test_op_new_mode(uint8_t session_less) + op->sess_type = RTE_CRYPTO_OP_SESSIONLESS; + first_xform = &cipher_xform; + sym_op->xform = first_xform; +- uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + +- (sizeof(struct rte_crypto_sym_xform) * 2); ++ uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH; + op->private_data_offset = len; + /* Fill in private data information */ +- rte_memcpy(&m_data.response_info, &response_info, +- sizeof(m_data)); ++ m_data.response_info.event = response_info.event; + rte_memcpy((uint8_t *)op + len, &m_data, sizeof(m_data)); + } + +@@ -460,7 +441,7 @@ test_sessionless_with_op_new_mode(void) uint32_t cap; int ret; @@ -9760,7 +12528,7 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && -@@ -486,7 +472,7 @@ test_session_with_op_new_mode(void) +@@ -486,7 +467,7 @@ test_session_with_op_new_mode(void) uint32_t cap; int ret; @@ -9769,7 +12537,17 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_SUCCESS(ret, "Failed to get adapter capabilities\n"); if (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && -@@ -564,7 +550,9 @@ configure_cryptodev(void) +@@ -530,7 +511,8 @@ configure_cryptodev(void) + NUM_MBUFS, MBUF_CACHE_SIZE, + DEFAULT_NUM_XFORMS * + sizeof(struct rte_crypto_sym_xform) + +- MAXIMUM_IV_LENGTH, ++ MAXIMUM_IV_LENGTH + ++ sizeof(union rte_event_crypto_metadata), + rte_socket_id()); + if (params.op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); +@@ -564,7 +546,9 @@ configure_cryptodev(void) params.session_mpool = rte_cryptodev_sym_session_pool_create( "CRYPTO_ADAPTER_SESSION_MP", @@ -9780,7 +12558,7 @@ index 8d42462d87..1c0a0fa5e3 100644 TEST_ASSERT_NOT_NULL(params.session_mpool, "session mempool allocation failed\n"); -@@ -706,7 +694,7 @@ test_crypto_adapter_create(void) +@@ -706,7 +690,7 @@ test_crypto_adapter_create(void) /* Create adapter with default port creation callback */ ret = rte_event_crypto_adapter_create(TEST_ADAPTER_ID, @@ -9789,7 +12567,7 @@ index 8d42462d87..1c0a0fa5e3 100644 &conf, 0); TEST_ASSERT_SUCCESS(ret, "Failed to create event crypto adapter\n"); -@@ -719,7 +707,7 @@ test_crypto_adapter_qp_add_del(void) +@@ -719,7 +703,7 @@ test_crypto_adapter_qp_add_del(void) uint32_t cap; int ret; @@ -9820,6 +12598,37 @@ index 3af749280a..7073030902 100644 { struct rte_eth_conf conf = { 0 }; return port_init_common(port, &conf, mp); +diff --git a/dpdk/app/test/test_event_timer_adapter.c b/dpdk/app/test/test_event_timer_adapter.c +index ad3f4dcc20..efd86cad58 100644 +--- a/dpdk/app/test/test_event_timer_adapter.c ++++ b/dpdk/app/test/test_event_timer_adapter.c +@@ -3,6 +3,8 @@ + * Copyright(c) 2017-2018 Intel Corporation. + */ + ++#include ++ + #include + #include + #include +@@ -46,7 +48,7 @@ static uint64_t global_info_bkt_tck_ns; + static volatile uint8_t arm_done; + + #define CALC_TICKS(tks) \ +- ((tks * global_bkt_tck_ns) / global_info_bkt_tck_ns) ++ ceil((double)(tks * global_bkt_tck_ns) / global_info_bkt_tck_ns) + + + static bool using_services; +@@ -964,8 +966,6 @@ adapter_create(void) + TEST_ASSERT_SUCCESS(rte_event_timer_adapter_free(adapter), + "Failed to free adapter"); + +- rte_mempool_free(eventdev_test_mempool); +- + return TEST_SUCCESS; + } + diff --git a/dpdk/app/test/test_eventdev.c b/dpdk/app/test/test_eventdev.c index 427dbbf77f..43ccb1ce97 100644 --- a/dpdk/app/test/test_eventdev.c @@ -9862,7 +12671,7 @@ index 573087c3c0..dd2e54db8b 100644 static uint32_t num_route_entries; #define NUM_ROUTE_ENTRIES num_route_entries diff --git a/dpdk/app/test/test_flow_classify.c b/dpdk/app/test/test_flow_classify.c -index ff5265c6af..ef0b6fdd5c 100644 +index ff5265c6af..951606f248 100644 --- a/dpdk/app/test/test_flow_classify.c +++ b/dpdk/app/test/test_flow_classify.c @@ -23,7 +23,7 @@ @@ -9874,6 +12683,133 @@ index ff5265c6af..ef0b6fdd5c 100644 #define MEMPOOL_CACHE_SIZE 256 #define MBUF_SIZE 512 #define NB_MBUF 512 +@@ -828,6 +828,12 @@ test_flow_classify(void) + cls_params.name = "flow_classifier"; + cls_params.socket_id = 0; + cls->cls = rte_flow_classifier_create(&cls_params); ++ if (cls->cls == NULL) { ++ printf("Line %i: flow classifier create has failed!\n", ++ __LINE__); ++ rte_free(cls); ++ return TEST_FAILED; ++ } + + /* initialise ACL table params */ + table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs); +diff --git a/dpdk/app/test/test_func_reentrancy.c b/dpdk/app/test/test_func_reentrancy.c +index 99ad902a24..969c6eb0f8 100644 +--- a/dpdk/app/test/test_func_reentrancy.c ++++ b/dpdk/app/test/test_func_reentrancy.c +@@ -89,6 +89,10 @@ ring_clean(unsigned int lcore_id) + char ring_name[MAX_STRING_SIZE]; + int i; + ++ rp = rte_ring_lookup("fr_test_once"); ++ if (rp != NULL) ++ rte_ring_free(rp); ++ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(ring_name, sizeof(ring_name), + "fr_test_%d_%d", lcore_id, i); +@@ -148,7 +152,10 @@ mempool_clean(unsigned int lcore_id) + char mempool_name[MAX_STRING_SIZE]; + int i; + +- /* verify all ring created successful */ ++ mp = rte_mempool_lookup("fr_test_once"); ++ if (mp != NULL) ++ rte_mempool_free(mp); ++ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(mempool_name, sizeof(mempool_name), "fr_test_%d_%d", + lcore_id, i); +@@ -208,6 +215,10 @@ hash_clean(unsigned lcore_id) + struct rte_hash *handle; + int i; + ++ handle = rte_hash_find_existing("fr_test_once"); ++ if (handle != NULL) ++ rte_hash_free(handle); ++ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_id, i); + +@@ -242,7 +253,7 @@ hash_create_free(__attribute__((unused)) void *arg) + rte_atomic32_inc(&obj_count); + } + +- /* create mutiple times simultaneously */ ++ /* create multiple times simultaneously */ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(hash_name, sizeof(hash_name), "fr_test_%d_%d", lcore_self, i); + hash_params.name = hash_name; +@@ -272,6 +283,10 @@ fbk_clean(unsigned lcore_id) + struct rte_fbk_hash_table *handle; + int i; + ++ handle = rte_fbk_hash_find_existing("fr_test_once"); ++ if (handle != NULL) ++ rte_fbk_hash_free(handle); ++ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_id, i); + +@@ -306,7 +321,7 @@ fbk_create_free(__attribute__((unused)) void *arg) + rte_atomic32_inc(&obj_count); + } + +- /* create mutiple fbk tables simultaneously */ ++ /* create multiple fbk tables simultaneously */ + for (i = 0; i < MAX_ITER_MULTI; i++) { + snprintf(fbk_name, sizeof(fbk_name), "fr_test_%d_%d", lcore_self, i); + fbk_params.name = fbk_name; +@@ -338,6 +353,10 @@ lpm_clean(unsigned int lcore_id) + struct rte_lpm *lpm; + int i; + ++ lpm = rte_lpm_find_existing("fr_test_once"); ++ if (lpm != NULL) ++ rte_lpm_free(lpm); ++ + for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { + snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_id, i); + +@@ -368,7 +387,7 @@ lpm_create_free(__attribute__((unused)) void *arg) + rte_atomic32_inc(&obj_count); + } + +- /* create mutiple fbk tables simultaneously */ ++ /* create multiple fbk tables simultaneously */ + for (i = 0; i < MAX_LPM_ITER_TIMES; i++) { + snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i); + lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, &config); +@@ -420,8 +439,7 @@ launch_test(struct test_case *pt_case) + { + int ret = 0; + unsigned lcore_id; +- unsigned cores_save = rte_lcore_count(); +- unsigned cores = RTE_MIN(cores_save, MAX_LCORES); ++ unsigned cores = RTE_MIN(rte_lcore_count(), MAX_LCORES); + unsigned count; + + if (pt_case->func == NULL) +@@ -442,14 +460,12 @@ launch_test(struct test_case *pt_case) + if (pt_case->func(pt_case->arg) < 0) + ret = -1; + +- cores = cores_save; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { +- if (cores == 1) +- break; +- cores--; + if (rte_eal_wait_lcore(lcore_id) < 0) + ret = -1; ++ } + ++ RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (pt_case->clean != NULL) + pt_case->clean(lcore_id); + } diff --git a/dpdk/app/test/test_hash.c b/dpdk/app/test/test_hash.c index 0052dce2de..2ac298e21e 100644 --- a/dpdk/app/test/test_hash.c @@ -9896,9 +12832,18 @@ diff --git a/dpdk/app/test/test_hash_readwrite_lf.c b/dpdk/app/test/test_hash_re similarity index 99% rename from dpdk/app/test/test_hash_readwrite_lf.c rename to dpdk/app/test/test_hash_readwrite_lf_perf.c -index 97c304054c..7bfc067f4e 100644 +index 97c304054c..858c883f24 100644 --- a/dpdk/app/test/test_hash_readwrite_lf.c +++ b/dpdk/app/test/test_hash_readwrite_lf_perf.c +@@ -56,7 +56,7 @@ struct rwc_perf { + uint32_t w_ks_r_hit_nsp[2][NUM_TEST]; + uint32_t w_ks_r_hit_sp[2][NUM_TEST]; + uint32_t w_ks_r_miss[2][NUM_TEST]; +- uint32_t multi_rw[NUM_TEST - 1][2][NUM_TEST]; ++ uint32_t multi_rw[NUM_TEST][2][NUM_TEST]; + uint32_t w_ks_r_hit_extbkt[2][NUM_TEST]; + }; + @@ -1241,7 +1241,7 @@ test_hash_add_ks_lookup_hit_extbkt(struct rwc_perf *rwc_perf_results, } @@ -9925,7 +12870,7 @@ index 97c304054c..7bfc067f4e 100644 +REGISTER_TEST_COMMAND(hash_readwrite_lf_perf_autotest, + test_hash_readwrite_lf_perf_main); diff --git a/dpdk/app/test/test_ipsec.c b/dpdk/app/test/test_ipsec.c -index 7dc83fee7e..6a4bd12f7f 100644 +index 7dc83fee7e..65924b0572 100644 --- a/dpdk/app/test/test_ipsec.c +++ b/dpdk/app/test/test_ipsec.c @@ -237,7 +237,7 @@ fill_crypto_xform(struct ipsec_unitest_params *ut_params, @@ -9946,7 +12891,33 @@ index 7dc83fee7e..6a4bd12f7f 100644 if (rc == 0) { ts_params->valid_dev = i; ts_params->valid_dev_found = 1; -@@ -743,7 +743,7 @@ create_sa(enum rte_security_session_action_type action_type, +@@ -544,12 +544,14 @@ struct rte_ipv4_hdr ipv4_outer = { + }; + + static struct rte_mbuf * +-setup_test_string(struct rte_mempool *mpool, +- const char *string, size_t len, uint8_t blocksize) ++setup_test_string(struct rte_mempool *mpool, const char *string, ++ size_t string_len, size_t len, uint8_t blocksize) + { + struct rte_mbuf *m = rte_pktmbuf_alloc(mpool); + size_t t_len = len - (blocksize ? (len % blocksize) : 0); + ++ RTE_VERIFY(len <= string_len); ++ + if (m) { + memset(m->buf_addr, 0, m->buf_len); + char *dst = rte_pktmbuf_append(m, t_len); +@@ -653,7 +655,7 @@ create_crypto_session(struct ipsec_unitest_params *ut, + if (s == NULL) + return -ENOMEM; + +- /* initiliaze SA crypto session for device */ ++ /* initialize SA crypto session for device */ + rc = rte_cryptodev_sym_session_init(dev_id, s, + ut->crypto_xforms, qp->mp_session_private); + if (rc == 0) { +@@ -743,7 +745,7 @@ create_sa(enum rte_security_session_action_type action_type, ut->ss[j].type = action_type; rc = create_session(ut, &ts->qp_conf, ts->valid_dev, j); if (rc != 0) @@ -9955,7 +12926,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 rc = rte_ipsec_sa_init(ut->ss[j].sa, &ut->sa_prm, sz); rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL; -@@ -1167,6 +1167,34 @@ test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i) +@@ -1167,6 +1169,34 @@ test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i) } } @@ -9990,7 +12961,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 static void destroy_sa(uint32_t j) { -@@ -1175,9 +1203,8 @@ destroy_sa(uint32_t j) +@@ -1175,9 +1205,8 @@ destroy_sa(uint32_t j) rte_ipsec_sa_fini(ut->ss[j].sa); rte_free(ut->ss[j].sa); @@ -10002,7 +12973,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } static int -@@ -1219,7 +1246,7 @@ test_ipsec_crypto_inb_burst_null_null(int i) +@@ -1219,7 +1248,7 @@ test_ipsec_crypto_inb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10011,7 +12982,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -1321,7 +1348,7 @@ test_ipsec_crypto_outb_burst_null_null(int i) +@@ -1321,13 +1350,14 @@ test_ipsec_crypto_outb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10020,7 +12991,15 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate input mbuf data */ -@@ -1430,7 +1457,7 @@ test_ipsec_inline_crypto_inb_burst_null_null(int i) + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + else { +@@ -1430,7 +1460,7 @@ test_ipsec_inline_crypto_inb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10029,7 +13008,17 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate inbound mbuf data */ -@@ -1508,7 +1535,7 @@ test_ipsec_inline_proto_inb_burst_null_null(int i) +@@ -1445,7 +1475,8 @@ test_ipsec_inline_crypto_inb_burst_null_null(int i) + /* Generate test mbuf data */ + ut_params->obuf[j] = setup_test_string( + ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } +@@ -1508,21 +1539,22 @@ test_ipsec_inline_proto_inb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10038,7 +13027,26 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate inbound mbuf data */ -@@ -1616,7 +1643,7 @@ test_ipsec_inline_crypto_outb_burst_null_null(int i) + for (j = 0; j < num_pkts && rc == 0; j++) { +- ut_params->ibuf[j] = setup_test_string( +- ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + else { + /* Generate test mbuf data */ + ut_params->obuf[j] = setup_test_string( + ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } +@@ -1616,13 +1648,14 @@ test_ipsec_inline_crypto_outb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10047,7 +13055,15 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -1694,7 +1721,7 @@ test_ipsec_inline_proto_outb_burst_null_null(int i) + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + +@@ -1694,21 +1727,23 @@ test_ipsec_inline_proto_outb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10056,7 +13072,26 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -1770,7 +1797,7 @@ test_ipsec_lksd_proto_inb_burst_null_null(int i) + for (j = 0; j < num_pkts && rc == 0; j++) { + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ null_plain_data, sizeof(null_plain_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[0] == NULL) + rc = TEST_FAILED; + + if (rc == 0) { + /* Generate test tunneled mbuf data for comparison */ + ut_params->obuf[j] = setup_test_string( +- ts_params->mbuf_pool, +- null_plain_data, test_cfg[i].pkt_sz, 0); ++ ts_params->mbuf_pool, null_plain_data, ++ sizeof(null_plain_data), test_cfg[i].pkt_sz, ++ 0); + if (ut_params->obuf[j] == NULL) + rc = TEST_FAILED; + } +@@ -1770,14 +1805,15 @@ test_ipsec_lksd_proto_inb_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10065,7 +13100,16 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -1883,7 +1910,7 @@ test_ipsec_replay_inb_inside_null_null(int i) + for (j = 0; j < num_pkts && rc == 0; j++) { + /* packet with sequence number 0 is invalid */ + ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool, +- null_encrypted_data, test_cfg[i].pkt_sz, 0); ++ null_encrypted_data, sizeof(null_encrypted_data), ++ test_cfg[i].pkt_sz, 0); + if (ut_params->ibuf[j] == NULL) + rc = TEST_FAILED; + } +@@ -1883,7 +1919,7 @@ test_ipsec_replay_inb_inside_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10074,7 +13118,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate inbound mbuf data */ -@@ -1976,7 +2003,7 @@ test_ipsec_replay_inb_outside_null_null(int i) +@@ -1976,7 +2012,7 @@ test_ipsec_replay_inb_outside_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10083,7 +13127,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -2076,7 +2103,7 @@ test_ipsec_replay_inb_repeat_null_null(int i) +@@ -2076,7 +2112,7 @@ test_ipsec_replay_inb_repeat_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10092,7 +13136,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -2177,7 +2204,7 @@ test_ipsec_replay_inb_inside_burst_null_null(int i) +@@ -2177,7 +2213,7 @@ test_ipsec_replay_inb_inside_burst_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i); @@ -10101,7 +13145,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate inbound mbuf data */ -@@ -2310,7 +2337,7 @@ test_ipsec_crypto_inb_burst_2sa_null_null(int i) +@@ -2310,7 +2346,7 @@ test_ipsec_crypto_inb_burst_2sa_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i); @@ -10110,7 +13154,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* create second rte_ipsec_sa */ -@@ -2320,7 +2347,7 @@ test_ipsec_crypto_inb_burst_2sa_null_null(int i) +@@ -2320,7 +2356,7 @@ test_ipsec_crypto_inb_burst_2sa_null_null(int i) if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i); destroy_sa(0); @@ -10119,7 +13163,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ -@@ -2396,7 +2423,7 @@ test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) +@@ -2396,7 +2432,7 @@ test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) test_cfg[i].replay_win_sz, test_cfg[i].flags, 0); if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i); @@ -10128,7 +13172,7 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* create second rte_ipsec_sa */ -@@ -2406,7 +2433,7 @@ test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) +@@ -2406,7 +2442,7 @@ test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i) if (rc != 0) { RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i); destroy_sa(0); @@ -10137,6 +13181,25 @@ index 7dc83fee7e..6a4bd12f7f 100644 } /* Generate test mbuf data */ +diff --git a/dpdk/app/test/test_kni.c b/dpdk/app/test/test_kni.c +index e47ab36e02..b338c916bb 100644 +--- a/dpdk/app/test/test_kni.c ++++ b/dpdk/app/test/test_kni.c +@@ -562,8 +562,12 @@ test_kni(void) + } + closedir(dir); + +- /* Initialize KNI subsytem */ +- rte_kni_init(KNI_TEST_MAX_PORTS); ++ /* Initialize KNI subsystem */ ++ ret = rte_kni_init(KNI_TEST_MAX_PORTS); ++ if (ret < 0) { ++ printf("fail to initialize KNI subsystem\n"); ++ return -1; ++ } + + if (test_kni_allocate_lcores() < 0) { + printf("No enough lcores for kni processing\n"); diff --git a/dpdk/app/test/test_kvargs.c b/dpdk/app/test/test_kvargs.c index a42056f361..2a2dae43a0 100644 --- a/dpdk/app/test/test_kvargs.c @@ -10214,6 +13277,264 @@ index a42056f361..2a2dae43a0 100644 fail: printf("while processing <%s>", *args); +diff --git a/dpdk/app/test/test_latencystats.c b/dpdk/app/test/test_latencystats.c +index 968e0bc470..0f2a346209 100644 +--- a/dpdk/app/test/test_latencystats.c ++++ b/dpdk/app/test/test_latencystats.c +@@ -6,6 +6,7 @@ + #include + #include + ++#include + #include + #include "rte_lcore.h" + #include "rte_metrics.h" +@@ -77,7 +78,7 @@ static int test_latencystats_get_names(void) + /* Success Test: Valid names and size */ + size = NUM_STATS; + ret = rte_latencystats_get_names(names, size); +- for (i = 0; i <= NUM_STATS; i++) { ++ for (i = 0; i < NUM_STATS; i++) { + if (strcmp(lat_stats_strings[i].name, names[i].name) == 0) + printf(" %s\n", names[i].name); + else +@@ -155,12 +156,21 @@ static int test_latency_packet_forward(void) + printf("allocate mbuf pool Failed\n"); + return TEST_FAILED; + } ++ ret = test_dev_start(portid, mp); ++ if (ret < 0) { ++ printf("test_dev_start(%hu, %p) failed, error code: %d\n", ++ portid, mp, ret); ++ return TEST_FAILED; ++ } ++ + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); ++ ++ rte_eth_dev_stop(portid); + test_put_mbuf_to_pool(mp, pbuf); + +- return TEST_SUCCESS; ++ return (ret >= 0) ? TEST_SUCCESS : TEST_FAILED; + } + + static struct +diff --git a/dpdk/app/test/test_link_bonding.c b/dpdk/app/test/test_link_bonding.c +index 3a46f943f1..e6301b82d9 100644 +--- a/dpdk/app/test/test_link_bonding.c ++++ b/dpdk/app/test/test_link_bonding.c +@@ -3025,7 +3025,7 @@ test_balance_tx_burst_slave_tx_fail(void) + first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 - + TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; + +- /* copy mbuf referneces for expected transmission failures */ ++ /* copy mbuf references for expected transmission failures */ + for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) + expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx]; + +diff --git a/dpdk/app/test/test_link_bonding_rssconf.c b/dpdk/app/test/test_link_bonding_rssconf.c +index 1a9571e5c6..32391e7ad7 100644 +--- a/dpdk/app/test/test_link_bonding_rssconf.c ++++ b/dpdk/app/test/test_link_bonding_rssconf.c +@@ -465,15 +465,85 @@ test_rss(void) + + TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); + +- TEST_ASSERT(slave_remove_and_add() == 1, "New slave should be synced"); ++ TEST_ASSERT(slave_remove_and_add() == 1, "remove and add slaves success."); + + remove_slaves_and_stop_bonded_device(); + + return TEST_SUCCESS; + } + ++ ++/** ++ * Test RSS configuration over bonded and slaves. ++ */ ++static int ++test_rss_config_lazy(void) ++{ ++ struct rte_eth_rss_conf bond_rss_conf = {0}; ++ struct slave_conf *port; ++ uint8_t rss_key[40]; ++ uint64_t rss_hf; ++ int retval; ++ uint16_t i; ++ uint8_t n; ++ ++ retval = rte_eth_dev_info_get(test_params.bond_port_id, ++ &test_params.bond_dev_info); ++ TEST_ASSERT((retval == 0), "Error during getting device (port %u) info: %s\n", ++ test_params.bond_port_id, strerror(-retval)); ++ ++ rss_hf = test_params.bond_dev_info.flow_type_rss_offloads; ++ if (rss_hf != 0) { ++ bond_rss_conf.rss_key = NULL; ++ bond_rss_conf.rss_hf = rss_hf; ++ retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id, ++ &bond_rss_conf); ++ TEST_ASSERT(retval != 0, "Succeeded in setting bonded port hash function"); ++ } ++ ++ /* Set all keys to zero for all slaves */ ++ FOR_EACH_PORT(n, port) { ++ port = &test_params.slave_ports[n]; ++ retval = rte_eth_dev_rss_hash_conf_get(port->port_id, ++ &port->rss_conf); ++ TEST_ASSERT_SUCCESS(retval, "Cannot get slaves RSS configuration"); ++ memset(port->rss_key, 0, sizeof(port->rss_key)); ++ port->rss_conf.rss_key = port->rss_key; ++ port->rss_conf.rss_key_len = sizeof(port->rss_key); ++ retval = rte_eth_dev_rss_hash_update(port->port_id, ++ &port->rss_conf); ++ TEST_ASSERT(retval != 0, "Succeeded in setting slaves RSS keys"); ++ } ++ ++ /* Set RSS keys for bonded port */ ++ memset(rss_key, 1, sizeof(rss_key)); ++ bond_rss_conf.rss_hf = rss_hf; ++ bond_rss_conf.rss_key = rss_key; ++ bond_rss_conf.rss_key_len = sizeof(rss_key); ++ ++ retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id, ++ &bond_rss_conf); ++ TEST_ASSERT(retval != 0, "Succeeded in setting bonded port RSS keys"); ++ ++ /* Test RETA propagation */ ++ for (i = 0; i < RXTX_QUEUE_COUNT; i++) { ++ FOR_EACH_PORT(n, port) { ++ port = &test_params.slave_ports[n]; ++ retval = reta_set(port->port_id, (i + 1) % RXTX_QUEUE_COUNT, ++ port->dev_info.reta_size); ++ TEST_ASSERT(retval != 0, "Succeeded in setting slaves RETA"); ++ } ++ ++ retval = reta_set(test_params.bond_port_id, i % RXTX_QUEUE_COUNT, ++ test_params.bond_dev_info.reta_size); ++ TEST_ASSERT(retval != 0, "Succeeded in setting bonded port RETA"); ++ } ++ ++ return TEST_SUCCESS; ++} ++ + /** +- * Test propagation logic, when RX_RSS mq_mode is turned off for bonding port ++ * Test RSS function logic, when RX_RSS mq_mode is turned off for bonding port + */ + static int + test_rss_lazy(void) +@@ -494,9 +564,7 @@ test_rss_lazy(void) + TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id), + "Failed to start bonding port (%d).", test_params.bond_port_id); + +- TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed"); +- +- TEST_ASSERT(slave_remove_and_add() == 0, "New slave shouldn't be synced"); ++ TEST_ASSERT_SUCCESS(test_rss_config_lazy(), "Succeeded in setting RSS hash when RX_RSS mq_mode is turned off"); + + remove_slaves_and_stop_bonded_device(); + +diff --git a/dpdk/app/test/test_lpm.c b/dpdk/app/test/test_lpm.c +index e969fe0510..88a12fba34 100644 +--- a/dpdk/app/test/test_lpm.c ++++ b/dpdk/app/test/test_lpm.c +@@ -173,7 +173,7 @@ test3(void) + status = rte_lpm_add(NULL, ip, depth, next_hop); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -211,7 +211,7 @@ test4(void) + status = rte_lpm_delete(NULL, ip, depth); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -249,7 +249,7 @@ test5(void) + status = rte_lpm_lookup(NULL, ip, &next_hop_return); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +diff --git a/dpdk/app/test/test_lpm6.c b/dpdk/app/test/test_lpm6.c +index 670aadb40e..1b788386a0 100644 +--- a/dpdk/app/test/test_lpm6.c ++++ b/dpdk/app/test/test_lpm6.c +@@ -262,7 +262,7 @@ test4(void) + status = rte_lpm6_add(NULL, ip, depth, next_hop); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -300,7 +300,7 @@ test5(void) + status = rte_lpm6_delete(NULL, ip, depth); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -338,7 +338,7 @@ test6(void) + status = rte_lpm6_lookup(NULL, ip, &next_hop_return); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -376,7 +376,7 @@ test7(void) + status = rte_lpm6_lookup_bulk_func(NULL, ip, next_hop_return, 10); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -414,7 +414,7 @@ test8(void) + status = rte_lpm6_delete_bulk_func(NULL, ip, depth, 10); + TEST_LPM_ASSERT(status < 0); + +- /*Create vaild lpm to use in rest of test. */ ++ /*Create valid lpm to use in rest of test. */ + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + +@@ -434,7 +434,7 @@ test8(void) + /* + * Call add, lookup and delete for a single rule with depth < 24. + * Check all the combinations for the first three bytes that result in a hit. +- * Delete the rule and check that the same test returs a miss. ++ * Delete the rule and check that the same test returns a miss. + */ + int32_t + test9(void) +@@ -1739,7 +1739,7 @@ test27(void) + * Call add, lookup and delete for a single rule with maximum 21bit next_hop + * size. + * Check that next_hop returned from lookup is equal to provisioned value. +- * Delete the rule and check that the same test returs a miss. ++ * Delete the rule and check that the same test returns a miss. + */ + int32_t + test28(void) diff --git a/dpdk/app/test/test_lpm_perf.c b/dpdk/app/test/test_lpm_perf.c index a2578fe90e..489719c40b 100644 --- a/dpdk/app/test/test_lpm_perf.c @@ -10228,9 +13549,18 @@ index a2578fe90e..489719c40b 100644 static uint32_t num_route_entries; #define NUM_ROUTE_ENTRIES num_route_entries diff --git a/dpdk/app/test/test_malloc.c b/dpdk/app/test/test_malloc.c -index a16e28cc32..57f796f9e5 100644 +index a16e28cc32..b8836c1edb 100644 --- a/dpdk/app/test/test_malloc.c +++ b/dpdk/app/test/test_malloc.c +@@ -570,7 +570,7 @@ test_realloc(void) + } + } + +- /* Print warnign if only a single socket, but don't fail the test */ ++ /* Print warning if only a single socket, but don't fail the test */ + if (socket_count < 2) + printf("WARNING: realloc_socket test needs memory on multiple sockets!\n"); + @@ -746,6 +746,18 @@ test_malloc_bad_params(void) if (bad_ptr != NULL) goto err_return; @@ -10250,10 +13580,28 @@ index a16e28cc32..57f796f9e5 100644 return 0; err_return: +@@ -856,7 +868,7 @@ test_alloc_socket(void) + } + } + +- /* Print warnign if only a single socket, but don't fail the test */ ++ /* Print warning if only a single socket, but don't fail the test */ + if (socket_count < 2) { + printf("WARNING: alloc_socket test needs memory on multiple sockets!\n"); + } diff --git a/dpdk/app/test/test_mbuf.c b/dpdk/app/test/test_mbuf.c -index 61ecffc184..a5bd1693b2 100644 +index 61ecffc184..f231d37ffd 100644 --- a/dpdk/app/test/test_mbuf.c +++ b/dpdk/app/test/test_mbuf.c +@@ -1136,7 +1136,7 @@ test_refcnt_mbuf(void) + + rte_eal_mp_wait_lcore(); + +- /* check that we porcessed all references */ ++ /* check that we processed all references */ + tref = 0; + master = rte_get_master_lcore(); + @@ -1144,7 +1144,7 @@ test_refcnt_mbuf(void) tref += refcnt_lcore[slave]; @@ -10263,7 +13611,51 @@ index 61ecffc184..a5bd1693b2 100644 tref, refcnt_lcore[master]); rte_mempool_dump(stdout, refcnt_pool); -@@ -2481,9 +2481,13 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) +@@ -2011,8 +2011,6 @@ test_pktmbuf_read_from_offset(struct rte_mempool *pktmbuf_pool) + NULL); + if (data_copy == NULL) + GOTO_FAIL("%s: Error in reading packet data!\n", __func__); +- if (strlen(data_copy) != MBUF_TEST_DATA_LEN2 - 5) +- GOTO_FAIL("%s: Incorrect data length!\n", __func__); + for (off = 0; off < MBUF_TEST_DATA_LEN2 - 5; off++) { + if (data_copy[off] != (char)0xcc) + GOTO_FAIL("Data corrupted at offset %u", off); +@@ -2034,8 +2032,6 @@ test_pktmbuf_read_from_offset(struct rte_mempool *pktmbuf_pool) + data_copy = rte_pktmbuf_read(m, hdr_len, 0, NULL); + if (data_copy == NULL) + GOTO_FAIL("%s: Error in reading packet data!\n", __func__); +- if (strlen(data_copy) != MBUF_TEST_DATA_LEN2) +- GOTO_FAIL("%s: Corrupted data content!\n", __func__); + for (off = 0; off < MBUF_TEST_DATA_LEN2; off++) { + if (data_copy[off] != (char)0xcc) + GOTO_FAIL("Data corrupted at offset %u", off); +@@ -2344,7 +2340,7 @@ test_pktmbuf_ext_shinfo_init_helper(struct rte_mempool *pktmbuf_pool) + if (rte_mbuf_refcnt_read(m) != 1) + GOTO_FAIL("%s: Invalid refcnt in mbuf\n", __func__); + +- buf_iova = rte_mempool_virt2iova(ext_buf_addr); ++ buf_iova = rte_mem_virt2iova(ext_buf_addr); + rte_pktmbuf_attach_extbuf(m, ext_buf_addr, buf_iova, buf_len, + ret_shinfo); + if (m->ol_flags != EXT_ATTACHED_MBUF) +@@ -2444,6 +2440,16 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) + .align = 3, + .flags = 0, + }; ++ const struct rte_mbuf_dynfield dynfield_fail_flag = { ++ .name = "test-dynfield", ++ .size = sizeof(uint8_t), ++ .align = __alignof__(uint8_t), ++ .flags = 1, ++ }; ++ const struct rte_mbuf_dynflag dynflag_fail_flag = { ++ .name = "test-dynflag", ++ .flags = 1, ++ }; + const struct rte_mbuf_dynflag dynflag = { + .name = "test-dynflag", + .flags = 0, +@@ -2481,9 +2487,13 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) offset3 = rte_mbuf_dynfield_register_offset(&dynfield3, offsetof(struct rte_mbuf, dynfield1[1])); @@ -10280,7 +13672,22 @@ index 61ecffc184..a5bd1693b2 100644 printf("dynfield: offset=%d, offset2=%d, offset3=%d\n", offset, offset2, offset3); -@@ -2519,7 +2523,7 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) +@@ -2501,6 +2511,14 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) + if (ret != -1) + GOTO_FAIL("dynamic field creation should fail (not avail)"); + ++ ret = rte_mbuf_dynfield_register(&dynfield_fail_flag); ++ if (ret != -1) ++ GOTO_FAIL("dynamic field creation should fail (invalid flag)"); ++ ++ ret = rte_mbuf_dynflag_register(&dynflag_fail_flag); ++ if (ret != -1) ++ GOTO_FAIL("dynamic flag creation should fail (invalid flag)"); ++ + flag = rte_mbuf_dynflag_register(&dynflag); + if (flag == -1) + GOTO_FAIL("failed to register dynamic flag, flag=%d: %s", +@@ -2519,7 +2537,7 @@ test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3, rte_bsf64(PKT_LAST_FREE)); if (flag3 != rte_bsf64(PKT_LAST_FREE)) @@ -10344,8 +13751,130 @@ index e9359df2ee..b70dd4775b 100644 /* * Test mcs lock & unlock on each core +diff --git a/dpdk/app/test/test_memory.c b/dpdk/app/test/test_memory.c +index 7d5ae99bab..140ac3f3cf 100644 +--- a/dpdk/app/test/test_memory.c ++++ b/dpdk/app/test/test_memory.c +@@ -6,6 +6,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -53,7 +54,7 @@ check_seg_fds(const struct rte_memseg_list *msl, const struct rte_memseg *ms, + /* ENOTSUP means segment is valid, but there is not support for + * segment fd API (e.g. on FreeBSD). + */ +- if (errno == ENOTSUP) ++ if (rte_errno == ENOTSUP) + return 1; + /* all other errors are treated as failures */ + return -1; +@@ -62,7 +63,7 @@ check_seg_fds(const struct rte_memseg_list *msl, const struct rte_memseg *ms, + /* we're able to get memseg fd - try getting its offset */ + ret = rte_memseg_get_fd_offset_thread_unsafe(ms, &offset); + if (ret < 0) { +- if (errno == ENOTSUP) ++ if (rte_errno == ENOTSUP) + return 1; + return -1; + } +diff --git a/dpdk/app/test/test_mempool.c b/dpdk/app/test/test_mempool.c +index c32a5d387d..6615172daa 100644 +--- a/dpdk/app/test/test_mempool.c ++++ b/dpdk/app/test/test_mempool.c +@@ -552,7 +552,7 @@ test_mempool(void) + GOTO_ERR(ret, err); + + /* test to initialize mempool objects and memory */ +- nb_objs = rte_mempool_obj_iter(mp_stack_mempool_iter, rte_pktmbuf_init, ++ nb_objs = rte_mempool_obj_iter(mp_stack_mempool_iter, my_obj_init, + NULL); + if (nb_objs == 0) + GOTO_ERR(ret, err); +@@ -633,7 +633,7 @@ test_mempool(void) + if (test_mempool_basic_ex(mp_nocache) < 0) + GOTO_ERR(ret, err); + +- /* mempool operation test based on single producer and single comsumer */ ++ /* mempool operation test based on single producer and single consumer */ + if (test_mempool_sp_sc() < 0) + GOTO_ERR(ret, err); + +diff --git a/dpdk/app/test/test_mempool_perf.c b/dpdk/app/test/test_mempool_perf.c +index 4c877834e7..2586c69a8e 100644 +--- a/dpdk/app/test/test_mempool_perf.c ++++ b/dpdk/app/test/test_mempool_perf.c +@@ -89,7 +89,7 @@ static rte_atomic32_t synchro; + static unsigned n_get_bulk; + static unsigned n_put_bulk; + +-/* number of objects retrived from mempool before putting them back */ ++/* number of objects retrieved from mempool before putting them back */ + static unsigned n_keep; + + /* number of enqueues / dequeues */ +diff --git a/dpdk/app/test/test_meter.c b/dpdk/app/test/test_meter.c +index f6fe6494ab..15d5a4839b 100644 +--- a/dpdk/app/test/test_meter.c ++++ b/dpdk/app/test/test_meter.c +@@ -444,7 +444,7 @@ tm_test_srtcm_color_aware_check(void) + * if using blind check + */ + +- /* previouly have a green, test points should keep unchanged */ ++ /* previously have a green, test points should keep unchanged */ + in[0] = in[1] = in[2] = in[3] = RTE_COLOR_GREEN; + out[0] = RTE_COLOR_GREEN; + out[1] = RTE_COLOR_YELLOW; +@@ -551,7 +551,7 @@ tm_test_trtcm_color_aware_check(void) + * if using blind check + */ + +- /* previouly have a green, test points should keep unchanged */ ++ /* previously have a green, test points should keep unchanged */ + in[0] = in[1] = in[2] = in[3] = RTE_COLOR_GREEN; + out[0] = RTE_COLOR_GREEN; + out[1] = RTE_COLOR_YELLOW; +@@ -648,7 +648,7 @@ tm_test_trtcm_rfc4115_color_aware_check(void) + * if using blind check + */ + +- /* previouly have a green, test points should keep unchanged */ ++ /* previously have a green, test points should keep unchanged */ + in[0] = in[1] = in[2] = in[3] = RTE_COLOR_GREEN; + out[0] = RTE_COLOR_GREEN; + out[1] = RTE_COLOR_YELLOW; +diff --git a/dpdk/app/test/test_pdump.c b/dpdk/app/test/test_pdump.c +index af206968b3..e377cfb5da 100644 +--- a/dpdk/app/test/test_pdump.c ++++ b/dpdk/app/test/test_pdump.c +@@ -152,11 +152,19 @@ send_pkts(void *empty) + ret = test_get_mbuf_from_pool(&mp, pbuf, poolname); + if (ret < 0) + printf("get_mbuf_from_pool failed\n"); +- do { ++ ++ ret = test_dev_start(portid, mp); ++ if (ret < 0) ++ printf("test_dev_start(%hu, %p) failed, error code: %d\n", ++ portid, mp, ret); ++ ++ while (ret >= 0 && flag_for_send_pkts) { + ret = test_packet_forward(pbuf, portid, QUEUE_ID); + if (ret < 0) + printf("send pkts Failed\n"); +- } while (flag_for_send_pkts); ++ }; ++ ++ rte_eth_dev_stop(portid); + test_put_mbuf_to_pool(mp, pbuf); + return empty; + } diff --git a/dpdk/app/test/test_pmd_perf.c b/dpdk/app/test/test_pmd_perf.c -index d61be58bb3..de7e726429 100644 +index d61be58bb3..832af747c6 100644 --- a/dpdk/app/test/test_pmd_perf.c +++ b/dpdk/app/test/test_pmd_perf.c @@ -151,7 +151,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) @@ -10357,7 +13886,44 @@ index d61be58bb3..de7e726429 100644 if (link_mbps == 0) link_mbps = link.link_speed; } else -@@ -609,10 +609,10 @@ poll_burst(void *args) +@@ -459,6 +459,7 @@ main_loop(__rte_unused void *args) + #define PACKET_SIZE 64 + #define FRAME_GAP 12 + #define MAC_PREAMBLE 8 ++#define MAX_RETRY_COUNT 5 + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + unsigned lcore_id; + unsigned i, portid, nb_rx = 0, nb_tx = 0; +@@ -466,6 +467,8 @@ main_loop(__rte_unused void *args) + int pkt_per_port; + uint64_t diff_tsc; + uint64_t packets_per_second, total_packets; ++ int retry_cnt = 0; ++ int free_pkt = 0; + + lcore_id = rte_lcore_id(); + conf = &lcore_conf[lcore_id]; +@@ -483,10 +486,19 @@ main_loop(__rte_unused void *args) + nb_tx = RTE_MIN(MAX_PKT_BURST, num); + nb_tx = rte_eth_tx_burst(portid, 0, + &tx_burst[idx], nb_tx); ++ if (nb_tx == 0) ++ retry_cnt++; + num -= nb_tx; + idx += nb_tx; ++ if (retry_cnt == MAX_RETRY_COUNT) { ++ retry_cnt = 0; ++ break; ++ } + } + } ++ for (free_pkt = idx; free_pkt < (MAX_TRAFFIC_BURST * conf->nb_ports); ++ free_pkt++) ++ rte_pktmbuf_free(tx_burst[free_pkt]); + printf("Total packets inject to prime ports = %u\n", idx); + + packets_per_second = (link_mbps * 1000 * 1000) / +@@ -609,10 +621,10 @@ poll_burst(void *args) static int exec_burst(uint32_t flags, int lcore) { @@ -10370,7 +13936,7 @@ index d61be58bb3..de7e726429 100644 int diff_tsc; conf = &lcore_conf[lcore]; -@@ -631,16 +631,14 @@ exec_burst(uint32_t flags, int lcore) +@@ -631,16 +643,14 @@ exec_burst(uint32_t flags, int lcore) rte_atomic64_set(&start, 1); /* start xmit */ @@ -10393,6 +13959,252 @@ index d61be58bb3..de7e726429 100644 } sleep(5); +@@ -758,7 +768,7 @@ test_pmd_perf(void) + "rte_eth_dev_start: err=%d, port=%d\n", + ret, portid); + +- /* always eanble promiscuous */ ++ /* always enable promiscuous */ + ret = rte_eth_promiscuous_enable(portid); + if (ret != 0) + rte_exit(EXIT_FAILURE, +diff --git a/dpdk/app/test/test_power_cpufreq.c b/dpdk/app/test/test_power_cpufreq.c +index d203810da9..51105f35be 100644 +--- a/dpdk/app/test/test_power_cpufreq.c ++++ b/dpdk/app/test/test_power_cpufreq.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include "test.h" + +@@ -34,37 +35,86 @@ test_power_caps(void) + #define TEST_POWER_LCORE_INVALID ((unsigned)RTE_MAX_LCORE) + #define TEST_POWER_FREQS_NUM_MAX ((unsigned)RTE_MAX_LCORE_FREQS) + +-#define TEST_POWER_SYSFILE_CUR_FREQ \ ++/* macros used for rounding frequency to nearest 100000 */ ++#define TEST_FREQ_ROUNDING_DELTA 50000 ++#define TEST_ROUND_FREQ_TO_N_100000 100000 ++ ++#define TEST_POWER_SYSFILE_CPUINFO_FREQ \ + "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_cur_freq" ++#define TEST_POWER_SYSFILE_SCALING_FREQ \ ++ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq" + + static uint32_t total_freq_num; + static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX]; + + static int +-check_cur_freq(unsigned lcore_id, uint32_t idx) ++check_cur_freq(unsigned int lcore_id, uint32_t idx, bool turbo) + { + #define TEST_POWER_CONVERT_TO_DECIMAL 10 ++#define MAX_LOOP 100 + FILE *f; + char fullpath[PATH_MAX]; + char buf[BUFSIZ]; ++ enum power_management_env env; + uint32_t cur_freq; ++ uint32_t freq_conv; + int ret = -1; ++ int i; + + if (snprintf(fullpath, sizeof(fullpath), +- TEST_POWER_SYSFILE_CUR_FREQ, lcore_id) < 0) { ++ TEST_POWER_SYSFILE_CPUINFO_FREQ, lcore_id) < 0) { + return 0; + } + f = fopen(fullpath, "r"); + if (f == NULL) { +- return 0; ++ if (snprintf(fullpath, sizeof(fullpath), ++ TEST_POWER_SYSFILE_SCALING_FREQ, lcore_id) < 0) { ++ return 0; ++ } ++ f = fopen(fullpath, "r"); ++ if (f == NULL) { ++ return 0; ++ } ++ } ++ for (i = 0; i < MAX_LOOP; i++) { ++ fflush(f); ++ if (fgets(buf, sizeof(buf), f) == NULL) ++ goto fail_all; ++ ++ cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL); ++ freq_conv = cur_freq; ++ ++ env = rte_power_get_env(); ++ ++ if (env == PM_ENV_PSTATE_CPUFREQ) { ++ /* convert the frequency to nearest 100000 value ++ * Ex: if cur_freq=1396789 then freq_conv=1400000 ++ * Ex: if cur_freq=800030 then freq_conv=800000 ++ */ ++ unsigned int freq_conv = 0; ++ freq_conv = (cur_freq + TEST_FREQ_ROUNDING_DELTA) ++ / TEST_ROUND_FREQ_TO_N_100000; ++ freq_conv = freq_conv * TEST_ROUND_FREQ_TO_N_100000; ++ } ++ ++ if (turbo) ++ ret = (freqs[idx] <= freq_conv ? 0 : -1); ++ else ++ ret = (freqs[idx] == freq_conv ? 0 : -1); ++ ++ if (ret == 0) ++ break; ++ ++ if (fseek(f, 0, SEEK_SET) < 0) { ++ printf("Fail to set file position indicator to 0\n"); ++ goto fail_all; ++ } ++ ++ /* wait for the value to be updated */ ++ rte_delay_ms(10); + } +- if (fgets(buf, sizeof(buf), f) == NULL) { +- goto fail_get_cur_freq; +- } +- cur_freq = strtoul(buf, NULL, TEST_POWER_CONVERT_TO_DECIMAL); +- ret = (freqs[idx] == cur_freq ? 0 : -1); + +-fail_get_cur_freq: ++fail_all: + fclose(f); + + return ret; +@@ -143,7 +193,7 @@ check_power_get_freq(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, count); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, count, false); + if (ret < 0) + return -1; + +@@ -193,7 +243,7 @@ check_power_set_freq(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false); + if (ret < 0) + return -1; + +@@ -206,6 +256,8 @@ check_power_freq_down(void) + { + int ret; + ++ rte_power_freq_enable_turbo(TEST_POWER_LCORE_ID); ++ + /* test with an invalid lcore id */ + ret = rte_power_freq_down(TEST_POWER_LCORE_INVALID); + if (ret >= 0) { +@@ -229,7 +281,7 @@ check_power_freq_down(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false); + if (ret < 0) + return -1; + +@@ -248,7 +300,7 @@ check_power_freq_down(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, 1); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, 1, false); + if (ret < 0) + return -1; + +@@ -284,7 +336,7 @@ check_power_freq_up(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 2, false); + if (ret < 0) + return -1; + +@@ -303,7 +355,7 @@ check_power_freq_up(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true); + if (ret < 0) + return -1; + +@@ -331,7 +383,7 @@ check_power_freq_max(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true); + if (ret < 0) + return -1; + +@@ -359,7 +411,7 @@ check_power_freq_min(void) + } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, total_freq_num - 1, false); + if (ret < 0) + return -1; + +@@ -391,9 +443,15 @@ check_power_turbo(void) + TEST_POWER_LCORE_ID); + return -1; + } ++ ret = rte_power_freq_max(TEST_POWER_LCORE_ID); ++ if (ret < 0) { ++ printf("Fail to scale up the freq to max on lcore %u\n", ++ TEST_POWER_LCORE_ID); ++ return -1; ++ } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, 0); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, 0, true); + if (ret < 0) + return -1; + +@@ -410,9 +468,15 @@ check_power_turbo(void) + TEST_POWER_LCORE_ID); + return -1; + } ++ ret = rte_power_freq_max(TEST_POWER_LCORE_ID); ++ if (ret < 0) { ++ printf("Fail to scale up the freq to max on lcore %u\n", ++ TEST_POWER_LCORE_ID); ++ return -1; ++ } + + /* Check the current frequency */ +- ret = check_cur_freq(TEST_POWER_LCORE_ID, 1); ++ ret = check_cur_freq(TEST_POWER_LCORE_ID, 1, false); + if (ret < 0) + return -1; + +diff --git a/dpdk/app/test/test_prefetch.c b/dpdk/app/test/test_prefetch.c +index 41f219af78..086c6865ed 100644 +--- a/dpdk/app/test/test_prefetch.c ++++ b/dpdk/app/test/test_prefetch.c +@@ -20,7 +20,7 @@ + static int + test_prefetch(void) + { +- int a; ++ int a = 0; + + rte_prefetch0(&a); + rte_prefetch1(&a); diff --git a/dpdk/app/test/test_rcu_qsbr.c b/dpdk/app/test/test_rcu_qsbr.c index b60dc5099c..5542b3c175 100644 --- a/dpdk/app/test/test_rcu_qsbr.c @@ -10574,6 +14386,92 @@ index b60dc5099c..5542b3c175 100644 num_cores = 0; RTE_LCORE_FOREACH_SLAVE(core_id) { enabled_core_ids[num_cores] = core_id; +diff --git a/dpdk/app/test/test_reciprocal_division_perf.c b/dpdk/app/test/test_reciprocal_division_perf.c +index a7be8aa71a..4f625873e5 100644 +--- a/dpdk/app/test/test_reciprocal_division_perf.c ++++ b/dpdk/app/test/test_reciprocal_division_perf.c +@@ -71,10 +71,12 @@ test_reciprocal_division_perf(void) + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); +- printf("Cycles per division(normal) : %3.2f\n", +- ((double)tot_cyc_n)/i); +- printf("Cycles per division(reciprocal) : %3.2f\n\n", +- ((double)tot_cyc_r)/i); ++ if (i != 0) { ++ printf("Cycles per division(normal) : %3.2f\n", ++ ((double)tot_cyc_n)/i); ++ printf("Cycles per division(reciprocal) : %3.2f\n\n", ++ ((double)tot_cyc_r)/i); ++ } + + tot_cyc_n = 0; + tot_cyc_r = 0; +@@ -111,11 +113,12 @@ test_reciprocal_division_perf(void) + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); +- printf("Cycles per division(normal) : %3.2f\n", +- ((double)tot_cyc_n)/i); +- printf("Cycles per division(reciprocal) : %3.2f\n\n", +- ((double)tot_cyc_r)/i); +- ++ if (i != 0) { ++ printf("Cycles per division(normal) : %3.2f\n", ++ ((double)tot_cyc_n)/i); ++ printf("Cycles per division(reciprocal) : %3.2f\n\n", ++ ((double)tot_cyc_r)/i); ++ } + tot_cyc_n = 0; + tot_cyc_r = 0; + +@@ -152,10 +155,12 @@ test_reciprocal_division_perf(void) + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); +- printf("Cycles per division(normal) : %3.2f\n", +- ((double)tot_cyc_n)/i); +- printf("Cycles per division(reciprocal) : %3.2f\n\n", +- ((double)tot_cyc_r)/i); ++ if (i != 0) { ++ printf("Cycles per division(normal) : %3.2f\n", ++ ((double)tot_cyc_n)/i); ++ printf("Cycles per division(reciprocal) : %3.2f\n\n", ++ ((double)tot_cyc_r)/i); ++ } + + tot_cyc_n = 0; + tot_cyc_r = 0; +@@ -190,10 +195,12 @@ test_reciprocal_division_perf(void) + tot_cyc_n); + printf("Total number of cycles reciprocal division : %"PRIu64"\n", + tot_cyc_r); +- printf("Cycles per division(normal) : %3.2f\n", +- ((double)tot_cyc_n)/i); +- printf("Cycles per division(reciprocal) : %3.2f\n", +- ((double)tot_cyc_r)/i); ++ if (i != 0) { ++ printf("Cycles per division(normal) : %3.2f\n", ++ ((double)tot_cyc_n)/i); ++ printf("Cycles per division(reciprocal) : %3.2f\n", ++ ((double)tot_cyc_r)/i); ++ } + + return result; + } +diff --git a/dpdk/app/test/test_red.c b/dpdk/app/test/test_red.c +index e973f3131e..05936cfee8 100644 +--- a/dpdk/app/test/test_red.c ++++ b/dpdk/app/test/test_red.c +@@ -1049,7 +1049,7 @@ static struct test_queue ft6_tqueue = { + static struct test_config func_test6_config = { + .ifname = "functional test 6 interface", + .msg = "functional test 6 : use several queues (each with its own run-time data),\n" +- " use several RED configurations (such that each configuration is sharte_red by multiple queues),\n" ++ " use several RED configurations (such that each configuration is shared by multiple queues),\n" + " increase average queue size to target level,\n" + " dequeue all packets until queue is empty,\n" + " confirm that average queue size is computed correctly while queue is empty\n" diff --git a/dpdk/app/test/test_ring.c b/dpdk/app/test/test_ring.c index aaf1e70ad8..4825c9e2e9 100644 --- a/dpdk/app/test/test_ring.c @@ -10616,9 +14514,18 @@ index 70ee46ffe6..3cf27965de 100644 param.size = bulk_sizes[i]; param.r = r; diff --git a/dpdk/app/test/test_service_cores.c b/dpdk/app/test/test_service_cores.c -index a922c7ddcc..2a4978e29a 100644 +index a922c7ddcc..2a52c1d452 100644 --- a/dpdk/app/test/test_service_cores.c +++ b/dpdk/app/test/test_service_cores.c +@@ -66,7 +66,7 @@ static int32_t dummy_mt_unsafe_cb(void *args) + rte_delay_ms(250); + rte_atomic32_clear((rte_atomic32_t *)atomic_lock); + } else { +- /* 2nd thread will fail to take lock, so set pass flag */ ++ /* 2nd thread will fail to take lock, so clear pass flag */ + *pass_test = 0; + } + @@ -114,6 +114,7 @@ unregister_all(void) } @@ -10627,6 +14534,38 @@ index a922c7ddcc..2a4978e29a 100644 return TEST_SUCCESS; } +diff --git a/dpdk/app/test/test_stack.c b/dpdk/app/test/test_stack.c +index c8dac1f55c..fe6f1aab9c 100644 +--- a/dpdk/app/test/test_stack.c ++++ b/dpdk/app/test/test_stack.c +@@ -419,7 +419,11 @@ test_stack(void) + static int + test_lf_stack(void) + { ++#if defined(RTE_STACK_LF_SUPPORTED) + return __test_stack(RTE_STACK_F_LF); ++#else ++ return TEST_SKIPPED; ++#endif + } + + REGISTER_TEST_COMMAND(stack_autotest, test_stack); +diff --git a/dpdk/app/test/test_stack_perf.c b/dpdk/app/test/test_stack_perf.c +index 3ab7267b1b..a0c7d4d9dd 100644 +--- a/dpdk/app/test/test_stack_perf.c ++++ b/dpdk/app/test/test_stack_perf.c +@@ -349,7 +349,11 @@ test_stack_perf(void) + static int + test_lf_stack_perf(void) + { ++#if defined(RTE_STACK_LF_SUPPORTED) + return __test_stack_perf(RTE_STACK_F_LF); ++#else ++ return TEST_SKIPPED; ++#endif + } + + REGISTER_TEST_COMMAND(stack_perf_autotest, test_stack_perf); diff --git a/dpdk/app/test/test_table_pipeline.c b/dpdk/app/test/test_table_pipeline.c index 441338ac01..bc412c3081 100644 --- a/dpdk/app/test/test_table_pipeline.c @@ -10650,6 +14589,96 @@ index 441338ac01..bc412c3081 100644 } /* Check pipeline consistency */ +diff --git a/dpdk/app/test/test_table_tables.c b/dpdk/app/test/test_table_tables.c +index 1aa269f95d..494fb6ffaa 100644 +--- a/dpdk/app/test/test_table_tables.c ++++ b/dpdk/app/test/test_table_tables.c +@@ -28,7 +28,8 @@ table_test table_tests[] = { + APP_METADATA_OFFSET(0)); \ + key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \ + APP_METADATA_OFFSET(32)); \ +- memset(key, 0, 32); \ ++ if (mbuf->priv_size + mbuf->buf_len >= 64) \ ++ memset(key, 0, 32); \ + k32 = (uint32_t *) key; \ + k32[0] = (value); \ + *signature = pipeline_test_hash(key, NULL, 0, 0); \ +@@ -289,10 +290,10 @@ test_table_lpm(void) + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; +- char entry; ++ uint64_t entry; + void *entry_ptr; + int key_found; +- uint32_t entry_size = 1; ++ uint32_t entry_size = sizeof(entry); + + /* Initialize params and create tables */ + struct rte_table_lpm_params lpm_params = { +@@ -354,7 +355,7 @@ test_table_lpm(void) + struct rte_table_lpm_key lpm_key; + lpm_key.ip = 0xadadadad; + +- table = rte_table_lpm_ops.f_create(&lpm_params, 0, 1); ++ table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size); + if (table == NULL) + return -9; + +@@ -455,10 +456,10 @@ test_table_lpm_ipv6(void) + struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX]; + void *table; + char *entries[RTE_PORT_IN_BURST_SIZE_MAX]; +- char entry; ++ uint64_t entry; + void *entry_ptr; + int key_found; +- uint32_t entry_size = 1; ++ uint32_t entry_size = sizeof(entry); + + /* Initialize params and create tables */ + struct rte_table_lpm_ipv6_params lpm_params = { +diff --git a/dpdk/app/test/test_timer.c b/dpdk/app/test/test_timer.c +index 8e0a589828..ab283b1bb5 100644 +--- a/dpdk/app/test/test_timer.c ++++ b/dpdk/app/test/test_timer.c +@@ -431,7 +431,7 @@ timer_basic_cb(struct rte_timer *tim, void *arg) + return; + } + +- /* Explicitelly stop timer 0. Once stop() called, we can even ++ /* Explicitly stop timer 0. Once stop() called, we can even + * erase the content of the structure: it is not referenced + * anymore by any code (in case of dynamic structure, it can + * be freed) */ +diff --git a/dpdk/app/test/test_timer_secondary.c b/dpdk/app/test/test_timer_secondary.c +index 790f180521..a4033b6a5d 100644 +--- a/dpdk/app/test/test_timer_secondary.c ++++ b/dpdk/app/test/test_timer_secondary.c +@@ -126,9 +126,9 @@ test_timer_secondary(void) + + mz = rte_memzone_reserve(TEST_INFO_MZ_NAME, sizeof(*test_info), + SOCKET_ID_ANY, 0); +- test_info = mz->addr; +- TEST_ASSERT_NOT_NULL(test_info, "Couldn't allocate memory for " ++ TEST_ASSERT_NOT_NULL(mz, "Couldn't allocate memory for " + "test data"); ++ test_info = mz->addr; + + test_info->tim_mempool = rte_mempool_create("test_timer_mp", + NUM_TIMERS, sizeof(struct rte_timer), 0, 0, +@@ -172,9 +172,9 @@ test_timer_secondary(void) + int i; + + mz = rte_memzone_lookup(TEST_INFO_MZ_NAME); +- test_info = mz->addr; +- TEST_ASSERT_NOT_NULL(test_info, "Couldn't lookup memzone for " ++ TEST_ASSERT_NOT_NULL(mz, "Couldn't lookup memzone for " + "test info"); ++ test_info = mz->addr; + + for (i = 0; i < NUM_TIMERS; i++) { + rte_mempool_get(test_info->tim_mempool, (void **)&tim); diff --git a/dpdk/buildtools/call-sphinx-build.py b/dpdk/buildtools/call-sphinx-build.py new file mode 100755 index 0000000000..b9a3994e17 @@ -10687,6 +14716,32 @@ index 0000000000..b9a3994e17 +# create a gcc format .d file giving all the dependencies of this doc build +with open(join(dst, '.html.d'), 'w') as d: + d.write('html: ' + ' '.join(srcfiles) + '\n') +diff --git a/dpdk/buildtools/check-experimental-syms.sh b/dpdk/buildtools/check-experimental-syms.sh +index f3603e5bac..fe07dd38fd 100755 +--- a/dpdk/buildtools/check-experimental-syms.sh ++++ b/dpdk/buildtools/check-experimental-syms.sh +@@ -18,7 +18,7 @@ then + exit 0 + fi + +-DUMPFILE=$(mktemp -t dpdk.${0##*/}.XXX.objdump) ++DUMPFILE=$(mktemp -t dpdk.${0##*/}.objdump.XXXXXX) + trap 'rm -f "$DUMPFILE"' EXIT + objdump -t $OBJFILE >$DUMPFILE + +diff --git a/dpdk/buildtools/map-list-symbol.sh b/dpdk/buildtools/map-list-symbol.sh +index 5509b4a7fa..3bf9bd66f8 100755 +--- a/dpdk/buildtools/map-list-symbol.sh ++++ b/dpdk/buildtools/map-list-symbol.sh +@@ -44,7 +44,7 @@ for file in $@; do + ret = 1; + } + } +- /^.*{/ { ++ /^.*\{/ { + if ("'$section'" == "all" || $1 == "'$section'") { + current_section = $1; + } diff --git a/dpdk/buildtools/meson.build b/dpdk/buildtools/meson.build index 6ef2c5721c..ea13d9fc3f 100644 --- a/dpdk/buildtools/meson.build @@ -10735,115 +14790,27 @@ index 0f285a343b..0740a711ff 100755 + tac | + awk "/^-l:$lib.a/&&c++ {next} 1" | # drop first duplicates of main lib + tac -diff --git a/dpdk/buildtools/pkg-config/meson.build b/dpdk/buildtools/pkg-config/meson.build -new file mode 100644 -index 0000000000..39a8fd1c8e ---- /dev/null -+++ b/dpdk/buildtools/pkg-config/meson.build -@@ -0,0 +1,59 @@ -+# SPDX-License-Identifier: BSD-3-Clause -+# Copyright(c) 2020 Intel Corporation -+ -+pkg = import('pkgconfig') -+pkg_extra_cflags = ['-include', 'rte_config.h'] + machine_args -+if is_freebsd -+ pkg_extra_cflags += ['-D__BSD_VISIBLE'] -+endif -+ -+# When calling pkg-config --static --libs, pkg-config will always output the -+# regular libs first, and then the extra libs from Libs.private field, -+# since the assumption is that those are additional dependencies for building -+# statically that the .a files depend upon. The output order of .pc fields is: -+# Libs Libs.private Requires Requires.private -+# The fields Requires* are for package names. -+# The flags of the DPDK libraries must be defined in Libs* fields. -+# However, the DPDK drivers are linked only in static builds (Libs.private), -+# and those need to come *before* the regular libraries (Libs field). -+# This requirement is satisfied by moving the regular libs in a separate file -+# included in the field Requires (after Libs.private). -+# Another requirement is to allow linking dependencies as shared libraries, -+# while linking static DPDK libraries and drivers. It is satisfied by -+# listing the static files in Libs.private with the explicit syntax -l:libfoo.a. -+# As a consequence, the regular DPDK libraries are already listed as static -+# in the field Libs.private. The second occurences of DPDK libraries, -+# included from Requires and used for shared library linkage case, -+# are skipped in the case of static linkage thanks to the flag --as-needed. -+ -+ -+pkg.generate(name: 'dpdk-libs', -+ filebase: 'libdpdk-libs', -+ description: '''Internal-only DPDK pkgconfig file. Not for direct use. -+Use libdpdk.pc instead of this file to query DPDK compile/link arguments''', -+ version: meson.project_version(), -+ subdirs: [get_option('include_subdir_arch'), '.'], -+ extra_cflags: pkg_extra_cflags, -+ libraries: ['-Wl,--as-needed'] + dpdk_libraries, -+ libraries_private: dpdk_extra_ldflags) -+ -+platform_flags = [] -+if not is_windows -+ platform_flags += ['-Wl,--export-dynamic'] # ELF only -+endif -+pkg.generate(name: 'DPDK', # main DPDK pkgconfig file -+ filebase: 'libdpdk', -+ version: meson.project_version(), -+ description: '''The Data Plane Development Kit (DPDK). -+Note that CFLAGS might contain an -march flag higher than typical baseline. -+This is required for a number of static inline functions in the public headers.''', -+ requires: ['libdpdk-libs', libbsd], # may need libbsd for string funcs -+ # if libbsd is not enabled, then this is blank -+ libraries_private: ['-Wl,--whole-archive'] + -+ dpdk_drivers + dpdk_static_libraries + -+ ['-Wl,--no-whole-archive'] + platform_flags -+) -+ -+# For static linking with dependencies as shared libraries, -+# the internal static libraries must be flagged explicitly. -+run_command(py3, 'set-static-linker-flags.py', check: true) -diff --git a/dpdk/buildtools/pkg-config/set-static-linker-flags.py b/dpdk/buildtools/pkg-config/set-static-linker-flags.py -new file mode 100644 -index 0000000000..2745db34c2 ---- /dev/null -+++ b/dpdk/buildtools/pkg-config/set-static-linker-flags.py -@@ -0,0 +1,38 @@ -+#!/usr/bin/env python3 -+# SPDX-License-Identifier: BSD-3-Clause -+# Copyright(c) 2020 Intel Corporation -+ -+# Script to fix flags for static linking in pkgconfig files from meson -+# Should be called from meson build itself -+import os -+import sys -+ -+ -+def fix_ldflag(f): -+ if not f.startswith('-lrte_'): -+ return f -+ return '-l:lib' + f[2:] + '.a' -+ -+ -+def fix_libs_private(line): -+ if not line.startswith('Libs.private'): -+ return line -+ ldflags = [fix_ldflag(flag) for flag in line.split()] -+ return ' '.join(ldflags) + '\n' -+ -+ -+def process_pc_file(filepath): -+ print('Processing', filepath) -+ with open(filepath) as src: -+ lines = src.readlines() -+ with open(filepath, 'w') as dst: -+ dst.writelines([fix_libs_private(line) for line in lines]) -+ -+ -+if 'MESON_BUILD_ROOT' not in os.environ: -+ print('This script must be called from a meson build environment') -+ sys.exit(1) -+for root, dirs, files in os.walk(os.environ['MESON_BUILD_ROOT']): -+ pc_files = [f for f in files if f.endswith('.pc')] -+ for f in pc_files: -+ process_pc_file(os.path.join(root, f)) +diff --git a/dpdk/buildtools/pmdinfogen/pmdinfogen.c b/dpdk/buildtools/pmdinfogen/pmdinfogen.c +index dc0b6d5ff4..e7214c1b4f 100644 +--- a/dpdk/buildtools/pmdinfogen/pmdinfogen.c ++++ b/dpdk/buildtools/pmdinfogen/pmdinfogen.c +@@ -431,7 +431,7 @@ static void output_pmd_info_string(struct elf_info *info, char *outfile) + + int main(int argc, char **argv) + { +- struct elf_info info = {0}; ++ struct elf_info info; + int rc = 1; + + if (argc < 3) { +@@ -440,6 +440,7 @@ int main(int argc, char **argv) + basename(argv[0])); + exit(127); + } ++ memset(&info, 0, sizeof(struct elf_info)); + use_stdin = !strcmp(argv[1], "-"); + use_stdout = !strcmp(argv[2], "-"); + parse_elf(&info, argv[1]); diff --git a/dpdk/buildtools/pmdinfogen/pmdinfogen.h b/dpdk/buildtools/pmdinfogen/pmdinfogen.h index c8a9e2136a..467216d12b 100644 --- a/dpdk/buildtools/pmdinfogen/pmdinfogen.h @@ -10857,6 +14824,127 @@ index c8a9e2136a..467216d12b 100644 }) #define TO_NATIVE(fend, width, x) CONVERT_NATIVE(fend, width, x) +diff --git a/dpdk/config/arm/arm64_armada_linux_gcc b/dpdk/config/arm/arm64_armada_linux_gcc +index fa40c0398f..d78c99e8e8 100644 +--- a/dpdk/config/arm/arm64_armada_linux_gcc ++++ b/dpdk/config/arm/arm64_armada_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-ar' + as = 'aarch64-linux-gnu-as' + strip = 'aarch64-linux-gnu-strip' +diff --git a/dpdk/config/arm/arm64_armv8_linux_gcc b/dpdk/config/arm/arm64_armv8_linux_gcc +index 88f0ff9dae..057d70bbdd 100644 +--- a/dpdk/config/arm/arm64_armv8_linux_gcc ++++ b/dpdk/config/arm/arm64_armv8_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_bluefield_linux_gcc b/dpdk/config/arm/arm64_bluefield_linux_gcc +index 86797d23cd..616e633495 100644 +--- a/dpdk/config/arm/arm64_bluefield_linux_gcc ++++ b/dpdk/config/arm/arm64_bluefield_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_dpaa_linux_gcc b/dpdk/config/arm/arm64_dpaa_linux_gcc +index 1a46821543..0108bb952a 100644 +--- a/dpdk/config/arm/arm64_dpaa_linux_gcc ++++ b/dpdk/config/arm/arm64_dpaa_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-ar' + as = 'aarch64-linux-gnu-as' + strip = 'aarch64-linux-gnu-strip' +diff --git a/dpdk/config/arm/arm64_emag_linux_gcc b/dpdk/config/arm/arm64_emag_linux_gcc +index 8edcd3e976..3bb5134224 100644 +--- a/dpdk/config/arm/arm64_emag_linux_gcc ++++ b/dpdk/config/arm/arm64_emag_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_n1sdp_linux_gcc b/dpdk/config/arm/arm64_n1sdp_linux_gcc +index 022e063039..421d06c77f 100644 +--- a/dpdk/config/arm/arm64_n1sdp_linux_gcc ++++ b/dpdk/config/arm/arm64_n1sdp_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_octeontx2_linux_gcc b/dpdk/config/arm/arm64_octeontx2_linux_gcc +index 365bd7cbdd..0d7a66c97e 100644 +--- a/dpdk/config/arm/arm64_octeontx2_linux_gcc ++++ b/dpdk/config/arm/arm64_octeontx2_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_thunderx2_linux_gcc b/dpdk/config/arm/arm64_thunderx2_linux_gcc +index 2b41acc615..24346ffe71 100644 +--- a/dpdk/config/arm/arm64_thunderx2_linux_gcc ++++ b/dpdk/config/arm/arm64_thunderx2_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/arm64_thunderx_linux_gcc b/dpdk/config/arm/arm64_thunderx_linux_gcc +index 6572ab615d..cbf60bac73 100644 +--- a/dpdk/config/arm/arm64_thunderx_linux_gcc ++++ b/dpdk/config/arm/arm64_thunderx_linux_gcc +@@ -1,6 +1,6 @@ + [binaries] + c = 'aarch64-linux-gnu-gcc' +-cpp = 'aarch64-linux-gnu-cpp' ++cpp = 'aarch64-linux-gnu-g++' + ar = 'aarch64-linux-gnu-gcc-ar' + strip = 'aarch64-linux-gnu-strip' + pkgconfig = 'aarch64-linux-gnu-pkg-config' +diff --git a/dpdk/config/arm/meson.build b/dpdk/config/arm/meson.build +index 60f7b05396..dceea336dd 100644 +--- a/dpdk/config/arm/meson.build ++++ b/dpdk/config/arm/meson.build +@@ -152,7 +152,7 @@ else + # 'Primary Part number', 'Revision'] + detect_vendor = find_program(join_paths( + meson.current_source_dir(), 'armv8_machine.py')) +- cmd = run_command(detect_vendor.path()) ++ cmd = run_command(detect_vendor.path(), check: false) + if cmd.returncode() == 0 + cmd_output = cmd.stdout().to_lower().strip().split(' ') + endif diff --git a/dpdk/config/common_base b/dpdk/config/common_base index 7dec7ed457..3406146372 100644 --- a/dpdk/config/common_base @@ -10934,10 +15022,10 @@ index 0000000000..80ac94d54d +defconfig_arm64-graviton2-linuxapp-gcc \ No newline at end of file diff --git a/dpdk/config/meson.build b/dpdk/config/meson.build -index 364a8d7394..b1f728ee86 100644 +index 364a8d7394..4b03746889 100644 --- a/dpdk/config/meson.build +++ b/dpdk/config/meson.build -@@ -14,6 +14,10 @@ foreach env:supported_exec_envs +@@ -14,12 +14,16 @@ foreach env:supported_exec_envs set_variable('is_' + env, exec_env == env) endforeach @@ -10948,6 +15036,14 @@ index 364a8d7394..b1f728ee86 100644 # set the major version, which might be used by drivers and libraries # depending on the configuration options pver = meson.project_version().split('.') + major_version = '@0@.@1@'.format(pver.get(0), pver.get(1)) +-abi_version = run_command(find_program('cat', 'more'), +- abi_version_file).stdout().strip() ++abi_version = run_command(find_program('cat', 'more'), abi_version_file, ++ check: true).stdout().strip() + # experimental libraries are versioned as 0.majorminor versions, e.g. 0.201 + ever = abi_version.split('.') + experimental_abi_version = '0.@0@@1@'.format(ever.get(0), ever.get(1)) @@ -50,9 +54,11 @@ eal_pmd_path = join_paths(get_option('prefix'), driver_install_path) # driver .so files often depend upon the bus drivers for their connect bus, # e.g. ixgbe depends on librte_bus_pci. This means that the bus drivers need @@ -10963,7 +15059,7 @@ index 364a8d7394..b1f728ee86 100644 # set the machine type and cflags for it if meson.is_cross_build() -@@ -98,14 +104,18 @@ dpdk_conf.set('RTE_TOOLCHAIN_' + toolchain.to_upper(), 1) +@@ -98,24 +104,25 @@ dpdk_conf.set('RTE_TOOLCHAIN_' + toolchain.to_upper(), 1) dpdk_conf.set('RTE_ARCH_64', cc.sizeof('void *') == 8) @@ -10987,10 +15083,28 @@ index 364a8d7394..b1f728ee86 100644 # some libs depend on maths lib add_project_link_arguments('-lm', language: 'c') dpdk_extra_ldflags += '-lm' -@@ -136,18 +146,25 @@ if numa_dep.found() and cc.has_header('numaif.h') + endif + +-# for linux link against dl, for bsd execinfo + if is_linux + link_lib = 'dl' +-elif is_freebsd +- link_lib = 'execinfo' + else + link_lib = '' + endif +@@ -136,18 +143,39 @@ if numa_dep.found() and cc.has_header('numaif.h') dpdk_extra_ldflags += '-lnuma' endif ++# Some false positives can trigger at LTO stage, so this warning needs to be ++# disabled on the linker as well for gcc 10. ++# Fixed in gcc-11 and not present =10.0') and cc.version().version_compare('<11.0') ++ add_project_link_arguments('-Wno-stringop-overflow', language: 'c') ++endif ++ +has_libfdt = 0 +fdt_dep = cc.find_library('libfdt', required: false) +if fdt_dep.found() and cc.has_header('fdt.h') @@ -11000,6 +15114,12 @@ index 364a8d7394..b1f728ee86 100644 + dpdk_extra_ldflags += '-lfdt' +endif + ++libexecinfo = cc.find_library('libexecinfo', required: false) ++if libexecinfo.found() and cc.has_header('execinfo.h') ++ add_project_link_arguments('-lexecinfo', language: 'c') ++ dpdk_extra_ldflags += '-lexecinfo' ++endif ++ # check for libbsd -libbsd = dependency('libbsd', required: false) +libbsd = dependency('libbsd', required: false, method: 'pkg-config') @@ -11019,7 +15139,16 @@ index 364a8d7394..b1f728ee86 100644 pcap_dep = cc.find_library('pcap', required: false) endif if pcap_dep.found() and cc.has_header('pcap.h', dependencies: pcap_dep) -@@ -166,6 +183,7 @@ warning_flags = [ +@@ -159,13 +187,13 @@ endif + add_project_arguments('-include', 'rte_config.h', language: 'c') + + # enable extra warnings and disable any unwanted warnings ++# -Wall is added by default at warning level 1, and -Wextra ++# at warning level 2 (DPDK default) + warning_flags = [ +- # -Wall is added by meson by default, so add -Wextra only +- '-Wextra', +- # additional warnings in alphabetical order '-Wcast-qual', '-Wdeprecated', @@ -11027,7 +15156,7 @@ index 364a8d7394..b1f728ee86 100644 '-Wformat-nonliteral', '-Wformat-security', '-Wmissing-declarations', -@@ -183,6 +201,10 @@ warning_flags = [ +@@ -183,6 +211,10 @@ warning_flags = [ '-Wno-packed-not-aligned', '-Wno-missing-field-initializers' ] @@ -11038,7 +15167,7 @@ index 364a8d7394..b1f728ee86 100644 if not dpdk_conf.get('RTE_ARCH_64') # for 32-bit, don't warn about casting a 32-bit pointer to 64-bit int - it's fine!! warning_flags += '-Wno-pointer-to-int-cast' -@@ -202,6 +224,11 @@ dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet')) +@@ -202,6 +234,11 @@ dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet')) dpdk_conf.set('RTE_MAX_VFIO_GROUPS', 64) dpdk_conf.set('RTE_DRIVER_MEMPOOL_BUCKET_SIZE_KB', 64) dpdk_conf.set('RTE_LIBRTE_DPAA2_USE_PHYS_IOVA', true) @@ -11050,7 +15179,7 @@ index 364a8d7394..b1f728ee86 100644 compile_time_cpuflags = [] -@@ -231,6 +258,16 @@ if is_freebsd +@@ -231,6 +268,16 @@ if is_freebsd add_project_arguments('-D__BSD_VISIBLE', language: 'c') endif @@ -11067,7 +15196,7 @@ index 364a8d7394..b1f728ee86 100644 if get_option('b_lto') if cc.has_argument('-ffat-lto-objects') add_project_arguments('-ffat-lto-objects', language: 'c') -@@ -243,3 +280,12 @@ if get_option('b_lto') +@@ -243,3 +290,12 @@ if get_option('b_lto') add_project_link_arguments('-Wno-lto-type-mismatch', language: 'c') endif endif @@ -11080,6 +15209,48 @@ index 364a8d7394..b1f728ee86 100644 + "default_library" to either "static" or "shared" to select default linkage + for apps and any examples.''') +endif +diff --git a/dpdk/config/ppc_64/meson.build b/dpdk/config/ppc_64/meson.build +index aa7d73d114..aed37a6b59 100644 +--- a/dpdk/config/ppc_64/meson.build ++++ b/dpdk/config/ppc_64/meson.build +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: BSD-3-Clause + # Copyright(c) 2018 Luca Boccassi ++# Copyright(c) 2021 IBM Corporation + + if not dpdk_conf.get('RTE_ARCH_64') + error('Only 64-bit compiles are supported for this platform type') +@@ -17,9 +18,27 @@ if not power9_supported + dpdk_conf.set('RTE_MACHINE','power8') + endif + +-# overrides specific to ppc64 +-dpdk_conf.set('RTE_MAX_LCORE', 1536) +-dpdk_conf.set('RTE_MAX_NUMA_NODES', 32) ++# Suppress the gcc warning "note: the layout of aggregates containing ++# vectors with 4-byte alignment has changed in GCC 5". ++if (cc.get_id() == 'gcc' and cc.version().version_compare('>=10.0') and ++ cc.version().version_compare('<12.0') and cc.has_argument('-Wno-psabi')) ++ add_project_arguments('-Wno-psabi', language: 'c') ++endif ++ ++# Certain POWER9 systems can scale as high as 1536 LCORES, but setting such a ++# high value can waste memory, cause timeouts in time limited autotests, and is ++# unlikely to be used in many production situations. Similarly, keeping the ++# default 64 LCORES seems too small as most POWER9 dual socket systems will have ++# at least 128 LCORES available. Set RTE_MAX_LCORE to 128 for POWER systems as ++# a compromise. ++dpdk_conf.set('RTE_MAX_LCORE', 128) ++ ++# POWER systems do not allocate NUMA nodes sequentially. A dual socket system ++# will have CPUs associated with NUMA nodes 0 & 8, so ensure that the second ++# NUMA node will be supported by setting RTE_MAX_NUMA_NODES to 16. High end ++# systems can scale even higher with as many as 32 NUMA nodes. ++dpdk_conf.set('RTE_MAX_NUMA_NODES', 16) ++ + dpdk_conf.set('RTE_CACHE_LINE_SIZE', 128) + dpdk_conf.set('RTE_MACHINE_CPUFLAG_ALTIVEC', 1) + dpdk_conf.set('RTE_MACHINE_CPUFLAG_VSX', 1) diff --git a/dpdk/config/rte_config.h b/dpdk/config/rte_config.h index d30786bc08..8ec0a58f19 100644 --- a/dpdk/config/rte_config.h @@ -11112,9 +15283,18 @@ index d30786bc08..8ec0a58f19 100644 /* Max. number of QuickAssist devices which can be attached */ #define RTE_PMD_QAT_MAX_PCI_DEVICES 48 diff --git a/dpdk/config/x86/meson.build b/dpdk/config/x86/meson.build -index 8b0fa3e6f1..adc857ba28 100644 +index 8b0fa3e6f1..855a7d0edd 100644 --- a/dpdk/config/x86/meson.build +++ b/dpdk/config/x86/meson.build +@@ -3,7 +3,7 @@ + + # get binutils version for the workaround of Bug 97 + if not is_windows +- ldver = run_command('ld', '-v').stdout().strip() ++ ldver = run_command('ld', '-v', check: true).stdout().strip() + if ldver.contains('2.30') and cc.has_argument('-mno-avx512f') + machine_args += '-mno-avx512f' + message('Binutils 2.30 detected, disabling AVX512 support as workaround for bug #97') @@ -15,11 +15,9 @@ if not is_windows endif @@ -11130,10 +15310,20 @@ index 8b0fa3e6f1..adc857ba28 100644 base_flags = ['SSE', 'SSE2', 'SSE3','SSSE3', 'SSE4_1', 'SSE4_2'] diff --git a/dpdk/devtools/check-forbidden-tokens.awk b/dpdk/devtools/check-forbidden-tokens.awk -index 8c89de3d4e..61ba707c9b 100755 +index 8c89de3d4e..026844141c 100755 --- a/dpdk/devtools/check-forbidden-tokens.awk +++ b/dpdk/devtools/check-forbidden-tokens.awk -@@ -54,7 +54,7 @@ BEGIN { +@@ -20,6 +20,9 @@ BEGIN { + # state machine assumes the comments structure is enforced by + # checkpatches.pl + (in_file) { ++ if ($0 ~ "^@@") { ++ in_comment = 0 ++ } + # comment start + if (index($0,comment_start) > 0) { + in_comment = 1 +@@ -54,7 +57,7 @@ BEGIN { } for (i in deny_folders) { re = "^\\+\\+\\+ b/" deny_folders[i]; @@ -11142,7 +15332,7 @@ index 8c89de3d4e..61ba707c9b 100755 in_file = 1 last_file = $0 } -@@ -62,7 +62,7 @@ BEGIN { +@@ -62,7 +65,7 @@ BEGIN { } END { if (count > 0) { @@ -11151,6 +15341,23 @@ index 8c89de3d4e..61ba707c9b 100755 print MESSAGE exit RET_ON_FAIL } +diff --git a/dpdk/devtools/check-maintainers.sh b/dpdk/devtools/check-maintainers.sh +index 85a300f0a0..49d38fbf13 100755 +--- a/dpdk/devtools/check-maintainers.sh ++++ b/dpdk/devtools/check-maintainers.sh +@@ -15,10 +15,10 @@ files () # [ ...] + if [ -z "$1" ] ; then + return + fi +- if [ -d .git ] ; then ++ if [ -r .git ] ; then + git ls-files "$1" + else +- find "$1" -type f | ++ find $1 -type f | + sed 's,^\./,,' + fi | + # if not ended by / diff --git a/dpdk/devtools/check-symbol-change.sh b/dpdk/devtools/check-symbol-change.sh index c5434f3bb0..ed2178e36e 100755 --- a/dpdk/devtools/check-symbol-change.sh @@ -11283,7 +15490,7 @@ index be565a1bea..52305fbb8c 100755 # Automatic configuration diff --git a/dpdk/devtools/test-meson-builds.sh b/dpdk/devtools/test-meson-builds.sh -index 688567714b..8678a3d824 100755 +index 688567714b..47fdb9dfb5 100755 --- a/dpdk/devtools/test-meson-builds.sh +++ b/dpdk/devtools/test-meson-builds.sh @@ -38,20 +38,21 @@ else @@ -11311,7 +15518,7 @@ index 688567714b..8678a3d824 100755 command -v $targetcc >/dev/null 2>&1 || return 1 DPDK_TARGET=$($targetcc -v 2>&1 | sed -n 's,^Target: ,,p') . $srcdir/devtools/load-devel-config -@@ -134,19 +135,17 @@ done +@@ -134,14 +135,12 @@ done # Test installation of the x86-default target, to be used for checking # the sample apps build using the pkg-config file for cflags and libs @@ -11327,12 +15534,19 @@ index 688567714b..8678a3d824 100755 # if pkg-config defines the necessary flags, test building some examples if pkg-config --define-prefix libdpdk >/dev/null 2>&1; then export PKGCONF="pkg-config --define-prefix" - for example in cmdline helloworld l2fwd l3fwd skeleton timer; do - echo "## Building $example" -- $MAKE -C $DESTDIR/usr/local/share/dpdk/examples/$example clean all -+ $MAKE -C $DESTDIR/usr/local/share/dpdk/examples/$example clean shared static - done +diff --git a/dpdk/devtools/test-null.sh b/dpdk/devtools/test-null.sh +index f39af2c064..6d763bc94f 100755 +--- a/dpdk/devtools/test-null.sh ++++ b/dpdk/devtools/test-null.sh +@@ -27,6 +27,7 @@ else fi + + (sleep 1 && echo stop) | +-$testpmd -c $coremask --no-huge -m 20 \ ++# testpmd only needs 20M, make it x2 (default number of cores) for NUMA systems ++$testpmd -c $coremask --no-huge -m 40 \ + $libs -w 0:0.0 --vdev net_null1 --vdev net_null2 $eal_options -- \ + --no-mlockall --total-num-mbufs=2048 $testpmd_options -ia diff --git a/dpdk/doc/api/doxy-api-index.md b/dpdk/doc/api/doxy-api-index.md index dff496be09..5568dbc616 100644 --- a/dpdk/doc/api/doxy-api-index.md @@ -11379,11 +15593,26 @@ index 1c4392eecc..12f0a26a90 100644 INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/drivers/bus/vdev \ @TOPDIR@/drivers/crypto/scheduler \ +diff --git a/dpdk/doc/api/generate_examples.sh b/dpdk/doc/api/generate_examples.sh +index 6fcfe513b6..dae7ee0be0 100755 +--- a/dpdk/doc/api/generate_examples.sh ++++ b/dpdk/doc/api/generate_examples.sh +@@ -5,6 +5,10 @@ + EXAMPLES_DIR=$1 + API_EXAMPLES=$2 + ++# generate a .d file including both C files and also build files, so we can ++# detect both file changes and file additions/deletions ++echo "$API_EXAMPLES: $(find ${EXAMPLES_DIR} -type f \( -name '*.c' -o -name 'meson.build' \) -printf '%p ' )" > ${API_EXAMPLES}.d ++ + exec > "${API_EXAMPLES}" + printf '/**\n' + printf '@page examples DPDK Example Programs\n\n' diff --git a/dpdk/doc/api/meson.build b/dpdk/doc/api/meson.build -index 1c48b7672e..c72b880e10 100644 +index 1c48b7672e..72f522627d 100644 --- a/dpdk/doc/api/meson.build +++ b/dpdk/doc/api/meson.build -@@ -3,53 +3,54 @@ +@@ -3,53 +3,53 @@ doxygen = find_program('doxygen', required: get_option('enable_docs')) @@ -11448,7 +15677,6 @@ index 1c48b7672e..c72b880e10 100644 +generate_examples = find_program('generate_examples.sh') +generate_css = find_program('doxy-html-custom.sh') + -+inputdir = join_paths(meson.source_root(), 'examples') +htmldir = join_paths('share', 'doc', 'dpdk') + +# due to the following bug: https://github.com/mesonbuild/meson/issues/4107 @@ -11457,20 +15685,20 @@ index 1c48b7672e..c72b880e10 100644 +# false it would be impossible to install the docs. +# So use a configure option for now. +example = custom_target('examples.dox', -+ input: inputdir, + output: 'examples.dox', -+ command: [generate_examples, '@INPUT@', '@OUTPUT@'], ++ command: [generate_examples, join_paths(dpdk_source_root, 'examples'), '@OUTPUT@'], ++ depfile: 'examples.dox.d', + install: get_option('enable_docs'), + install_dir: htmldir, + build_by_default: get_option('enable_docs')) + +cdata = configuration_data() +cdata.set('VERSION', meson.project_version()) -+cdata.set('API_EXAMPLES', join_paths(meson.build_root(), 'doc', 'api', 'examples.dox')) -+cdata.set('OUTPUT', join_paths(meson.build_root(), 'doc', 'api')) ++cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api', 'examples.dox')) ++cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api')) +cdata.set('HTML_OUTPUT', 'api') -+cdata.set('TOPDIR', meson.source_root()) -+cdata.set('STRIP_FROM_PATH', meson.source_root()) ++cdata.set('TOPDIR', dpdk_source_root) ++cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, join_paths(dpdk_build_root, 'doc', 'api')])) + +doxy_conf = configure_file(input: 'doxy-api.conf.in', + output: 'doxy-api.conf', @@ -11488,7 +15716,7 @@ index 1c48b7672e..c72b880e10 100644 +doc_targets += doxy_build +doc_target_names += 'Doxygen_API' diff --git a/dpdk/doc/build-sdk-meson.txt b/dpdk/doc/build-sdk-meson.txt -index fc7fe37b54..8fb60a7c11 100644 +index fc7fe37b54..61c8e3515c 100644 --- a/dpdk/doc/build-sdk-meson.txt +++ b/dpdk/doc/build-sdk-meson.txt @@ -1,3 +1,6 @@ @@ -11538,15 +15766,32 @@ index fc7fe37b54..8fb60a7c11 100644 Performing the Build -@@ -182,7 +190,7 @@ From examples/helloworld/Makefile:: - PC_FILE := $(shell pkg-config --path libdpdk) - CFLAGS += -O3 $(shell pkg-config --cflags libdpdk) - LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk) -- LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk) -+ LDFLAGS_STATIC = $(shell pkg-config --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) +diff --git a/dpdk/doc/guides/bbdevs/fpga_lte_fec.rst b/dpdk/doc/guides/bbdevs/fpga_lte_fec.rst +index 206b6f4f9b..8509de934f 100644 +--- a/dpdk/doc/guides/bbdevs/fpga_lte_fec.rst ++++ b/dpdk/doc/guides/bbdevs/fpga_lte_fec.rst +@@ -50,7 +50,7 @@ FPGA LTE FEC does not support the following: + Installation + -------------- + +-Section 3 of the DPDK manual provides instuctions on installing and compiling DPDK. The ++Section 3 of the DPDK manual provides instructions on installing and compiling DPDK. The + default set of bbdev compile flags may be found in config/common_base, where for example + the flag to build the FPGA LTE FEC device, ``CONFIG_RTE_LIBRTE_PMD_BBDEV_FPGA_LTE_FEC``, is already + set. It is assumed DPDK has been compiled using for instance: +diff --git a/dpdk/doc/guides/bbdevs/turbo_sw.rst b/dpdk/doc/guides/bbdevs/turbo_sw.rst +index 20620c2e20..c74be1286d 100644 +--- a/dpdk/doc/guides/bbdevs/turbo_sw.rst ++++ b/dpdk/doc/guides/bbdevs/turbo_sw.rst +@@ -156,7 +156,7 @@ Example: + the SDK libraries as mentioned above. + For AVX2 machine it is possible to only enable CONFIG_RTE_BBDEV_SDK_AVX2 + for limited 4G functionality. +- If no flag are set the PMD driver will still build but its capabilities ++ If no flag are set the PMD will still build but its capabilities + will be limited accordingly. + + To use the PMD in an application, user must: diff --git a/dpdk/doc/guides/compressdevs/qat_comp.rst b/dpdk/doc/guides/compressdevs/qat_comp.rst index 6421f767c4..757611a30c 100644 --- a/dpdk/doc/guides/compressdevs/qat_comp.rst @@ -11564,10 +15809,30 @@ index 6421f767c4..757611a30c 100644 * When using Deflate dynamic huffman encoding for compression, the input size (op.src.length) must be < CONFIG_RTE_PMD_QAT_COMP_IM_BUFFER_SIZE from the config file, diff --git a/dpdk/doc/guides/conf.py b/dpdk/doc/guides/conf.py -index e2b52e2df9..c1a82be95b 100644 +index e2b52e2df9..279b830d7b 100644 --- a/dpdk/doc/guides/conf.py +++ b/dpdk/doc/guides/conf.py -@@ -237,7 +237,7 @@ def generate_overview_table(output_filename, table_id, section, table_name, titl +@@ -25,7 +25,6 @@ + import sphinx_rtd_theme + + html_theme = "sphinx_rtd_theme" +- html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + except: + print('Install the sphinx ReadTheDocs theme for improved html documentation ' + 'layout: pip install sphinx_rtd_theme') +@@ -34,7 +33,10 @@ + project = 'Data Plane Development Kit' + html_logo = '../logo/DPDK_logo_vertical_rev_small.png' + latex_logo = '../logo/DPDK_logo_horizontal_tag.png' +-html_add_permalinks = "" ++if LooseVersion(sphinx_version) >= LooseVersion('3.5'): ++ html_permalinks = False ++else: ++ html_add_permalinks = "" + html_show_copyright = False + highlight_language = 'none' + +@@ -237,7 +239,7 @@ def generate_overview_table(output_filename, table_id, section, table_name, titl ini_filename)) continue @@ -11576,7 +15841,7 @@ index e2b52e2df9..c1a82be95b 100644 # Get the first letter only. ini_data[ini_filename][name] = value[0] -@@ -314,16 +314,22 @@ def print_table_css(outfile, table_id): +@@ -314,16 +316,22 @@ def print_table_css(outfile, table_id): cursor: default; overflow: hidden; } @@ -11602,7 +15867,7 @@ index e2b52e2df9..c1a82be95b 100644 } table#idx col:first-child { width: 0; -@@ -332,9 +338,11 @@ def print_table_css(outfile, table_id): +@@ -332,9 +340,11 @@ def print_table_css(outfile, table_id): vertical-align: bottom; } table#idx td { @@ -11615,7 +15880,7 @@ index e2b52e2df9..c1a82be95b 100644 table#idx td:first-child { padding-left: 1em; text-align: left; -@@ -410,4 +418,8 @@ def setup(app): +@@ -410,4 +420,8 @@ def setup(app): # Process the numref references once the doctree has been created. app.connect('doctree-resolved', process_numref) @@ -11900,6 +16165,19 @@ index a21f4e7a41..ea9d99606b 100644 .. _deprecating_entire_abi: +diff --git a/dpdk/doc/guides/contributing/coding_style.rst b/dpdk/doc/guides/contributing/coding_style.rst +index 841ef6d5c8..95e2d4c22c 100644 +--- a/dpdk/doc/guides/contributing/coding_style.rst ++++ b/dpdk/doc/guides/contributing/coding_style.rst +@@ -591,7 +591,7 @@ Return Value + ~~~~~~~~~~~~ + + * Functions which create objects, or allocate memory, should return pointer types, and NULL on error. +- The error type should be indicated may setting the variable ``rte_errno`` appropriately. ++ The error type should be indicated by setting the variable ``rte_errno`` appropriately. + * Functions which work on bursts of packets, such as RX-like or TX-like functions, should return the number of packets handled. + * Other functions returning int should generally behave like system calls: + returning 0 on success and -1 on error, setting ``rte_errno`` to indicate the specific type of error. diff --git a/dpdk/doc/guides/contributing/documentation.rst b/dpdk/doc/guides/contributing/documentation.rst index 27e4b13be1..3924771cf0 100644 --- a/dpdk/doc/guides/contributing/documentation.rst @@ -12011,7 +16289,7 @@ index 0686450e45..5ca037757e 100644 Once submitted your patches will appear on the mailing list and in Patchwork. diff --git a/dpdk/doc/guides/contributing/stable.rst b/dpdk/doc/guides/contributing/stable.rst -index 4d38bb8606..021c762fc6 100644 +index 4d38bb8606..40f42801f6 100644 --- a/dpdk/doc/guides/contributing/stable.rst +++ b/dpdk/doc/guides/contributing/stable.rst @@ -51,7 +51,7 @@ agreement and a commitment from a maintainer. The current policy is that each @@ -12023,6 +16301,15 @@ index 4d38bb8606..021c762fc6 100644 A LTS release may align with the declaration of a new major ABI version, please read the :doc:`abi_policy` for more information. +@@ -95,7 +95,7 @@ Features should not be backported to stable releases. It may be acceptable, in + limited cases, to back port features for the LTS release where: + + * There is a justifiable use case (for example a new PMD). +-* The change is non-invasive. ++* The change is noninvasive. + * The work of preparing the backport is done by the proposer. + * There is support within the community. + @@ -107,7 +107,7 @@ The Stable and LTS release are coordinated on the stable@dpdk.org mailing list. @@ -12117,6 +16404,32 @@ index 5d8fb46efe..ca6c169858 100644 As a reference, the following table shows a mapping between the past DPDK versions and the Multi-Buffer library version supported by them: +diff --git a/dpdk/doc/guides/cryptodevs/caam_jr.rst b/dpdk/doc/guides/cryptodevs/caam_jr.rst +index 6d9daf7364..4ee0100247 100644 +--- a/dpdk/doc/guides/cryptodevs/caam_jr.rst ++++ b/dpdk/doc/guides/cryptodevs/caam_jr.rst +@@ -24,7 +24,7 @@ accelerators. This provides significant improvement to system level performance. + + SEC HW accelerator above 4.x+ version are also known as CAAM. + +-caam_jr PMD is one of DPAA drivers which uses uio interface to interact with ++caam_jr PMD is one of DPAA drivers which uses UIO interface to interact with + Linux kernel for configure and destroy the device instance (ring). + + +diff --git a/dpdk/doc/guides/cryptodevs/ccp.rst b/dpdk/doc/guides/cryptodevs/ccp.rst +index a43fe92de9..b2f786f7a2 100644 +--- a/dpdk/doc/guides/cryptodevs/ccp.rst ++++ b/dpdk/doc/guides/cryptodevs/ccp.rst +@@ -105,7 +105,7 @@ The following parameters (all optional) can be provided in the previous two call + + * ccp_auth_opt: Specify authentication operations to perform on CPU using openssl APIs. + +-To validate ccp pmd, l2fwd-crypto example can be used with following command: ++To validate ccp PMD, l2fwd-crypto example can be used with following command: + + .. code-block:: console + diff --git a/dpdk/doc/guides/cryptodevs/features/kasumi.ini b/dpdk/doc/guides/cryptodevs/features/kasumi.ini index f3d061009b..7ee866e8f4 100644 --- a/dpdk/doc/guides/cryptodevs/features/kasumi.ini @@ -12197,6 +16510,32 @@ index 9b6a4287e8..29cc258aae 100644 ; ; Supported crypto algorithms of the 'zuc' crypto driver. +diff --git a/dpdk/doc/guides/cryptodevs/openssl.rst b/dpdk/doc/guides/cryptodevs/openssl.rst +index 7407294813..360c49851a 100644 +--- a/dpdk/doc/guides/cryptodevs/openssl.rst ++++ b/dpdk/doc/guides/cryptodevs/openssl.rst +@@ -83,7 +83,7 @@ This code has NOT been verified on FreeBSD yet. + Initialization + -------------- + +-User can use app/test application to check how to use this pmd and to verify ++User can use app/test application to check how to use this PMD and to verify + crypto processing. + + Test name is cryptodev_openssl_autotest. +diff --git a/dpdk/doc/guides/cryptodevs/overview.rst b/dpdk/doc/guides/cryptodevs/overview.rst +index e2a1e08ec1..f9a58fbd3d 100644 +--- a/dpdk/doc/guides/cryptodevs/overview.rst ++++ b/dpdk/doc/guides/cryptodevs/overview.rst +@@ -19,7 +19,7 @@ Supported Feature Flags + + - "OOP SGL In SGL Out" feature flag stands for + "Out-of-place Scatter-gather list Input, Scatter-gather list Output", +- which means pmd supports different scatter-gather styled input and output buffers ++ which means PMD supports different scatter-gather styled input and output buffers + (i.e. both can consists of multiple segments). + + - "OOP SGL In LB Out" feature flag stands for diff --git a/dpdk/doc/guides/cryptodevs/qat.rst b/dpdk/doc/guides/cryptodevs/qat.rst index 6197875fe3..c8bc514d61 100644 --- a/dpdk/doc/guides/cryptodevs/qat.rst @@ -12317,6 +16656,41 @@ index 6197875fe3..c8bc514d61 100644 The first 3 columns indicate the service: * S = Symmetric crypto service (via cryptodev API) +diff --git a/dpdk/doc/guides/cryptodevs/scheduler.rst b/dpdk/doc/guides/cryptodevs/scheduler.rst +index 7004ca431a..dd3de7f4d7 100644 +--- a/dpdk/doc/guides/cryptodevs/scheduler.rst ++++ b/dpdk/doc/guides/cryptodevs/scheduler.rst +@@ -126,7 +126,7 @@ operation: + than the designated threshold, otherwise it will be handled by the secondary + slave. + +- A typical usecase in this mode is with the QAT cryptodev as the primary and ++ A typical use case in this mode is with the QAT cryptodev as the primary and + a software cryptodev as the secondary slave. This may help applications to + process additional crypto workload than what the QAT cryptodev can handle on + its own, by making use of the available CPU cycles to deal with smaller +diff --git a/dpdk/doc/guides/cryptodevs/virtio.rst b/dpdk/doc/guides/cryptodevs/virtio.rst +index 1496ec9208..d5c218cef1 100644 +--- a/dpdk/doc/guides/cryptodevs/virtio.rst ++++ b/dpdk/doc/guides/cryptodevs/virtio.rst +@@ -63,7 +63,7 @@ QEMU can then be started using the following parameters: + -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 + [...] + +-Secondly bind the uio_generic driver for the virtio-crypto device. ++Secondly bind the uio_pci_generic driver for the virtio-crypto device. + For example, 0000:00:04.0 is the domain, bus, device and function + number of the virtio-crypto device: + +@@ -73,7 +73,7 @@ number of the virtio-crypto device: + echo -n 0000:00:04.0 > /sys/bus/pci/drivers/virtio-pci/unbind + echo "1af4 1054" > /sys/bus/pci/drivers/uio_pci_generic/new_id + +-Finally the front-end virtio crypto PMD driver can be installed: ++Finally the front-end virtio crypto PMD can be installed: + + .. code-block:: console + diff --git a/dpdk/doc/guides/eventdevs/index.rst b/dpdk/doc/guides/eventdevs/index.rst index 570905b813..bb66a5eacc 100644 --- a/dpdk/doc/guides/eventdevs/index.rst @@ -12415,6 +16789,32 @@ index fad84cf42d..d4b2515ce5 100644 Debugging Options ~~~~~~~~~~~~~~~~~ +diff --git a/dpdk/doc/guides/eventdevs/opdl.rst b/dpdk/doc/guides/eventdevs/opdl.rst +index cbfd1f11b7..f220959249 100644 +--- a/dpdk/doc/guides/eventdevs/opdl.rst ++++ b/dpdk/doc/guides/eventdevs/opdl.rst +@@ -87,7 +87,7 @@ due to the static nature of the underlying queues. It is because of this + that the implementation can achieve such high throughput and low latency + + The following list is a comprehensive outline of the what is supported and +-the limitations / restrictions imposed by the opdl pmd ++the limitations / restrictions imposed by the opdl PMD + + - The order in which packets moved between queues is static and fixed \ + (dynamic scheduling is not supported). +diff --git a/dpdk/doc/guides/freebsd_gsg/build_sample_apps.rst b/dpdk/doc/guides/freebsd_gsg/build_sample_apps.rst +index 0c1b9cb79f..bd3ec8a923 100644 +--- a/dpdk/doc/guides/freebsd_gsg/build_sample_apps.rst ++++ b/dpdk/doc/guides/freebsd_gsg/build_sample_apps.rst +@@ -139,7 +139,7 @@ Other options, specific to Linux and are not supported under FreeBSD are as foll + * ``--huge-dir``: + The directory where hugetlbfs is mounted. + +-* ``mbuf-pool-ops-name``: ++* ``--mbuf-pool-ops-name``: + Pool ops name for mbuf to use. + + * ``--file-prefix``: diff --git a/dpdk/doc/guides/freebsd_gsg/install_from_ports.rst b/dpdk/doc/guides/freebsd_gsg/install_from_ports.rst index 29f16cc6c5..dce028bc62 100644 --- a/dpdk/doc/guides/freebsd_gsg/install_from_ports.rst @@ -12428,6 +16828,19 @@ index 29f16cc6c5..dce028bc62 100644 the instructions given in the next chapter, :ref:`building_from_source` An example application can therefore be copied to a user's home directory and +diff --git a/dpdk/doc/guides/howto/pvp_reference_benchmark.rst b/dpdk/doc/guides/howto/pvp_reference_benchmark.rst +index 64b1f4d8ec..971cb25d03 100644 +--- a/dpdk/doc/guides/howto/pvp_reference_benchmark.rst ++++ b/dpdk/doc/guides/howto/pvp_reference_benchmark.rst +@@ -26,7 +26,7 @@ Setup overview + + PVP setup using 2 NICs + +-In this diagram, each red arrow represents one logical core. This use-case ++In this diagram, each red arrow represents one logical core. This use case + requires 6 dedicated logical cores. A forwarding configuration with a single + NIC is also possible, requiring 3 logical cores. + diff --git a/dpdk/doc/guides/linux_gsg/build_dpdk.rst b/dpdk/doc/guides/linux_gsg/build_dpdk.rst index 4aeb4697d9..c536e354ef 100644 --- a/dpdk/doc/guides/linux_gsg/build_dpdk.rst @@ -12534,7 +16947,7 @@ index 4aeb4697d9..c536e354ef 100644 +In addition, the test applications are built under the app directory, which may be used for testing. A kmod directory is also present that contains kernel modules which may be loaded if needed. diff --git a/dpdk/doc/guides/linux_gsg/build_sample_apps.rst b/dpdk/doc/guides/linux_gsg/build_sample_apps.rst -index 2f606535c3..2c2f5faec5 100644 +index 2f606535c3..8b9dc52a6d 100644 --- a/dpdk/doc/guides/linux_gsg/build_sample_apps.rst +++ b/dpdk/doc/guides/linux_gsg/build_sample_apps.rst @@ -4,7 +4,7 @@ @@ -12546,6 +16959,24 @@ index 2f606535c3..2c2f5faec5 100644 It also provides a pointer to where sample applications are stored. .. note:: +@@ -120,7 +120,7 @@ The EAL options are as follows: + + * ``-d``: + Add a driver or driver directory to be loaded. +- The application should use this option to load the pmd drivers ++ The application should use this option to load the PMDs + that are built as shared libraries. + + * ``-m MB``: +@@ -136,7 +136,7 @@ The EAL options are as follows: + * ``--huge-dir``: + The directory where hugetlbfs is mounted. + +-* ``mbuf-pool-ops-name``: ++* ``--mbuf-pool-ops-name``: + Pool ops name for mbuf to use. + + * ``--file-prefix``: @@ -185,7 +185,7 @@ Each bit of the mask corresponds to the equivalent logical core number as report Since these logical core numbers, and their mapping to specific cores on specific NUMA sockets, can vary from platform to platform, it is recommended that the core layout for each platform be considered when choosing the coremask/corelist to use in each case. @@ -12556,7 +16987,7 @@ index 2f606535c3..2c2f5faec5 100644 The physical id attribute listed for each processor indicates the CPU socket to which it belongs. This can be useful when using other processors to understand the mapping of the logical cores to the sockets. diff --git a/dpdk/doc/guides/linux_gsg/eal_args.include.rst b/dpdk/doc/guides/linux_gsg/eal_args.include.rst -index ed8b0e35b0..7b2f6b1d43 100644 +index ed8b0e35b0..56c19c9b00 100644 --- a/dpdk/doc/guides/linux_gsg/eal_args.include.rst +++ b/dpdk/doc/guides/linux_gsg/eal_args.include.rst @@ -132,7 +132,7 @@ Debugging options @@ -12568,6 +16999,14 @@ index ed8b0e35b0..7b2f6b1d43 100644 Can be specified multiple times. +@@ -147,6 +147,6 @@ Other options + + Display the version information on startup. + +-* ``mbuf-pool-ops-name``: ++* ``--mbuf-pool-ops-name``: + + Pool ops name for mbuf to use. diff --git a/dpdk/doc/guides/linux_gsg/enable_func.rst b/dpdk/doc/guides/linux_gsg/enable_func.rst index b2bda80bb7..459a952ce3 100644 --- a/dpdk/doc/guides/linux_gsg/enable_func.rst @@ -12658,7 +17097,7 @@ index b2bda80bb7..459a952ce3 100644 To help prevent additional workloads from running on those cores, it is possible to use the ``isolcpus`` Linux kernel parameter to isolate them from the general Linux scheduler. diff --git a/dpdk/doc/guides/linux_gsg/linux_drivers.rst b/dpdk/doc/guides/linux_gsg/linux_drivers.rst -index 238f3e9002..96817e78cd 100644 +index 238f3e9002..d8e5ad711a 100644 --- a/dpdk/doc/guides/linux_gsg/linux_drivers.rst +++ b/dpdk/doc/guides/linux_gsg/linux_drivers.rst @@ -52,8 +52,8 @@ be loaded as shown below: @@ -12672,7 +17111,24 @@ index 238f3e9002..96817e78cd 100644 Since DPDK release 1.7 onward provides VFIO support, use of UIO is optional for platforms that support using VFIO. -@@ -120,7 +120,7 @@ Binding and Unbinding Network Ports to/from the Kernel Modules +@@ -72,6 +72,16 @@ Note that in order to use VFIO, your kernel must support it. + VFIO kernel modules have been included in the Linux kernel since version 3.6.0 and are usually present by default, + however please consult your distributions documentation to make sure that is the case. + ++For DMA mapping of either external memory or hugepages, VFIO interface is used. ++VFIO does not support partial unmap of once mapped memory. Hence DPDK's memory is ++mapped in hugepage granularity or system page granularity. Number of DMA ++mappings is limited by kernel with user locked memory limit of a process (rlimit) ++for system/hugepage memory. Another per-container overall limit applicable both ++for external memory and system memory was added in kernel 5.1 defined by ++VFIO module parameter ``dma_entry_limit`` with a default value of 64K. ++When application is out of DMA entries, these limits need to be adjusted to ++increase the allowed limit. ++ + Also, to use VFIO, both kernel and BIOS must support and be configured to use IO virtualization (such as Intel® VT-d). + + .. note:: +@@ -120,7 +130,7 @@ Binding and Unbinding Network Ports to/from the Kernel Modules PMDs Which use the bifurcated driver should not be unbind from their kernel drivers. this section is for PMDs which use the UIO or VFIO drivers. As of release 1.4, DPDK applications no longer automatically unbind all supported network ports from the kernel driver in use. @@ -12854,6 +17310,84 @@ index 7931ef3bb5..732e7ad3a9 100644 + +doc_targets += html_guides +doc_target_names += 'HTML_Guides' +diff --git a/dpdk/doc/guides/nics/af_packet.rst b/dpdk/doc/guides/nics/af_packet.rst +index efd6f1ca73..cf098fcaa4 100644 +--- a/dpdk/doc/guides/nics/af_packet.rst ++++ b/dpdk/doc/guides/nics/af_packet.rst +@@ -5,7 +5,7 @@ AF_PACKET Poll Mode Driver + ========================== + + The AF_PACKET socket in Linux allows an application to receive and send raw +-packets. This Linux-specific PMD driver binds to an AF_PACKET socket and allows ++packets. This Linux-specific PMD binds to an AF_PACKET socket and allows + a DPDK application to send and receive raw packets through the Kernel. + + In order to improve Rx and Tx performance this implementation makes use of +diff --git a/dpdk/doc/guides/nics/af_xdp.rst b/dpdk/doc/guides/nics/af_xdp.rst +index b434b25df7..515f768ff5 100644 +--- a/dpdk/doc/guides/nics/af_xdp.rst ++++ b/dpdk/doc/guides/nics/af_xdp.rst +@@ -12,7 +12,7 @@ For the full details behind AF_XDP socket, you can refer to + `AF_XDP documentation in the Kernel + `_. + +-This Linux-specific PMD driver creates the AF_XDP socket and binds it to a ++This Linux-specific PMD creates the AF_XDP socket and binds it to a + specific netdev queue, it allows a DPDK application to send and receive raw + packets through the socket which would bypass the kernel network stack. + Current implementation only supports single queue, multi-queues feature will +diff --git a/dpdk/doc/guides/nics/avp.rst b/dpdk/doc/guides/nics/avp.rst +index 1a194fc23c..a749f2a0f6 100644 +--- a/dpdk/doc/guides/nics/avp.rst ++++ b/dpdk/doc/guides/nics/avp.rst +@@ -35,7 +35,7 @@ to another with minimal packet loss. + Features and Limitations of the AVP PMD + --------------------------------------- + +-The AVP PMD driver provides the following functionality. ++The AVP PMD provides the following functionality. + + * Receive and transmit of both simple and chained mbuf packets, + +@@ -74,7 +74,7 @@ Launching a VM with an AVP type network attachment + The following example will launch a VM with three network attachments. The + first attachment will have a default vif-model of "virtio". The next two + network attachments will have a vif-model of "avp" and may be used with a DPDK +-application which is built to include the AVP PMD driver. ++application which is built to include the AVP PMD. + + .. code-block:: console + +diff --git a/dpdk/doc/guides/nics/bnxt.rst b/dpdk/doc/guides/nics/bnxt.rst +index 434ba9d6cc..60ad3127e8 100644 +--- a/dpdk/doc/guides/nics/bnxt.rst ++++ b/dpdk/doc/guides/nics/bnxt.rst +@@ -54,14 +54,14 @@ automatically when the port is started if allowed by the current configuration. + RX Requirements for Vector Mode + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +-Vector mode receive will be enabled if the following constrainsts are met: ++Vector mode receive will be enabled if the following constraints are met: + * Packets must fit within a single mbuf (no scatter RX). + * LRO offload must be disabled. + + TX Requirements for Vector Mode + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +-Vector mode transmit will be enabled if the following constrainsts are met: ++Vector mode transmit will be enabled if the following constraints are met: + * Packets must be contained within a single mbuf (no gather TX). + * All transmit offloads other than VLAN insertion must be disabled. + +@@ -123,7 +123,7 @@ Chipsets and adapters supported by the bnxt PMD include: + `_ + of the `Broadcom website `_. + +- * **Broadcom StrataGX® BCM5871X Series of Communucations Processors** ++ * **Broadcom StrataGX® BCM5871X Series of Communications Processors** + + These ARM based processors target a broad range of networking applications + including virtual CPE (vCPE) and NFV appliances, 10G service routers and diff --git a/dpdk/doc/guides/nics/dpaa2.rst b/dpdk/doc/guides/nics/dpaa2.rst index fdfa6fdd5a..e54a5ff4d2 100644 --- a/dpdk/doc/guides/nics/dpaa2.rst @@ -12874,6 +17408,35 @@ index fdfa6fdd5a..e54a5ff4d2 100644 +------------+ +diff --git a/dpdk/doc/guides/nics/e1000em.rst b/dpdk/doc/guides/nics/e1000em.rst +index b6a2534e36..63c0b1b337 100644 +--- a/dpdk/doc/guides/nics/e1000em.rst ++++ b/dpdk/doc/guides/nics/e1000em.rst +@@ -8,9 +8,9 @@ The DPDK EM poll mode driver supports the following emulated devices: + + * qemu-kvm emulated Intel® 82540EM Gigabit Ethernet Controller (qemu e1000 device) + +-* VMware* emulated Intel® 82545EM Gigabit Ethernet Controller ++* VMware emulated Intel® 82545EM Gigabit Ethernet Controller + +-* VMware emulated Intel® 8274L Gigabit Ethernet Controller. ++* VMware emulated Intel® 82574L Gigabit Ethernet Controller. + + Validated Hypervisors + --------------------- +diff --git a/dpdk/doc/guides/nics/ena.rst b/dpdk/doc/guides/nics/ena.rst +index bbf27f235a..d39201c20b 100644 +--- a/dpdk/doc/guides/nics/ena.rst ++++ b/dpdk/doc/guides/nics/ena.rst +@@ -198,7 +198,7 @@ Example output: + + [...] + EAL: PCI device 0000:00:06.0 on NUMA socket -1 +- EAL: Invalid NUMA socket, default to 0 ++ EAL: Device 0000:00:06.0 is not NUMA-aware, defaulting socket to 0 + EAL: probe driver: 1d0f:ec20 net_ena + + Interactive-mode selected diff --git a/dpdk/doc/guides/nics/enic.rst b/dpdk/doc/guides/nics/enic.rst index 65e536d422..24d2b5713a 100644 --- a/dpdk/doc/guides/nics/enic.rst @@ -12984,10 +17547,42 @@ index b0a2f8e5f7..30a4d80ead 100644 Multiprocess aware = Y Other kdrv = Y ARMv8 = Y +diff --git a/dpdk/doc/guides/nics/fm10k.rst b/dpdk/doc/guides/nics/fm10k.rst +index 4e178c2cc6..2f03d22490 100644 +--- a/dpdk/doc/guides/nics/fm10k.rst ++++ b/dpdk/doc/guides/nics/fm10k.rst +@@ -118,9 +118,9 @@ Switch manager + ~~~~~~~~~~~~~~ + + The Intel FM10000 family of NICs integrate a hardware switch and multiple host +-interfaces. The FM10000 PMD driver only manages host interfaces. For the ++interfaces. The FM10000 PMD only manages host interfaces. For the + switch component another switch driver has to be loaded prior to the +-FM10000 PMD driver. The switch driver can be acquired from Intel support. ++FM10000 PMD. The switch driver can be acquired from Intel support. + Only Testpoint is validated with DPDK, the latest version that has been + validated with DPDK is 4.1.6. + diff --git a/dpdk/doc/guides/nics/hns3.rst b/dpdk/doc/guides/nics/hns3.rst -index 505488b6ca..567c65d536 100644 +index 505488b6ca..7eb6d727ca 100644 --- a/dpdk/doc/guides/nics/hns3.rst +++ b/dpdk/doc/guides/nics/hns3.rst +@@ -1,12 +1,12 @@ + .. SPDX-License-Identifier: BSD-3-Clause +- Copyright(c) 2018-2019 Hisilicon Limited. ++ Copyright(c) 2018-2019 HiSilicon Limited. + + HNS3 Poll Mode Driver + =============================== + + The hns3 PMD (librte_pmd_hns3) provides poll mode driver support +-for the inbuilt Hisilicon Network Subsystem(HNS) network engine +-found in the Hisilicon Kunpeng 920 SoC. ++for the inbuilt HiSilicon Network Subsystem(HNS) network engine ++found in the HiSilicon Kunpeng 920 SoC. + + Features + -------- @@ -22,13 +22,14 @@ Features of the HNS3 PMD are: - Port hardware statistics - Jumbo frames @@ -13066,11 +17661,48 @@ index 9b90b389ec..58eb023983 100644 - ``CONFIG_RTE_LIBRTE_ICE_16BYTE_RX_DESC`` (default ``n``) Toggle to use a 16-byte RX descriptor, by default the RX descriptor is 32 byte. +diff --git a/dpdk/doc/guides/nics/intel_vf.rst b/dpdk/doc/guides/nics/intel_vf.rst +index ade5152595..9de7e2b444 100644 +--- a/dpdk/doc/guides/nics/intel_vf.rst ++++ b/dpdk/doc/guides/nics/intel_vf.rst +@@ -575,7 +575,7 @@ Fast Host-based Packet Processing + + Software Defined Network (SDN) trends are demanding fast host-based packet handling. + In a virtualization environment, +-the DPDK VF PMD driver performs the same throughput result as a non-VT native environment. ++the DPDK VF PMD performs the same throughput result as a non-VT native environment. + + With such host instance fast packet processing, lots of services such as filtering, QoS, + DPI can be offloaded on the host fast path. diff --git a/dpdk/doc/guides/nics/ixgbe.rst b/dpdk/doc/guides/nics/ixgbe.rst -index 5c3a7e4f26..6ca2a33f09 100644 +index 5c3a7e4f26..8305bf0dbb 100644 --- a/dpdk/doc/guides/nics/ixgbe.rst +++ b/dpdk/doc/guides/nics/ixgbe.rst -@@ -253,6 +253,16 @@ Before binding ``vfio`` with legacy mode in X550 NICs, use ``modprobe vfio `` +@@ -82,6 +82,23 @@ To guarantee the constraint, capabilities in dev_conf.rxmode.offloads will be ch + + fdir_conf->mode will also be checked. + ++Disable SDP3 TX_DISABLE for Fiber Links ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++The following ``devargs`` option can be enabled at runtime. It must ++be passed as part of EAL arguments. For example, ++ ++.. code-block:: console ++ ++ dpdk-testpmd -a fiber_sdp3_no_tx_disable=1 -- -i ++ ++- ``fiber_sdp3_no_tx_disable`` (default **0**) ++ ++ Not all IXGBE implementations with SFP cages use the SDP3 signal as ++ TX_DISABLE as a means to disable the laser on fiber SFP modules. ++ This option informs the driver that in this case, SDP3 is not to be ++ used as a check for link up by testing for laser on/off. ++ + VF Runtime Options + ^^^^^^^^^^^^^^^^^^ + +@@ -253,6 +270,16 @@ Before binding ``vfio`` with legacy mode in X550 NICs, use ``modprobe vfio `` ``nointxmask=1`` to load ``vfio`` module if the intx is not shared with other devices. @@ -13087,10 +17719,32 @@ index 5c3a7e4f26..6ca2a33f09 100644 Inline crypto processing support -------------------------------- +diff --git a/dpdk/doc/guides/nics/kni.rst b/dpdk/doc/guides/nics/kni.rst +index 90d3040cf5..f403de1fc0 100644 +--- a/dpdk/doc/guides/nics/kni.rst ++++ b/dpdk/doc/guides/nics/kni.rst +@@ -33,7 +33,7 @@ Usage + + EAL ``--vdev`` argument can be used to create KNI device instance, like:: + +- testpmd --vdev=net_kni0 --vdev=net_kn1 -- -i ++ testpmd --vdev=net_kni0 --vdev=net_kni1 -- -i + + Above command will create ``kni0`` and ``kni1`` Linux network interfaces, + those interfaces can be controlled by standard Linux tools. diff --git a/dpdk/doc/guides/nics/mlx4.rst b/dpdk/doc/guides/nics/mlx4.rst -index d0e8a8b2ff..1f1e2f6c77 100644 +index d0e8a8b2ff..c90a2f6f77 100644 --- a/dpdk/doc/guides/nics/mlx4.rst +++ b/dpdk/doc/guides/nics/mlx4.rst +@@ -14,7 +14,7 @@ the `Mellanox website `_. Help is also provided by + the `Mellanox community `_. + + There is also a `section dedicated to this poll mode driver +-`_. ++`_. + + .. note:: + @@ -92,6 +92,10 @@ These options can be modified in the ``.config`` file. adds additional run-time checks and debugging messages at the cost of lower performance. @@ -13102,6 +17756,15 @@ index d0e8a8b2ff..1f1e2f6c77 100644 Environment variables ~~~~~~~~~~~~~~~~~~~~~ +@@ -256,7 +260,7 @@ Mellanox OFED as a fallback + - `Mellanox OFED`_ version: **4.4, 4.5, 4.6**. + - firmware version: **2.42.5000** and above. + +-.. _`Mellanox OFED`: http://www.mellanox.com/page/products_dyn?product_family=26&mtag=linux_sw_drivers ++.. _`Mellanox OFED`: https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/ + + .. note:: + @@ -294,11 +298,6 @@ Installing Mellanox OFED 5. Continue with :ref:`section 2 of the Quick Start Guide `. @@ -13115,7 +17778,7 @@ index d0e8a8b2ff..1f1e2f6c77 100644 Quick Start Guide diff --git a/dpdk/doc/guides/nics/mlx5.rst b/dpdk/doc/guides/nics/mlx5.rst -index 18573cf6a0..bbad7d0d5b 100644 +index 18573cf6a0..8f7b285271 100644 --- a/dpdk/doc/guides/nics/mlx5.rst +++ b/dpdk/doc/guides/nics/mlx5.rst @@ -2,12 +2,14 @@ @@ -13134,6 +17797,15 @@ index 18573cf6a0..bbad7d0d5b 100644 **Mellanox BlueField** families of 10/25/40/50/100/200 Gb/s adapters as well as their virtual functions (VF) in SR-IOV context. +@@ -16,7 +18,7 @@ Information and documentation about these adapters can be found on the + `Mellanox community `__. + + There is also a `section dedicated to this poll mode driver +-`__. ++`_. + + .. note:: + @@ -107,22 +109,37 @@ Limitations process. If the external memory is registered by primary process but has different virtual address in secondary process, unexpected error may happen. @@ -13176,7 +17848,30 @@ index 18573cf6a0..bbad7d0d5b 100644 - VLAN pop offload command: -@@ -270,6 +287,10 @@ These options can be modified in the ``.config`` file. +@@ -210,6 +227,22 @@ Limitations + - Rx queue with LRO offload enabled, receiving a non-LRO packet, can forward + it with size limited to max LRO size, not to max RX packet length. + ++- Timestamps: ++ ++ - CQE timestamp field width is limited by hardware to 63 bits, MSB is zero. ++ - In the free-running mode the timestamp counter is reset on power on ++ and 63-bit value provides over 1800 years of uptime till overflow. ++ - In the real-time mode ++ (configurable with ``REAL_TIME_CLOCK_ENABLE`` firmware settings), ++ the timestamp presents the nanoseconds elapsed since 01-Jan-1970, ++ hardware timestamp overflow will happen on 19-Jan-2038 ++ (0x80000000 seconds since 01-Jan-1970). ++ - The send scheduling is based on timestamps ++ from the reference "Clock Queue" completions, ++ the scheduled send timestamps should not be specified with non-zero MSB. ++ ++- The NIC egress flow rules on representor port are not supported. ++ + Statistics + ---------- + +@@ -270,6 +303,10 @@ These options can be modified in the ``.config`` file. 64. Default armv8a configuration of make build and meson build set it to 128 then brings performance degradation. @@ -13187,7 +17882,23 @@ index 18573cf6a0..bbad7d0d5b 100644 Environment variables ~~~~~~~~~~~~~~~~~~~~~ -@@ -315,9 +336,9 @@ Run-time configuration +@@ -290,15 +327,6 @@ Environment variables + The register would be flushed to HW usually when the write-combining buffer + becomes full, but it depends on CPU design. + +- Except for vectorized Tx burst routines, a write memory barrier is enforced +- after updating the register so that the update can be immediately visible to +- HW. +- +- When vectorized Tx burst is called, the barrier is set only if the burst size +- is not aligned to MLX5_VPMD_TX_MAX_BURST. However, setting this environmental +- variable will bring better latency even though the maximum throughput can +- slightly decline. +- + Run-time configuration + ~~~~~~~~~~~~~~~~~~~~~~ + +@@ -315,9 +343,9 @@ Run-time configuration Supported on: @@ -13199,7 +17910,7 @@ index 18573cf6a0..bbad7d0d5b 100644 and BlueField. - ``rxq_cqe_pad_en`` parameter [int] -@@ -348,17 +369,16 @@ Run-time configuration +@@ -348,17 +376,16 @@ Run-time configuration Supported on: @@ -13220,7 +17931,7 @@ index 18573cf6a0..bbad7d0d5b 100644 Multi-Packet Rx Queue (MPRQ a.k.a Striding RQ) can further save PCIe bandwidth by posting a single large buffer for multiple packets. Instead of posting a -@@ -383,6 +403,20 @@ Run-time configuration +@@ -383,6 +410,20 @@ Run-time configuration The size of Rx queue should be bigger than the number of strides. @@ -13241,7 +17952,7 @@ index 18573cf6a0..bbad7d0d5b 100644 - ``mprq_max_memcpy_len`` parameter [int] The maximum length of packet to memcpy in case of Multi-Packet Rx queue. Rx -@@ -453,14 +487,14 @@ Run-time configuration +@@ -453,17 +494,24 @@ Run-time configuration If ``txq_inline_min`` key is not present, the value may be queried by the driver from the NIC via DevX if this feature is available. If there is no DevX enabled/supported the value 18 (supposing L2 header including VLAN) is set @@ -13258,7 +17969,17 @@ index 18573cf6a0..bbad7d0d5b 100644 it is not recommended and may prevent NIC from sending packets over some configurations. -@@ -543,7 +577,7 @@ Run-time configuration ++ For ConnectX-4 and ConnectX-4 Lx NICs, automatically configured value ++ is insufficient for some traffic, because they require at least all L2 headers ++ to be inlined. For example, Q-in-Q adds 4 bytes to default 18 bytes ++ of Ethernet and VLAN, thus ``txq_inline_min`` must be set to 22. ++ MPLS would add 4 bytes per label. Final value must account for all possible ++ L2 encapsulation headers used in particular environment. ++ + Please, note, this minimal data inlining disengages eMPW feature (Enhanced + Multi-Packet Write), because last one does not support partial packet inlining. + This is not very critical due to minimal data inlining is mostly required +@@ -543,7 +591,7 @@ Run-time configuration - ``txq_mpw_en`` parameter [int] A nonzero value enables Enhanced Multi-Packet Write (eMPW) for ConnectX-5, @@ -13267,7 +17988,7 @@ index 18573cf6a0..bbad7d0d5b 100644 up multiple packets in a single descriptor session in order to save PCI bandwidth and improve performance at the cost of a slightly higher CPU usage. When ``txq_inline_mpw`` is set along with ``txq_mpw_en``, TX burst function copies -@@ -559,16 +593,17 @@ Run-time configuration +@@ -559,16 +607,17 @@ Run-time configuration The rdma core library can map doorbell register in two ways, depending on the environment variable "MLX5_SHUT_UP_BF": @@ -13289,7 +18010,7 @@ index 18573cf6a0..bbad7d0d5b 100644 If ``tx_db_nc`` is set to one, the doorbell is forced to be mapped to non cached memory, the PMD will not perform the extra write memory barrier -@@ -589,7 +624,7 @@ Run-time configuration +@@ -589,7 +638,7 @@ Run-time configuration - ``tx_vec_en`` parameter [int] @@ -13298,7 +18019,7 @@ index 18573cf6a0..bbad7d0d5b 100644 and BlueField NICs if the number of global Tx queues on the port is less than ``txqs_max_vec``. The parameter is deprecated and ignored. -@@ -658,7 +693,7 @@ Run-time configuration +@@ -658,7 +707,7 @@ Run-time configuration +------+-----------+-----------+-------------+-------------+ | 1 | 24 bits | vary 0-32 | 32 bits | yes | +------+-----------+-----------+-------------+-------------+ @@ -13307,7 +18028,7 @@ index 18573cf6a0..bbad7d0d5b 100644 +------+-----------+-----------+-------------+-------------+ If there is no E-Switch configuration the ``dv_xmeta_en`` parameter is -@@ -670,6 +705,17 @@ Run-time configuration +@@ -670,6 +719,17 @@ Run-time configuration of the extensive metadata features. The legacy Verbs supports FLAG and MARK metadata actions over NIC Rx steering domain only. @@ -13325,7 +18046,18 @@ index 18573cf6a0..bbad7d0d5b 100644 - ``dv_flow_en`` parameter [int] A nonzero value enables the DV flow steering assuming it is supported -@@ -886,7 +932,7 @@ Mellanox OFED/EN +@@ -786,6 +846,10 @@ Below are some firmware configurations listed. + + FLEX_PARSER_PROFILE_ENABLE=0 + ++- enable realtime timestamp format:: ++ ++ REAL_TIME_CLOCK_ENABLE=1 ++ + Prerequisites + ------------- + +@@ -886,7 +950,7 @@ Mellanox OFED/EN - ConnectX-5: **16.21.1000** and above. - ConnectX-5 Ex: **16.21.1000** and above. - ConnectX-6: **20.99.5374** and above. @@ -13334,7 +18066,19 @@ index 18573cf6a0..bbad7d0d5b 100644 - BlueField: **18.25.1010** and above. While these libraries and kernel modules are available on OpenFabrics -@@ -911,28 +957,43 @@ required from that distribution. +@@ -895,9 +959,9 @@ managers on most distributions, this PMD requires Ethernet extensions that + may not be supported at the moment (this is a work in progress). + + `Mellanox OFED +-`__ and ++`__ and + `Mellanox EN +-`__ ++`__ + include the necessary support and should be used in the meantime. For DPDK, + only libibverbs, libmlx5, mlnx-ofed-kernel packages and firmware updates are + required from that distribution. +@@ -911,28 +975,43 @@ required from that distribution. Supported NICs -------------- @@ -13400,7 +18144,16 @@ index 18573cf6a0..bbad7d0d5b 100644 Quick Start Guide on OFED/EN ---------------------------- -@@ -1195,6 +1256,19 @@ Supported hardware offloads +@@ -1027,7 +1106,7 @@ the DPDK application. + + echo -n " /sys/bus/pci/drivers/mlx5_core/unbind + +-5. Enbale switchdev mode:: ++5. Enable switchdev mode:: + + echo switchdev > /sys/class/net//compat/devlink/mode + +@@ -1195,6 +1274,19 @@ Supported hardware offloads | | | ConnectX-5 | | ConnectX-5 | +-----------------------+-----------------+-----------------+ @@ -13420,10 +18173,41 @@ index 18573cf6a0..bbad7d0d5b 100644 Notes for testpmd ----------------- +diff --git a/dpdk/doc/guides/nics/netvsc.rst b/dpdk/doc/guides/nics/netvsc.rst +index 6dbb9a5513..a6b0d597ea 100644 +--- a/dpdk/doc/guides/nics/netvsc.rst ++++ b/dpdk/doc/guides/nics/netvsc.rst +@@ -14,7 +14,7 @@ checksum and segmentation offloads. + Features and Limitations of Hyper-V PMD + --------------------------------------- + +-In this release, the hyper PMD driver provides the basic functionality of packet reception and transmission. ++In this release, the hyper PMD provides the basic functionality of packet reception and transmission. + + * It supports merge-able buffers per packet when receiving packets and scattered buffer per packet + when transmitting packets. The packet size supported is from 64 to 65536. +@@ -62,7 +62,7 @@ store it in a shell variable: + + .. _`UUID`: https://en.wikipedia.org/wiki/Universally_unique_identifier + +-There are several possible ways to assign the uio device driver for a device. ++There are several possible ways to assign the UIO device driver for a device. + The easiest way (but only on 4.18 or later) + is to use the `driverctl Device Driver control utility`_ to override + the normal kernel device. diff --git a/dpdk/doc/guides/nics/nfp.rst b/dpdk/doc/guides/nics/nfp.rst -index 5f2a0698f6..020e37d131 100644 +index 5f2a0698f6..ef88740c5c 100644 --- a/dpdk/doc/guides/nics/nfp.rst +++ b/dpdk/doc/guides/nics/nfp.rst +@@ -14,7 +14,7 @@ This document explains how to use DPDK with the Netronome Poll Mode + Driver (PMD) supporting Netronome's Network Flow Processor 6xxx + (NFP-6xxx) and Netronome's Flow Processor 4xxx (NFP-4xxx). + +-NFP is a SRIOV capable device and the PMD driver supports the physical ++NFP is a SRIOV capable device and the PMD supports the physical + function (PF) and the virtual functions (VFs). + + Dependencies @@ -102,22 +102,39 @@ directory per firmware application. Options 1 and 2 for firmware filenames allow more than one SmartNIC, same type of SmartNIC or different ones, and to upload a different firmware to each SmartNIC. @@ -13457,15 +18241,15 @@ index 5f2a0698f6..020e37d131 100644 +PCI ports. +NFP ports belonging to same PF can be seen inside PMD initialization with a -+suffix added to the PCI ID: wwww:xx:yy.z_port_n. For example, a PF with PCI ID ++suffix added to the PCI ID: wwww:xx:yy.z_portn. For example, a PF with PCI ID +0000:03:00.0 and four ports is seen by the PMD code as: + + .. code-block:: console + -+ 0000:03:00.0_port_0 -+ 0000:03:00.0_port_1 -+ 0000:03:00.0_port_2 -+ 0000:03:00.0_port_3 ++ 0000:03:00.0_port0 ++ 0000:03:00.0_port1 ++ 0000:03:00.0_port2 ++ 0000:03:00.0_port3 + + .. Note:: + @@ -13474,6 +18258,59 @@ index 5f2a0698f6..020e37d131 100644 PF multiprocess support ----------------------- +diff --git a/dpdk/doc/guides/nics/octeontx.rst b/dpdk/doc/guides/nics/octeontx.rst +index 8fc53810b2..c015127b4e 100644 +--- a/dpdk/doc/guides/nics/octeontx.rst ++++ b/dpdk/doc/guides/nics/octeontx.rst +@@ -122,7 +122,7 @@ following ``make`` command: + Initialization + -------------- + +-The OCTEON TX ethdev pmd is exposed as a vdev device which consists of a set ++The OCTEON TX ethdev PMD is exposed as a vdev device which consists of a set + of PKI and PKO PCIe VF devices. On EAL initialization, + PKI/PKO PCIe VF devices will be probed and then the vdev device can be created + from the application code, or from the EAL command line based on +@@ -140,7 +140,7 @@ the number of interesting ports with ``nr_ports`` argument. + + Dependency + ~~~~~~~~~~ +-``eth_octeontx`` pmd is depend on ``event_octeontx`` eventdev device and ++``eth_octeontx`` PMD is depend on ``event_octeontx`` eventdev device and + ``octeontx_fpavf`` external mempool handler. + + Example: +diff --git a/dpdk/doc/guides/nics/octeontx2.rst b/dpdk/doc/guides/nics/octeontx2.rst +index db62a4523f..9c341169ff 100644 +--- a/dpdk/doc/guides/nics/octeontx2.rst ++++ b/dpdk/doc/guides/nics/octeontx2.rst +@@ -162,7 +162,7 @@ Runtime Config Options + + -w 0002:02:00.0,max_sqb_count=64 + +- With the above configuration, each send queue's decscriptor buffer count is ++ With the above configuration, each send queue's descriptor buffer count is + limited to a maximum of 64 buffers. + + - ``switch header enable`` (default ``none``) +@@ -191,7 +191,7 @@ Limitations + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The OCTEON TX2 SoC family NIC has inbuilt HW assisted external mempool manager. +-``net_octeontx2`` pmd only works with ``mempool_octeontx2`` mempool handler ++``net_octeontx2`` PMD only works with ``mempool_octeontx2`` mempool handler + as it is performance wise most effective way for packet allocation and Tx buffer + recycling on OCTEON TX2 SoC platform. + +@@ -204,7 +204,7 @@ the host interface irrespective of the offload configuration. + Multicast MAC filtering + ~~~~~~~~~~~~~~~~~~~~~~~ + +-``net_octeontx2`` pmd supports multicast mac filtering feature only on physical ++``net_octeontx2`` PMD supports multicast mac filtering feature only on physical + function devices. + + SDP interface support diff --git a/dpdk/doc/guides/nics/pcap_ring.rst b/dpdk/doc/guides/nics/pcap_ring.rst index cf230ae40a..8fdb49179a 100644 --- a/dpdk/doc/guides/nics/pcap_ring.rst @@ -13509,6 +18346,673 @@ index 67d9b054d5..f79ebf518c 100644 which may be used on DPDK firmware variant only (see notes about its limitations above). +diff --git a/dpdk/doc/guides/nics/thunderx.rst b/dpdk/doc/guides/nics/thunderx.rst +index 3b75a9a9af..8958b08f6a 100644 +--- a/dpdk/doc/guides/nics/thunderx.rst ++++ b/dpdk/doc/guides/nics/thunderx.rst +@@ -219,7 +219,7 @@ Each port consists of a primary VF and n secondary VF(s). Each VF provides 8 Tx/ + When a given port is configured to use more than 8 queues, it requires one (or more) secondary VF. + Each secondary VF adds 8 additional queues to the queue set. + +-During PMD driver initialization, the primary VF's are enumerated by checking the ++During PMD initialization, the primary VF's are enumerated by checking the + specific flag (see sqs message in DPDK boot log - sqs indicates secondary queue set). + They are at the beginning of VF list (the remain ones are secondary VF's). + +@@ -320,7 +320,7 @@ Module params + skip_data_bytes + ~~~~~~~~~~~~~~~ + This feature is used to create a hole between HEADROOM and actual data. Size of hole is specified +-in bytes as module param("skip_data_bytes") to pmd. ++in bytes as module param("skip_data_bytes") to PMD. + This scheme is useful when application would like to insert vlan header without disturbing HEADROOM. + + Example: +diff --git a/dpdk/doc/guides/nics/virtio.rst b/dpdk/doc/guides/nics/virtio.rst +index d1f5fb8986..3059bb8fba 100644 +--- a/dpdk/doc/guides/nics/virtio.rst ++++ b/dpdk/doc/guides/nics/virtio.rst +@@ -17,7 +17,7 @@ With this enhancement, virtio could achieve quite promising performance. + For basic qemu-KVM installation and other Intel EM poll mode driver in guest VM, + please refer to Chapter "Driver for VM Emulated Devices". + +-In this chapter, we will demonstrate usage of virtio PMD driver with two backends, ++In this chapter, we will demonstrate usage of virtio PMD with two backends, + standard qemu vhost back end and vhost kni back end. + + Virtio Implementation in DPDK +@@ -40,7 +40,7 @@ end if necessary. + Features and Limitations of virtio PMD + -------------------------------------- + +-In this release, the virtio PMD driver provides the basic functionality of packet reception and transmission. ++In this release, the virtio PMD provides the basic functionality of packet reception and transmission. + + * It supports merge-able buffers per packet when receiving packets and scattered buffer per packet + when transmitting packets. The packet size supported is from 64 to 1518. +@@ -71,7 +71,7 @@ In this release, the virtio PMD driver provides the basic functionality of packe + + * Virtio supports software vlan stripping and inserting. + +-* Virtio supports using port IO to get PCI resource when uio/igb_uio module is not available. ++* Virtio supports using port IO to get PCI resource when UIO module is not available. + + Prerequisites + ------------- +@@ -103,7 +103,8 @@ Host2VM communication example + + insmod rte_kni.ko + +- Other basic DPDK preparations like hugepage enabling, uio port binding are not listed here. ++ Other basic DPDK preparations like hugepage enabling, ++ UIO port binding are not listed here. + Please refer to the *DPDK Getting Started Guide* for detailed instructions. + + #. Launch the kni user application: +@@ -473,7 +474,7 @@ are shown in below table: + Split virtqueue in-order non-mergeable path virtio_recv_pkts_inorder virtio_xmit_pkts_inorder + Split virtqueue vectorized Rx path virtio_recv_pkts_vec virtio_xmit_pkts + Packed virtqueue mergeable path virtio_recv_mergeable_pkts_packed virtio_xmit_pkts_packed +- Packed virtqueue non-meregable path virtio_recv_pkts_packed virtio_xmit_pkts_packed ++ Packed virtqueue non-mergeable path virtio_recv_pkts_packed virtio_xmit_pkts_packed + Packed virtqueue in-order mergeable path virtio_recv_mergeable_pkts_packed virtio_xmit_pkts_packed + Packed virtqueue in-order non-mergeable path virtio_recv_pkts_packed virtio_xmit_pkts_packed + ============================================ ================================= ======================== +diff --git a/dpdk/doc/guides/nics/vmxnet3.rst b/dpdk/doc/guides/nics/vmxnet3.rst +index ae146f0d55..190cf91a47 100644 +--- a/dpdk/doc/guides/nics/vmxnet3.rst ++++ b/dpdk/doc/guides/nics/vmxnet3.rst +@@ -119,7 +119,8 @@ This section describes an example setup for Phy-vSwitch-VM-Phy communication. + + .. note:: + +- Other instructions on preparing to use DPDK such as, hugepage enabling, uio port binding are not listed here. ++ Other instructions on preparing to use DPDK such as, ++ hugepage enabling, UIO port binding are not listed here. + Please refer to *DPDK Getting Started Guide and DPDK Sample Application's User Guide* for detailed instructions. + + The packet reception and transmission flow path is:: +diff --git a/dpdk/doc/guides/prog_guide/bbdev.rst b/dpdk/doc/guides/prog_guide/bbdev.rst +index d39167af1f..27e6848b94 100644 +--- a/dpdk/doc/guides/prog_guide/bbdev.rst ++++ b/dpdk/doc/guides/prog_guide/bbdev.rst +@@ -639,7 +639,7 @@ optionally the ``soft_output`` mbuf data pointers. + "soft output","soft LLR output buffer (optional)" + "op_flags","bitmask of all active operation capabilities" + "rv_index","redundancy version index [0..3]" +- "iter_max","maximum number of iterations to perofrm in decode all CBs" ++ "iter_max","maximum number of iterations to perform in decode all CBs" + "iter_min","minimum number of iterations to perform in decoding all CBs" + "iter_count","number of iterations to performed in decoding all CBs" + "ext_scale","scale factor on extrinsic info (5 bits)" +diff --git a/dpdk/doc/guides/prog_guide/compressdev.rst b/dpdk/doc/guides/prog_guide/compressdev.rst +index a089db1fad..18004e5ca2 100644 +--- a/dpdk/doc/guides/prog_guide/compressdev.rst ++++ b/dpdk/doc/guides/prog_guide/compressdev.rst +@@ -2,7 +2,7 @@ + Copyright(c) 2017-2018 Cavium Networks. + + Compression Device Library +-=========================== ++========================== + + The compression framework provides a generic set of APIs to perform compression services + as well as to query and configure compression devices both physical(hardware) and virtual(software) +@@ -28,14 +28,14 @@ From the command line using the --vdev EAL option + + .. code-block:: console + +- --vdev ',socket_id=0' ++ --vdev ',socket_id=0' + + .. Note:: + +- * If DPDK application requires multiple software compression PMD devices then required +- number of ``--vdev`` with appropriate libraries are to be added. ++ * If a DPDK application requires multiple software compression PMD devices then the ++ required number of ``--vdev`` args with appropriate libraries are to be added. + +- * An Application with multiple compression device instances exposed by the same PMD must ++ * An application with multiple compression device instances exposed by the same PMD must + specify a unique name for each device. + + Example: ``--vdev 'pmd0' --vdev 'pmd1'`` +@@ -53,7 +53,7 @@ All virtual compression devices support the following initialization parameters: + Device Identification + ~~~~~~~~~~~~~~~~~~~~~ + +-Each device, whether virtual or physical is uniquely designated by two ++Each device, whether virtual or physical, is uniquely designated by two + identifiers: + + - A unique device index used to designate the compression device in all functions +@@ -76,7 +76,7 @@ The ``rte_compressdev_configure`` API is used to configure a compression device. + The ``rte_compressdev_config`` structure is used to pass the configuration + parameters. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + + Configuration of Queue Pairs + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@@ -85,87 +85,88 @@ Each compression device queue pair is individually configured through the + ``rte_compressdev_queue_pair_setup`` API. + + The ``max_inflight_ops`` is used to pass maximum number of +-rte_comp_op that could be present in a queue at-a-time. +-PMD then can allocate resources accordingly on a specified socket. ++``rte_comp_op`` that could be present in a queue at a time. ++The PMD can then allocate resources accordingly on a specified socket. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + +-Logical Cores, Memory and Queues Pair Relationships +-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++Logical Cores, Memory and Queue Pair Relationships ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-Library supports NUMA similarly as described in Cryptodev library section. ++The Compressdev library supports NUMA similarly as described in Cryptodev library section. + +-A queue pair cannot be shared and should be exclusively used by a single processing +-context for enqueuing operations or dequeuing operations on the same compression device ++A queue pair cannot be shared, and should be exclusively used by a single processing ++context for enqueuing operations or dequeuing operations on the same compression device, + since sharing would require global locks and hinder performance. It is however possible + to use a different logical core to dequeue an operation on a queue pair from the logical +-core on which it was enqueued. This means that a compression burst enqueue/dequeue ++core on which it was enqueued. This means that for a compression burst, enqueue/dequeue + APIs are a logical place to transition from one logical core to another in a + data processing pipeline. + + Device Features and Capabilities +---------------------------------- ++-------------------------------- + + Compression devices define their functionality through two mechanisms, global device +-features and algorithm features. Global devices features identify device +-wide level features which are applicable to the whole device such as supported hardware ++features and algorithm features. Global device features identify device ++wide level features which are applicable to the whole device, such as supported hardware + acceleration and CPU features. List of compression device features can be seen in the + RTE_COMPDEV_FF_XXX macros. + +-The algorithm features lists individual algo feature which device supports per-algorithm, +-such as a stateful compression/decompression, checksums operation etc. List of algorithm +-features can be seen in the RTE_COMP_FF_XXX macros. ++The algorithm features are features which the device supports per-algorithm, ++such as a stateful compression/decompression, checksums operation etc. ++The list of algorithm features can be seen in the RTE_COMP_FF_XXX macros. + + Capabilities + ~~~~~~~~~~~~ + Each PMD has a list of capabilities, including algorithms listed in +-enum ``rte_comp_algorithm`` and its associated feature flag and +-sliding window range in log base 2 value. Sliding window tells +-the minimum and maximum size of lookup window that algorithm uses ++the enum ``rte_comp_algorithm``, its associated feature flag, and ++sliding window range in log base 2 value. The sliding window range ++defines the minimum and maximum size of a lookup window that an algorithm uses + to find duplicates. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + + Each Compression poll mode driver defines its array of capabilities +-for each algorithm it supports. See PMD implementation for capability ++for each algorithm it supports. See the PMD implementation for capability + initialization. + + Capabilities Discovery + ~~~~~~~~~~~~~~~~~~~~~~ + +-PMD capability and features are discovered via ``rte_compressdev_info_get`` function. ++PMD capability and features are discovered via the ``rte_compressdev_info_get`` function. + + The ``rte_compressdev_info`` structure contains all the relevant information for the device. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + + Compression Operation +----------------------- ++--------------------- + + DPDK compression supports two types of compression methodologies: + +-- Stateless, data associated to a compression operation is compressed without any reference ++- Stateless - data associated with a compression operation is compressed without any reference + to another compression operation. + +-- Stateful, data in each compression operation is compressed with reference to previous compression ++- Stateful - data in each compression operation is compressed with reference to previous compression + operations in the same data stream i.e. history of data is maintained between the operations. + +-For more explanation, please refer RFC https://www.ietf.org/rfc/rfc1951.txt ++For more explanation, please refer to the RFC https://www.ietf.org/rfc/rfc1951.txt + + Operation Representation + ~~~~~~~~~~~~~~~~~~~~~~~~ + +-Compression operation is described via ``struct rte_comp_op``, which contains both input and ++A compression operation is described via ``struct rte_comp_op``, which contains both input and + output data. The operation structure includes the operation type (stateless or stateful), +-the operation status and the priv_xform/stream handle, source, destination and checksum buffer ++the operation status, the priv_xform/stream handle, source, destination and checksum buffer + pointers. It also contains the source mempool from which the operation is allocated. +-PMD updates consumed field with amount of data read from source buffer and produced +-field with amount of data of written into destination buffer along with status of +-operation. See section *Produced, Consumed And Operation Status* for more details. +- +-Compression operations mempool also has an ability to allocate private memory with the +-operation for application's purposes. Application software is responsible for specifying +-all the operation specific fields in the ``rte_comp_op`` structure which are then used ++The PMD updates the consumed field with the amount of data read from the source buffer, ++and the produced field with the amount of data written into the destination buffer, ++along with status of operation. ++See the section :ref:`compressdev_prod_cons_op_status`: for more details. ++ ++The compression operations mempool also has the ability to allocate private memory with the ++operation for the application's use. The application software is responsible for specifying ++all the operation specific fields in the ``rte_comp_op`` structure, which are then used + by the compression PMD to process the requested operation. + + +@@ -181,27 +182,27 @@ A ``rte_comp_op`` contains a field indicating the pool it originated from. + + ``rte_comp_op_alloc()`` and ``rte_comp_op_bulk_alloc()`` are used to allocate + compression operations from a given compression operation mempool. +-The operation gets reset before being returned to a user so that operation ++The operation gets reset before being returned to a user so that the operation + is always in a good known state before use by the application. + + ``rte_comp_op_free()`` is called by the application to return an operation to + its allocating pool. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + + Passing source data as mbuf-chain +-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + If input data is scattered across several different buffers, then +-Application can either parse through all such buffers and make one ++the application can either parse through all such buffers and make one + mbuf-chain and enqueue it for processing or, alternatively, it can +-make multiple sequential enqueue_burst() calls for each of them +-processing them statefully. See *Compression API Stateful Operation* ++make multiple sequential enqueue_burst() calls for each of them, ++processing them statefully. See :ref:`compressdev_stateful_op`: + for stateful processing of ops. + + Operation Status + ~~~~~~~~~~~~~~~~ +-Each operation carries a status information updated by PMD after it is processed. +-Following are currently supported: ++Each operation carries status information updated by the PMD after it is processed. ++The following are currently supported: + + - RTE_COMP_OP_STATUS_SUCCESS, + Operation is successfully completed +@@ -225,22 +226,25 @@ Following are currently supported: + - RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE, + Output buffer ran out of space before operation completed, but this + is not an error case. Output data up to op.produced can be used and +- next op in the stream should continue on from op.consumed+1. ++ the next op in the stream should continue on from op.consumed+1. + + Operation status after enqueue / dequeue + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Some of the above values may arise in the op after an +-``rte_compressdev_enqueue_burst()``. If number ops enqueued < number ops requested then +-the app should check the op.status of nb_enqd+1. If status is RTE_COMP_OP_STATUS_NOT_PROCESSED, +-it likely indicates a full-queue case for a hardware device and a retry after dequeuing some ops is likely +-to be successful. If the op holds any other status, e.g. RTE_COMP_OP_STATUS_INVALID_ARGS, a retry with ++``rte_compressdev_enqueue_burst()``. If the number of ops enqueued < the number of ops requested ++then the app should check the op.status of nb_enqd+1. ++If the status is RTE_COMP_OP_STATUS_NOT_PROCESSED, it likely indicates a full-queue case for a ++hardware device, and a retry after dequeuing some ops is likely to be successful. ++If the op holds any other status, e.g. RTE_COMP_OP_STATUS_INVALID_ARGS, a retry with + the same op is unlikely to be successful. + + ++.. _compressdev_prod_cons_op_status: ++ + Produced, Consumed And Operation Status + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-- If status is RTE_COMP_OP_STATUS_SUCCESS, ++- If the status is RTE_COMP_OP_STATUS_SUCCESS, + consumed = amount of data read from input buffer, and + produced = amount of data written in destination buffer + - If status is RTE_COMP_OP_STATUS_ERROR, +@@ -253,37 +257,37 @@ Produced, Consumed And Operation Status + - If status is RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE, + consumed = amount of data read, and + produced = amount of data successfully produced until +- out of space condition hit. PMD has ability to recover +- from here, so application can submit next op from +- consumed+1 and a destination buffer with available space. ++ out of space condition hit. The PMD has ability to recover ++ from here, so an application can submit the next op from ++ consumed+1, and a destination buffer with available space. + + Transforms + ---------- + + Compression transforms (``rte_comp_xform``) are the mechanism + to specify the details of the compression operation such as algorithm, +-window size and checksum. ++window size, and checksum. + + Compression API Hash support + ---------------------------- + +-Compression API allows application to enable digest calculation ++The compression API allows an application to enable digest calculation + alongside compression and decompression of data. A PMD reflects its + support for hash algorithms via capability algo feature flags. +-If supported, PMD calculates digest always on plaintext i.e. ++If supported, the PMD always calculates the digest on plaintext i.e. + before compression and after decompression. + + Currently supported list of hash algos are SHA-1 and SHA2 family + SHA256. + +-See *DPDK API Reference* for details. ++See the `DPDK API Reference `_ for details. + +-If required, application should set valid hash algo in compress ++If required, the application should set the valid hash algo in compress + or decompress xforms during ``rte_compressdev_stream_create()`` +-or ``rte_compressdev_private_xform_create()`` and pass a valid ++or ``rte_compressdev_private_xform_create()``, and pass a valid + output buffer in ``rte_comp_op`` hash field struct to store the +-resulting digest. Buffer passed should be contiguous and large +-enough to store digest which is 20 bytes for SHA-1 and ++resulting digest. The buffer passed should be contiguous and large ++enough to store digest, which is 20 bytes for SHA-1 and + 32 bytes for SHA2-256. + + Compression API Stateless operation +@@ -295,20 +299,21 @@ An op is processed stateless if it has + (required only on compression side), + - All required input in source buffer + +-When all of the above conditions are met, PMD initiates stateless processing ++When all of the above conditions are met, the PMD initiates stateless processing + and releases acquired resources after processing of current operation is +-complete. Application can enqueue multiple stateless ops in a single burst ++complete. The application can enqueue multiple stateless ops in a single burst + and must attach priv_xform handle to such ops. + + priv_xform in Stateless operation + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-priv_xform is PMD internally managed private data that it maintains to do stateless processing. +-priv_xforms are initialized provided a generic xform structure by an application via making call +-to ``rte_compressdev_private_xform_create``, at an output PMD returns an opaque priv_xform reference. +-If PMD support SHAREABLE priv_xform indicated via algorithm feature flag, then application can +-attach same priv_xform with many stateless ops at-a-time. If not, then application needs to +-create as many priv_xforms as it expects to have stateless operations in-flight. ++A priv_xform is private data managed internally by the PMD to do stateless processing. ++A priv_xform is initialized by an application providing a generic xform structure ++to ``rte_compressdev_private_xform_create``, which returns an opaque priv_xform reference. ++If the PMD supports SHAREABLE priv_xform, indicated via algorithm feature flag, ++then the application can attach the same priv_xform with many stateless ops at a time. ++If not, then the application needs to create as many priv_xforms as it expects to have ++stateless operations in-flight. + + .. figure:: img/stateless-op.* + +@@ -320,8 +325,9 @@ create as many priv_xforms as it expects to have stateless operations in-flight. + Stateless Ops using Shareable priv_xform + + +-Application should call ``rte_compressdev_private_xform_create()`` and attach to stateless op before +-enqueuing them for processing and free via ``rte_compressdev_private_xform_free()`` during termination. ++The application should call ``rte_compressdev_private_xform_create()`` and attach it to a stateless ++op before enqueuing them for processing and free via ``rte_compressdev_private_xform_free()`` ++during termination. + + An example pseudocode to setup and process NUM_OPS stateless ops with each of length OP_LEN + using priv_xform would look like: +@@ -332,7 +338,7 @@ using priv_xform would look like: + * pseudocode for stateless compression + */ + +- uint8_t cdev_id = rte_compressdev_get_dev_id(); ++ uint8_t cdev_id = rte_compressdev_get_dev_id(); + + /* configure the device. */ + if (rte_compressdev_configure(cdev_id, &conf) < 0) +@@ -399,75 +405,80 @@ using priv_xform would look like: + + + Stateless and OUT_OF_SPACE +-~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-OUT_OF_SPACE is a condition when output buffer runs out of space and where PMD +-still has more data to produce. If PMD runs into such condition, then PMD returns +-RTE_COMP_OP_OUT_OF_SPACE_TERMINATED error. In such case, PMD resets itself and can set ++OUT_OF_SPACE is a condition when the output buffer runs out of space and where the PMD ++still has more data to produce. If the PMD runs into such condition, then the PMD returns ++RTE_COMP_OP_OUT_OF_SPACE_TERMINATED error. In such case, the PMD resets itself and can set + consumed=0 and produced=amount of output it could produce before hitting out_of_space. +-Application would need to resubmit the whole input with a larger output buffer, if it ++The application would need to resubmit the whole input with a larger output buffer, if it + wants the operation to be completed. + + Hash in Stateless + ~~~~~~~~~~~~~~~~~ +-If hash is enabled, digest buffer will contain valid data after op is successfully ++If hash is enabled, the digest buffer will contain valid data after an op is successfully + processed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS. + + Checksum in Stateless + ~~~~~~~~~~~~~~~~~~~~~ +-If checksum is enabled, checksum will only be available after op is successfully ++If checksum is enabled, checksum will only be available after an op is successfully + processed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS. + ++.. _compressdev_stateful_op: ++ + Compression API Stateful operation + ----------------------------------- + +-Compression API provide RTE_COMP_FF_STATEFUL_COMPRESSION and +-RTE_COMP_FF_STATEFUL_DECOMPRESSION feature flag for PMD to reflect ++The compression API provides RTE_COMP_FF_STATEFUL_COMPRESSION and ++RTE_COMP_FF_STATEFUL_DECOMPRESSION feature flag for the PMD to reflect + its support for Stateful operations. + +-A Stateful operation in DPDK compression means application invokes enqueue +-burst() multiple times to process related chunk of data because +-application broke data into several ops. ++A Stateful operation in DPDK compression means the application invokes enqueue ++burst() multiple times to process a related chunk of data because the ++application broke the data into several ops. + +-In such case ++In such cases + - ops are setup with op_type RTE_COMP_OP_STATEFUL, +-- all ops except last set to flush value = RTE_COMP_FLUSH_NONE/SYNC +-and last set to flush value RTE_COMP_FLUSH_FULL/FINAL. ++- all ops except the last are set with flush value = RTE_COMP_FLUSH_NONE/SYNC ++and the last is set with flush value RTE_COMP_FLUSH_FULL/FINAL. + +-In case of either one or all of the above conditions, PMD initiates +-stateful processing and releases acquired resources after processing ++In case of either one or all of the above conditions, the PMD initiates ++stateful processing and releases acquired resources after processing the + operation with flush value = RTE_COMP_FLUSH_FULL/FINAL is complete. +-Unlike stateless, application can enqueue only one stateful op from +-a particular stream at a time and must attach stream handle ++Unlike stateless, the application can enqueue only one stateful op from ++a particular stream at a time and must attach a stream handle + to each op. + + Stream in Stateful operation + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-`stream` in DPDK compression is a logical entity which identifies related set of ops, say, a one large +-file broken into multiple chunks then file is represented by a stream and each chunk of that file is +-represented by compression op `rte_comp_op`. Whenever application wants a stateful processing of such +-data, then it must get a stream handle via making call to ``rte_compressdev_stream_create()`` +-with xform, at an output the target PMD will return an opaque stream handle to application which +-it must attach to all of the ops carrying data of that stream. In stateful processing, every op +-requires previous op data for compression/decompression. A PMD allocates and set up resources such +-as history, states, etc. within a stream, which are maintained during the processing of the related ops. ++A stream in DPDK compression is a logical entity which identifies a related set of ops. ++For example, one large file broken into multiple chunks, then the file is represented by a stream, ++and each chunk of that file is represented by a compression op ``rte_comp_op``. ++Whenever an application wants stateful processing of such data, then it must get a stream handle ++via making call to ``rte_compressdev_stream_create()`` with an xform, which will return an opaque ++stream handle to attach to all of the ops carrying data of that stream. ++In stateful processing, every op requires previous op data for compression/decompression. ++A PMD allocates and sets up resources such as history, states, etc. within a stream, ++which are maintained during the processing of related ops. + +-Unlike priv_xforms, stream is always a NON_SHAREABLE entity. One stream handle must be attached to only +-one set of related ops and cannot be reused until all of them are processed with status Success or failure. ++Unlike priv_xforms, a stream is always a NON_SHAREABLE entity. One stream handle must be attached ++to only one set of related ops and cannot be reused until all of them are processed with a ++success/failure status. + + .. figure:: img/stateful-op.* + + Stateful Ops + + +-Application should call ``rte_compressdev_stream_create()`` and attach to op before ++An application should call ``rte_compressdev_stream_create()`` and attach it to the op before + enqueuing them for processing and free via ``rte_compressdev_stream_free()`` during +-termination. All ops that are to be processed statefully should carry *same* stream. ++termination. All ops that are to be processed statefully should carry the *same* stream. + +-See *DPDK API Reference* document for details. ++See the `DPDK API Reference `_ for details. + +-An example pseudocode to set up and process a stream having NUM_CHUNKS with each chunk size of CHUNK_LEN would look like: ++An example pseudocode to set up and process a stream having NUM_CHUNKS, ++with each chunk size of CHUNK_LEN, would look like: + + .. code-block:: c + +@@ -475,7 +486,7 @@ An example pseudocode to set up and process a stream having NUM_CHUNKS with each + * pseudocode for stateful compression + */ + +- uint8_t cdev_id = rte_compressdev_get_dev_id(); ++ uint8_t cdev_id = rte_compressdev_get_dev_id(); + + /* configure the device. */ + if (rte_compressdev_configure(cdev_id, &conf) < 0) +@@ -549,64 +560,65 @@ An example pseudocode to set up and process a stream having NUM_CHUNKS with each + + + Stateful and OUT_OF_SPACE +-~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++~~~~~~~~~~~~~~~~~~~~~~~~~ + +-If PMD supports stateful operation, then OUT_OF_SPACE status is not an actual +-error for the PMD. In such case, PMD returns with status ++If a PMD supports stateful operation, then an OUT_OF_SPACE status is not an actual ++error for the PMD. In such a case, the PMD returns with status + RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE with consumed = number of input bytes +-read and produced = length of complete output buffer. +-Application should enqueue next op with source starting at consumed+1 and an ++read, and produced = length of complete output buffer. ++The application should enqueue the next op with source starting at consumed+1, and an + output buffer with available space. + + Hash in Stateful + ~~~~~~~~~~~~~~~~ +-If enabled, digest buffer will contain valid digest after last op in stream ++If enabled, the digest buffer will contain valid digest after the last op in a stream + (having flush = RTE_COMP_FLUSH_FINAL) is successfully processed i.e. dequeued + with status = RTE_COMP_OP_STATUS_SUCCESS. + + Checksum in Stateful + ~~~~~~~~~~~~~~~~~~~~ +-If enabled, checksum will only be available after last op in stream ++If enabled, the checksum will only be available after the last op in a stream + (having flush = RTE_COMP_FLUSH_FINAL) is successfully processed i.e. dequeued + with status = RTE_COMP_OP_STATUS_SUCCESS. + + Burst in compression API +-------------------------- ++------------------------ + + Scheduling of compression operations on DPDK's application data path is + performed using a burst oriented asynchronous API set. A queue pair on a compression +-device accepts a burst of compression operations using enqueue burst API. On physical +-devices the enqueue burst API will place the operations to be processed ++device accepts a burst of compression operations using the enqueue burst API. ++On physical devices the enqueue burst API will place the operations to be processed + on the device's hardware input queue, for virtual devices the processing of the + operations is usually completed during the enqueue call to the compression + device. The dequeue burst API will retrieve any processed operations available + from the queue pair on the compression device, from physical devices this is usually +-directly from the devices processed queue, and for virtual device's from a ++directly from the devices processed queue, and for virtual device's from an + ``rte_ring`` where processed operations are placed after being processed on the + enqueue call. + +-A burst in DPDK compression can be a combination of stateless and stateful operations with a condition +-that for stateful ops only one op at-a-time should be enqueued from a particular stream i.e. no-two ops +-should belong to same stream in a single burst. However a burst may contain multiple stateful ops as long +-as each op is attached to a different stream i.e. a burst can look like: ++A burst in DPDK compression can be a combination of stateless and stateful operations with a ++condition that for stateful ops only one op at a time should be enqueued from a particular stream ++i.e. two ops should never belong to the same stream in a single burst. ++However, a burst may contain multiple stateful ops, as long as each op is attached to a different ++stream, i.e. a burst can look like: + + +---------------+--------------+--------------+-----------------+--------------+--------------+ + | enqueue_burst | op1.no_flush | op2.no_flush | op3.flush_final | op4.no_flush | op5.no_flush | + +---------------+--------------+--------------+-----------------+--------------+--------------+ + +-Where, op1 .. op5 all belong to different independent data units. op1, op2, op4, op5 must be stateful +-as stateless ops can only use flush full or final and op3 can be of type stateless or stateful. +-Every op with type set to RTE_COMP_OP_STATELESS must be attached to priv_xform and +-Every op with type set to RTE_COMP_OP_STATEFUL *must* be attached to stream. ++Where, op1 .. op5 all belong to different independent data units. op1, op2, op4, op5 must be ++stateful as stateless ops can only use flush full or final and op3 can be of type stateless or ++stateful. Every op with type set to RTE_COMP_OP_STATELESS must be attached to priv_xform and ++every op with type set to RTE_COMP_OP_STATEFUL *must* be attached to stream. + + Since each operation in a burst is independent and thus can be completed +-out-of-order, applications which need ordering, should setup per-op user data +-area with reordering information so that it can determine enqueue order at ++out of order, applications which need ordering should setup a per-op user data ++area, with reordering information so that it can determine enqueue order at + dequeue. + +-Also if multiple threads calls enqueue_burst() on same queue pair then it’s +-application onus to use proper locking mechanism to ensure exclusive enqueuing +-of operations. ++Also, if multiple threads calls enqueue_burst() on the same queue pair then it's ++the application's responsibility to use a proper locking mechanism to ensure ++exclusive enqueuing of operations. + + Enqueue / Dequeue Burst APIs + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@@ -629,9 +641,10 @@ Sample code + ----------- + + There are unit test applications that show how to use the compressdev library inside +-app/test/test_compressdev.c ++``app/test/test_compressdev.c`` + + Compression Device API + ~~~~~~~~~~~~~~~~~~~~~~ + +-The compressdev Library API is described in the *DPDK API Reference* document. ++The compressdev Library API is described in the ++`DPDK API Reference `_. diff --git a/dpdk/doc/guides/prog_guide/cryptodev_lib.rst b/dpdk/doc/guides/prog_guide/cryptodev_lib.rst index ac16437740..c839379885 100644 --- a/dpdk/doc/guides/prog_guide/cryptodev_lib.rst @@ -13519,6 +19023,58 @@ index ac16437740..c839379885 100644 The cryptodev Library API is described in the -`DPDK API Reference `_ +`DPDK API Reference `_ +diff --git a/dpdk/doc/guides/prog_guide/dev_kit_build_system.rst b/dpdk/doc/guides/prog_guide/dev_kit_build_system.rst +index 74dba4dd16..5e36e382ba 100644 +--- a/dpdk/doc/guides/prog_guide/dev_kit_build_system.rst ++++ b/dpdk/doc/guides/prog_guide/dev_kit_build_system.rst +@@ -9,7 +9,7 @@ Development Kit Build System + The DPDK requires a build system for compilation activities and so on. + This section describes the constraints and the mechanisms used in the DPDK framework. + +-There are two use-cases for the framework: ++There are two use cases for the framework: + + * Compilation of the DPDK libraries and sample applications; + the framework generates specific binary libraries, +diff --git a/dpdk/doc/guides/prog_guide/env_abstraction_layer.rst b/dpdk/doc/guides/prog_guide/env_abstraction_layer.rst +index 48a2fec066..6c84566596 100644 +--- a/dpdk/doc/guides/prog_guide/env_abstraction_layer.rst ++++ b/dpdk/doc/guides/prog_guide/env_abstraction_layer.rst +@@ -465,7 +465,7 @@ devices would fail anyway. + - By default, the mempool, first asks for IOVA-contiguous memory using + ``RTE_MEMZONE_IOVA_CONTIG``. This is slow in RTE_IOVA_PA mode and it may + affect the application boot time. +- - It is easy to enable large amount of IOVA-contiguous memory use-cases ++ - It is easy to enable large amount of IOVA-contiguous memory use cases + with IOVA in VA mode. + + It is expected that all PCI drivers work in both RTE_IOVA_PA and +diff --git a/dpdk/doc/guides/prog_guide/eventdev.rst b/dpdk/doc/guides/prog_guide/eventdev.rst +index 7bcd7603b1..b415d6355f 100644 +--- a/dpdk/doc/guides/prog_guide/eventdev.rst ++++ b/dpdk/doc/guides/prog_guide/eventdev.rst +@@ -120,7 +120,7 @@ Ports + ~~~~~ + + Ports are the points of contact between worker cores and the eventdev. The +-general use-case will see one CPU core using one port to enqueue and dequeue ++general use case will see one CPU core using one port to enqueue and dequeue + events from an eventdev. Ports are linked to queues in order to retrieve events + from those queues (more details in `Linking Queues and Ports`_ below). + +diff --git a/dpdk/doc/guides/prog_guide/flow_classify_lib.rst b/dpdk/doc/guides/prog_guide/flow_classify_lib.rst +index f0ed5a1a04..7dae0bc8c6 100644 +--- a/dpdk/doc/guides/prog_guide/flow_classify_lib.rst ++++ b/dpdk/doc/guides/prog_guide/flow_classify_lib.rst +@@ -366,7 +366,7 @@ Packet Matching + ~~~~~~~~~~~~~~~ + + The ``rte_flow_classifier_query`` API is used to find packets which match a +-given flow Flow rule in the table. ++given flow rule in the table. + This API calls the flow_classify_run internal function which calls the + ``table.ops.f_lookup`` API to see if any packets in a burst match any + of the Flow rules in the table. diff --git a/dpdk/doc/guides/prog_guide/img/ring-mp-enqueue3.svg b/dpdk/doc/guides/prog_guide/img/ring-mp-enqueue3.svg index da483b031e..83ef7dba13 100644 --- a/dpdk/doc/guides/prog_guide/img/ring-mp-enqueue3.svg @@ -13941,6 +19497,22 @@ index 32d09ccf82..f5904f4d1b 100644 The KNI interfaces are created by a DPDK application dynamically via the ``rte_kni_alloc()`` function. +diff --git a/dpdk/doc/guides/prog_guide/lpm6_lib.rst b/dpdk/doc/guides/prog_guide/lpm6_lib.rst +index d1aea91ca9..8425d14805 100644 +--- a/dpdk/doc/guides/prog_guide/lpm6_lib.rst ++++ b/dpdk/doc/guides/prog_guide/lpm6_lib.rst +@@ -64,9 +64,9 @@ that are most commonly used in IPv6. + + The main data structure is built using the following elements: + +-* A table with 224 entries ++* A table with 2^24 entries + +-* A number of tables, configurable by the user through the API, with 28 entries ++* A number of tables, configurable by the user through the API, with 2^8 entries + + The first table, called tbl24, is indexed using the first 24 bits of the IP address be looked up, + while the rest of the tables, called tbl8s, diff --git a/dpdk/doc/guides/prog_guide/lto.rst b/dpdk/doc/guides/prog_guide/lto.rst index 43f4c63379..277a6f1090 100644 --- a/dpdk/doc/guides/prog_guide/lto.rst @@ -13955,7 +19527,7 @@ index 43f4c63379..277a6f1090 100644 in config file. diff --git a/dpdk/doc/guides/prog_guide/multi_proc_support.rst b/dpdk/doc/guides/prog_guide/multi_proc_support.rst -index a84083b96c..1a4a9e2d4d 100644 +index a84083b96c..f2e16647e6 100644 --- a/dpdk/doc/guides/prog_guide/multi_proc_support.rst +++ b/dpdk/doc/guides/prog_guide/multi_proc_support.rst @@ -75,7 +75,7 @@ and point to the same objects, in both processes. @@ -13967,6 +19539,15 @@ index a84083b96c..1a4a9e2d4d 100644 Deployment Models ----------------- +@@ -325,7 +325,7 @@ supported. However, since sending messages (not requests) does not involve an + IPC thread, sending messages while processing another message or request is + supported. + +-Since the memory sybsystem uses IPC internally, memory allocations and IPC must ++Since the memory subsystem uses IPC internally, memory allocations and IPC must + not be mixed: it is not safe to use IPC inside a memory-related callback, nor is + it safe to allocate/free memory inside IPC callbacks. Attempting to do so may + lead to a deadlock. diff --git a/dpdk/doc/guides/prog_guide/packet_classif_access_ctrl.rst b/dpdk/doc/guides/prog_guide/packet_classif_access_ctrl.rst index 2945eacf55..f99302a5e8 100644 --- a/dpdk/doc/guides/prog_guide/packet_classif_access_ctrl.rst @@ -13984,6 +19565,19 @@ index 2945eacf55..f99302a5e8 100644 It is purely a runtime decision which method to choose, there is no build-time difference. All implementations operates over the same internal RT structures and use similar principles. The main difference is that vector implementations can manually exploit IA SIMD instructions and process several input data flows in parallel. At startup ACL library determines the highest available classify method for the given platform and sets it as default one. Though the user has an ability to override the default classifier function for a given ACL context or perform particular search using non-default classify method. In that case it is user responsibility to make sure that given platform supports selected classify implementation. +diff --git a/dpdk/doc/guides/prog_guide/qos_framework.rst b/dpdk/doc/guides/prog_guide/qos_framework.rst +index a159709450..f39b099f03 100644 +--- a/dpdk/doc/guides/prog_guide/qos_framework.rst ++++ b/dpdk/doc/guides/prog_guide/qos_framework.rst +@@ -737,7 +737,7 @@ Strict priority scheduling of traffic classes within the same pipe is implemente + which selects the queues in ascending order. + Therefore, queue 0 (associated with TC 0, highest priority TC) is handled before + queue 1 (TC 1, lower priority than TC 0), +-which is handled before queue 2 (TC 2, lower priority than TC 1) and it conitnues until queues of all TCs except the ++which is handled before queue 2 (TC 2, lower priority than TC 1) and it continues until queues of all TCs except the + lowest priority TC are handled. At last, queues 12..15 (best effort TC, lowest priority TC) are handled. + + Upper Limit Enforcement diff --git a/dpdk/doc/guides/prog_guide/rcu_lib.rst b/dpdk/doc/guides/prog_guide/rcu_lib.rst index 8d0dfcf291..9b0bf138f6 100644 --- a/dpdk/doc/guides/prog_guide/rcu_lib.rst @@ -13997,6 +19591,26 @@ index 8d0dfcf291..9b0bf138f6 100644 deleted entry. It can be noted that, the critical sections for D2 is a quiescent state +diff --git a/dpdk/doc/guides/prog_guide/rte_flow.rst b/dpdk/doc/guides/prog_guide/rte_flow.rst +index a254c81efa..ce19d94710 100644 +--- a/dpdk/doc/guides/prog_guide/rte_flow.rst ++++ b/dpdk/doc/guides/prog_guide/rte_flow.rst +@@ -65,12 +65,12 @@ Flow rules can also be grouped, the flow rule priority is specific to the + group they belong to. All flow rules in a given group are thus processed within + the context of that group. Groups are not linked by default, so the logical + hierarchy of groups must be explicitly defined by flow rules themselves in each +-group using the JUMP action to define the next group to redirect too. Only flow +-rules defined in the default group 0 are guarantee to be matched against, this ++group using the JUMP action to define the next group to redirect to. Only flow ++rules defined in the default group 0 are guaranteed to be matched against. This + makes group 0 the origin of any group hierarchy defined by an application. + + Support for multiple actions per rule may be implemented internally on top +-of non-default hardware priorities, as a result both features may not be ++of non-default hardware priorities. As a result, both features may not be + simultaneously available to applications. + + Considering that allowed pattern/actions combinations cannot be known in diff --git a/dpdk/doc/guides/prog_guide/thread_safety_dpdk_functions.rst b/dpdk/doc/guides/prog_guide/thread_safety_dpdk_functions.rst index 0f539db2b8..5618e25e47 100644 --- a/dpdk/doc/guides/prog_guide/thread_safety_dpdk_functions.rst @@ -14012,10 +19626,63 @@ index 0f539db2b8..5618e25e47 100644 Interrupt Thread ---------------- +diff --git a/dpdk/doc/guides/prog_guide/writing_efficient_code.rst b/dpdk/doc/guides/prog_guide/writing_efficient_code.rst +index 849f63efe7..0a2ce32753 100644 +--- a/dpdk/doc/guides/prog_guide/writing_efficient_code.rst ++++ b/dpdk/doc/guides/prog_guide/writing_efficient_code.rst +@@ -119,8 +119,8 @@ The code algorithm that dequeues messages may be something similar to the follow + my_process_bulk(obj_table, count); + } + +-PMD Driver +----------- ++PMD ++--- + + The DPDK Poll Mode Driver (PMD) is also able to work in bulk/burst mode, + allowing the factorization of some code for each call in the send or receive function. +@@ -143,20 +143,21 @@ In order to achieve higher throughput, + the DPDK attempts to aggregate the cost of processing each packet individually by processing packets in bursts. + + Using the testpmd application as an example, +-the burst size can be set on the command line to a value of 16 (also the default value). +-This allows the application to request 16 packets at a time from the PMD. ++the burst size can be set on the command line to a value of 32 (also the default value). ++This allows the application to request 32 packets at a time from the PMD. + The testpmd application then immediately attempts to transmit all the packets that were received, +-in this case, all 16 packets. ++in this case, all 32 packets. + + The packets are not transmitted until the tail pointer is updated on the corresponding TX queue of the network port. + This behavior is desirable when tuning for high throughput because +-the cost of tail pointer updates to both the RX and TX queues can be spread across 16 packets, ++the cost of tail pointer updates to both the RX and TX queues can be spread ++across 32 packets, + effectively hiding the relatively slow MMIO cost of writing to the PCIe* device. + However, this is not very desirable when tuning for low latency because +-the first packet that was received must also wait for another 15 packets to be received. +-It cannot be transmitted until the other 15 packets have also been processed because ++the first packet that was received must also wait for another 31 packets to be received. ++It cannot be transmitted until the other 31 packets have also been processed because + the NIC will not know to transmit the packets until the TX tail pointer has been updated, +-which is not done until all 16 packets have been processed for transmission. ++which is not done until all 32 packets have been processed for transmission. + + To consistently achieve low latency, even under heavy system load, + the application developer should avoid processing packets in bunches. diff --git a/dpdk/doc/guides/rawdevs/ntb.rst b/dpdk/doc/guides/rawdevs/ntb.rst -index 58472135f5..aa7d809649 100644 +index 58472135f5..439bc51473 100644 --- a/dpdk/doc/guides/rawdevs/ntb.rst +++ b/dpdk/doc/guides/rawdevs/ntb.rst +@@ -18,7 +18,7 @@ BIOS setting on Intel Skylake + ----------------------------- + + Intel Non-transparent Bridge needs special BIOS setting. Since the PMD only +-supports Intel Skylake platform, introduce BIOS setting here. The referencce ++supports Intel Skylake platform, introduce BIOS setting here. The reference + is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf + + - Set the needed PCIe port as NTB to NTB mode on both hosts. @@ -52,11 +52,11 @@ NTB PMD needs kernel PCI driver to support write combining (WC) to get better performance. The difference will be more than 10 times. To enable WC, there are 2 ways. @@ -14031,10 +19698,23 @@ index 58472135f5..aa7d809649 100644 - Enable WC for NTB device's Bar 2 and Bar 4 (Mapped memory) manually. The reference is https://www.kernel.org/doc/html/latest/x86/mtrr.html diff --git a/dpdk/doc/guides/rel_notes/deprecation.rst b/dpdk/doc/guides/rel_notes/deprecation.rst -index afa94b43e2..58109590cc 100644 +index afa94b43e2..7ac836098a 100644 --- a/dpdk/doc/guides/rel_notes/deprecation.rst +++ b/dpdk/doc/guides/rel_notes/deprecation.rst -@@ -67,12 +67,6 @@ Deprecation Notices +@@ -59,6 +59,12 @@ Deprecation Notices + - ``rte_eth_dev_stop`` + - ``rte_eth_dev_close`` + ++* ethdev: Will add ``RTE_ETH_`` prefix to all ethdev macros/enums in v21.11. ++ Macros will be added for backward compatibility. ++ Backward compatibility macros will be removed on v22.11. ++ A few old backward compatibility macros from 2013 that does not have ++ proper prefix will be removed on v21.11. ++ + * ethdev: New offload flags ``DEV_RX_OFFLOAD_FLOW_MARK`` will be added in 19.11. + This will allow application to enable or disable PMDs from updating + ``rte_mbuf::hash::fdir``. +@@ -67,12 +73,6 @@ Deprecation Notices In 19.11 PMDs will still update the field even when the offload is not enabled. @@ -14047,7 +19727,7 @@ index afa94b43e2..58109590cc 100644 * sched: To allow more traffic classes, flexible mapping of pipe queues to traffic classes, and subport level configuration of pipes and queues changes will be made to macros, data structures and API functions defined -@@ -81,8 +75,3 @@ Deprecation Notices +@@ -81,8 +81,3 @@ Deprecation Notices * metrics: The function ``rte_metrics_init`` will have a non-void return in order to notify errors instead of calling ``rte_exit``. @@ -14056,6 +19736,106 @@ index afa94b43e2..58109590cc 100644 - to set new power environment if power environment was already initialized. - In this case the function will return -1 unless the environment is unset first - (using ``rte_power_unset_env``). Other function usage scenarios will not change. +diff --git a/dpdk/doc/guides/rel_notes/known_issues.rst b/dpdk/doc/guides/rel_notes/known_issues.rst +index 68c3d22bea..0eee6c0e97 100644 +--- a/dpdk/doc/guides/rel_notes/known_issues.rst ++++ b/dpdk/doc/guides/rel_notes/known_issues.rst +@@ -250,7 +250,7 @@ PMD does not work with --no-huge EAL command line parameter + + **Description**: + Currently, the DPDK does not store any information about memory allocated by ``malloc()` (for example, NUMA node, +- physical address), hence PMD drivers do not work when the ``--no-huge`` command line parameter is supplied to EAL. ++ physical address), hence PMDs do not work when the ``--no-huge`` command line parameter is supplied to EAL. + + **Implication**: + Sending and receiving data with PMD will not work. +@@ -419,7 +419,7 @@ Binding PCI devices to igb_uio fails on Linux kernel 3.9 when more than one devi + ------------------------------------------------------------------------------------------ + + **Description**: +- A known bug in the uio driver included in Linux kernel version 3.9 prevents more than one PCI device to be ++ A known bug in the UIO driver included in Linux kernel version 3.9 prevents more than one PCI device to be + bound to the igb_uio driver. + + **Implication**: +@@ -614,7 +614,7 @@ I40e VF may not receive packets in the promiscuous mode + Poll Mode Driver (PMD). + + +-uio pci generic module bind failed in X710/XL710/XXV710 ++uio_pci_generic module bind failed in X710/XL710/XXV710 + ------------------------------------------------------- + + **Description**: +@@ -671,7 +671,7 @@ virtio tx_burst() function cannot do TSO on shared packets + Poll Mode Driver (PMD). + + +-igb uio legacy mode can not be used in X710/XL710/XXV710 ++igb_uio legacy mode can not be used in X710/XL710/XXV710 + -------------------------------------------------------- + + **Description**: +@@ -752,7 +752,7 @@ Netvsc driver and application restart + handshake sequence with the host. + + **Resolution/Workaround**: +- Either reboot the guest or remove and reinsert the hv_uio_generic module. ++ Either reboot the guest or remove and reinsert the uio_hv_generic module. + + **Affected Environment/Platform**: + Linux Hyper-V. +@@ -816,7 +816,7 @@ Kernel crash when hot-unplug igb_uio device while DPDK application is running + + **Reason**: + When device is hot-unplugged, igb_uio driver will be removed which will destroy UIO resources. +- Later trying to access any uio resource will cause kernel crash. ++ Later trying to access any UIO resource will cause kernel crash. + + **Resolution/Workaround**: + If using DPDK for PCI HW hot-unplug, prefer to bind device with VFIO instead of IGB_UIO. +diff --git a/dpdk/doc/guides/rel_notes/release_16_04.rst b/dpdk/doc/guides/rel_notes/release_16_04.rst +index e9f1e6ff6c..7e7fcd0ac4 100644 +--- a/dpdk/doc/guides/rel_notes/release_16_04.rst ++++ b/dpdk/doc/guides/rel_notes/release_16_04.rst +@@ -57,7 +57,7 @@ New Features + + * **Enabled Virtio 1.0 support.** + +- Enabled Virtio 1.0 support for Virtio pmd driver. ++ Enabled Virtio 1.0 support for Virtio PMD. + + * **Supported Virtio for ARM.** + +diff --git a/dpdk/doc/guides/rel_notes/release_16_11.rst b/dpdk/doc/guides/rel_notes/release_16_11.rst +index 92e0ec694e..3cec9143cf 100644 +--- a/dpdk/doc/guides/rel_notes/release_16_11.rst ++++ b/dpdk/doc/guides/rel_notes/release_16_11.rst +@@ -77,7 +77,7 @@ New Features + the current version, even 64 bytes packets take two slots with Virtio PMD on guest + side. + +- The main impact is better performance for 0% packet loss use-cases, as it ++ The main impact is better performance for 0% packet loss use cases, as it + behaves as if the virtqueue size was enlarged, so more packets can be buffered + in the case of system perturbations. On the downside, small performance degradations + were measured when running micro-benchmarks. +diff --git a/dpdk/doc/guides/rel_notes/release_18_02.rst b/dpdk/doc/guides/rel_notes/release_18_02.rst +index 3523ea7fdc..4a1b8a92db 100644 +--- a/dpdk/doc/guides/rel_notes/release_18_02.rst ++++ b/dpdk/doc/guides/rel_notes/release_18_02.rst +@@ -142,9 +142,9 @@ New Features + * ``VIRTIO_NET_F_GUEST_UFO``, ``VIRTIO_NET_F_HOST_UFO`` + * ``VIRTIO_NET_F_GSO`` + +- Also added ``VIRTIO_NET_F_GUEST_ANNOUNCE`` feature support in virtio pmd. ++ Also added ``VIRTIO_NET_F_GUEST_ANNOUNCE`` feature support in virtio PMD. + In a scenario where the vhost backend doesn't have the ability to generate +- RARP packets, the VM running virtio pmd can still be live migrated if ++ RARP packets, the VM running virtio PMD can still be live migrated if + ``VIRTIO_NET_F_GUEST_ANNOUNCE`` feature is negotiated. + + * **Updated the AESNI-MB PMD.** diff --git a/dpdk/doc/guides/rel_notes/release_18_08.rst b/dpdk/doc/guides/rel_notes/release_18_08.rst index 8a09dee95c..4ae388c331 100644 --- a/dpdk/doc/guides/rel_notes/release_18_08.rst @@ -14079,8 +19859,50 @@ index ace1534eff..87dfbf5c7d 100644 correctly - ``arm64-bluefield-linux-gcc``. * **Updated the enic driver.** +diff --git a/dpdk/doc/guides/rel_notes/release_19_05.rst b/dpdk/doc/guides/rel_notes/release_19_05.rst +index b4c6972e35..52829bdb08 100644 +--- a/dpdk/doc/guides/rel_notes/release_19_05.rst ++++ b/dpdk/doc/guides/rel_notes/release_19_05.rst +@@ -93,13 +93,13 @@ New Features + Updated the KNI kernel module to set the ``max_mtu`` according to the given + initial MTU size. Without it, the maximum MTU was 1500. + +- Updated the KNI PMD driver to set the ``mbuf_size`` and MTU based on ++ Updated the KNI PMD to set the ``mbuf_size`` and MTU based on + the given mb-pool. This provide the ability to pass jumbo frames + if the mb-pool contains a suitable buffer size. + + * **Added the AF_XDP PMD.** + +- Added a Linux-specific PMD driver for AF_XDP. This PMD can create an AF_XDP socket ++ Added a Linux-specific PMD for AF_XDP. This PMD can create an AF_XDP socket + and bind it to a specific netdev queue. It allows a DPDK application to send + and receive raw packets through the socket which would bypass the kernel + network stack to achieve high performance packet processing. +@@ -311,7 +311,7 @@ ABI Changes + + The ``rte_eth_dev_info`` structure has had two extra fields + added: ``min_mtu`` and ``max_mtu``. Each of these are of type ``uint16_t``. +- The values of these fields can be set specifically by the PMD drivers as ++ The values of these fields can be set specifically by the PMDs as + supported values can vary from device to device. + + * cryptodev: in 18.08 a new structure ``rte_crypto_asym_op`` was introduced and +diff --git a/dpdk/doc/guides/rel_notes/release_19_08.rst b/dpdk/doc/guides/rel_notes/release_19_08.rst +index cbb27e8dc3..d2baa828b1 100644 +--- a/dpdk/doc/guides/rel_notes/release_19_08.rst ++++ b/dpdk/doc/guides/rel_notes/release_19_08.rst +@@ -151,7 +151,7 @@ New Features + * Added multi-queue support to allow one af_xdp vdev with multiple netdev + queues. + * Enabled "need_wakeup" feature which can provide efficient support for the +- usecase where the application and driver executing on the same core. ++ use case where the application and driver executing on the same core. + + * **Enabled infinite Rx in the PCAP PMD.** + diff --git a/dpdk/doc/guides/rel_notes/release_19_11.rst b/dpdk/doc/guides/rel_notes/release_19_11.rst -index 84aa03a1f2..511d7f87bd 100644 +index 84aa03a1f2..5a40e635b3 100644 --- a/dpdk/doc/guides/rel_notes/release_19_11.rst +++ b/dpdk/doc/guides/rel_notes/release_19_11.rst @@ -206,7 +206,7 @@ New Features @@ -14092,6 +19914,15 @@ index 84aa03a1f2..511d7f87bd 100644 * Flow engine selected based on RDMA Core library version. DV flow engine selected if version is rdma-core-24.0 or higher. Verbs flow engine selected otherwise. +@@ -236,7 +236,7 @@ New Features + + * **Added Marvell OCTEON TX2 crypto PMD.** + +- Added a new PMD driver for hardware crypto offload block on ``OCTEON TX2`` ++ Added a new PMD for hardware crypto offload block on ``OCTEON TX2`` + SoC. + + See :doc:`../cryptodevs/octeontx2` for more details @@ -474,9 +474,8 @@ API Changes * event: The function ``rte_event_eth_tx_adapter_enqueue`` takes an additional @@ -14104,7 +19935,7 @@ index 84aa03a1f2..511d7f87bd 100644 * sched: The pipe nodes configuration parameters such as number of pipes, pipe queue sizes, pipe profiles, etc., are moved from port level structure -@@ -918,3 +917,2313 @@ Tested Platforms +@@ -918,3 +917,3905 @@ Tested Platforms * OFED: * MLNX_OFED 4.7-1.0.0.2 @@ -16286,13 +22117,12 @@ index 84aa03a1f2..511d7f87bd 100644 +* rib: fix insertion in some cases +* rib: fix missing header include +* rib: fix missing header includes -+* (tag: 19.11.7-20.11-21.02-rc2) app/testpmd: fix setting maximum packet length -+* (tag: 19.11.7-20.11-21.02-rc2-backports) net/mlx5: fix port attach in secondary process -+* (tag: 19.11.7-21.02rc2-21.02-rc3-backports) net/mlx5: fix VXLAN decap on non-VXLAN flow -+* (tag: 19.11.7-21.02rc2-21.02-rc3) mempool: fix panic on dump or audit -+* (tag: 19.11.7-21.02rc3-21.02-backports) mem: fix build -+* (tag: 19.11.7-21.02rc3-21.02) usertools: fix binding built-in kernel driver -+* (tag: v19.11.7-rc1) version: 19.11.7-rc1 ++* app/testpmd: fix setting maximum packet length ++* net/mlx5: fix port attach in secondary process ++* net/mlx5: fix VXLAN decap on non-VXLAN flow ++* mempool: fix panic on dump or audit ++* mem: fix build ++* usertools: fix binding built-in kernel driver +* test/distributor: fix return buffer queue overload +* test/event_crypto: set cipher operation in transform +* test: fix buffer overflow in Tx burst @@ -16418,6 +22248,1649 @@ index 84aa03a1f2..511d7f87bd 100644 +* The UDP fragmentation offload feature of Virtio-net device can not be turned on in the VM. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=207075 + +* mlx5 VLAN packets will not do RSS. Bug: https://bugs.dpdk.org/show_bug.cgi?id=661 ++ ++19.11.8 Release Notes ++--------------------- ++ ++19.11.8 Fixes ++~~~~~~~~~~~~~ ++ ++* Regenerate meson.build changes required due to reverts ++* Revert "Revert "Revert "build: always link whole DPDK static libraries""" ++* Revert "Revert "Revert "build/pkg-config: improve static linking flags""" ++* Revert "Revert "Revert "build/pkg-config: move pkg-config file creation""" ++* Revert "Revert "Revert "build/pkg-config: output drivers first for static build""" ++* Revert "Revert "Revert "build/pkg-config: prevent overlinking""" ++* Revert "Revert "Revert "devtools: test static linkage with pkg-config""" ++ ++19.11.8 Validation ++~~~~~~~~~~~~~~~~~~ ++ ++* Intel(R) Testing ++ ++ * Builds ++ ++ * Basic Intel NIC (ixgbe, i40e) testing ++ ++ * PF (i40e) ++ * PF (ixgbe) ++ * VF (i40e) ++ * VF (ixgbe) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++* Intel(R) Testing with Open vSwitch ++ ++ * OVS build and link testing with OVS 2.13 (make based) ++ * OVS build and link testing with OVS 2.14 (make based) ++ ++* Canonical(R) Testing ++ ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.04 (meson based) ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.10 (meson based) ++ * OVS-DPDK tests on x86_64 ++ ++19.11.9 Release Notes ++--------------------- ++ ++19.11.9 Fixes ++~~~~~~~~~~~~~ ++ ++* app/bbdev: fix HARQ error messages ++* app/crypto-perf: check memory allocation ++* app/eventdev: fix lcore parsing skipping last core ++* app/eventdev: fix overflow in lcore list parsing ++* app: fix exit messages ++* app/testpmd: fix bitmap of link speeds when force speed ++* app/testpmd: fix build with musl ++* app/testpmd: fix DCB forwarding configuration ++* app/testpmd: fix DCB re-configuration ++* app/testpmd: fix forward lcores number for DCB ++* app/testpmd: fix max queue number for Tx offloads ++* app/testpmd: fix NVGRE encap configuration ++* app/testpmd: fix segment number check ++* app/testpmd: fix Tx/Rx descriptor query error log ++* app/testpmd: remove unnecessary UDP tunnel check ++* bpf: fix JSLT validation ++* build: detect execinfo library on Linux ++* build: exclude meson files from examples installation ++* buildtools: fix build with busybox ++* bus/dpaa: fix 64-bit arch detection ++* bus/dpaa: fix build with musl ++* bus/dpaa: fix statistics reading ++* bus/fslmc: fix random portal hangs with qbman 5.0 ++* bus/fslmc: remove unused debug macro ++* common/dpaax/caamflib: fix build with musl ++* common/dpaax: fix possible null pointer access ++* common/iavf: use pad byte to specify MAC type ++* common/qat: increase IM buffer size for GEN3 ++* common/sfc_efx/base: limit reported MCDI response length ++* compress/qat: enable compression on GEN3 ++* config/ppc: reduce number of cores and NUMA nodes ++* crypto/dpaa2_sec: fix close and uninit functions ++* crypto/dpaa_sec: affine the thread portal affinity ++* crypto/qat: fix null authentication request ++* crypto/qat: fix offset for out-of-place scatter-gather ++* doc: fix build with Sphinx 4 ++* doc: fix HiSilicon copyright syntax ++* doc: fix multiport syntax in nfp guide ++* doc: fix names of UIO drivers ++* doc: fix sphinx rtd theme import in GHA ++* drivers/crypto: fix build with -fno-common ++* drivers/net: check process type in close operation ++* eal: add C++ include guard for reciprocal header ++* eal/arm64: fix platform register bit ++* eal: fix comment of OS-specific header files ++* eal: fix hang in control thread creation ++* eal: fix race in control thread creation ++* eal: fix service core list parsing ++* eal/windows: add cleanup function stub ++* eal/windows: fix default thread priority ++* ethdev: add missing buses in device iterator ++* ethdev: fix redundant flow after RSS expansion ++* ethdev: update flow item GTP QFI definition ++* ethdev: validate input in EEPROM info ++* ethdev: validate input in module EEPROM dump ++* ethdev: validate input in register info ++* eventdev: fix case to initiate crypto adapter service ++* eventdev: fix memory leakage on thread creation failure ++* eventdev: remove redundant thread name setting ++* event/dpaa2: remove unused macros ++* event/octeontx2: fix device reconfigure for single slot ++* examples: add eal cleanup to examples ++* examples/bbdev: fix header include for musl ++* examples/ethtool: remove unused parsing ++* examples/flow_classify: fix NUMA check of port and core ++* examples/l2fwd-cat: fix NUMA check of port and core ++* examples/l2fwd-crypto: fix packet length while decryption ++* examples/l2fwd-crypto: skip masked devices ++* examples/l3fwd: fix LPM IPv6 subnets ++* examples/l3fwd-power: fix empty poll thresholds ++* examples/packet_ordering: fix port configuration ++* examples/ptpclient: remove wrong comment ++* examples/rxtx_callbacks: fix port ID format specifier ++* examples/skeleton: fix NUMA check of port and core ++* examples/timer: fix time interval ++* examples/vhost: check memory table query ++* examples/vhost_crypto: remove unused short option ++* fbarray: fix log message on truncation error ++* net/mlx5: fix flow split combined with counter ++* ipc: check malloc sync reply result ++* ipc: use monotonic clock ++* kni: fix compilation on SLES15-SP3 ++* license: fix typos ++* log/linux: make default output stderr ++* mbuf: check shared memory before dumping dynamic space ++* mem: fix freeing segments in --huge-unlink mode ++* net/af_xdp: fix error handling during Rx queue setup ++* net/ark: refactor Rx buffer recovery ++* net/ark: update packet director initial state ++* net/bnx2x: fix build with GCC 11 ++* net/bnx2x: fix build with GCC 11 ++* net/bnxt: check PCI config read ++* net/bnxt: drop unused attribute ++* net/bnxt: fix build failures after merging patches ++* net/bnxt: fix configuring LRO ++* net/bnxt: fix device readiness check ++* net/bnxt: fix double free in port start failure ++* net/bnxt: fix dynamic VNIC count ++* net/bnxt: fix firmware fatal error handling ++* net/bnxt: fix FW readiness check during recovery ++* net/bnxt: fix handling of null flow mask ++* net/bnxt: fix health check alarm cancellation ++* net/bnxt: fix HWRM and FW incompatibility handling ++* net/bnxt: fix link state operations ++* net/bnxt: fix memory allocation for command response ++* net/bnxt: fix mismatched type comparison in MAC restore ++* net/bnxt: fix PCI write check ++* net/bnxt: fix PTP support for Thor ++* net/bnxt: fix queues per VNIC ++* net/bnxt: fix ring count calculation for Thor ++* net/bnxt: fix RSS context cleanup ++* net/bnxt: fix Rx and Tx timestamps ++* net/bnxt: fix Rx buffer posting ++* net/bnxt: fix Rx descriptor status ++* net/bnxt: fix Rx queue count ++* net/bnxt: fix Rx timestamp when FIFO pending bit is set ++* net/bnxt: fix single PF per port check ++* net/bnxt: fix timesync when PTP is not supported ++* net/bnxt: fix Tx length hint threshold ++* net/bnxt: fix Tx timestamp init ++* net/bnxt: fix VF info allocation ++* net/bnxt: fix VNIC configuration ++* net/bnxt: fix xstats get ++* net/bnxt: prevent device access in error state ++* net/bnxt: refactor multi-queue Rx configuration ++* net/bnxt: remove unnecessary forward declarations ++* net/bnxt: remove unused function parameters ++* net/bnxt: remove unused macro ++* net/bnxt: reset filter indices on free ++* net/bnxt: use prefix on global function ++* net/bonding: fix adding itself as its slave ++* net/bonding: fix LACP system address check ++* net/bonding: fix leak on remove ++* net/bonding: fix socket ID check ++* net/cxgbe: remove use of uint type ++* net/dpaa2: fix getting link status ++* net/e1000/base: fix timeout for shadow RAM write ++* net/e1000: fix flow error message object ++* net/e1000: fix max Rx packet size ++* net/e1000: fix Rx error counter for bad length ++* net/e1000: remove MTU setting limitation ++* net/ena/base: fix type conversions by explicit casting ++* net/ena: fix releasing Tx ring mbufs ++* net/ena: remove endian swap functions ++* net/ena: switch memcpy to optimized version ++* net/failsafe: fix RSS hash offload reporting ++* net/failsafe: report minimum and maximum MTU ++* net: fix comment in IPv6 header ++* net/hinic: fix crash in secondary process ++* net/hns3: clear hash map on flow director clear ++* net/hns3: delete redundant blank line ++* net/hns3: fix DCB mode check ++* net/hns3: fix DCB reconfiguration ++* net/hns3: fix flow control exception ++* net/hns3: fix flow control mode ++* net/hns3: fix flow counter value ++* net/hns3: fix FLR miss detection ++* net/hns3: fix handling link update ++* net/hns3: fix HW buffer size on MTU update ++* net/hns3: fix mailbox error message ++* net/hns3: fix MTU config complexity ++* net/hns3: fix ordering in secondary process initialization ++* net/hns3: fix processing Tx offload flags ++* net/hns3: fix querying flow director counter for out param ++* net/hns3: fix requested FC mode rollback ++* net/hns3: fix rollback after setting PVID failure ++* net/hns3: fix secondary process request start/stop Rx/Tx ++* net/hns3: fix typos on comments ++* net/hns3: fix VF mailbox head field ++* net/hns3: fix VMDq mode check ++* net/hns3: log time delta in decimal format ++* net/hns3: remove meaningless packet buffer rollback ++* net/hns3: remove unused macro ++* net/hns3: remove unused macros ++* net/hns3: remove unused macros ++* net/hns3: remove unused mailbox macro and struct ++* net/hns3: remove unused VMDq code ++* net/hns3: return error on PCI config write failure ++* net/hns3: support get device version when dump register ++* net/hns3: update HiSilicon copyright syntax ++* net/i40e: announce request queue capability in PF ++* net/i40e: fix input set field mask ++* net/i40e: fix IPv4 fragment offload ++* net/i40e: fix lack of MAC type when set MAC address ++* net/i40e: fix negative VEB index ++* net/i40e: fix parsing packet type for NEON ++* net/i40e: fix primary MAC type when starting port ++* net/i40e: fix VF RSS configuration ++* net/i40e: remove redundant VSI check in Tx queue setup ++* net/i40evf: fix packet loss for X722 ++* net/iavf: fix lack of MAC type when set MAC address ++* net/iavf: fix primary MAC type when starting port ++* net/iavf: fix TSO max segment size ++* net/iavf: fix Tx context descriptor ++* net/iavf: fix VF to PF command failure handling ++* net/ice/base: cleanup filter list on error ++* net/ice/base: fix build with GCC 11 ++* net/ice/base: fix memory allocation for MAC addresses ++* net/ice/base: fix memory allocation wrapper ++* net/ice/base: fix payload indicator on ptype ++* net/ice: check some functions return ++* net/ice: fix disabling promiscuous mode ++* net/ice: fix fast mbuf freeing ++* net/ice: fix illegal access when removing MAC filter ++* net/ice: fix VLAN filter with PF ++* net/ice: fix VSI array out of bounds access ++* net/ixgbe: fix RSS RETA being reset after port start ++* net/ixgbe: fix Rx errors statistics for UDP checksum ++* net/kni: check init result ++* net/memif: fix Tx bps statistics for zero-copy ++* net/mlx4: fix buffer leakage on device close ++* net/mlx4: fix leak when configured repeatedly ++* net/mlx4: fix RSS action with null hash key ++* net/mlx4: fix secondary process initialization ordering ++* net/mlx5: fix drop action for Direct Rules/Verbs ++* net/mlx5: fix leak when configured repeatedly ++* net/mlx5: fix metadata item validation for ingress flows ++* net/mlx5: fix probing device in legacy bonding mode ++* net/mlx5: fix Rx metadata leftovers ++* net/mlx5: fix Rx segmented packets on mbuf starvation ++* net/mlx5: fix secondary process initialization ordering ++* net/mlx5: remove drop queue function prototypes ++* net/mlx5: support RSS expansion for IPv6 GRE ++* net/nfp: fix reporting of RSS capabilities ++* net/octeontx2: fix VLAN filter ++* net/pcap: fix format string ++* net/qede: accept bigger RSS table ++* net/qede: reduce log verbosity ++* net/tap: check ioctl on restore ++* net/tap: fix build with GCC 11 ++* net/tap: fix interrupt vector array size ++* net/virtio: fix interrupt unregistering for listening socket ++* net/virtio: fix vectorized Rx queue rearm ++* power: do not skip saving original P-state governor ++* power: fix sanity checks for guest channel read ++* power: remove duplicated symbols from map file ++* power: save original ACPI governor always ++* raw/ntb: check memory allocations ++* raw/ntb: check SPAD user index ++* raw/skeleton: add missing check after setting attribute ++* Revert "kni: fix compilation on SLES15-SP3" ++* service: clean references to removed symbol ++* stack: allow lock-free only on relevant architectures ++* test/bpf: fix error message ++* test: check flow classifier creation ++* test: check thread creation ++* test/cmdline: fix inputs array ++* test/cmdline: silence clang 12 warning ++* test/crypto: fix auth-cipher compare length in OOP ++* test/crypto: fix build with GCC 11 ++* test/distributor: fix burst flush on worker quit ++* test/distributor: fix worker notification in burst mode ++* test/event: fix timeout accuracy ++* test: fix autotest handling of skipped tests ++* test: fix build with GCC 11 ++* test: fix division by zero ++* test: fix TCP header initialization ++* test/kni: check init result ++* test/kni: fix a comment ++* test/mempool: fix object initializer ++* test/power: add delay before checking CPU frequency ++* test/power: add turbo mode to frequency check ++* test/power: fix CPU frequency check ++* test/power: fix low frequency test when turbo enabled ++* test/power: fix turbo test ++* test/power: round CPU frequency to check ++* test: proceed if timer subsystem already initialized ++* test/table: fix build with GCC 11 ++* test/timer: check memzone allocation ++* vdpa/ifc: check PCI config read ++* vfio: do not merge contiguous areas ++* vfio: fix API description ++* vfio: fix DMA mapping granularity for IOVA as VA ++* vfio: fix duplicated user mem map ++* vfio: fix stdbool usage without include ++* vhost: fix batch dequeue potential buffer overflow ++* vhost: fix initialization of temporary header ++* vhost: fix packed ring potential buffer overflow ++* vhost: fix queue initialization ++* vhost: fix split ring potential buffer overflow ++ ++19.11.9 Validation ++~~~~~~~~~~~~~~~~~~ ++ ++* [Intel(R) Testing](http://mails.dpdk.org/archives/stable/2021-July/032349.html) ++ ++ * Builds ++ ++ * Basic Intel NIC (ixgbe, i40e) testing ++ ++ * PF (i40e) ++ * PF (ixgbe) ++ * VF (i40e) ++ * VF (ixgbe) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++* [Intel(R) Testing with Open vSwitch](http://mails.dpdk.org/archives/stable/2021-June/031702.html) ++ ++ * OVS build and link testing with OVS 2.13 (make based) ++ * OVS build and link testing with OVS 2.14 (make based) ++ * VSPERF tests ++ ++ * phy2phy_tput ++ * pvp_tput ++ * pvp_cont ++ * pvvp_tput ++ * pvpv_cont ++ * ovsdpdk_jumbo_p2p ++ * ovsdpdk_jumbo_pvp ++ * ovsdpdk_jumbo_p2p_upper_bound ++ * ovsdpdk_mq_pvp_rxqs_testpmd ++ * ovsdpdk_mq_pvp_rxqs_linux_bridge ++ ++* [Canonical(R) Testing](http://mails.dpdk.org/archives/stable/2021-July/031997.html) ++ ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.04 (meson based) ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.10 (meson based) ++ * Functional and performance tests based on OVS-DPDK on x86_64 ++ * Autopkgtests for DPDK and OpenvSwitch ++ ++* [Red Hat(R) Testing](http://mails.dpdk.org/archives/stable/2021-June/031619.html) ++ ++ * Platform ++ ++ * RHEL 8 ++ * Kernel 4.18 ++ * Qemu 6.0 ++ * X540-AT2 NIC(ixgbe, 10G) ++ * Tested on 19.11.9-RC3 ++ ++ * Tests ++ ++ * Guest with device assignment(PF) throughput testing(1G hugepage size): PASS ++ * Guest with device assignment(PF) throughput testing(2M hugepage size) : PASS ++ * Guest with device assignment(VF) throughput testing: PASS ++ * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing: PASS ++ * PVP vhost-user 2Q throughput testing: PASS ++ * PVP vhost-user 1Q - cross numa node throughput testing: PASS ++ * Guest with vhost-user 2 queues throughput testing: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect: PASS ++ * PVP 1Q live migration testing: PASS ++ * PVP 1Q cross numa node live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M): PASS ++ * Guest with ovs+dpdk+vhost-user 2Q live migration testing: PASS ++ * Host PF + DPDK testing: PASS ++ * Host VF + DPDK testing: PASS ++ ++* [Nvidia (R) Testing](http://mails.dpdk.org/archives/stable/2021-July/032381.html) ++ ++ * functional tests on Mellanox hardware ++ ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.3-1.0.0.1 / Firmware: 14.30.1004 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.3-1.0.0.1 / Firmware: 16.30.1004 ++ ++ * Basic functionality: ++ ++ * Send and receive multiple types of traffic. ++ * testpmd xstats counter test. ++ * testpmd timestamp test. ++ * Changing/checking link status through testpmd. ++ * RTE flow tests: Items: eth / vlan / ipv4 / ipv6 / tcp / udp / icmp / gre / nvgre / vxlan ip in ip / mplsoudp / mplsogre ++ * Actions: drop / queue / rss / mark / flag / jump / count / raw_encap / raw_decap / vxlan_encap / vxlan_decap / NAT / dec_ttl ++ * Some RSS tests. ++ * VLAN filtering, stripping and insertion tests. ++ * Checksum and TSO tests. ++ * ptype tests. ++ * link_status_interrupt example application tests. ++ * l3fwd-power example application tests. ++ * Multi-process example applications tests. ++ ++ * Compilation tests with multiple configurations in the following OS/driver combinations are also passing: ++ ++ * Ubuntu 20.04.2 with MLNX_OFED_LINUX-5.3-1.0.0.1. ++ * Ubuntu 20.04.2 with rdma-core master (a66e2a5). ++ * Ubuntu 20.04.2 with rdma-core v28.0. ++ * Ubuntu 18.04.5 with rdma-core v17.1. ++ * Ubuntu 18.04.5 with rdma-core master (a66e2a5) (i386). ++ * Ubuntu 16.04.7 with rdma-core v22.7. ++ * Fedora 34 with rdma-core v35.0. ++ * Fedora 35 (Rawhide) with rdma-core v35.0 (only with gcc). ++ * CentOS 7 7.9.2009 with rdma-core master (a66e2a5). ++ * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.3-1.0.0.1. ++ * CentOS 8 8.3.2011 with rdma-core master (7f2d460). ++ * OpenSUSE Leap 15.3 with rdma-core v31.0. ++ ++19.11.9 Known Issues ++~~~~~~~~~~~~~~~~~~~~ ++ ++This time there are a few issues which were identified in the tests. But none ++of them is an in-place regression. So far they are all issues with newer ++compilers, toolchains and kernels that happen to be incompatible with the ++19.11.x code. ++ ++* Due to a kernel patch backport in SUSE Linux Enterprise Server 15 SP3 ++ [compilation of kni fails there](https://bugs.dpdk.org/show_bug.cgi?id=728). ++ A fix would break existing SP2 installation and ++ [further options are discussed](http://mails.dpdk.org/archives/stable/2021-June/031210.html) ++ ++* A [Build issue with clang 12.0.1](https://bugs.dpdk.org/show_bug.cgi?id=745) ++ ++* A make [build issue with Fedora 34 with GCC11](https://bugs.dpdk.org/show_bug.cgi?id=744) ++ ++* Meson based [build issues with ICC-19.1.1](https://bugs.dpdk.org/show_bug.cgi?id=747) ++ ++19.11.10 Release Notes ++---------------------- ++ ++19.11.10 Fixes ++~~~~~~~~~~~~~~ ++ ++* app/crypto-perf: fix out-of-place mempool allocation ++* app/test: fix IPv6 header initialization ++* app/testpmd: change port link speed without stopping all ++* app/testpmd: fix help string for port reset ++* app/testpmd: fix IPv4 checksum ++* app/testpmd: fix MAC address after port reset ++* app/testpmd: fix offloads for newly attached port ++* app/testpmd: fix Tx checksum calculation for tunnel ++* bitmap: fix buffer overrun in bitmap init ++* bus: clarify log for non-NUMA-aware devices ++* bus/dpaa: fix freeing in FMAN interface destructor ++* common/mlx5: fix compatibility with OFED port query API ++* common/mlx5: fix Netlink port name padding in probing ++* common/mlx5: use new port query API if available ++* cryptodev: fix freeing after device release ++* crypto/mvsam: fix AES-GCM session parameters ++* crypto/mvsam: fix capabilities ++* crypto/mvsam: fix options parsing ++* crypto/mvsam: fix session data reset ++* crypto/octeontx: fix freeing after device release ++* crypto/qat: fix Arm build with special memcpy ++* devtools: fix file listing in maintainers check ++* distributor: fix 128-bit write alignment ++* doc: add limitation for ConnectX-4 with L2 in mlx5 guide ++* doc: announce common prefix for ethdev ++* doc: fix default burst size in testpmd ++* doc: fix spelling ++* drivers/net: fix memzone allocations for DMA memory ++* ethdev: fix doc of flow action ++* eventdev: fix event port setup in tx adapter ++* flow_classify: fix leaking rules on delete ++* (github-cpaelzer-stable/19.11) telemetry: fix race in telemetry control thread creation ++* (HEAD -> 19.11, tag: v19.11.10-rc2, origin-stable/19.11) version: 19.11.10-rc2 ++* ipc: stop mp control thread on cleanup ++* kni: fix crash on userspace VA for segmented packets ++* kni: fix mbuf allocation for kernel side use ++* mempool/octeontx2: fix shift calculation ++* net/bnxt: check access to possible null pointer ++* net/bnxt: cleanup code ++* net/bnxt: clear cached statistics ++* net/bnxt: detect bad opaque in Rx completion ++* net/bnxt: fix auto-negotiation on Whitney+ ++* net/bnxt: fix check for PTP support in FW ++* net/bnxt: fix error handling in VNIC prepare ++* net/bnxt: fix error messages in VNIC prepare ++* net/bnxt: fix missing barriers in completion handling ++* net/bnxt: fix nested lock during bonding ++* net/bnxt: fix ring and context memory allocation ++* net/bnxt: fix Rx burst size constraint ++* net/bnxt: fix Rx interrupt setting ++* net/bnxt: fix scalar Tx completion handling ++* net/bnxt: fix Tx descriptor status implementation ++* net/bnxt: fix typo in log message ++* net/bnxt: improve probing log message ++* net/bnxt: invoke device removal event on recovery failure ++* net/bnxt: remove unnecessary code ++* net/bnxt: remove unnecessary comment ++* net/bnxt: set flow error after tunnel redirection free ++* net/bnxt: set flow error when free filter not available ++* net/bnxt: use common function to free VNIC resource ++* net/bnxt: workaround spurious zero stats in Thor ++* net/bonding: check flow setting ++* net/bonding: fix error message on flow verify ++* net/ena: enable multi-segment in Tx offload flags ++* net/ena: trigger reset on Tx prepare failure ++* net/hinic/base: fix LRO ++* net/hinic: increase protection of the VLAN ++* net/hns3: fix delay for waiting to stop Rx/Tx ++* net/hns3: fix filter parsing comment ++* net/hns3: fix Tx prepare after stop ++* net/hns3: fix VLAN strip log ++* net/hns3: increase VF reset retry maximum ++* net/i40e: fix descriptor scan on Arm ++* net/i40e: fix multi-process shared data ++* net/iavf: fix RSS key access out of bound ++* net/iavf: fix Tx threshold check ++* net/ice/base: fix first profile mask ++* net/ice/base: revert change of first profile mask ++* net/ice: fix default RSS key generation ++* net/ice: fix memzone leak when firmware is missing ++* net/ixgbe: fix flow entry access after freeing ++* net/mlx5: fix incorrect r/w lock usage in DMA unmap ++* net/mlx5: fix IPIP multi-tunnel validation ++* net/mlx5: fix match MPLS over GRE with key ++* net/mlx5: fix MPLS RSS expansion ++* net/mlx5: fix overflow in mempool argument ++* net/mlx5: fix representor interrupt handler ++* net/mlx5: fix RoCE LAG bond device probing ++* net/mlx5: fix RSS flow item expansion for GRE key ++* net/mlx5: fix Rx/Tx queue checks ++* net/mlx5: fix switchdev mode recognition ++* net/mlx5: fix typo in vectorized Rx comments ++* net/mlx5: limit implicit MPLS RSS expansion over GRE ++* net/mlx5: limit inner RSS expansion for MPLS ++* net/mlx5: remove redundant operations in NEON Rx ++* net/mlx5: remove unsupported flow item MPLS over IP ++* net/mlx5: workaround drop action with old kernel ++* net/mvpp2: fix configured state dependency ++* net/mvpp2: fix port speed overflow ++* net/octeontx2: fix default MCAM allocation size ++* net/octeontx2: fix flow creation limit on CN98xx ++* net/octeontx2: use runtime LSO format indices ++* net/octeontx/base: fix debug build with clang ++* net/pfe: remove unnecessary null check ++* net/sfc: fix MAC stats lock in xstats query by ID ++* net/sfc: fix MAC stats update for stopped device ++* net/sfc: fix reading adapter state without locking ++* net/sfc: fix xstats query by ID according to ethdev ++* net/sfc: fix xstats query by unsorted list of IDs ++* net/softnic: fix connection memory leak ++* net/softnic: fix memory leak as profile is freed ++* net/virtio: fix aarch32 build ++* net/virtio: fix refill order in packed ring datapath ++* net/virtio: report maximum MTU in device info ++* power: fix namespace for internal struct ++* rib: fix max depth IPv6 lookup ++* (tag: v19.11.10-rc1) version: 19.11.10-rc1 ++* test/crypto: fix mbuf reset after null check ++* test/crypto: fix mempool size for session-less ++* test/crypto: fix typo in AES case ++* test/crypto: fix typo in ESN case ++* test/mbuf: fix virtual address conversion ++* tests/eal: fix memory leak ++* vhost/crypto: check request pointer before dereference ++* vhost: fix crash on reconnect ++* vhost: fix missing guest pages table NUMA realloc ++* vhost: fix missing memory table NUMA realloc ++* vhost: utilize dynamic memory allocator ++ ++19.11.10 Validation ++~~~~~~~~~~~~~~~~~~~ ++ ++* [Intel(R) Testing](http://mails.dpdk.org/archives/stable/2021-August/033130.html) ++ ++ * Builds ++ ++ * Basic Intel NIC (ixgbe, i40e) testing ++ ++ * PF (i40e) ++ * PF (ixgbe) ++ * VF (i40e) ++ * VF (ixgbe) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++* [Intel(R) Testing with Open vSwitch] ++ ++ * OVS build and link testing with OVS 2.13 (make based) ++ * OVS build and link testing with OVS 2.14 (make based) ++ * VSPERF tests ++ ++ * phy2phy_tput ++ * pvp_tput ++ * pvp_cont ++ * pvvp_tput ++ * pvpv_cont ++ * ovsdpdk_jumbo_p2p ++ * ovsdpdk_jumbo_pvp ++ * ovsdpdk_jumbo_p2p_upper_bound ++ * ovsdpdk_mq_pvp_rxqs_testpmd ++ * ovsdpdk_mq_pvp_rxqs_linux_bridge ++ ++* [Canonical(R) Testing](http://mails.dpdk.org/archives/stable/2021-August/033126.html) ++ ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.04 (meson based) ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.10 (meson based) ++ * Functional and performance tests based on OVS-DPDK on x86_64 ++ * Autopkgtests for DPDK and OpenvSwitch ++ ++* [Red Hat(R) Testing](http://mails.dpdk.org/archives/stable/2021-September/033218.html) ++ ++ * Platform ++ ++ * RHEL 8 ++ * Kernel 4.18 ++ * Qemu 6.0 ++ * X540-AT2 NIC(ixgbe, 10G) ++ * Tested on 19.11.9-RC3 ++ ++ * Tests ++ ++ * Guest with device assignment(PF) throughput testing(1G hugepage size): PASS ++ * Guest with device assignment(PF) throughput testing(2M hugepage size) : PASS ++ * Guest with device assignment(VF) throughput testing: PASS ++ * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing: PASS ++ * PVP vhost-user 2Q throughput testing: PASS ++ * PVP vhost-user 1Q - cross numa node throughput testing: PASS ++ * Guest with vhost-user 2 queues throughput testing: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect: PASS ++ * PVP 1Q live migration testing: PASS ++ * PVP 1Q cross numa node live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M): PASS ++ * Guest with ovs+dpdk+vhost-user 2Q live migration testing: PASS ++ * Host PF + DPDK testing: PASS ++ * Host VF + DPDK testing: PASS ++ ++* [Nvidia (R) Testing](http://mails.dpdk.org/archives/stable/2021-August/033131.html) ++ ++ * functional tests on Mellanox hardware ++ ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.4-1.0.3.0 / Firmware: 14.31.1014 ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / kernel: 5.14.0-rc7 / Driver: rdma-core v36.0 / Firmware: 14.31.1014 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.4-1.0.3.0 / Firmware: 16.31.1014 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / kernel: 5.14.0-rc7 / Driver: v36.0 / Firmware: 16.31.1014 ++ ++ * Basic functionality: ++ ++ * Send and receive multiple types of traffic. ++ * testpmd xstats counter test. ++ * testpmd timestamp test. ++ * Changing/checking link status through testpmd. ++ * RTE flow tests: Items: eth / vlan / ipv4 / ipv6 / tcp / udp / icmp / gre / nvgre / vxlan ip in ip / mplsoudp / mplsogre ++ * Actions: drop / queue / rss / mark / flag / jump / count / raw_encap / raw_decap / vxlan_encap / vxlan_decap / NAT / dec_ttl ++ * Some RSS tests. ++ * VLAN filtering, stripping and insertion tests. ++ * Checksum and TSO tests. ++ * ptype tests. ++ * link_status_interrupt example application tests. ++ * l3fwd-power example application tests. ++ * Multi-process example applications tests. ++ ++ * Compilation tests with multiple configurations in the following OS/driver combinations are also passing: ++ ++ * Ubuntu 20.04.2 with MLNX_OFED_LINUX-5.4-1.0.3.0. ++ * Ubuntu 20.04.2 with rdma-core master (64d1ae5). ++ * Ubuntu 20.04.2 with rdma-core v28.0. ++ * Ubuntu 18.04.5 with rdma-core v17.1. ++ * Ubuntu 18.04.5 with rdma-core master (5b0f5b2) (i386). ++ * Ubuntu 16.04.7 with rdma-core v22.7. ++ * Fedora 34 with rdma-core v36.0. ++ * Fedora 35 (Rawhide) with rdma-core v36.0 (only with gcc). ++ * CentOS 7 7.9.2009 with rdma-core master (64d1ae5). ++ * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.4-1.0.3.0. ++ * CentOS 8 8.3.2011 with rdma-core master (64d1ae5). ++ * OpenSUSE Leap 15.3 with rdma-core v31.0. ++ ++19.11.10 Known Issues ++~~~~~~~~~~~~~~~~~~~~~ ++ ++A few issues are still present, but none of them is an in-place regression. ++So far they are all issues with newer compilers, toolchains and kernels that ++happen to be incompatible with the 19.11.x code. ++ ++* Due to a kernel patch backport in SUSE Linux Enterprise Server 15 SP3 ++ [compilation of kni fails there](https://bugs.dpdk.org/show_bug.cgi?id=728). ++ A fix would break existing SP2 installation and ++ [further options are discussed](http://mails.dpdk.org/archives/stable/2021-June/031210.html) ++ ++* A [Build issue with clang 12.0.1](https://bugs.dpdk.org/show_bug.cgi?id=745) ++ ++* A make [build issue with Fedora 34 with GCC11](https://bugs.dpdk.org/show_bug.cgi?id=744) ++ ++* Meson based [build issues with ICC-19.1.1](https://bugs.dpdk.org/show_bug.cgi?id=747) ++ ++19.11.11 Release Notes ++---------------------- ++ ++19.11.11 Fixes ++~~~~~~~~~~~~~~ ++ ++* app/crypto-perf: fix AAD template copy overrun ++* app/eventdev: fix terminal colour after control-c exit ++* app/testpmd: fix access to DSCP table entries ++* app/testpmd: fix check without outer checksum ++* app/testpmd: fix DCB in VT configuration ++* app/testpmd: fix dump of Tx offload flags ++* app/testpmd: fix hexadecimal parser with odd length ++* app/testpmd: fix hex string parser in flow commands ++* app/testpmd: fix packet burst spreading stats ++* app/testpmd: fix RSS key length ++* app/testpmd: fix RSS type display ++* app/testpmd: fix Tx retry in flowgen engine ++* app/testpmd: remove unused header file ++* app/testpmd: retain all original dev conf when config DCB ++* bitrate: fix calculation to match API description ++* bitrate: fix registration to match API description ++* bpf: allow self-xor operation ++* bus/fslmc: remove unused device count ++* bus/vmbus: fix leak on device scan ++* bus/vmbus: fix ring buffer mapping in secondary process ++* common/cpt: fix KASUMI input length ++* common/dpaax/caamflib: fix IV for short MAC-I in SNOW3G ++* common/dpaax: fix physical address conversion ++* common/iavf: fix ARQ resource leak ++* common/qat: fix queue pairs number ++* config/ppc: ignore GCC 11 psabi warnings ++* contigmem: update for FreeBSD 13 ++* cryptodev: fix stringop-overflow build failure with gcc 10 ++* crypto/openssl: fix CCM processing 0 length source ++* crypto/qat: fix status in RSA decryption ++* crypto/qat: fix uncleared cookies after operation ++* doc: capitalise PMD ++* doc: describe timestamp limitations for mlx5 ++* doc: fix default mempool option in guides ++* doc: fix emulated device names in e1000 guide ++* doc: fix numbers power of 2 in LPM6 guide ++* doc: remove repeated repeated words ++* doc: strip build artefacts for examples file list ++* drivers/crypto: fix IPsec TTL decrement option ++* drivers/net: fix typo in vector Rx comment ++* drivers/net: fix vector Rx comments ++* eal: fix device iterator when no bus is selected ++* eal/freebsd: fix incorrect variable name ++* eal/freebsd: ignore in-memory option ++* eal/freebsd: lock memory device to prevent conflicts ++* eal/freebsd: update CPU macro for FreeBSD 13 ++* eal/linux: fix uevent message parsing ++* eal/linux: remove unused variable for socket memory ++* eal/ppc: ignore GCC 10 stringop-overflow warnings ++* eal: reset lcore task callback and argument ++* eal/x86: avoid cast-align warning in memcpy functions ++* eal/x86: fix some CPU extended features definitions ++* efd: allow more CPU sockets in table creation ++* ethdev: fix crash on owner delete ++* ethdev: fix PCI device release in secondary process ++* ethdev: fix typos ++* ethdev: fix xstats by ID API documentation ++* eventdev/eth_rx: fix WRR buffer overrun ++* eventdev/eth_tx: fix queue delete logic ++* event/sw: remove unused inflight events count ++* examples/fips_validation: fix device start ++* examples/fips_validation: remove unused allocation ++* examples/l3fwd-power: fix early shutdown ++* examples/multi_process: fix Rx packets distribution ++* examples/ntb: fix build dependency ++* examples/performance-thread: fix build with ASan ++* examples/performance-thread: fix build with clang 12.0.1 ++* examples/performance-thread: remove unused hits count ++* examples/ptpclient: fix delay request message ++* examples/service_cores: fix lcore count check ++* fix PMD wording ++* fix spelling in comments and doxygen ++* hash: fix Doxygen comment of Toeplitz file ++* (HEAD -> 19.11) net/ice: build failure with make and clang < 13 ++* igb_uio: fix build for switch fall through ++* interrupt: fix request notifier interrupt processing ++* kni: check error code of allmulticast mode switch ++* kni: fix build for SLES15-SP3 ++* kni: fix build for SLES15-SP3 (Make) ++* kni: update kernel API to set random MAC address ++* lpm6: fix buffer overflow ++* mbuf: avoid cast-align warning in data offset macro ++* mbuf: enforce no option for dynamic fields and flags ++* mbuf: fix dump of dynamic fields and flags ++* mbuf: fix typo in comment ++* mem: fix dynamic hugepage mapping in container ++* net/af_packet: fix ignoring full ring on Tx ++* net/af_xdp: disable secondary process support ++* net: avoid cast-align warning in VLAN insert function ++* net/axgbe: fix unreleased lock in I2C transfer ++* net/bnxt: check FW capability for VLAN offloads ++* net/bnxt: fix double allocation of ring groups ++* net/bnxt: fix firmware version query ++* net/bnxt: fix function driver register/unregister ++* net/bnxt: fix memzone free for Tx and Rx rings ++* net/bnxt: fix ring group free ++* net/bnxt: fix Rx next consumer index in mbuf alloc fail ++* net/bnxt: fix tunnel port accounting ++* net/bnxt: fix Tx queue startup state ++* net/bnxt: fix VLAN indication in Rx mbuf ++* net/bonding: fix dedicated queue mode in vector burst ++* net/bonding: fix RSS key length ++* net/ena: advertise scattered Rx capability ++* net/ena: fix offload capabilities verification ++* net/ena: fix per-queue offload capabilities ++* net/enic: avoid error message when no advanced filtering ++* net/enic: fix filter mode detection ++* net/failsafe: fix secondary process probe ++* net: fix aliasing in checksum computation ++* net: fix checksum API documentation ++* net/hinic/base: remove some unused variables ++* net/hns3: fix input parameters of MAC functions ++* net/hns3: simplify queue DMA address arithmetic ++* net/i40e/base: fix AOC media type ++* net/i40e/base: fix function name in comments ++* net/i40e/base: fix PF reset ++* net/i40e/base: fix PHY identifiers for 2.5G and 5G adapters ++* net/i40e/base: fix potentially uninitialized variables ++* net/i40e/base: fix resource leakage ++* net/i40e/base: fix update link data for X722 ++* net/i40e/base: fix using checksum before check ++* net/i40e: build failure with make and clang < 13 ++* net/i40e: build failure with make and clang 13 ++* net/i40e: fix 32-bit build ++* net/i40e: fix device startup resource release ++* net/i40e: fix forward outer IPv6 VXLAN ++* net/i40e: fix mbuf leak ++* net/i40e: fix risk in descriptor read in NEON Rx ++* net/i40e: fix risk in descriptor read in scalar Rx ++* net/i40e: fix Rx packet statistics ++* net/i40e: support 25G AOC/ACC cables ++* net/iavf: fix mbuf leak ++* net/iavf: fix overflow in maximum packet length config ++* net/iavf: fix Rx queue buffer size alignment ++* net/ice/base: fix typo in comment ++* net/ice: build failure with make and clang 13 ++* net/ice: fix memzone leak after device init failure ++* net/ice: fix memzone leak on queue re-configure ++* net/ice: save rule on switch filter creation ++* net/ixgbe: build failure with make and clang < 13 ++* net/ixgbe: build failure with make and clang 13 ++* net/ixgbe: fix hash handle leak ++* net/ixgbe: fix MAC resource leak ++* net/ixgbe: fix mbuf leak ++* net/ixgbe: fix port initialization if MTU config fails ++* net/ixgbe: fix queue release ++* net/ixgbe: fix queue resource leak ++* net/ixgbe: fix Rx multicast statistics after reset ++* net/liquidio: remove unused counter ++* net/memif: fix chained mbuf determination ++* net/mlx4: fix empty Ethernet spec with VLAN ++* net/mlx5: fix Altivec Rx ++* net/mlx5: fix flow tables double release ++* net/mlx5: fix GENEVE and VXLAN-GPE flow item matching ++* net/mlx5: fix GENEVE protocol type translation ++* net/mlx5: fix GRE flow item matching ++* net/mlx5: fix GRE protocol type translation ++* net/mlx5: fix metadata and meter split shared tag ++* net/mlx5: fix MPLS tunnel outer layer overwrite ++* net/mlx5: fix RETA update without stopping device ++* net/mlx5: fix RSS expansion scheme for GRE header ++* net/mlx5: fix RSS RETA update ++* net/mlx5: fix VXLAN-GPE next protocol translation ++* net/nfp: fix minimum descriptor sizes ++* net/nfp: remove unused message length ++* net/octeontx2: fix MTU when PTP is enabled ++* net/pcap: fix resource leakage on port probe ++* net/qede/base: remove unused message size ++* net/qede: fix minsize build ++* net/softnic: fix useless address check ++* net/virtio: avoid unneeded link interrupt configuration ++* net/virtio: fix indirect descriptor reconnection ++* net/virtio: fix mbuf count on Rx queue setup ++* net/virtio-user: fix Rx interrupts with multi-queue ++* net/vmxnet3: fix build with clang 13 ++* power: fix build with clang 13 ++* remove repeated 'the' in the code ++* Revert "net/ena: trigger reset on Tx prepare failure" ++* rib: fix IPv6 depth mask ++* ring: fix Doxygen comment of internal function ++* stack: fix reload head when pop fails ++* (tag: 19.11.11-beta1) doc: fix typo in coding style ++* (tag: v19.11.11-rc1) version: 19.11.11-rc1 ++* (tag: v19.11.11-rc2, origin-stable/19.11, github-cpaelzer-stable/19.11) version: 19.11.11-rc2 ++* test/atomic: fix 128-bit atomic test with many cores ++* test/bpf: fix undefined behavior with clang ++* test/compress: fix buffer overflow ++* test/crypto: fix data lengths ++* test/crypto: fix unnecessary stats retrieval ++* test/crypto: skip plain text compare for null cipher ++* test/distributor: remove unused counter ++* test/event_crypto: fix event crypto metadata write ++* test/event: fix timer adapter creation test ++* test: fix ring PMD initialisation ++* test/func_reentrancy: free memzones after test ++* test/latency: fix loop boundary ++* test/mem: fix memory autotests on FreeBSD ++* test/power: fix CPU frequency when turbo enabled ++* test/red: fix typo in test description ++* test/service: fix some comment ++* vfio: fix FreeBSD clear group stub ++* vfio: fix FreeBSD documentation ++* vhost: add sanity check on inflight last index ++* vhost: clean IOTLB cache on vring stop ++* vhost: log socket path on adding connection ++ ++19.11.11 Validation ++~~~~~~~~~~~~~~~~~~~ ++ ++* [Intel(R) Testing](http://mails.dpdk.org/archives/stable/2021-December/035423.html) ++ ++ * Builds ++ ++ * Basic Intel NIC (ixgbe, i40e) testing ++ ++ * PF (i40e) ++ * PF (ixgbe) ++ * VF (i40e) ++ * VF (ixgbe) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++* [Canonical(R) Testing](http://mails.dpdk.org/archives/stable/2022-January/035541.html) ++ ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.04 (meson based) ++ * Functional and performance tests based on OVS-DPDK on x86_64 ++ * Autopkgtests for DPDK and OpenvSwitch ++ ++* [Red Hat(R) Testing](http://mails.dpdk.org/archives/stable/2021-December/035405.html) ++ ++ * Platform ++ ++ * RHEL 8 ++ * Kernel 4.18 ++ * Qemu 6.0 ++ * X540-AT2 NIC(ixgbe, 10G) ++ * Tested on 19.11.9-RC3 ++ ++ * Tests ++ ++ * Guest with device assignment(PF) throughput testing(1G hugepage size): PASS ++ * Guest with device assignment(PF) throughput testing(2M hugepage size) : PASS ++ * Guest with device assignment(VF) throughput testing: PASS ++ * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing: PASS ++ * PVP vhost-user 2Q throughput testing: PASS ++ * PVP vhost-user 1Q - cross numa node throughput testing: PASS ++ * Guest with vhost-user 2 queues throughput testing: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect: PASS ++ * PVP 1Q live migration testing: PASS ++ * PVP 1Q cross numa node live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M): PASS ++ * Guest with ovs+dpdk+vhost-user 2Q live migration testing: PASS ++ * Host PF + DPDK testing: PASS ++ * Host VF + DPDK testing: PASS ++ ++* [Nvidia (R) Testing](http://mails.dpdk.org/archives/stable/2021-December/035526.html) ++ ++ * functional tests on Mellanox hardware ++ ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.5-1.0.3.2 / Firmware: 14.32.1010 ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / kernel: 5.14.0-rc7 / Driver: rdma-core v36.0 / Firmware: 14.32.1010 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.5-1.0.3.2 / Firmware: 16.32.1010 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / kernel: 5.14.0-rc7 / Driver: v36.0 / Firmware: 16.32.1010 ++ ++ * Basic functionality: ++ ++ * Send and receive multiple types of traffic. ++ * testpmd xstats counter test. ++ * testpmd timestamp test. ++ * Changing/checking link status through testpmd. ++ * RTE flow tests: Items: eth / vlan / ipv4 / ipv6 / tcp / udp / icmp / gre / nvgre / vxlan ip in ip / mplsoudp / mplsogre ++ * Actions: drop / queue / rss / mark / flag / jump / count / raw_encap / raw_decap / vxlan_encap / vxlan_decap / NAT / dec_ttl ++ * Some RSS tests. ++ * VLAN filtering, stripping and insertion tests. ++ * Checksum and TSO tests. ++ * ptype tests. ++ * link_status_interrupt example application tests. ++ * l3fwd-power example application tests. ++ * Multi-process example applications tests. ++ ++ * Compilation tests with multiple configurations in the following OS/driver combinations are also passing: ++ ++ * Ubuntu 20.04.2 with MLNX_OFED_LINUX-5.5-1.0.3.2. ++ * Ubuntu 20.04.2 with rdma-core master (c52b43e). ++ * Ubuntu 20.04.2 with rdma-core v28.0. ++ * Ubuntu 18.04.5 with rdma-core v17.1. ++ * Ubuntu 18.04.5 with rdma-core master (c52b43e) (i386). ++ * Ubuntu 16.04.7 with rdma-core v22.7. ++ * Fedora 35 with rdma-core v38.0 (only gcc passes). ++ * Fedora 36 (Rawhide) with rdma-core v38.0 ++ * CentOS 7 7.9.2009 with rdma-core master (940f53f). ++ * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.5-1.0.3.2. ++ * CentOS 8 8.3.2011 with rdma-core master (940f53f). ++ * OpenSUSE Leap 15.3 with rdma-core v31.0. ++ ++19.11.11 Known Issues ++~~~~~~~~~~~~~~~~~~~~~ ++ ++A few issues are still present, but none of them is an in-place regression. ++So far these are all issues with newer compilers, toolchains and kernels that ++happen to be incompatible with the older 19.11.x codebase. ++We are happy to state that this time not only more compile issues got ++identified, but also that a lot of them got fixed in 19.11.11. ++ ++* Identified in 19.11.10 and 19.11.11-rc*, but fixed in this release: ++ ++ * [performance-thread build failure with clang 12.0.1](https://bugs.dpdk.org/show_bug.cgi?id=745) ++ * [net/nfp fail with clang 13](https://bugs.dpdk.org/show_bug.cgi?id=904) ++ * [net/i40e fail with clang 13](https://bugs.dpdk.org/show_bug.cgi?id=901) ++ * [net/ice fail with clang 13](https://bugs.dpdk.org/show_bug.cgi?id=902) ++ * [net/ixgbe fail with clang 13](https://bugs.dpdk.org/show_bug.cgi?id=903) ++ * [FreeBSD13 issues with gcc 10.3.0 and clang 11](https://bugs.dpdk.org/show_bug.cgi?id=905) ++ * [gcc implicit-fallthrough](https://bugs.dpdk.org/show_bug.cgi?id=907) ++ * [gcc stringop-overflow](https://bugs.dpdk.org/show_bug.cgi?id=908) ++ * [make based build with FreeBSD13 and clang 11.0.1](https://bugs.dpdk.org/show_bug.cgi?id=913) ++ * [SUSE Linux Enterprise Server 15 SP3 kernels](https://bugs.dpdk.org/show_bug.cgi?id=812) ++ ++* Remaining known issues in 19.11.11 ++ ++ * [Make based build issue with Fedora 34 and GCC11 - maybe-uninitialized](https://bugs.dpdk.org/show_bug.cgi?id=744) ++ * [Meson based build issue with ICC-19.1.1 - cast discards qualifiers from target type](https://bugs.dpdk.org/show_bug.cgi?id=747) ++ * [net/quede build fail with clang 13 - unused-but-set-variable](https://bugs.dpdk.org/show_bug.cgi?id=912) ++ ++19.11.12 Release Notes ++---------------------- ++ ++ ++19.11.12 Fixes ++~~~~~~~~~~~~~~ ++ ++* acl: add missing C++ guards ++* app/compress-perf: fix number of queue pairs to setup ++* app/compress-perf: fix socket ID type during init ++* app/pdump: abort on multi-core capture limit ++* app/testpmd: check starting port is not in bonding ++* app/testpmd: fix bonding mode set ++* app/testpmd: fix build without drivers ++* app/testpmd: fix dereference before null check ++* app/testpmd: fix show RSS RETA on Windows ++* build: fix warning about using -Wextra flag ++* build: fix warnings when running external commands ++* build: remove deprecated Meson functions ++* bus/dpaa: fix C++ include guard ++* bus/ifpga: remove useless check while browsing devices ++* common/mlx5: add Netlink event helpers ++* compressdev: add missing C++ guards ++* compressdev: fix missing space in log macro ++* compressdev: fix socket ID type ++* compress/octeontx: fix null pointer dereference ++* config/ppc: fix build with GCC >= 10 ++* cryptodev: add backward-compatible enum ++* cryptodev: fix clang C++ include ++* cryptodev: fix RSA key type name ++* crypto/virtio: fix out-of-bounds access ++* devtools: fix comment detection in forbidden token check ++* distributor: fix potential overflow ++* doc: add dependency on examples for API doxygen ++* doc: fix FIPS guide ++* doc: fix KNI PMD name typo ++* doc: fix typos and punctuation in flow API guide ++* doc: remove obsolete vector Tx explanations from mlx5 guide ++* doc: replace broken links in mlx guides ++* drivers: remove warning with Meson 0.59 ++* eal: fix C++ include ++* eal: fix missing C++ guards ++* eal/freebsd: add missing C++ include guards ++* eal/linux: fix illegal memory access in uevent handler ++* eal/linux: log hugepage create errors with filename ++* ethdev: add missing C++ guards ++* ethdev: fix cast for C++ compatibility ++* ethdev: fix doxygen comments for device info struct ++* eventdev: add missing C++ guards ++* eventdev/eth_tx: fix queue add error code ++* eventdev: fix C++ include ++* examples/distributor: reduce Tx queue number to 1 ++* examples/flow_classify: fix failure message ++* examples/l2fwd-crypto: fix port mask overflow ++* examples/l3fwd: fix buffer overflow in Tx ++* (HEAD -> 19.11, origin-stable/19.11, github-cpaelzer-stable/19.11) Revert "common/qat: fix queue pairs number" ++* ipc: end multiprocess thread during cleanup ++* ipsec: fix C++ include ++* kni: add missing C++ guards ++* kni: fix freeing order in device release ++* kni: fix ioctl signature ++* maintainers: update for stable branches ++* net/af_xdp: add missing trailing newline in logs ++* net/af_xdp: ensure socket is deleted on Rx queue setup error ++* net/bnxt: cap maximum number of unicast MAC addresses ++* net/bnxt: fix a typo introduced in backport ++* net/bnxt: fix handling of VF configuration change ++* net/bnxt: fix memzone allocation per VNIC ++* net/bnxt: fix multicast address set ++* net/bnxt: fix queue stop operation ++* net/bnxt: fix xstats query ++* net/bnxt: get maximum supported multicast filters count ++* net/bnxt: handle ring cleanup in case of error ++* net/bnxt: restore RSS configuration after reset recovery ++* net/bonding: fix mode type mismatch ++* net/bonding: fix promiscuous and allmulticast state ++* net/bonding: fix reference count on mbufs ++* net/bonding: fix RSS with early configure ++* net/cxgbe: fix dangling pointer by mailbox access rework ++* net/cxgbe: remove useless address check ++* net/cxgbe: remove useless C++ include guard ++* net/dpaa2: remove useless C++ include guard ++* net/ena: fix checksum flag for L4 ++* net/ena: fix meta descriptor DF flag setup ++* net/ena: remove unused enumeration ++* net/ena: remove unused offload variables ++* net/ena: skip timer if reset is triggered ++* net/hns3: fix max packet size rollback in PF ++* net/hns3: fix multi-process action register and unregister ++* net/hns3: fix residual MAC after setting default MAC ++* net/hns3: fix RSS key with null ++* net/hns3: fix RSS TC mode entry ++* net/hns3: fix secondary process reference count ++* net/hns3: fix using enum as boolean ++* net/hns3: fix VF RSS TC mode entry ++* net/hns3: increase time waiting for PF reset completion ++* net/hns3: remove duplicate macro definition ++* net/hns3: unregister MP action on close for secondary ++* net/iavf: count continuous DD bits for Arm ++* net/ice: build failure with make and GCC > 11 ++* net/ice: fix link up when starting device ++* net/ixgbe: add vector Rx parameter check ++* net/ixgbe: check filter init failure ++* net/ixgbe: fix FSP check for X550EM devices ++* net/ixgbe: reset security context pointer on close ++* net/memif: remove pointer deference before null check ++* net/memif: remove unnecessary Rx interrupt stub ++* net/mlx5: fix committed bucket size ++* net/mlx5: fix initial link status detection ++* net/mlx5: fix link status change detection ++* net/mlx5: fix matcher priority with ICMP or ICMPv6 ++* net/mlx5: fix maximum packet headers size for TSO ++* net/mlx5: fix modify port action validation ++* net/mlx5: fix netlink header path ++* net/mlx5: fix NIC egress flow mismatch in switchdev mode ++* net/mlx5: reject jump to root table ++* net/nfb: fix array indexes in deinit functions ++* net/nfb: fix multicast/promiscuous mode switching ++* net/nfp: remove useless range checks ++* net/sfc: demand Tx fast free offload on EF10 simple datapath ++* net/sfc: do not push fast free offload to default TxQ config ++* net/sfc: validate queue span when parsing flow action RSS ++* net/virtio: fix Tx queue 0 overriden by queue 128 ++* net/virtio-user: check FD flags getting failure ++* pmdinfogen: fix compilation with Clang 3.4.2 on CentOS 7 ++* raw/ifpga/base: fix port feature ID ++* raw/ifpga/base: fix SPI transaction ++* raw/ifpga: fix build with optimization ++* raw/ifpga: fix interrupt handle allocation ++* raw/ifpga: fix monitor thread ++* raw/ifpga: fix variable initialization in probing ++* raw/ntb: clear all valid doorbell bits on init ++* ring: fix error code when creating ring ++* stack: fix stubs header export ++* table: fix C++ include ++* (tag: 19.11.12-before-rc3-patches) net/bnxt: fix xstats names query overrun ++* (tag: 19.11.12-stable-from-rc3) vhost: add missing c++ guards ++* (tag: v19.11.12-rc1) version: 19.11.12-rc1 ++* telemetry: add missing C++ guards ++* test/efd: fix sockets mask size ++* test/mbuf: fix mbuf data content check ++* test/mem: fix error check ++* vdpa/ifc: fix log info mismatch ++* vfio: cleanup the multiprocess sync handle ++* vhost: fix C++ include ++* vhost: fix FD leak with inflight messages ++* vhost: fix queue number check when setting inflight FD ++* vhost: fix unsafe vring addresses modifications ++ ++19.11.12 Validation ++~~~~~~~~~~~~~~~~~~~ ++ ++* [Intel(R) Testing](http://mails.dpdk.org/archives/stable/2022-March/037534.html) ++ ++ * Builds ++ ++ * Basic Intel NIC (ixgbe, i40e) testing ++ ++ * PF (i40e) ++ * PF (ixgbe) ++ * VF (i40e) ++ * VF (ixgbe) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++* [Canonical(R) Testing](http://mails.dpdk.org/archives/stable/2022-March/037549.html) ++ ++ * Build tests of DPDK & OVS 2.13.3 on Ubuntu 20.04 (meson based) ++ * Functional and performance tests based on OVS-DPDK on x86_64 ++ * Autopkgtests for DPDK and OpenvSwitch ++ ++* [Red Hat(R) Testing]( http://mails.dpdk.org/archives/stable/2022-April/037593.html ) ++ ++ * Platform ++ ++ * RHEL 8 ++ * Kernel 4.18 ++ * Qemu 6.2 ++ * X540-AT2 NIC(ixgbe, 10G) ++ * Tested on 19.11.12-RC1 ++ ++ * Tests ++ ++ * Guest with device assignment(PF) throughput testing(1G hugepage size): PASS ++ * Guest with device assignment(PF) throughput testing(2M hugepage size) : PASS ++ * Guest with device assignment(VF) throughput testing: PASS ++ * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing: PASS ++ * PVP vhost-user 2Q throughput testing: PASS ++ * PVP vhost-user 1Q - cross numa node throughput testing: PASS ++ * Guest with vhost-user 2 queues throughput testing: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect: PASS ++ * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect: PASS ++ * PVP 1Q live migration testing: PASS ++ * PVP 1Q cross numa node live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M): PASS ++ * Guest with ovs+dpdk+vhost-user 2Q live migration testing: PASS ++ * Guest with ovs+dpdk+vhost-user 4Q live migration testing: PASS ++ * Host PF + DPDK testing: PASS ++ * Host VF + DPDK testing: PASS ++ ++* [Nvidia(R) Testing](http://mails.dpdk.org/archives/stable/2022-April/037579.html) ++ ++ * functional tests on Mellanox hardware ++ ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.5-1.0.3.2 / Firmware: 14.32.1010 ++ * NIC: ConnectX-4 Lx / OS: Ubuntu 20.04 LTS / Kernel: 5.17.0 / Driver: rdma-core v39.0 / Firmware: 14.32.1010 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / Driver: MLNX_OFED_LINUX-5.5-1.0.3.2 / Firmware: 16.32.1010 ++ * NIC: ConnectX-5 / OS: Ubuntu 20.04 LTS / Kernel: 5.17.0 / Driver: v39.0 / Firmware: 16.32.1010 ++ ++ * Functionality: ++ ++ * Send and receive multiple types of traffic. ++ * testpmd xstats counter test. ++ * testpmd timestamp test. ++ * Changing/checking link status through testpmd. ++ * RTE flow tests: Items: eth / vlan / ipv4 / ipv6 / tcp / udp / icmp / gre / nvgre / vxlan ip in ip / mplsoudp / mplsogre ++ * Actions: drop / queue / rss / mark / flag / jump / count / raw_encap / raw_decap / vxlan_encap / vxlan_decap / NAT / dec_ttl ++ * Some RSS tests. ++ * VLAN filtering, stripping and insertion tests. ++ * Checksum and TSO tests. ++ * ptype tests. ++ * link_status_interrupt example application tests. ++ * l3fwd-power example application tests. ++ * Multi-process example applications tests. ++ ++ * Compilation tests with multiple configurations in the following OS/driver combinations are also passing: ++ ++ * Ubuntu 20.04.4 with MLNX_OFED_LINUX-5.5-1.0.3.2. ++ * Ubuntu 20.04.4 with rdma-core v39.0. ++ * Ubuntu 20.04.4 with rdma-core v28.0. ++ * Ubuntu 18.04.6 with rdma-core v17.1. ++ * Ubuntu 18.04.6 with rdma-core master (91004ec) (i386). ++ * Ubuntu 16.04.7 with rdma-core v22.7. ++ * Fedora 35 with rdma-core v39.0. ++ * Fedora 37 (Rawhide) with rdma-core v39.0 ++ * CentOS 7 7.9.2009 with rdma-core master (91004ec). ++ * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.5-1.0.3.2. ++ * CentOS 8 8.4.2105 with rdma-core master (91004ec). ++ * OpenSUSE Leap 15.3 with rdma-core v31.0. ++ ++* [Broadcom(R) Testing](http://mails.dpdk.org/archives/stable/2022-April/037569.html) ++ ++ * Basic functionality: Send and receive multiple types of traffic. ++ * Changing/checking link status through testpmd. ++ * RSS tests with tunnel and non-tunnel packets ++ * TSO tests with tunnel and non-tunnel packets ++ * VLAN filtering/strip tests. ++ * unicast/multicast MAC filtering tests ++ * statistics tests ++ * Rx/Tx Checksum offload tests ++ * MTU tests and jumbo frame tests ++ * Promiscuous/allmulti tests ++ * Basic flow offload tests ++ * Used: NIC: BCM57414 NetXtreme-E 10Gb/25Gb Ethernet Controller, Firmware: 222.0.112.0 ++ * Used: NIC: BCM57508 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet, Firmware : 222.0.112.0 ++ ++19.11.12 Known Issues ++~~~~~~~~~~~~~~~~~~~~~ ++ ++A few issues are still present, but none of them is an in-place regression. ++So far these are mostly issues with newer compilers, toolchains and kernels ++that happen to be incompatible with the older 19.11.x codebase. ++We are happy to state that - again - more of them got fixed in 19.11.12. ++ ++* Identified up to 19.11.12-rc1, but fixed in this release: ++ ++ * [Make based build issue with Fedora 34 and GCC11 - maybe-uninitialized](https://bugs.dpdk.org/show_bug.cgi?id=744) ++ * net/mlx5: fix netlink header path - build issue breaking some Ubuntu 16.04/18.04/20.04, openSUSE Leap 15.3, and CentOS 7/8 installations ++ * net/cxgbe: remove useless address check - reported by GCC 12 ++ * [pmdinfogen build failure with clang 3.4.2](https://bugs.dpdk.org/show_bug.cgi?id=984) ++ * [net/bnxt: fix a typo introduced in backport](https://bugs.dpdk.org/show_bug.cgi?id=977) ++ ++* Remaining known build issues in 19.11.12 ++ ++ * [Meson based build issue with ICC-19.1.1 - cast discards qualifiers from target type](https://bugs.dpdk.org/show_bug.cgi?id=747) ++ * [net/quede build fail with clang 13 - unused-but-set-variable](https://bugs.dpdk.org/show_bug.cgi?id=912) ++ * [net/ena build failure with gcc 12](https://bugs.dpdk.org/show_bug.cgi?id=991) ++ * [librte_eal build error with gcc 12](https://bugs.dpdk.org/show_bug.cgi?id=985) ++ * [net/qede build failure with make and clang 13](https://bugs.dpdk.org/show_bug.cgi?id=912) ++ ++19.11.13 Release Notes ++---------------------- ++ ++ ++19.11.13 Fixes ++~~~~~~~~~~~~~~ ++ ++* acl: fix rules with 8-byte field size ++* app/testpmd: check statistics query before printing ++* app/testpmd: fix bonding slave devices not released ++* app/testpmd: fix metering and policing command for RFC4115 ++* app/testpmd: fix multicast address pool leak ++* app/testpmd: fix port status of bonding slave device ++* app/testpmd: fix supported RSS offload display ++* app/testpmd: perform SW IP checksum for GRO/GSO packets ++* app/testpmd: remove useless pointer checks ++* app/testpmd: replace hardcoded min mbuf number with macro ++* app/testpmd: revert MAC update in checksum forwarding ++* bus/fslmc: fix VFIO setup ++* common/cpt: fix build with GCC 12 ++* common/dpaax: fix short MAC-I IV calculation for ZUC ++* config: fix C++ cross compiler for ARM ++* crypto/dpaa2_sec: fix buffer pool ID check ++* crypto/dpaa2_sec: fix operation status for simple FD ++* crypto/dpaa_sec: fix digest size ++* crypto/dpaa_sec: fix secondary process probing ++* crypto/qat: fix DOCSIS crash ++* crypto/scheduler: fix queue pair in scheduler failover ++* devtools: fix null test for NUMA systems ++* doc: fix grammar and formatting in compressdev guide ++* drivers/crypto: fix warnings for OpenSSL version ++* eal: fix C++ include for device event and DMA ++* eal/freebsd: fix use of newer cpuset macros ++* eal/windows: fix data race when creating threads ++* eal/x86: drop export of internal alignment macro ++* eal/x86: fix unaligned access for small memcpy ++* ethdev: clarify null location case in xstats get ++* ethdev: fix RSS update when RSS is disabled ++* ethdev: prohibit polling stopped queue ++* eventdev/eth_tx: fix adapter creation ++* eventdev/eth_tx: fix queue delete ++* examples/bond: fix invalid use of trylock ++* examples/distributor: fix distributor on Rx core ++* examples/fips_validation: handle empty payload ++* examples/ipsec-secgw: fix promiscuous mode option ++* examples/l2fwd-crypto: fix stats refresh rate ++* examples/link_status_interrupt: fix stats refresh rate ++* examples/vhost: fix crash when no VMDq ++* examples/vhost: fix retry logic on Rx path ++* kni: fix build ++* kni: fix build with Linux 5.18 ++* kni: use dedicated function to set MAC address ++* kni: use dedicated function to set random MAC address ++* malloc: fix allocation of almost hugepage size ++* mem: skip attaching external memory in secondary process ++* net/bnxt: allow Tx only or Rx only ++* net/bnxt: cleanup MTU setting ++* net/bnxt: fix compatibility with some old firmwares ++* net/bnxt: fix freeing VNIC filters ++* net/bnxt: recheck FW readiness if in reset process ++* net/bnxt: remove unused macro ++* net/bonding: fix mbuf fast free usage ++* net/bonding: fix RSS inconsistency between ports ++* net/bonding: fix RSS key config with extended key length ++* net/bonding: fix stopping non-active slaves ++* net/cxgbe: fix port ID in Rx mbuf ++* net/cxgbe: fix Tx queue stuck with mbuf chain coalescing ++* net/dpaa: fix event queue detach ++* net/hns3: fix insecure way to query MAC statistics ++* net/hns3: fix xstats get return if xstats is null ++* net/hns3: remove duplicate definition ++* net/iavf: fix queue start exception handling ++* net/iavf: fix Rx queue interrupt setting ++* net/iavf: increase reset complete wait count ++* net/iavf: net/iavf: fix mbuf release in multi-process ++* net/ice/base: fix getting sched node from ID type ++* net/ice: fix build with GCC 12 ++* net/ice: fix meson build error with gcc11.2 ++* net/ipn3ke: fix xstats get return if xstats is null ++* net/ixgbe: add option for link up check on pin SDP3 ++* net/memif: fix overwriting of head segment ++* net/mlx5: add minimum WQE size for striding RQ ++* net/mlx5: fix GTP handling in header modify action ++* net/mlx5: fix LRO validation in Rx setup ++* net/mlx5: fix mark enabling for Rx ++* net/mlx5: fix MPRQ stride devargs adjustment ++* net/mlx5: fix Rx queue recovery mechanism (CVE-2022-28199) ++* net/mlx5: fix Tx when inlining is impossible ++* net/mlx5: improve stride parameter names ++* net/mvpp2: fix xstats get return if xstats is null ++* net/netvsc: fix calculation of checksums based on mbuf flag ++* net/netvsc: fix vmbus device reference in multi-process ++* net/nfp: fix disabling VLAN stripping ++* net/nfp: fix initialization ++* net/nfp: remove unneeded header inclusion ++* net/octeontx: fix port close ++* net/qede: fix build with GCC 12 ++* net/vhost: fix access to freed memory ++* net/vhost: fix deadlock on vring state change ++* net/vhost: fix TSO feature default disablement ++* net/virtio-user: fix socket non-blocking mode ++* raw/ifpga: remove virtual devices on close ++* raw/ifpga: unregister interrupt on close ++* Revert "net/iavf: fix Rx queue interrupt setting" ++* Revert "net/mlx5: fix RSS expansion scheme for GRE header" ++* rib: fix traversal with /32 route ++* service: fix lingering active status ++* test: avoid hang if queues are full and Tx fails ++* test/bonding: fix RSS test when disable RSS ++* test: check memory allocation for CRC ++* test/crypto: fix authentication IV for ZUC SGL ++* test/crypto: fix cipher offset for ZUC ++* test/crypto: fix null check for ZUC authentication ++* test/crypto: fix SNOW3G vector IV format ++* test/crypto: fix ZUC vector IV format ++* test/hash: fix out of bound access ++* test/ipsec: fix build with GCC 12 ++* test/table: fix buffer overflow on lpm entry ++* vdpa/ifc/base: fix null pointer dereference ++* vdpa/ifc: fix build with GCC 12 ++* version: 19.11.13-rc1 ++* version: 19.11.13-rc2 ++* version: 19.11.13-rc3 ++* vhost: add some trailing newline in log messages ++* vhost/crypto: fix build with GCC 12 ++* vhost/crypto: fix descriptor processing ++* vhost: discard too small descriptor chains (CVE-2022-2132) ++* vhost: fix header spanned across more than two descriptors (CVE-2022-2132) ++* vhost: fix missing enqueue pseudo-header calculation ++* vhost: fix missing virtqueue lock protection ++ ++19.11.13 Validation ++~~~~~~~~~~~~~~~~~~~ ++ ++* Red Hat(R) Testing ++ ++ * Platform ++ ++ * RHEL 8 ++ * Kernel 4.18 ++ * Qemu 6.2 ++ * X540-AT2 NIC(ixgbe, 10G) ++ ++ * Functionality ++ ++ * Guest with device assignment(PF) throughput testing(1G hugepage size) ++ * Guest with device assignment(PF) throughput testing(2M hugepage size) ++ * Guest with device assignment(VF) throughput testing ++ * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing ++ * PVP vhost-user 2Q throughput testing ++ * PVP vhost-user 1Q cross numa node throughput testing ++ * Guest with vhost-user 2 queues throughput testing ++ * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect ++ * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect ++ * PVP 1Q live migration testing ++ * PVP 1Q cross numa node live migration testing ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing ++ * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M) ++ * Guest with ovs+dpdk+vhost-user 2Q live migration testing ++ * Guest with ovs+dpdk+vhost-user 4Q live migration testing ++ * Host PF + DPDK testing ++ * Host VF + DPDK testing ++ ++ ++* Intel(R) Testing ++ ++ * Basic Intel(R) NIC(ixgbe, i40e and ice) testing ++ * PF (i40e) ++ * PF (ixgbe) ++ * PF (ice) ++ * VF (i40e) ++ * VF (ixgbe) ++ * VF (ice) ++ * Compile Testing ++ * Intel NIC single core/NIC performance ++ * Power and IPsec ++ ++ * Basic cryptodev and virtio testing ++ ++ * vhost/virtio basic loopback, PVP and performance test ++ * cryptodev Function/Performance ++ ++ ++* Nvidia(R) Testing ++ ++ * Basic functionality with testpmd ++ ++ * Tx/Rx ++ * xstats ++ * Timestamps ++ * Link status ++ * RTE flow and flow_director ++ * RSS ++ * VLAN filtering, stripping and insertion ++ * Checksum/TSO ++ * ptype ++ * link_status_interrupt example application ++ * l3fwd-power example application ++ * Multi-process example applications ++ ++ * Build tests ++ ++ * Ubuntu 20.04.4 with MLNX_OFED_LINUX-5.7-1.0.2.0. ++ * Ubuntu 20.04.4 with rdma-core master (23a0021). ++ * Ubuntu 20.04.4 with rdma-core v28.0. ++ * Ubuntu 18.04.6 with rdma-core v17.1. ++ * Ubuntu 18.04.6 with rdma-core master (23a0021) (i386). ++ * Ubuntu 16.04.7 with rdma-core v22.7. ++ * Fedora 35 with rdma-core v39.0 (with gcc only). ++ * Fedora 37 (Rawhide) with rdma-core v39.0 (with clang only). ++ * CentOS 7 7.9.2009 with rdma-core master (23a0021). ++ * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.7-1.0.2.0. ++ * CentOS 8 8.4.2105 with rdma-core master (23a0021). ++ * OpenSUSE Leap 15.4 with rdma-core v38.1. ++ ++ * ConnectX-5 ++ ++ * Ubuntu 20.04 ++ * Driver MLNX_OFED_LINUX-5.5-1.0.3.2 ++ * fw 16.32.1010 ++ ++ * ConnectX-4 Lx ++ ++ * Ubuntu 20.04 ++ * Driver MLNX_OFED_LINUX-5.5-1.0.3.2 ++ * fw 14.32.1010 ++ ++19.11.13 Known Issues ++~~~~~~~~~~~~~~~~~~~~~ ++ ++* Compilation ++ ++ * Building this release with certain new compiler toolchains is not ++ supported. See individual bugzilla items for details. ++ * https://bugs.dpdk.org/show_bug.cgi?id=985 ++ * https://bugs.dpdk.org/show_bug.cgi?id=912 ++ * https://bugs.dpdk.org/show_bug.cgi?id=991 ++ * https://bugs.dpdk.org/show_bug.cgi?id=1063 ++ * https://bugs.dpdk.org/show_bug.cgi?id=1064 +diff --git a/dpdk/doc/guides/rel_notes/release_2_1.rst b/dpdk/doc/guides/rel_notes/release_2_1.rst +index beadc51ba4..eb390a0941 100644 +--- a/dpdk/doc/guides/rel_notes/release_2_1.rst ++++ b/dpdk/doc/guides/rel_notes/release_2_1.rst +@@ -243,7 +243,7 @@ New Features + * **Added fm10k jumbo frame support.** + + Added support for jumbo frame less than 15K in both VF and PF functions in the +- fm10k pmd. ++ fm10k PMD. + + + * **Added fm10k mac vlan filtering support.** +diff --git a/dpdk/doc/guides/rel_notes/release_2_2.rst b/dpdk/doc/guides/rel_notes/release_2_2.rst +index cea5c8746d..029b758e90 100644 +--- a/dpdk/doc/guides/rel_notes/release_2_2.rst ++++ b/dpdk/doc/guides/rel_notes/release_2_2.rst +@@ -10,8 +10,8 @@ New Features + * **Introduce ARMv7 and ARMv8 architectures.** + + * It is now possible to build DPDK for the ARMv7 and ARMv8 platforms. +- * ARMv7 can be tested with virtual PMD drivers. +- * ARMv8 can be tested with virtual and physical PMD drivers. ++ * ARMv7 can be tested with virtual PMDs. ++ * ARMv8 can be tested with virtual and physical PMDs. + + * **Enabled freeing of ring.** + +@@ -322,7 +322,7 @@ Drivers + + Several customers have reported a link flap issue on 82579. The symptoms + are random and intermittent link losses when 82579 is connected to specific +- switches. the Issue was root caused as an inter-operability problem between ++ switches. the Issue was root caused as an interoperability problem between + the NIC and at least some Broadcom PHYs in the Energy Efficient Ethernet + wake mechanism. + +diff --git a/dpdk/doc/guides/sample_app_ug/bbdev_app.rst b/dpdk/doc/guides/sample_app_ug/bbdev_app.rst +index 405e706a46..e5c055d05a 100644 +--- a/dpdk/doc/guides/sample_app_ug/bbdev_app.rst ++++ b/dpdk/doc/guides/sample_app_ug/bbdev_app.rst +@@ -31,7 +31,7 @@ Limitations + Compiling the Application + ------------------------- + +-#. DPDK needs to be built with ``baseband_turbo_sw`` PMD driver enabled along ++#. DPDK needs to be built with ``baseband_turbo_sw`` PMD enabled along + with ``FLEXRAN SDK`` Libraries. Refer to *SW Turbo Poll Mode Driver* + documentation for more details on this. + diff --git a/dpdk/doc/guides/sample_app_ug/ethtool.rst b/dpdk/doc/guides/sample_app_ug/ethtool.rst index 8f7fc6ca66..253004dd00 100644 --- a/dpdk/doc/guides/sample_app_ug/ethtool.rst @@ -16453,6 +23926,24 @@ index dc7972aa9a..24fb23b898 100644 The application has some sanity checking built-in, so if there is a function (e.g.; the RX core) which doesn't have a cpu core mask assigned, the application +diff --git a/dpdk/doc/guides/sample_app_ug/fips_validation.rst b/dpdk/doc/guides/sample_app_ug/fips_validation.rst +index 2953fddeb9..b5f24a67fa 100644 +--- a/dpdk/doc/guides/sample_app_ug/fips_validation.rst ++++ b/dpdk/doc/guides/sample_app_ug/fips_validation.rst +@@ -79,11 +79,12 @@ Compiling the Application + .. code-block:: console + + dos2unix AES/req/* +- dos2unix AES_GCM/req/* ++ dos2unix GCM/req/* + dos2unix CCM/req/* + dos2unix CMAC/req/* + dos2unix HMAC/req/* + dos2unix TDES/req/* ++ dos2unix SHA/req/* + + Running the Application + ----------------------- diff --git a/dpdk/doc/guides/sample_app_ug/flow_classify.rst b/dpdk/doc/guides/sample_app_ug/flow_classify.rst index bc234b50a7..451a0db88f 100644 --- a/dpdk/doc/guides/sample_app_ug/flow_classify.rst @@ -16480,7 +23971,7 @@ index 5e5a6cd8a0..d3653e57b2 100644 uint32_t dest_ip, uint32_t dest_mask, struct rte_flow_error *error) diff --git a/dpdk/doc/guides/sample_app_ug/ipsec_secgw.rst b/dpdk/doc/guides/sample_app_ug/ipsec_secgw.rst -index d6d8d44686..eb1a57a98f 100644 +index d6d8d44686..6f6e168c9b 100644 --- a/dpdk/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/dpdk/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -92,7 +92,7 @@ The application has a number of command line options:: @@ -16501,6 +23992,41 @@ index d6d8d44686..eb1a57a98f 100644 size for each Security Association (available only with librte_ipsec code path). +@@ -330,7 +330,7 @@ where each options means: + + * *protect *: the specified traffic is protected by SA rule + with id SA_idx +- * *bypass*: the specified traffic traffic is bypassed ++ * *bypass*: the specified traffic is bypassed + * *discard*: the specified traffic is discarded + + ```` +diff --git a/dpdk/doc/guides/sample_app_ug/keep_alive.rst b/dpdk/doc/guides/sample_app_ug/keep_alive.rst +index 865ba69e5c..58e7985b12 100644 +--- a/dpdk/doc/guides/sample_app_ug/keep_alive.rst ++++ b/dpdk/doc/guides/sample_app_ug/keep_alive.rst +@@ -78,7 +78,7 @@ options. + Explanation + ----------- + +-The following sections provide some explanation of the The ++The following sections provide some explanation of the + Keep-Alive/'Liveliness' conceptual scheme. As mentioned in the + overview section, the initialization and run-time paths are very + similar to those of the :doc:`l2_forward_real_virtual`. +diff --git a/dpdk/doc/guides/sample_app_ug/l2_forward_cat.rst b/dpdk/doc/guides/sample_app_ug/l2_forward_cat.rst +index 0a813200ba..2b4651e0fe 100644 +--- a/dpdk/doc/guides/sample_app_ug/l2_forward_cat.rst ++++ b/dpdk/doc/guides/sample_app_ug/l2_forward_cat.rst +@@ -198,7 +198,7 @@ queried for system CPU information and L3CA capabilities via + ``pqos_cap_get(...)`` and ``pqos_cap_get_type(..., PQOS_CAP_TYPE_L3CA, ...)`` + calls. When all capability and topology information is collected, the requested + CAT configuration is validated. A check is then performed (on per socket basis) +-for a sufficient number of un-associated COS. COS are selected and ++for a sufficient number of unassociated COS. COS are selected and + configured via the ``pqos_l3ca_set(...)`` call. Finally, COS are associated to + relevant CPUs via ``pqos_l3ca_assoc_set(...)`` calls. + diff --git a/dpdk/doc/guides/sample_app_ug/l2_forward_event.rst b/dpdk/doc/guides/sample_app_ug/l2_forward_event.rst index 8c519c3046..c5fad93d00 100644 --- a/dpdk/doc/guides/sample_app_ug/l2_forward_event.rst @@ -16555,9 +24081,18 @@ index 39d6b0067a..671d0c7c19 100644 For each port, there is only one RX queue (only one lcore is able to poll a given port). The number of TX queues depends on the number of available lcores. diff --git a/dpdk/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst b/dpdk/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst -index a44fbcd52c..4e58c6c612 100644 +index a44fbcd52c..c17e3f3af8 100644 --- a/dpdk/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst +++ b/dpdk/doc/guides/sample_app_ug/l3_forward_access_ctrl.rst +@@ -220,7 +220,7 @@ Once the application starts, it transitions through three phases: + + * **Final Phase** - Perform the following tasks: + +- Calls the EAL, PMD driver and ACL library to free resource, then quits. ++ Calls the EAL, PMD and ACL library to free resource, then quits. + + Compiling the Application + ------------------------- @@ -236,7 +236,7 @@ The application has a number of command line options: .. code-block:: console @@ -16639,8 +24174,40 @@ index 9c374da6f7..f2a79a6397 100644 Thereafter, the initialization done depends on whether the process is configured as a primary or secondary instance. In the primary instance, a memory pool is created for the packet mbufs and the network ports to be used are initialized - +diff --git a/dpdk/doc/guides/sample_app_ug/performance_thread.rst b/dpdk/doc/guides/sample_app_ug/performance_thread.rst +index 5fed46465f..a2db452c01 100644 +--- a/dpdk/doc/guides/sample_app_ug/performance_thread.rst ++++ b/dpdk/doc/guides/sample_app_ug/performance_thread.rst +@@ -1194,7 +1194,7 @@ Tracing of events can be individually masked, and the mask may be programmed + at run time. An unmasked event results in a callback that provides information + about the event. The default callback simply prints trace information. The + default mask is 0 (all events off) the mask can be modified by calling the +-function ``lthread_diagniostic_set_mask()``. ++function ``lthread_diagnostic_set_mask()``. + + It is possible register a user callback function to implement more + sophisticated diagnostic functions. +diff --git a/dpdk/doc/guides/sample_app_ug/vhost.rst b/dpdk/doc/guides/sample_app_ug/vhost.rst +index a71ada6549..881ea21e68 100644 +--- a/dpdk/doc/guides/sample_app_ug/vhost.rst ++++ b/dpdk/doc/guides/sample_app_ug/vhost.rst +@@ -72,7 +72,7 @@ Run testpmd inside guest + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Make sure you have DPDK built inside the guest. Also make sure the +-corresponding virtio-net PCI device is bond to a uio driver, which ++corresponding virtio-net PCI device is bond to a UIO driver, which + could be done by: + + .. code-block:: console +@@ -200,4 +200,4 @@ Common Issues + * Option "builtin-net-driver" is incompatible with QEMU + + QEMU vhost net device start will fail if protocol feature is not negotiated. +- DPDK virtio-user pmd can be the replacement of QEMU. ++ DPDK virtio-user PMD can be the replacement of QEMU. diff --git a/dpdk/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/dpdk/doc/guides/testpmd_app_ug/testpmd_funcs.rst -index 73ef0b41d3..17a41c21e5 100644 +index 73ef0b41d3..e727126dbd 100644 --- a/dpdk/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/dpdk/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -237,7 +237,7 @@ Display the RSS hash functions and RSS hash key of a port:: @@ -16672,7 +24239,17 @@ index 73ef0b41d3..17a41c21e5 100644 set bonding mon_period -@@ -4435,14 +4435,14 @@ Sample QinQ flow rules +@@ -3944,7 +3944,8 @@ This section lists supported pattern items and their attributes, if any. + - ``gtp_psc``: match GTP PDU extension header with type 0x85. + + - ``pdu_type {unsigned}``: PDU type. +- - ``qfi {unsigned}``: QoS flow identifier. ++ ++ - ``qfi {unsigned}``: PPP, RQI and QoS flow identifier. + + - ``pppoes``, ``pppoed``: match PPPoE header. + +@@ -4435,14 +4436,14 @@ Sample QinQ flow rules Before creating QinQ rule(s) the following commands should be issued to enable QinQ:: testpmd> port stop 0 @@ -16690,6 +24267,15 @@ index 73ef0b41d3..17a41c21e5 100644 testpmd> port start 0 Validate and create a QinQ rule on port 0 to steer traffic to a VF queue in a VM. +@@ -4732,7 +4733,7 @@ Sample Raw encapsulation rule + + Raw encapsulation configuration can be set by the following commands + +-Eecapsulating VxLAN:: ++Encapsulating VxLAN:: + + testpmd> set raw_encap 4 eth src is 10:11:22:33:44:55 / vlan tci is 1 + inner_type is 0x0800 / ipv4 / udp dst is 4789 / vxlan vni diff --git a/dpdk/doc/guides/tools/testbbdev.rst b/dpdk/doc/guides/tools/testbbdev.rst index 7e95696609..bddfd8ae83 100644 --- a/dpdk/doc/guides/tools/testbbdev.rst @@ -16703,6 +24289,19 @@ index 7e95696609..bddfd8ae83 100644 sanity tests. Execution of tests can be customized using various parameters passed to a python running script. +diff --git a/dpdk/doc/guides/tools/testeventdev.rst b/dpdk/doc/guides/tools/testeventdev.rst +index 2ed67a6340..1e67879408 100644 +--- a/dpdk/doc/guides/tools/testeventdev.rst ++++ b/dpdk/doc/guides/tools/testeventdev.rst +@@ -220,7 +220,7 @@ to the ordered queue. The worker receives the events from ordered queue and + forwards to atomic queue. Since the events from an ordered queue can be + processed in parallel on the different workers, the ingress order of events + might have changed on the downstream atomic queue enqueue. On enqueue to the +-atomic queue, the eventdev PMD driver reorders the event to the original ++atomic queue, the eventdev PMD reorders the event to the original + ingress order(i.e producer ingress order). + + When the event is dequeued from the atomic queue by the worker, this test diff --git a/dpdk/doc/guides/windows_gsg/build_dpdk.rst b/dpdk/doc/guides/windows_gsg/build_dpdk.rst index 6711e07e21..a0e51dfcb3 100644 --- a/dpdk/doc/guides/windows_gsg/build_dpdk.rst @@ -17022,11 +24621,182 @@ index f2fe7a2194..18c4649917 100644 } static const struct rte_bbdev_ops pmd_ops = { +diff --git a/dpdk/drivers/bus/dpaa/base/fman/fman.c b/dpdk/drivers/bus/dpaa/base/fman/fman.c +index 6d77a7e393..4affce433d 100644 +--- a/dpdk/drivers/bus/dpaa/base/fman/fman.c ++++ b/dpdk/drivers/bus/dpaa/base/fman/fman.c +@@ -50,7 +50,7 @@ if_destructor(struct __fman_if *__if) + free(bp); + } + cleanup: +- free(__if); ++ rte_free(__if); + } + + static int +diff --git a/dpdk/drivers/bus/dpaa/base/fman/fman_hw.c b/dpdk/drivers/bus/dpaa/base/fman/fman_hw.c +index 9ab8e835dc..d28ed0bb8a 100644 +--- a/dpdk/drivers/bus/dpaa/base/fman/fman_hw.c ++++ b/dpdk/drivers/bus/dpaa/base/fman/fman_hw.c +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: BSD-3-Clause + * +- * Copyright 2017 NXP ++ * Copyright 2017,2020 NXP + * + */ + +@@ -219,20 +219,20 @@ fman_if_stats_get(struct fman_if *p, struct rte_eth_stats *stats) + struct memac_regs *regs = m->ccsr_map; + + /* read recved packet count */ +- stats->ipackets = ((u64)in_be32(®s->rfrm_u)) << 32 | +- in_be32(®s->rfrm_l); +- stats->ibytes = ((u64)in_be32(®s->roct_u)) << 32 | +- in_be32(®s->roct_l); +- stats->ierrors = ((u64)in_be32(®s->rerr_u)) << 32 | +- in_be32(®s->rerr_l); ++ stats->ipackets = (u64)in_be32(®s->rfrm_l) | ++ ((u64)in_be32(®s->rfrm_u)) << 32; ++ stats->ibytes = (u64)in_be32(®s->roct_l) | ++ ((u64)in_be32(®s->roct_u)) << 32; ++ stats->ierrors = (u64)in_be32(®s->rerr_l) | ++ ((u64)in_be32(®s->rerr_u)) << 32; + + /* read xmited packet count */ +- stats->opackets = ((u64)in_be32(®s->tfrm_u)) << 32 | +- in_be32(®s->tfrm_l); +- stats->obytes = ((u64)in_be32(®s->toct_u)) << 32 | +- in_be32(®s->toct_l); +- stats->oerrors = ((u64)in_be32(®s->terr_u)) << 32 | +- in_be32(®s->terr_l); ++ stats->opackets = (u64)in_be32(®s->tfrm_l) | ++ ((u64)in_be32(®s->tfrm_u)) << 32; ++ stats->obytes = (u64)in_be32(®s->toct_l) | ++ ((u64)in_be32(®s->toct_u)) << 32; ++ stats->oerrors = (u64)in_be32(®s->terr_l) | ++ ((u64)in_be32(®s->terr_u)) << 32; + } + + void +@@ -244,10 +244,9 @@ fman_if_stats_get_all(struct fman_if *p, uint64_t *value, int n) + uint64_t base_offset = offsetof(struct memac_regs, reoct_l); + + for (i = 0; i < n; i++) +- value[i] = ((u64)in_be32((char *)regs +- + base_offset + 8 * i + 4)) << 32 | +- ((u64)in_be32((char *)regs +- + base_offset + 8 * i)); ++ value[i] = (((u64)in_be32((char *)regs + base_offset + 8 * i) | ++ (u64)in_be32((char *)regs + base_offset + ++ 8 * i + 4)) << 32); + } + + void +diff --git a/dpdk/drivers/bus/dpaa/base/fman/netcfg_layer.c b/dpdk/drivers/bus/dpaa/base/fman/netcfg_layer.c +index 36eca88cd4..2ec504c5d2 100644 +--- a/dpdk/drivers/bus/dpaa/base/fman/netcfg_layer.c ++++ b/dpdk/drivers/bus/dpaa/base/fman/netcfg_layer.c +@@ -8,7 +8,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -89,7 +89,7 @@ netcfg_acquire(void) + */ + skfd = socket(AF_PACKET, SOCK_RAW, 0); + if (unlikely(skfd < 0)) { +- error(0, errno, "%s(): open(SOCK_RAW)", __func__); ++ err(0, "%s(): open(SOCK_RAW)", __func__); + return NULL; + } + +diff --git a/dpdk/drivers/bus/dpaa/base/qbman/bman_driver.c b/dpdk/drivers/bus/dpaa/base/qbman/bman_driver.c +index 750b756b93..ee35e03da1 100644 +--- a/dpdk/drivers/bus/dpaa/base/qbman/bman_driver.c ++++ b/dpdk/drivers/bus/dpaa/base/qbman/bman_driver.c +@@ -11,6 +11,7 @@ + #include + #include "bman_priv.h" + #include ++#include + + /* + * Global variables of the max portal/pool number this bman version supported +@@ -40,7 +41,8 @@ static int fsl_bman_portal_init(uint32_t idx, int is_shared) + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), + &cpuset); + if (ret) { +- error(0, ret, "pthread_getaffinity_np()"); ++ errno = ret; ++ err(0, "pthread_getaffinity_np()"); + return ret; + } + pcfg.cpu = -1; +@@ -60,7 +62,8 @@ static int fsl_bman_portal_init(uint32_t idx, int is_shared) + map.index = idx; + ret = process_portal_map(&map); + if (ret) { +- error(0, ret, "process_portal_map()"); ++ errno = ret; ++ err(0, "process_portal_map()"); + return ret; + } + /* Make the portal's cache-[enabled|inhibited] regions */ +@@ -104,8 +107,10 @@ static int fsl_bman_portal_finish(void) + cfg = bman_destroy_affine_portal(); + DPAA_BUG_ON(cfg != &pcfg); + ret = process_portal_unmap(&map.addr); +- if (ret) +- error(0, ret, "process_portal_unmap()"); ++ if (ret) { ++ errno = ret; ++ err(0, "process_portal_unmap()"); ++ } + return ret; + } + diff --git a/dpdk/drivers/bus/dpaa/base/qbman/qman_driver.c b/dpdk/drivers/bus/dpaa/base/qbman/qman_driver.c -index 69244ef701..e1dee17542 100644 +index 69244ef701..2aa3b682d0 100644 --- a/dpdk/drivers/bus/dpaa/base/qbman/qman_driver.c +++ b/dpdk/drivers/bus/dpaa/base/qbman/qman_driver.c -@@ -132,7 +132,7 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) +@@ -9,6 +9,8 @@ + #include + #include "qman_priv.h" + #include ++#include ++ + #include + + /* Global variable containing revision id (even on non-control plane systems +@@ -40,7 +42,8 @@ static int fsl_qman_portal_init(uint32_t index, int is_shared) + map.index = index; + ret = process_portal_map(&map); + if (ret) { +- error(0, ret, "process_portal_map()"); ++ errno = ret; ++ err(0, "process_portal_map()"); + return ret; + } + qpcfg.channel = map.channel; +@@ -86,8 +89,10 @@ static int fsl_qman_portal_finish(void) + cfg = qman_destroy_affine_portal(NULL); + DPAA_BUG_ON(cfg != &qpcfg); + ret = process_portal_unmap(&map.addr); +- if (ret) +- error(0, ret, "process_portal_unmap()"); ++ if (ret) { ++ errno = ret; ++ err(0, "process_portal_unmap()"); ++ } + return ret; + } + +@@ -132,11 +137,12 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) struct qm_portal_config *q_pcfg; struct dpaa_ioctl_irq_map irq_map; struct dpaa_ioctl_portal_map q_map = {0}; @@ -17035,7 +24805,23 @@ index 69244ef701..e1dee17542 100644 q_pcfg = kzalloc((sizeof(struct qm_portal_config)), 0); if (!q_pcfg) { -@@ -169,7 +169,7 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) +- error(0, -1, "q_pcfg kzalloc failed"); ++ /* kzalloc sets errno */ ++ err(0, "q_pcfg kzalloc failed"); + return NULL; + } + +@@ -145,7 +151,8 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) + q_map.index = QBMAN_ANY_PORTAL_IDX; + ret = process_portal_map(&q_map); + if (ret) { +- error(0, ret, "process_portal_map()"); ++ errno = ret; ++ err(0, "process_portal_map()"); + kfree(q_pcfg); + return NULL; + } +@@ -169,7 +176,7 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) if (!portal) { pr_err("Qman portal initialisation failed (%d)\n", q_pcfg->cpu); @@ -17044,7 +24830,7 @@ index 69244ef701..e1dee17542 100644 } irq_map.type = dpaa_portal_qman; -@@ -178,11 +178,9 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) +@@ -178,11 +185,9 @@ struct qman_portal *fsl_qman_fq_portal_create(int *fd) *fd = q_fd; return portal; @@ -17074,11 +24860,62 @@ index f27820db37..327d9269f7 100644 /* Expectation is that device would be name=device_name */ if (strncmp(str, "name=", 5) != 0) { DPAA_BUS_DEBUG("Invalid device string (%s)\n", str); +diff --git a/dpdk/drivers/bus/dpaa/include/fsl_fman.h b/dpdk/drivers/bus/dpaa/include/fsl_fman.h +index 1d1ce86719..6b426a7b93 100644 +--- a/dpdk/drivers/bus/dpaa/include/fsl_fman.h ++++ b/dpdk/drivers/bus/dpaa/include/fsl_fman.h +@@ -7,10 +7,6 @@ + #ifndef __FSL_FMAN_H + #define __FSL_FMAN_H + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + /* Status field in FD is updated on Rx side by FMAN with following information. + * Refer to field description in FM BG. + */ +diff --git a/dpdk/drivers/bus/dpaa/include/fsl_qman.h b/dpdk/drivers/bus/dpaa/include/fsl_qman.h +index 4deea5e75e..2660234adb 100644 +--- a/dpdk/drivers/bus/dpaa/include/fsl_qman.h ++++ b/dpdk/drivers/bus/dpaa/include/fsl_qman.h +@@ -16,7 +16,7 @@ extern "C" { + #include + + /* FQ lookups (turn this on for 64bit user-space) */ +-#if (__WORDSIZE == 64) ++#ifdef RTE_ARCH_64 + #define CONFIG_FSL_QMAN_FQ_LOOKUP + /* if FQ lookups are supported, this controls the number of initialised, + * s/w-consumed FQs that can be supported at any one time. +diff --git a/dpdk/drivers/bus/dpaa/include/netcfg.h b/dpdk/drivers/bus/dpaa/include/netcfg.h +index bf7bfae8cb..e1f0461fcd 100644 +--- a/dpdk/drivers/bus/dpaa/include/netcfg.h ++++ b/dpdk/drivers/bus/dpaa/include/netcfg.h +@@ -9,7 +9,6 @@ + #define __NETCFG_H + + #include +-#include + + /* Configuration information related to a specific ethernet port */ + struct fm_eth_port_cfg { diff --git a/dpdk/drivers/bus/dpaa/rte_dpaa_bus.h b/dpdk/drivers/bus/dpaa/rte_dpaa_bus.h -index 9bf2cd9d68..373aca9785 100644 +index 9bf2cd9d68..f85bf86cc3 100644 --- a/dpdk/drivers/bus/dpaa/rte_dpaa_bus.h +++ b/dpdk/drivers/bus/dpaa/rte_dpaa_bus.h -@@ -132,7 +132,23 @@ static inline void *rte_dpaa_mem_ptov(phys_addr_t paddr) +@@ -16,6 +16,10 @@ + #include + #include + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #define DPAA_MEMPOOL_OPS_NAME "dpaa" + + #define DEV_TO_DPAA_DEVICE(ptr) \ +@@ -132,7 +136,23 @@ static inline void *rte_dpaa_mem_ptov(phys_addr_t paddr) } /* If not, Fallback to full memseg list searching */ @@ -17104,10 +24941,26 @@ index 9bf2cd9d68..373aca9785 100644 /** diff --git a/dpdk/drivers/bus/fslmc/fslmc_bus.c b/dpdk/drivers/bus/fslmc/fslmc_bus.c -index b3e964aa92..7431177f2e 100644 +index b3e964aa92..727015fdc3 100644 --- a/dpdk/drivers/bus/fslmc/fslmc_bus.c +++ b/dpdk/drivers/bus/fslmc/fslmc_bus.c -@@ -608,6 +608,11 @@ fslmc_bus_dev_iterate(const void *start, const char *str, +@@ -308,7 +308,6 @@ static int + rte_fslmc_scan(void) + { + int ret; +- int device_count = 0; + char fslmc_dirpath[PATH_MAX]; + DIR *dir; + struct dirent *entry; +@@ -342,7 +341,6 @@ rte_fslmc_scan(void) + /* Error in parsing directory - exit gracefully */ + goto scan_fail_cleanup; + } +- device_count += 1; + } + + closedir(dir); +@@ -608,6 +606,11 @@ fslmc_bus_dev_iterate(const void *start, const char *str, struct rte_dpaa2_device *dev; char *dup, *dev_name = NULL; @@ -17119,8 +24972,21 @@ index b3e964aa92..7431177f2e 100644 /* Expectation is that device would be name=device_name */ if (strncmp(str, "name=", 5) != 0) { DPAA2_BUS_DEBUG("Invalid device string (%s)\n", str); +diff --git a/dpdk/drivers/bus/fslmc/fslmc_logs.h b/dpdk/drivers/bus/fslmc/fslmc_logs.h +index dd74cb7dcf..a1e14dd84e 100644 +--- a/dpdk/drivers/bus/fslmc/fslmc_logs.h ++++ b/dpdk/drivers/bus/fslmc/fslmc_logs.h +@@ -18,8 +18,6 @@ extern int dpaa2_logtype_bus; + rte_log(RTE_LOG_DEBUG, dpaa2_logtype_bus, "fslmc: %s(): " fmt "\n", \ + __func__, ##args) + +-#define BUS_INIT_FUNC_TRACE() DPAA2_BUS_DEBUG(" >>") +- + #define DPAA2_BUS_INFO(fmt, args...) \ + DPAA2_BUS_LOG(INFO, fmt, ## args) + #define DPAA2_BUS_ERR(fmt, args...) \ diff --git a/dpdk/drivers/bus/fslmc/fslmc_vfio.c b/dpdk/drivers/bus/fslmc/fslmc_vfio.c -index 970969d2bf..bf9e3e49a5 100644 +index 970969d2bf..95f7586ab5 100644 --- a/dpdk/drivers/bus/fslmc/fslmc_vfio.c +++ b/dpdk/drivers/bus/fslmc/fslmc_vfio.c @@ -448,11 +448,14 @@ fslmc_vfio_setup_device(const char *sysfs_base, const char *dev_addr, @@ -17177,6 +25043,31 @@ index 970969d2bf..bf9e3e49a5 100644 if (rte_mcp_ptr_list) { free(rte_mcp_ptr_list); rte_mcp_ptr_list = NULL; +@@ -912,6 +903,7 @@ fslmc_vfio_setup_group(void) + { + int groupid; + int ret; ++ int vfio_container_fd; + struct vfio_group_status status = { .argsz = sizeof(status) }; + + /* if already done once */ +@@ -930,8 +922,15 @@ fslmc_vfio_setup_group(void) + return 0; + } + ++ ret = rte_vfio_container_create(); ++ if (ret < 0) { ++ DPAA2_BUS_ERR("Failed to open VFIO container"); ++ return ret; ++ } ++ vfio_container_fd = ret; ++ + /* Get the actual group fd */ +- ret = rte_vfio_get_group_fd(groupid); ++ ret = rte_vfio_container_group_bind(vfio_container_fd, groupid); + if (ret < 0) + return ret; + vfio_group.fd = ret; diff --git a/dpdk/drivers/bus/fslmc/mc/fsl_mc_sys.h b/dpdk/drivers/bus/fslmc/mc/fsl_mc_sys.h index d0c7b39f8d..a310c5697e 100644 --- a/dpdk/drivers/bus/fslmc/mc/fsl_mc_sys.h @@ -17267,10 +25158,31 @@ index 0bb2ce880f..34374ae4b6 100644 /* Decode the outcome */ QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_FQ_QUERY_NP); diff --git a/dpdk/drivers/bus/fslmc/qbman/qbman_portal.c b/dpdk/drivers/bus/fslmc/qbman/qbman_portal.c -index d4223bdc8b..54bea97820 100644 +index d4223bdc8b..e88cecc34a 100644 --- a/dpdk/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/dpdk/drivers/bus/fslmc/qbman/qbman_portal.c -@@ -999,6 +999,8 @@ static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, +@@ -311,17 +311,9 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) + eqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI); + p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask; + p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT; +- if ((p->desc.qman_version & QMAN_REV_MASK) >= QMAN_REV_5000 +- && (d->cena_access_mode == qman_cena_fastest_access)) +- p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI) +- & p->eqcr.pi_ci_mask; +- else +- p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) +- & p->eqcr.pi_ci_mask; +- p->eqcr.available = p->eqcr.pi_ring_size - +- qm_cyc_diff(p->eqcr.pi_ring_size, +- p->eqcr.ci & (p->eqcr.pi_ci_mask<<1), +- p->eqcr.pi & (p->eqcr.pi_ci_mask<<1)); ++ p->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) ++ & p->eqcr.pi_ci_mask; ++ p->eqcr.available = p->eqcr.pi_ring_size; + + portal_idx_map[p->desc.idx] = p; + return p; +@@ -999,6 +991,8 @@ static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); memcpy(&p[1], &cl[1], 28); memcpy(&p[8], &fd[i], sizeof(*fd)); @@ -17279,7 +25191,7 @@ index d4223bdc8b..54bea97820 100644 if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; -@@ -1006,7 +1008,6 @@ static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, +@@ -1006,7 +1000,6 @@ static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); } eqcr_pi++; @@ -17288,7 +25200,7 @@ index d4223bdc8b..54bea97820 100644 if (!(eqcr_pi & half_mask)) s->eqcr.pi_vb ^= QB_VALID_BIT; diff --git a/dpdk/drivers/bus/ifpga/ifpga_bus.c b/dpdk/drivers/bus/ifpga/ifpga_bus.c -index dfd6b1fba9..addbc3e86b 100644 +index dfd6b1fba9..1d9e63dab0 100644 --- a/dpdk/drivers/bus/ifpga/ifpga_bus.c +++ b/dpdk/drivers/bus/ifpga/ifpga_bus.c @@ -24,6 +24,7 @@ @@ -17299,6 +25211,26 @@ index dfd6b1fba9..addbc3e86b 100644 #include "rte_rawdev.h" #include "rte_rawdev_pmd.h" +@@ -65,8 +66,7 @@ ifpga_find_afu_dev(const struct rte_rawdev *rdev, + struct rte_afu_device *afu_dev = NULL; + + TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) { +- if (afu_dev && +- afu_dev->rawdev == rdev && ++ if (afu_dev->rawdev == rdev && + !ifpga_afu_id_cmp(&afu_dev->id, afu_id)) + return afu_dev; + } +@@ -79,8 +79,7 @@ rte_ifpga_find_afu_by_name(const char *name) + struct rte_afu_device *afu_dev = NULL; + + TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) { +- if (afu_dev && +- !strcmp(afu_dev->device.name, name)) ++ if (!strcmp(afu_dev->device.name, name)) + return afu_dev; + } + return NULL; diff --git a/dpdk/drivers/bus/ifpga/rte_bus_ifpga.h b/dpdk/drivers/bus/ifpga/rte_bus_ifpga.h index 88a6289642..a6eeaaf568 100644 --- a/dpdk/drivers/bus/ifpga/rte_bus_ifpga.h @@ -17491,10 +25423,29 @@ index 64cd84a689..a0bb1f5fd3 100644 } diff --git a/dpdk/drivers/bus/pci/pci_common.c b/dpdk/drivers/bus/pci/pci_common.c -index 3f55420769..ab73c009ac 100644 +index 3f55420769..cabfe69ec8 100644 --- a/dpdk/drivers/bus/pci/pci_common.c +++ b/dpdk/drivers/bus/pci/pci_common.c -@@ -288,8 +288,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev) +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -150,7 +151,9 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr, + } + + if (dev->device.numa_node < 0) { +- RTE_LOG(WARNING, EAL, " Invalid NUMA socket, default to 0\n"); ++ if (rte_socket_count() > 1) ++ RTE_LOG(INFO, EAL, "Device %s is not NUMA-aware, defaulting socket to 0\n", ++ dev->name); + dev->device.numa_node = 0; + } + +@@ -288,8 +291,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev) * all registered drivers that have a matching entry in its id_table * for discovered devices. */ @@ -17505,7 +25456,7 @@ index 3f55420769..ab73c009ac 100644 { struct rte_pci_device *dev = NULL; size_t probed = 0, failed = 0; -@@ -675,7 +675,7 @@ rte_pci_get_iommu_class(void) +@@ -675,7 +678,7 @@ rte_pci_get_iommu_class(void) struct rte_pci_bus rte_pci_bus = { .bus = { .scan = rte_pci_scan, @@ -17582,11 +25533,63 @@ index 2bc46530c9..78a032cea8 100644 * @return * 0 on success, negative on error */ +diff --git a/dpdk/drivers/bus/vmbus/linux/vmbus_bus.c b/dpdk/drivers/bus/vmbus/linux/vmbus_bus.c +index 3c924eee14..68f6cc5742 100644 +--- a/dpdk/drivers/bus/vmbus/linux/vmbus_bus.c ++++ b/dpdk/drivers/bus/vmbus/linux/vmbus_bus.c +@@ -236,13 +236,14 @@ vmbus_scan_one(const char *name) + char filename[PATH_MAX]; + char dirname[PATH_MAX]; + unsigned long tmp; ++ char *dev_name; + + dev = calloc(1, sizeof(*dev)); + if (dev == NULL) + return -1; + + dev->device.bus = &rte_vmbus_bus.bus; +- dev->device.name = strdup(name); ++ dev->device.name = dev_name = strdup(name); + if (!dev->device.name) + goto error; + +@@ -261,6 +262,7 @@ vmbus_scan_one(const char *name) + + /* skip non-network devices */ + if (rte_uuid_compare(dev->class_id, vmbus_nic_uuid) != 0) { ++ free(dev_name); + free(dev); + return 0; + } +@@ -312,6 +314,7 @@ vmbus_scan_one(const char *name) + } else { /* already registered */ + VMBUS_LOG(NOTICE, + "%s already registered", name); ++ free(dev_name); + free(dev); + } + return 0; +@@ -322,6 +325,7 @@ vmbus_scan_one(const char *name) + error: + VMBUS_LOG(DEBUG, "failed"); + ++ free(dev_name); + free(dev); + return -1; + } diff --git a/dpdk/drivers/bus/vmbus/linux/vmbus_uio.c b/dpdk/drivers/bus/vmbus/linux/vmbus_uio.c -index 10e50c9b5a..5dc0c47de6 100644 +index 10e50c9b5a..fd64be93b0 100644 --- a/dpdk/drivers/bus/vmbus/linux/vmbus_uio.c +++ b/dpdk/drivers/bus/vmbus/linux/vmbus_uio.c -@@ -165,7 +165,7 @@ vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx, +@@ -11,6 +11,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -165,7 +166,7 @@ vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx, dev->resource[idx].addr = mapaddr; vmbus_map_addr = RTE_PTR_ADD(mapaddr, size); @@ -17595,20 +25598,304 @@ index 10e50c9b5a..5dc0c47de6 100644 maps[idx].addr = mapaddr; maps[idx].size = size; -@@ -242,7 +242,7 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, +@@ -203,6 +204,37 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, + struct stat sb; + void *mapaddr; + int fd; ++ struct mapped_vmbus_resource *uio_res; ++ int channel_idx; ++ ++ uio_res = vmbus_uio_find_resource(dev); ++ if (!uio_res) { ++ VMBUS_LOG(ERR, "can not find resources for mapping subchan"); ++ return -ENOMEM; ++ } ++ ++ if (rte_eal_process_type() == RTE_PROC_PRIMARY) { ++ if (uio_res->nb_subchannels >= UIO_MAX_SUBCHANNEL) { ++ VMBUS_LOG(ERR, ++ "exceeding max subchannels UIO_MAX_SUBCHANNEL(%d)", ++ UIO_MAX_SUBCHANNEL); ++ VMBUS_LOG(ERR, "Change UIO_MAX_SUBCHANNEL and recompile"); ++ return -ENOMEM; ++ } ++ } else { ++ for (channel_idx = 0; channel_idx < uio_res->nb_subchannels; ++ channel_idx++) ++ if (uio_res->subchannel_maps[channel_idx].relid == ++ chan->relid) ++ break; ++ if (channel_idx == uio_res->nb_subchannels) { ++ VMBUS_LOG(ERR, ++ "couldn't find sub channel %d from shared mapping in primary", ++ chan->relid); ++ return -ENOMEM; ++ } ++ vmbus_map_addr = uio_res->subchannel_maps[channel_idx].addr; ++ } + + snprintf(ring_path, sizeof(ring_path), + "%s/%s/channels/%u/ring", +@@ -239,58 +271,33 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, + if (mapaddr == MAP_FAILED) + return -EIO; + ++ if (rte_eal_process_type() == RTE_PROC_PRIMARY) { ++ ++ /* Add this mapping to uio_res for use by secondary */ ++ uio_res->subchannel_maps[uio_res->nb_subchannels].relid = ++ chan->relid; ++ uio_res->subchannel_maps[uio_res->nb_subchannels].addr = ++ mapaddr; ++ uio_res->subchannel_maps[uio_res->nb_subchannels].size = ++ file_size; ++ uio_res->nb_subchannels++; ++ ++ vmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size); ++ } else { ++ if (mapaddr != vmbus_map_addr) { ++ VMBUS_LOG(ERR, "failed to map channel %d to addr %p", ++ chan->relid, mapaddr); ++ vmbus_unmap_resource(mapaddr, file_size); ++ return -EIO; ++ } ++ } ++ *ring_size = file_size / 2; *ring_buf = mapaddr; - vmbus_map_addr = RTE_PTR_ADD(ring_buf, file_size); -+ vmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size); return 0; } +-int +-vmbus_uio_map_secondary_subchan(const struct rte_vmbus_device *dev, +- const struct vmbus_channel *chan) +-{ +- const struct vmbus_br *br = &chan->txbr; +- char ring_path[PATH_MAX]; +- void *mapaddr, *ring_buf; +- uint32_t ring_size; +- int fd; +- +- snprintf(ring_path, sizeof(ring_path), +- "%s/%s/channels/%u/ring", +- SYSFS_VMBUS_DEVICES, dev->device.name, +- chan->relid); +- +- ring_buf = br->vbr; +- ring_size = br->dsize + sizeof(struct vmbus_bufring); +- VMBUS_LOG(INFO, "secondary ring_buf %p size %u", +- ring_buf, ring_size); +- +- fd = open(ring_path, O_RDWR); +- if (fd < 0) { +- VMBUS_LOG(ERR, "Cannot open %s: %s", +- ring_path, strerror(errno)); +- return -errno; +- } +- +- mapaddr = vmbus_map_resource(ring_buf, fd, 0, 2 * ring_size, 0); +- close(fd); +- +- if (mapaddr == ring_buf) +- return 0; +- +- if (mapaddr == MAP_FAILED) +- VMBUS_LOG(ERR, +- "mmap subchan %u in secondary failed", chan->relid); +- else { +- VMBUS_LOG(ERR, +- "mmap subchan %u in secondary address mismatch", +- chan->relid); +- vmbus_unmap_resource(mapaddr, 2 * ring_size); +- } +- return -1; +-} +- + int vmbus_uio_map_rings(struct vmbus_channel *chan) + { + const struct rte_vmbus_device *dev = chan->device; +diff --git a/dpdk/drivers/bus/vmbus/private.h b/dpdk/drivers/bus/vmbus/private.h +index f19b14e4a6..5b8b01b808 100644 +--- a/dpdk/drivers/bus/vmbus/private.h ++++ b/dpdk/drivers/bus/vmbus/private.h +@@ -36,6 +36,13 @@ struct vmbus_map { + uint64_t size; /* length */ + }; + ++#define UIO_MAX_SUBCHANNEL 128 ++struct subchannel_map { ++ uint16_t relid; ++ void *addr; ++ uint64_t size; ++}; ++ + /* + * For multi-process we need to reproduce all vmbus mappings in secondary + * processes, so save them in a tailq. +@@ -44,10 +51,14 @@ struct mapped_vmbus_resource { + TAILQ_ENTRY(mapped_vmbus_resource) next; + + rte_uuid_t id; ++ + int nb_maps; +- struct vmbus_channel *primary; + struct vmbus_map maps[VMBUS_MAX_RESOURCE]; ++ + char path[PATH_MAX]; ++ ++ int nb_subchannels; ++ struct subchannel_map subchannel_maps[UIO_MAX_SUBCHANNEL]; + }; + + TAILQ_HEAD(mapped_vmbus_res_list, mapped_vmbus_resource); +@@ -66,6 +77,8 @@ struct vmbus_channel { + uint16_t relid; + uint16_t subchannel_id; + uint8_t monitor_id; ++ ++ struct vmbus_mon_page *monitor_page; + }; + + #define VMBUS_MAX_CHANNELS 64 +@@ -108,8 +121,6 @@ bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev, + int vmbus_uio_get_subchan(struct vmbus_channel *primary, + struct vmbus_channel **subchan); + int vmbus_uio_map_rings(struct vmbus_channel *chan); +-int vmbus_uio_map_secondary_subchan(const struct rte_vmbus_device *dev, +- const struct vmbus_channel *chan); + + void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen); + +diff --git a/dpdk/drivers/bus/vmbus/rte_bus_vmbus.h b/dpdk/drivers/bus/vmbus/rte_bus_vmbus.h +index 4cf73ce815..81b17817f1 100644 +--- a/dpdk/drivers/bus/vmbus/rte_bus_vmbus.h ++++ b/dpdk/drivers/bus/vmbus/rte_bus_vmbus.h +@@ -292,7 +292,7 @@ struct iova_list { + * @param data + * Pointer to the buffer additional data to send + * @param dlen +- * Maximum size of what the the buffer will hold ++ * Maximum size of what the buffer will hold + * @param xact + * Identifier of the request + * @param flags +diff --git a/dpdk/drivers/bus/vmbus/vmbus_channel.c b/dpdk/drivers/bus/vmbus/vmbus_channel.c +index 46b3ba3f9f..43c6c32d7e 100644 +--- a/dpdk/drivers/bus/vmbus/vmbus_channel.c ++++ b/dpdk/drivers/bus/vmbus/vmbus_channel.c +@@ -27,19 +27,7 @@ vmbus_sync_set_bit(volatile uint32_t *addr, uint32_t mask) + } + + static inline void +-vmbus_send_interrupt(const struct rte_vmbus_device *dev, uint32_t relid) +-{ +- uint32_t *int_addr; +- uint32_t int_mask; +- +- int_addr = dev->int_page + relid / 32; +- int_mask = 1u << (relid % 32); +- +- vmbus_sync_set_bit(int_addr, int_mask); +-} +- +-static inline void +-vmbus_set_monitor(const struct rte_vmbus_device *dev, uint32_t monitor_id) ++vmbus_set_monitor(const struct vmbus_channel *channel, uint32_t monitor_id) + { + uint32_t *monitor_addr, monitor_mask; + unsigned int trigger_index; +@@ -47,16 +35,14 @@ vmbus_set_monitor(const struct rte_vmbus_device *dev, uint32_t monitor_id) + trigger_index = monitor_id / HV_MON_TRIG_LEN; + monitor_mask = 1u << (monitor_id % HV_MON_TRIG_LEN); + +- monitor_addr = &dev->monitor_page->trigs[trigger_index].pending; ++ monitor_addr = &channel->monitor_page->trigs[trigger_index].pending; + vmbus_sync_set_bit(monitor_addr, monitor_mask); + } + + static void +-vmbus_set_event(const struct rte_vmbus_device *dev, +- const struct vmbus_channel *chan) ++vmbus_set_event(const struct vmbus_channel *chan) + { +- vmbus_send_interrupt(dev, chan->relid); +- vmbus_set_monitor(dev, chan->monitor_id); ++ vmbus_set_monitor(chan, chan->monitor_id); + } + + /* +@@ -94,7 +80,6 @@ rte_vmbus_set_latency(const struct rte_vmbus_device *dev, + void + rte_vmbus_chan_signal_tx(const struct vmbus_channel *chan) + { +- const struct rte_vmbus_device *dev = chan->device; + const struct vmbus_br *tbr = &chan->txbr; + + /* Make sure all updates are done before signaling host */ +@@ -104,7 +89,7 @@ rte_vmbus_chan_signal_tx(const struct vmbus_channel *chan) + if (tbr->vbr->imask) + return; + +- vmbus_set_event(dev, chan); ++ vmbus_set_event(chan); + } + + +@@ -230,7 +215,7 @@ void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read) + if (write_sz <= pending_sz) + return; + +- vmbus_set_event(chan->device, chan); ++ vmbus_set_event(chan); + } + + int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len, +@@ -337,6 +322,7 @@ int vmbus_chan_create(const struct rte_vmbus_device *device, + chan->subchannel_id = subid; + chan->relid = relid; + chan->monitor_id = monitor_id; ++ chan->monitor_page = device->monitor_page; + *new_chan = chan; + + err = vmbus_uio_map_rings(chan); +@@ -363,10 +349,8 @@ int rte_vmbus_chan_open(struct rte_vmbus_device *device, + + err = vmbus_chan_create(device, device->relid, 0, + device->monitor_id, new_chan); +- if (!err) { ++ if (!err) + device->primary = *new_chan; +- uio_res->primary = *new_chan; +- } + + return err; + } diff --git a/dpdk/drivers/bus/vmbus/vmbus_common.c b/dpdk/drivers/bus/vmbus/vmbus_common.c -index 48a219f735..3adef01c95 100644 +index 48a219f735..34676c48af 100644 --- a/dpdk/drivers/bus/vmbus/vmbus_common.c +++ b/dpdk/drivers/bus/vmbus/vmbus_common.c -@@ -131,7 +131,7 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr, +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -113,7 +114,9 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr, + dev->driver = dr; + + if (dev->device.numa_node < 0) { +- VMBUS_LOG(WARNING, " Invalid NUMA socket, default to 0"); ++ if (rte_socket_count() > 1) ++ VMBUS_LOG(INFO, "Device %s is not NUMA-aware, defaulting socket to 0", ++ guid); + dev->device.numa_node = 0; + } + +@@ -131,7 +134,7 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr, } /* @@ -17617,8 +25904,124 @@ index 48a219f735..3adef01c95 100644 * registere drivers for the vmbus device. * Return -1 if initialization failed, * and 1 if no driver found for this device. +diff --git a/dpdk/drivers/bus/vmbus/vmbus_common_uio.c b/dpdk/drivers/bus/vmbus/vmbus_common_uio.c +index 8e476f2eaf..e8db2fcbed 100644 +--- a/dpdk/drivers/bus/vmbus/vmbus_common_uio.c ++++ b/dpdk/drivers/bus/vmbus/vmbus_common_uio.c +@@ -69,8 +69,10 @@ vmbus_uio_map_secondary(struct rte_vmbus_device *dev) + fd, offset, + uio_res->maps[i].size, 0); + +- if (mapaddr == uio_res->maps[i].addr) ++ if (mapaddr == uio_res->maps[i].addr) { ++ dev->resource[i].addr = mapaddr; + continue; /* successful map */ ++ } + + if (mapaddr == MAP_FAILED) + VMBUS_LOG(ERR, +@@ -88,19 +90,39 @@ vmbus_uio_map_secondary(struct rte_vmbus_device *dev) + /* fd is not needed in slave process, close it */ + close(fd); + +- dev->primary = uio_res->primary; +- if (!dev->primary) { +- VMBUS_LOG(ERR, "missing primary channel"); +- return -1; ++ /* Create and map primary channel */ ++ if (vmbus_chan_create(dev, dev->relid, 0, ++ dev->monitor_id, &dev->primary)) { ++ VMBUS_LOG(ERR, "cannot create primary channel"); ++ goto failed_primary; + } + +- STAILQ_FOREACH(chan, &dev->primary->subchannel_list, next) { +- if (vmbus_uio_map_secondary_subchan(dev, chan) != 0) { +- VMBUS_LOG(ERR, "cannot map secondary subchan"); +- return -1; ++ /* Create and map sub channels */ ++ for (i = 0; i < uio_res->nb_subchannels; i++) { ++ if (rte_vmbus_subchan_open(dev->primary, &chan)) { ++ VMBUS_LOG(ERR, ++ "failed to create subchannel at index %d", i); ++ goto failed_secondary; + } + } ++ + return 0; ++ ++failed_secondary: ++ while (!STAILQ_EMPTY(&dev->primary->subchannel_list)) { ++ chan = STAILQ_FIRST(&dev->primary->subchannel_list); ++ vmbus_unmap_resource(chan->txbr.vbr, chan->txbr.dsize * 2); ++ rte_vmbus_chan_close(chan); ++ } ++ rte_vmbus_chan_close(dev->primary); ++ ++failed_primary: ++ for (i = 0; i != uio_res->nb_maps; i++) { ++ vmbus_unmap_resource( ++ uio_res->maps[i].addr, uio_res->maps[i].size); ++ } ++ ++ return -1; + } + + static int +@@ -188,6 +210,11 @@ vmbus_uio_unmap(struct mapped_vmbus_resource *uio_res) + if (uio_res == NULL) + return; + ++ for (i = 0; i < uio_res->nb_subchannels; i++) { ++ vmbus_unmap_resource(uio_res->subchannel_maps[i].addr, ++ uio_res->subchannel_maps[i].size); ++ } ++ + for (i = 0; i != uio_res->nb_maps; i++) { + vmbus_unmap_resource(uio_res->maps[i].addr, + (size_t)uio_res->maps[i].size); +@@ -211,8 +238,11 @@ vmbus_uio_unmap_resource(struct rte_vmbus_device *dev) + return; + + /* secondary processes - just free maps */ +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) +- return vmbus_uio_unmap(uio_res); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ vmbus_uio_unmap(uio_res); ++ rte_free(dev->primary); ++ return; ++ } + + TAILQ_REMOVE(uio_res_list, uio_res, next); + +diff --git a/dpdk/drivers/common/cpt/cpt_hw_types.h b/dpdk/drivers/common/cpt/cpt_hw_types.h +index e2b127de41..31aad5df9c 100644 +--- a/dpdk/drivers/common/cpt/cpt_hw_types.h ++++ b/dpdk/drivers/common/cpt/cpt_hw_types.h +@@ -460,7 +460,7 @@ typedef union { + uint64_t dbell_cnt : 20; + /** [ 19: 0](R/W/H) Number of instruction queue 64-bit words + * to add to the CPT instruction doorbell count. Readback value +- * is the the current number of pending doorbell requests. ++ * is the current number of pending doorbell requests. + * + * If counter overflows CPT()_VQ()_MISC_INT[DBELL_DOVF] is set. + * +diff --git a/dpdk/drivers/common/cpt/cpt_mcode_defines.h b/dpdk/drivers/common/cpt/cpt_mcode_defines.h +index f356e62811..305cb2fa33 100644 +--- a/dpdk/drivers/common/cpt/cpt_mcode_defines.h ++++ b/dpdk/drivers/common/cpt/cpt_mcode_defines.h +@@ -348,7 +348,7 @@ typedef struct buf_ptr { + /* IOV Pointer */ + typedef struct{ + int buf_cnt; +- buf_ptr_t bufs[0]; ++ buf_ptr_t bufs[]; + } iov_ptr_t; + + typedef union opcode_info { diff --git a/dpdk/drivers/common/cpt/cpt_ucode.h b/dpdk/drivers/common/cpt/cpt_ucode.h -index d5a0135d73..e92e3678c6 100644 +index d5a0135d73..f634546823 100644 --- a/dpdk/drivers/common/cpt/cpt_ucode.h +++ b/dpdk/drivers/common/cpt/cpt_ucode.h @@ -298,7 +298,7 @@ cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, const uint8_t *key, @@ -17630,26 +26033,50 @@ index d5a0135d73..e92e3678c6 100644 } /* Only for FC_GEN case */ -@@ -377,7 +377,7 @@ fill_sg_comp_from_iov(sg_comp_t *list, +@@ -377,31 +377,27 @@ fill_sg_comp_from_iov(sg_comp_t *list, { int32_t j; uint32_t extra_len = extra_buf ? extra_buf->size : 0; - uint32_t size = *psize - extra_len; +- buf_ptr_t *bufs; + uint32_t size = *psize; - buf_ptr_t *bufs; - bufs = from->bufs; -@@ -386,9 +386,6 @@ fill_sg_comp_from_iov(sg_comp_t *list, +- bufs = from->bufs; + for (j = 0; (j < from->buf_cnt) && size; j++) { ++ phys_addr_t dma_addr = from->bufs[j].dma_addr; ++ uint32_t buf_sz = from->bufs[j].size; ++ sg_comp_t *to = &list[i >> 2]; + phys_addr_t e_dma_addr; uint32_t e_len; - sg_comp_t *to = &list[i >> 2]; - +- sg_comp_t *to = &list[i >> 2]; +- - if (!bufs[j].size) - continue; -- + if (unlikely(from_offset)) { - if (from_offset >= bufs[j].size) { - from_offset -= bufs[j].size; -@@ -420,18 +417,19 @@ fill_sg_comp_from_iov(sg_comp_t *list, +- if (from_offset >= bufs[j].size) { +- from_offset -= bufs[j].size; ++ if (from_offset >= buf_sz) { ++ from_offset -= buf_sz; + continue; + } +- e_dma_addr = bufs[j].dma_addr + from_offset; +- e_len = (size > (bufs[j].size - from_offset)) ? +- (bufs[j].size - from_offset) : size; ++ e_dma_addr = dma_addr + from_offset; ++ e_len = (size > (buf_sz - from_offset)) ? ++ (buf_sz - from_offset) : size; + from_offset = 0; + } else { +- e_dma_addr = bufs[j].dma_addr; +- e_len = (size > bufs[j].size) ? +- bufs[j].size : size; ++ e_dma_addr = dma_addr; ++ e_len = (size > buf_sz) ? buf_sz : size; + } + + to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); +@@ -420,18 +416,19 @@ fill_sg_comp_from_iov(sg_comp_t *list, to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); } @@ -17672,7 +26099,7 @@ index d5a0135d73..e92e3678c6 100644 /* insert the rest of the data */ if (next_len) { i++; -@@ -720,9 +718,6 @@ cpt_enc_hmac_prep(uint32_t flags, +@@ -720,9 +717,6 @@ cpt_enc_hmac_prep(uint32_t flags, m_vaddr = (uint8_t *)m_vaddr + size; m_dma += size; @@ -17682,7 +26109,7 @@ index d5a0135d73..e92e3678c6 100644 if (unlikely(!(flags & VALID_IV_BUF))) { iv_len = 0; iv_offset = ENCR_IV_OFFSET(d_offs); -@@ -754,6 +749,11 @@ cpt_enc_hmac_prep(uint32_t flags, +@@ -754,6 +748,11 @@ cpt_enc_hmac_prep(uint32_t flags, opcode.s.major = CPT_MAJOR_OP_FC; opcode.s.minor = 0; @@ -17694,7 +26121,7 @@ index d5a0135d73..e92e3678c6 100644 auth_dlen = auth_offset + auth_data_len; enc_dlen = encr_data_len + encr_offset; if (unlikely(encr_data_len & 0xf)) { -@@ -764,11 +764,6 @@ cpt_enc_hmac_prep(uint32_t flags, +@@ -764,11 +763,6 @@ cpt_enc_hmac_prep(uint32_t flags, enc_dlen = ROUNDUP16(encr_data_len) + encr_offset; } @@ -17706,7 +26133,7 @@ index d5a0135d73..e92e3678c6 100644 if (unlikely(auth_dlen > enc_dlen)) { inputlen = auth_dlen; outputlen = auth_dlen + mac_len; -@@ -1071,9 +1066,6 @@ cpt_dec_hmac_prep(uint32_t flags, +@@ -1071,9 +1065,6 @@ cpt_dec_hmac_prep(uint32_t flags, hash_type = cpt_ctx->hash_type; mac_len = cpt_ctx->mac_len; @@ -17716,7 +26143,7 @@ index d5a0135d73..e92e3678c6 100644 if (unlikely(!(flags & VALID_IV_BUF))) { iv_len = 0; iv_offset = ENCR_IV_OFFSET(d_offs); -@@ -1130,6 +1122,11 @@ cpt_dec_hmac_prep(uint32_t flags, +@@ -1130,6 +1121,11 @@ cpt_dec_hmac_prep(uint32_t flags, opcode.s.major = CPT_MAJOR_OP_FC; opcode.s.minor = 1; @@ -17728,7 +26155,7 @@ index d5a0135d73..e92e3678c6 100644 enc_dlen = encr_offset + encr_data_len; auth_dlen = auth_offset + auth_data_len; -@@ -1141,9 +1138,6 @@ cpt_dec_hmac_prep(uint32_t flags, +@@ -1141,9 +1137,6 @@ cpt_dec_hmac_prep(uint32_t flags, outputlen = enc_dlen; } @@ -17738,7 +26165,16 @@ index d5a0135d73..e92e3678c6 100644 vq_cmd_w0.u64 = 0; vq_cmd_w0.s.param1 = encr_data_len; vq_cmd_w0.s.param2 = auth_data_len; -@@ -2620,10 +2614,13 @@ fill_sess_aead(struct rte_crypto_sym_xform *xform, +@@ -2316,7 +2309,7 @@ cpt_kasumi_dec_prep(uint64_t d_offs, + /* consider iv len */ + encr_offset += iv_len; + +- inputlen = iv_len + (RTE_ALIGN(encr_data_len, 8) / 8); ++ inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8); + outputlen = inputlen; + + /* save space for offset ctrl & iv */ +@@ -2620,10 +2613,13 @@ fill_sess_aead(struct rte_crypto_sym_xform *xform, sess->iv_length = aead_form->iv.length; sess->aad_length = aead_form->aad_length; @@ -17755,7 +26191,7 @@ index d5a0135d73..e92e3678c6 100644 return 0; } -@@ -2723,8 +2720,9 @@ fill_sess_cipher(struct rte_crypto_sym_xform *xform, +@@ -2723,8 +2719,9 @@ fill_sess_cipher(struct rte_crypto_sym_xform *xform, sess->iv_length = c_form->iv.length; sess->is_null = is_null; @@ -17767,7 +26203,7 @@ index d5a0135d73..e92e3678c6 100644 return 0; } -@@ -2823,8 +2821,10 @@ fill_sess_auth(struct rte_crypto_sym_xform *xform, +@@ -2823,8 +2820,10 @@ fill_sess_auth(struct rte_crypto_sym_xform *xform, sess->auth_iv_offset = a_form->iv.offset; sess->auth_iv_length = a_form->iv.length; } @@ -17780,7 +26216,7 @@ index d5a0135d73..e92e3678c6 100644 return 0; } -@@ -2867,9 +2867,13 @@ fill_sess_gmac(struct rte_crypto_sym_xform *xform, +@@ -2867,9 +2866,13 @@ fill_sess_gmac(struct rte_crypto_sym_xform *xform, sess->iv_length = a_form->iv.length; sess->mac_len = a_form->digest_length; @@ -17797,6 +26233,107 @@ index d5a0135d73..e92e3678c6 100644 return 0; } +diff --git a/dpdk/drivers/common/dpaax/Makefile b/dpdk/drivers/common/dpaax/Makefile +index 59bd8ae15d..ff4f89890d 100644 +--- a/dpdk/drivers/common/dpaax/Makefile ++++ b/dpdk/drivers/common/dpaax/Makefile +@@ -16,6 +16,7 @@ CFLAGS += -Wno-pointer-arith + CFLAGS += -Wno-cast-qual + + CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax ++CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib + + # versioning export map + EXPORT_MAP := rte_common_dpaax_version.map +@@ -23,7 +24,7 @@ EXPORT_MAP := rte_common_dpaax_version.map + # + # all source are stored in SRCS-y + # +-SRCS-y += dpaax_iova_table.c dpaa_of.c ++SRCS-y += dpaax_iova_table.c dpaa_of.c caamflib.c + + LDLIBS += -lrte_eal + +diff --git a/dpdk/drivers/common/dpaax/caamflib.c b/dpdk/drivers/common/dpaax/caamflib.c +new file mode 100644 +index 0000000000..55e20281ca +--- /dev/null ++++ b/dpdk/drivers/common/dpaax/caamflib.c +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) ++ * ++ * Copyright 2020 NXP ++ * ++ */ ++ ++#include ++ ++/* ++ * SEC HW block revision. ++ * ++ * This *must not be confused with SEC version*: ++ * - SEC HW block revision format is "v" ++ * - SEC revision format is "x.y" ++ */ ++enum rta_sec_era rta_sec_era; +diff --git a/dpdk/drivers/common/dpaax/caamflib/compat.h b/dpdk/drivers/common/dpaax/caamflib/compat.h +index ce946ccb5c..95d887a9d6 100644 +--- a/dpdk/drivers/common/dpaax/caamflib/compat.h ++++ b/dpdk/drivers/common/dpaax/caamflib/compat.h +@@ -11,7 +11,7 @@ + #include + #include + +-#ifdef __GLIBC__ ++#ifdef RTE_EXEC_ENV_LINUX + #include + #include + #include +@@ -24,7 +24,7 @@ + #error "Undefined endianness" + #endif + +-#else ++#else /* !RTE_EXEC_ENV_LINUX */ + #error Environment not supported! + #endif + +@@ -40,7 +40,7 @@ + #define __maybe_unused __attribute__((unused)) + #endif + +-#if defined(__GLIBC__) && !defined(pr_debug) ++#if !defined(pr_debug) + #if !defined(SUPPRESS_PRINTS) && defined(RTA_DEBUG) + #define pr_debug(fmt, ...) \ + RTE_LOG(DEBUG, PMD, "%s(): " fmt "\n", __func__, ##__VA_ARGS__) +@@ -49,7 +49,7 @@ + #endif + #endif /* pr_debug */ + +-#if defined(__GLIBC__) && !defined(pr_err) ++#if !defined(pr_err) + #if !defined(SUPPRESS_PRINTS) + #define pr_err(fmt, ...) \ + RTE_LOG(ERR, PMD, "%s(): " fmt "\n", __func__, ##__VA_ARGS__) +@@ -58,7 +58,7 @@ + #endif + #endif /* pr_err */ + +-#if defined(__GLIBC__) && !defined(pr_warn) ++#if !defined(pr_warn) + #if !defined(SUPPRESS_PRINTS) + #define pr_warn(fmt, ...) \ + RTE_LOG(WARNING, PMD, "%s(): " fmt "\n", __func__, ##__VA_ARGS__) +@@ -101,7 +101,7 @@ + #endif + + /* Use Linux naming convention */ +-#ifdef __GLIBC__ ++#if defined(RTE_EXEC_ENV_LINUX) || defined(__GLIBC__) + #define swab16(x) rte_bswap16(x) + #define swab32(x) rte_bswap32(x) + #define swab64(x) rte_bswap64(x) diff --git a/dpdk/drivers/common/dpaax/caamflib/desc.h b/dpdk/drivers/common/dpaax/caamflib/desc.h index e4139aaa9f..635d6bad07 100644 --- a/dpdk/drivers/common/dpaax/caamflib/desc.h @@ -17811,14 +26348,14 @@ index e4139aaa9f..635d6bad07 100644 /* Block size of any entity covered/uncovered with a KEK/TKEK */ #define KEK_BLOCKSIZE 16 diff --git a/dpdk/drivers/common/dpaax/caamflib/desc/pdcp.h b/dpdk/drivers/common/dpaax/caamflib/desc/pdcp.h -index b5e2d24e47..476115323c 100644 +index b5e2d24e47..595d0e0318 100644 --- a/dpdk/drivers/common/dpaax/caamflib/desc/pdcp.h +++ b/dpdk/drivers/common/dpaax/caamflib/desc/pdcp.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+ * Copyright 2008-2013 Freescale Semiconductor, Inc. - * Copyright 2019 NXP -+ * Copyright 2019-2020 NXP ++ * Copyright 2019-2021 NXP */ #ifndef __DESC_PDCP_H__ @@ -17889,6 +26426,107 @@ index b5e2d24e47..476115323c 100644 /* Insert Cipher Key */ KEY(p, KEY1, cipherdata->key_enc_flags, +@@ -3638,9 +3691,10 @@ cnstr_shdsc_pdcp_short_mac(uint32_t *descbuf, + break; + + case PDCP_AUTH_TYPE_SNOW: ++ /* IV calculation based on 3GPP specs. 36331, section:5.3.7.4 */ + iv[0] = 0xFFFFFFFF; +- iv[1] = swap ? swab32(0x04000000) : 0x04000000; +- iv[2] = swap ? swab32(0xF8000000) : 0xF8000000; ++ iv[1] = swab32(0x04000000); ++ iv[2] = swab32(0xF8000000); + + KEY(p, KEY2, authdata->key_enc_flags, authdata->key, + authdata->keylen, INLINE_KEY(authdata)); +@@ -3717,7 +3771,7 @@ cnstr_shdsc_pdcp_short_mac(uint32_t *descbuf, + return -ENOTSUP; + } + iv[0] = 0xFFFFFFFF; +- iv[1] = swap ? swab32(0xFC000000) : 0xFC000000; ++ iv[1] = swab32(0xFC000000); + iv[2] = 0x00000000; /* unused */ + + KEY(p, KEY2, authdata->key_enc_flags, authdata->key, +diff --git a/dpdk/drivers/common/dpaax/compat.h b/dpdk/drivers/common/dpaax/compat.h +index 12c9d99179..d2883d02d4 100644 +--- a/dpdk/drivers/common/dpaax/compat.h ++++ b/dpdk/drivers/common/dpaax/compat.h +@@ -34,7 +34,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/dpdk/drivers/common/dpaax/dpaax_iova_table.c b/dpdk/drivers/common/dpaax/dpaax_iova_table.c +index 98b076e09f..3f3be4ff9f 100644 +--- a/dpdk/drivers/common/dpaax/dpaax_iova_table.c ++++ b/dpdk/drivers/common/dpaax/dpaax_iova_table.c +@@ -369,8 +369,10 @@ dpaax_iova_table_dump(void) + } + + DPAAX_DEBUG(" === Start of PA->VA Translation Table ==="); +- if (dpaax_iova_table_p == NULL) ++ if (dpaax_iova_table_p == NULL) { + DPAAX_DEBUG("\tNULL"); ++ return; ++ } + + entry = dpaax_iova_table_p->entries; + for (i = 0; i < dpaax_iova_table_p->count; i++) { +diff --git a/dpdk/drivers/common/dpaax/dpaax_iova_table.h b/dpdk/drivers/common/dpaax/dpaax_iova_table.h +index fef97f6dde..599f5b842b 100644 +--- a/dpdk/drivers/common/dpaax/dpaax_iova_table.h ++++ b/dpdk/drivers/common/dpaax/dpaax_iova_table.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright 2018 NXP ++ * Copyright 2018-2021 NXP + */ + + #ifndef _DPAAX_IOVA_TABLE_H_ +@@ -97,6 +97,12 @@ dpaax_iova_table_get_va(phys_addr_t paddr) { + + /* paddr > entry->start && paddr <= entry->(start+len) */ + index = (paddr_align - entry[i].start)/DPAAX_MEM_SPLIT; ++ /* paddr is within range, but no vaddr entry ever written ++ * at index ++ */ ++ if ((void *)(uintptr_t)entry[i].pages[index] == NULL) ++ return NULL; ++ + vaddr = (void *)((uintptr_t)entry[i].pages[index] + offset); + break; + } while (1); +diff --git a/dpdk/drivers/common/dpaax/meson.build b/dpdk/drivers/common/dpaax/meson.build +index d41bb50732..dc3e26d8f1 100644 +--- a/dpdk/drivers/common/dpaax/meson.build ++++ b/dpdk/drivers/common/dpaax/meson.build +@@ -8,7 +8,9 @@ if not is_linux + reason = 'only supported on linux' + endif + +-sources = files('dpaax_iova_table.c', 'dpaa_of.c') ++sources = files('dpaax_iova_table.c', 'dpaa_of.c', 'caamflib.c') ++ ++includes += include_directories('caamflib') + + cflags += ['-D_GNU_SOURCE'] + if cc.has_argument('-Wno-cast-qual') +diff --git a/dpdk/drivers/common/dpaax/rte_common_dpaax_version.map b/dpdk/drivers/common/dpaax/rte_common_dpaax_version.map +index f72eba761d..837ce01af3 100644 +--- a/dpdk/drivers/common/dpaax/rte_common_dpaax_version.map ++++ b/dpdk/drivers/common/dpaax/rte_common_dpaax_version.map +@@ -21,3 +21,7 @@ DPDK_20.0 { + + local: *; + }; ++ ++INTERNAL { ++ rta_sec_era; ++}; diff --git a/dpdk/drivers/common/octeontx/octeontx_mbox.c b/dpdk/drivers/common/octeontx/octeontx_mbox.c index 2fd2531072..effe0b267e 100644 --- a/dpdk/drivers/common/octeontx/octeontx_mbox.c @@ -17981,6 +26619,20 @@ index a0536e0aed..600084ff31 100644 * effect flow tag calculation and thus RSS. */ enum npc_kpu_lh_ltype { +diff --git a/dpdk/drivers/common/octeontx2/otx2_dev.h b/dpdk/drivers/common/octeontx2/otx2_dev.h +index 7d9839c334..61d8ff6e41 100644 +--- a/dpdk/drivers/common/octeontx2/otx2_dev.h ++++ b/dpdk/drivers/common/octeontx2/otx2_dev.h +@@ -46,6 +46,9 @@ + ((RVU_PCI_REV_MAJOR(otx2_dev_revid(dev)) == 0x0) && \ + (RVU_PCI_REV_MIDR_ID(otx2_dev_revid(dev)) == 0x0)) + ++#define otx2_dev_is_98xx(dev) \ ++ (RVU_PCI_REV_MIDR_ID(otx2_dev_revid(dev)) == 0x3) ++ + struct otx2_dev; + + /* Link status callback */ diff --git a/dpdk/drivers/common/octeontx2/otx2_io_arm64.h b/dpdk/drivers/common/octeontx2/otx2_io_arm64.h index 7e45329b38..3380c9874f 100644 --- a/dpdk/drivers/common/octeontx2/otx2_io_arm64.h @@ -18481,7 +27133,7 @@ index 2a1cf3e179..e3d2b9c79a 100644 RTE_PMD_REGISTER_PCI_TABLE(QAT_PCI_NAME, pci_id_qat_map); +RTE_PMD_REGISTER_KMOD_DEP(QAT_PCI_NAME, "* igb_uio | uio_pci_generic | vfio-pci"); diff --git a/dpdk/drivers/common/qat/qat_device.h b/dpdk/drivers/common/qat/qat_device.h -index 131375e838..c3f5ae8990 100644 +index 131375e838..7460dfd852 100644 --- a/dpdk/drivers/common/qat/qat_device.h +++ b/dpdk/drivers/common/qat/qat_device.h @@ -16,12 +16,53 @@ @@ -18501,7 +27153,8 @@ index 131375e838..c3f5ae8990 100644 enum qat_comp_num_im_buffers { QAT_NUM_INTERM_BUFS_GEN1 = 12, QAT_NUM_INTERM_BUFS_GEN2 = 20, - QAT_NUM_INTERM_BUFS_GEN3 = 20 +- QAT_NUM_INTERM_BUFS_GEN3 = 20 ++ QAT_NUM_INTERM_BUFS_GEN3 = 64 }; +struct qat_device_info { @@ -19125,10 +27778,27 @@ index 25578880db..b039dfdfc5 100644 build = false reason = 'missing dependency, "libisal"' diff --git a/dpdk/drivers/compress/octeontx/otx_zip_pmd.c b/dpdk/drivers/compress/octeontx/otx_zip_pmd.c -index 9e00c86630..bff8ef035e 100644 +index 9e00c86630..3876b5e74a 100644 --- a/dpdk/drivers/compress/octeontx/otx_zip_pmd.c +++ b/dpdk/drivers/compress/octeontx/otx_zip_pmd.c -@@ -406,7 +406,7 @@ zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, +@@ -394,6 +394,8 @@ zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, + } + + name = rte_malloc(NULL, RTE_COMPRESSDEV_NAME_MAX_LEN, 0); ++ if (name == NULL) ++ return (-ENOMEM); + snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, + "zip_pmd_%u_qp_%u", + dev->data->dev_id, qp_id); +@@ -401,12 +403,14 @@ zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, + /* Allocate the queue pair data structure. */ + qp = rte_zmalloc_socket(name, sizeof(*qp), + RTE_CACHE_LINE_SIZE, socket_id); +- if (qp == NULL) ++ if (qp == NULL) { ++ rte_free(name); + return (-ENOMEM); ++ } qp->name = name; @@ -19137,10 +27807,55 @@ index 9e00c86630..bff8ef035e 100644 qp->processed_pkts = zip_pmd_qp_create_processed_pkts_ring(qp, max_inflight_ops, socket_id); if (qp->processed_pkts == NULL) +diff --git a/dpdk/drivers/compress/qat/qat_comp.c b/dpdk/drivers/compress/qat/qat_comp.c +index 533e34f6bb..cd06809463 100644 +--- a/dpdk/drivers/compress/qat/qat_comp.c ++++ b/dpdk/drivers/compress/qat/qat_comp.c +@@ -68,8 +68,8 @@ qat_comp_build_request(void *in_op, uint8_t *out_msg, + ICP_QAT_FW_COMP_EOP + : ICP_QAT_FW_COMP_NOT_EOP, + ICP_QAT_FW_COMP_NOT_BFINAL, +- ICP_QAT_FW_COMP_NO_CNV, +- ICP_QAT_FW_COMP_NO_CNV_RECOVERY); ++ ICP_QAT_FW_COMP_CNV, ++ ICP_QAT_FW_COMP_CNV_RECOVERY); + } + + if (likely(qat_xform->qat_comp_request_type == +@@ -286,7 +286,8 @@ qat_comp_process_response(void **op, uint8_t *resp, void *op_cookie, + rx_op->status = RTE_COMP_OP_STATUS_ERROR; + rx_op->debug_status = ERR_CODE_QAT_COMP_WRONG_FW; + *op = (void *)rx_op; +- QAT_DP_LOG(ERR, "QAT has wrong firmware"); ++ QAT_DP_LOG(ERR, ++ "This QAT hardware doesn't support compression operation"); + ++(*dequeue_err_count); + return 0; + } diff --git a/dpdk/drivers/compress/qat/qat_comp_pmd.c b/dpdk/drivers/compress/qat/qat_comp_pmd.c -index 05b7dfe774..5cdabadef7 100644 +index 05b7dfe774..dafd3da317 100644 --- a/dpdk/drivers/compress/qat/qat_comp_pmd.c +++ b/dpdk/drivers/compress/qat/qat_comp_pmd.c +@@ -82,13 +82,13 @@ qat_comp_qp_release(struct rte_compressdev *dev, uint16_t queue_pair_id) + qat_private->qat_dev->qps_in_use[QAT_SERVICE_COMPRESSION][queue_pair_id] + = NULL; + +- for (i = 0; i < qp->nb_descriptors; i++) { +- +- struct qat_comp_op_cookie *cookie = qp->op_cookies[i]; ++ if (qp != NULL) ++ for (i = 0; i < qp->nb_descriptors; i++) { ++ struct qat_comp_op_cookie *cookie = qp->op_cookies[i]; + +- rte_free(cookie->qat_sgl_src_d); +- rte_free(cookie->qat_sgl_dst_d); +- } ++ rte_free(cookie->qat_sgl_src_d); ++ rte_free(cookie->qat_sgl_dst_d); ++ } + + return qat_qp_release((struct qat_qp **) + &(dev->data->queue_pairs[queue_pair_id])); @@ -139,6 +139,7 @@ qat_comp_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, = *qp_addr; @@ -19149,7 +27864,166 @@ index 05b7dfe774..5cdabadef7 100644 for (i = 0; i < qp->nb_descriptors; i++) { -@@ -660,8 +661,12 @@ static const struct rte_driver compdev_qat_driver = { +@@ -195,7 +196,7 @@ qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev, + struct array_of_ptrs *array_of_pointers; + int size_of_ptr_array; + uint32_t full_size; +- uint32_t offset_of_sgls, offset_of_flat_buffs = 0; ++ uint32_t offset_of_flat_buffs; + int i; + int num_im_sgls = qat_gen_config[ + comp_dev->qat_dev->qat_dev_gen].comp_num_im_bufs_required; +@@ -210,31 +211,31 @@ qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev, + return memzone; + } + +- /* Create a memzone to hold intermediate buffers and associated +- * meta-data needed by the firmware. The memzone contains 3 parts: ++ /* Create multiple memzones to hold intermediate buffers and associated ++ * meta-data needed by the firmware. ++ * The first memzone contains: + * - a list of num_im_sgls physical pointers to sgls +- * - the num_im_sgl sgl structures, each pointing to +- * QAT_NUM_BUFS_IN_IM_SGL flat buffers +- * - the flat buffers: num_im_sgl * QAT_NUM_BUFS_IN_IM_SGL +- * buffers, each of buff_size ++ * All other memzones contain: ++ * - the sgl structure, pointing to QAT_NUM_BUFS_IN_IM_SGL flat buffers ++ * - the flat buffers: QAT_NUM_BUFS_IN_IM_SGL buffers, ++ * each of buff_size + * num_im_sgls depends on the hardware generation of the device + * buff_size comes from the user via the config file + */ + + size_of_ptr_array = num_im_sgls * sizeof(phys_addr_t); +- offset_of_sgls = (size_of_ptr_array + (~QAT_64_BYTE_ALIGN_MASK)) +- & QAT_64_BYTE_ALIGN_MASK; +- offset_of_flat_buffs = +- offset_of_sgls + num_im_sgls * sizeof(struct qat_inter_sgl); ++ offset_of_flat_buffs = sizeof(struct qat_inter_sgl); + full_size = offset_of_flat_buffs + +- num_im_sgls * buff_size * QAT_NUM_BUFS_IN_IM_SGL; ++ buff_size * QAT_NUM_BUFS_IN_IM_SGL; + +- memzone = rte_memzone_reserve_aligned(inter_buff_mz_name, full_size, ++ memzone = rte_memzone_reserve_aligned(inter_buff_mz_name, ++ size_of_ptr_array, + comp_dev->compressdev->data->socket_id, + RTE_MEMZONE_IOVA_CONTIG, QAT_64_BYTE_ALIGN); + if (memzone == NULL) { +- QAT_LOG(ERR, "Can't allocate intermediate buffers" +- " for device %s", comp_dev->qat_dev->name); ++ QAT_LOG(ERR, ++ "Can't allocate intermediate buffers for device %s", ++ comp_dev->qat_dev->name); + return NULL; + } + +@@ -243,17 +244,50 @@ qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev, + QAT_LOG(DEBUG, "Memzone %s: addr = %p, phys = 0x%"PRIx64 + ", size required %d, size created %zu", + inter_buff_mz_name, mz_start, mz_start_phys, +- full_size, memzone->len); ++ size_of_ptr_array, memzone->len); + + array_of_pointers = (struct array_of_ptrs *)mz_start; + for (i = 0; i < num_im_sgls; i++) { +- uint32_t curr_sgl_offset = +- offset_of_sgls + i * sizeof(struct qat_inter_sgl); +- struct qat_inter_sgl *sgl = +- (struct qat_inter_sgl *)(mz_start + curr_sgl_offset); ++ const struct rte_memzone *mz; ++ struct qat_inter_sgl *sgl; + int lb; +- array_of_pointers->pointer[i] = mz_start_phys + curr_sgl_offset; + ++ snprintf(inter_buff_mz_name, RTE_MEMZONE_NAMESIZE, ++ "%s_inter_buff_%d", comp_dev->qat_dev->name, i); ++ mz = rte_memzone_lookup(inter_buff_mz_name); ++ if (mz == NULL) { ++ mz = rte_memzone_reserve_aligned(inter_buff_mz_name, ++ full_size, ++ comp_dev->compressdev->data->socket_id, ++ RTE_MEMZONE_IOVA_CONTIG, ++ QAT_64_BYTE_ALIGN); ++ if (mz == NULL) { ++ QAT_LOG(ERR, ++ "Can't allocate intermediate buffers for device %s", ++ comp_dev->qat_dev->name); ++ while (--i >= 0) { ++ snprintf(inter_buff_mz_name, ++ RTE_MEMZONE_NAMESIZE, ++ "%s_inter_buff_%d", ++ comp_dev->qat_dev->name, ++ i); ++ rte_memzone_free( ++ rte_memzone_lookup( ++ inter_buff_mz_name)); ++ } ++ rte_memzone_free(memzone); ++ return NULL; ++ } ++ } ++ ++ QAT_LOG(DEBUG, "Memzone %s: addr = %p, phys = 0x%"PRIx64 ++ ", size required %d, size created %zu", ++ inter_buff_mz_name, mz->addr, mz->iova, ++ full_size, mz->len); ++ ++ array_of_pointers->pointer[i] = mz->iova; ++ ++ sgl = (struct qat_inter_sgl *) mz->addr; + sgl->num_bufs = QAT_NUM_BUFS_IN_IM_SGL; + sgl->num_mapped_bufs = 0; + sgl->resrvd = 0; +@@ -265,8 +299,8 @@ qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev, + #endif + for (lb = 0; lb < QAT_NUM_BUFS_IN_IM_SGL; lb++) { + sgl->buffers[lb].addr = +- mz_start_phys + offset_of_flat_buffs + +- (((i * QAT_NUM_BUFS_IN_IM_SGL) + lb) * buff_size); ++ mz->iova + offset_of_flat_buffs + ++ lb * buff_size; + sgl->buffers[lb].len = buff_size; + sgl->buffers[lb].resrvd = 0; + #if QAT_IM_BUFFER_DEBUG +@@ -278,7 +312,7 @@ qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev, + } + #if QAT_IM_BUFFER_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "IM buffer memzone start:", +- mz_start, offset_of_flat_buffs + 32); ++ memzone->addr, size_of_ptr_array); + #endif + return memzone; + } +@@ -441,6 +475,16 @@ _qat_comp_dev_config_clear(struct qat_comp_dev_private *comp_dev) + { + /* Free intermediate buffers */ + if (comp_dev->interm_buff_mz) { ++ char mz_name[RTE_MEMZONE_NAMESIZE]; ++ int i = qat_gen_config[ ++ comp_dev->qat_dev->qat_dev_gen].comp_num_im_bufs_required; ++ ++ while (--i >= 0) { ++ snprintf(mz_name, RTE_MEMZONE_NAMESIZE, ++ "%s_inter_buff_%d", ++ comp_dev->qat_dev->name, i); ++ rte_memzone_free(rte_memzone_lookup(mz_name)); ++ } + rte_memzone_free(comp_dev->interm_buff_mz); + comp_dev->interm_buff_mz = NULL; + } +@@ -618,7 +662,8 @@ qat_comp_pmd_dequeue_frst_op_burst(void *qp, struct rte_comp_op **ops, + + tmp_qp->qat_dev->comp_dev->compressdev->dev_ops = + &compress_qat_dummy_ops; +- QAT_LOG(ERR, "QAT PMD detected wrong FW version !"); ++ QAT_LOG(ERR, ++ "This QAT hardware doesn't support compression operation"); + + } else { + tmp_qp->qat_dev->comp_dev->compressdev->dequeue_burst = +@@ -660,33 +705,35 @@ static const struct rte_driver compdev_qat_driver = { .alias = qat_comp_drv_name }; int @@ -19157,14 +28031,14 @@ index 05b7dfe774..5cdabadef7 100644 +qat_comp_dev_create(struct qat_pci_device *qat_pci_dev, + struct qat_dev_cmd_param *qat_dev_cmd_param) { +- if (qat_pci_dev->qat_dev_gen == QAT_GEN3) { +- QAT_LOG(ERR, "Compression PMD not supported on QAT c4xxx"); +- return 0; +- } +- + int i = 0; + struct qat_device_info *qat_dev_instance = + &qat_pci_devs[qat_pci_dev->qat_dev_id]; - if (qat_pci_dev->qat_dev_gen == QAT_GEN3) { - QAT_LOG(ERR, "Compression PMD not supported on QAT c4xxx"); - return 0; -@@ -669,24 +674,27 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev) - struct rte_compressdev_pmd_init_params init_params = { .name = "", - .socket_id = qat_pci_dev->pci_dev->device.numa_node, @@ -19197,7 +28071,7 @@ index 05b7dfe774..5cdabadef7 100644 sizeof(struct qat_comp_dev_private), &init_params); -@@ -700,25 +708,62 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev) +@@ -700,25 +747,62 @@ qat_comp_dev_create(struct qat_pci_device *qat_pci_dev) compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED; @@ -19263,7 +28137,7 @@ index 05b7dfe774..5cdabadef7 100644 QAT_LOG(DEBUG, "Created QAT COMP device %s as compressdev instance %d", name, compressdev->data->dev_id); -@@ -737,6 +782,9 @@ qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev) +@@ -737,6 +821,9 @@ qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev) if (comp_dev == NULL) return 0; @@ -19274,9 +28148,18 @@ index 05b7dfe774..5cdabadef7 100644 qat_comp_dev_close(comp_dev->compressdev); diff --git a/dpdk/drivers/compress/qat/qat_comp_pmd.h b/dpdk/drivers/compress/qat/qat_comp_pmd.h -index 6979de14d4..ed27120604 100644 +index 6979de14d4..2325df23b5 100644 --- a/dpdk/drivers/compress/qat/qat_comp_pmd.h +++ b/dpdk/drivers/compress/qat/qat_comp_pmd.h +@@ -12,7 +12,7 @@ + + #include "qat_device.h" + +-/**< Intel(R) QAT Compression PMD driver name */ ++/**< Intel(R) QAT Compression PMD name */ + #define COMPRESSDEV_NAME_QAT_PMD compress_qat + + /** private data structure for a QAT compression device. @@ -32,10 +32,14 @@ struct qat_comp_dev_private { /**< The device's pool for qat_comp_xforms */ struct rte_mempool *streampool; @@ -19672,29 +28555,32 @@ index 7dc83e69e1..3c5af17e68 100644 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_pmd_drv); RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd); RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD, -diff --git a/dpdk/drivers/crypto/caam_jr/Makefile b/dpdk/drivers/crypto/caam_jr/Makefile -index 1b1f25a2a2..5b27b84c09 100644 ---- a/dpdk/drivers/crypto/caam_jr/Makefile -+++ b/dpdk/drivers/crypto/caam_jr/Makefile -@@ -16,6 +16,13 @@ CFLAGS += -D _GNU_SOURCE - CFLAGS += -O3 - CFLAGS += $(WERROR_FLAGS) - -+# FIXME: temporary solution for Bugzilla 469 -+ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) -+ifeq ($(shell test $(GCC_VERSION) -ge 100 && echo 1), 1) -+CFLAGS += -fcommon -+endif -+endif -+ - CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include - CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax - CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib/ diff --git a/dpdk/drivers/crypto/caam_jr/caam_jr.c b/dpdk/drivers/crypto/caam_jr/caam_jr.c -index 8aaa3d45f6..d6fa8cf7e8 100644 +index 8aaa3d45f6..143dd9df76 100644 --- a/dpdk/drivers/crypto/caam_jr/caam_jr.c +++ b/dpdk/drivers/crypto/caam_jr/caam_jr.c -@@ -2084,7 +2084,7 @@ static struct rte_security_ops caam_jr_security_ops = { +@@ -37,8 +37,6 @@ + static uint8_t cryptodev_driver_id; + int caam_jr_logtype; + +-enum rta_sec_era rta_sec_era; +- + /* Lists the states possible for the SEC user space driver. */ + enum sec_driver_state_e { + SEC_DRIVER_STATE_IDLE, /* Driver not initialized */ +@@ -1890,8 +1888,9 @@ caam_jr_set_ipsec_session(__rte_unused struct rte_cryptodev *dev, + session->encap_pdb.options = + (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) | + PDBOPTS_ESP_OIHI_PDB_INL | +- PDBOPTS_ESP_IVSRC | +- PDBHMO_ESP_ENCAP_DTTL; ++ PDBOPTS_ESP_IVSRC; ++ if (ipsec_xform->options.dec_ttl) ++ session->encap_pdb.options |= PDBHMO_ESP_ENCAP_DTTL; + if (ipsec_xform->options.esn) + session->encap_pdb.options |= PDBOPTS_ESP_ESN; + session->encap_pdb.spi = ipsec_xform->spi; +@@ -2084,7 +2083,7 @@ static struct rte_security_ops caam_jr_security_ops = { static void close_job_ring(struct sec_job_ring_t *job_ring) { @@ -19703,7 +28589,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 /* Producer index is frozen. If consumer index is not equal * with producer index, then we have descs to flush. */ -@@ -2093,7 +2093,7 @@ close_job_ring(struct sec_job_ring_t *job_ring) +@@ -2093,7 +2092,7 @@ close_job_ring(struct sec_job_ring_t *job_ring) /* free the uio job ring */ free_job_ring(job_ring->irq_fd); @@ -19712,7 +28598,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 caam_jr_dma_free(job_ring->input_ring); caam_jr_dma_free(job_ring->output_ring); g_job_rings_no--; -@@ -2197,7 +2197,7 @@ caam_jr_dev_uninit(struct rte_cryptodev *dev) +@@ -2197,7 +2196,7 @@ caam_jr_dev_uninit(struct rte_cryptodev *dev) * */ static void * @@ -19721,7 +28607,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 { struct sec_job_ring_t *job_ring = NULL; int i, ret = 0; -@@ -2207,7 +2207,7 @@ init_job_ring(void *reg_base_addr, uint32_t irq_id) +@@ -2207,7 +2206,7 @@ init_job_ring(void *reg_base_addr, uint32_t irq_id) int irq_coalescing_count = 0; for (i = 0; i < MAX_SEC_JOB_RINGS; i++) { @@ -19730,7 +28616,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 job_ring = &g_job_rings[i]; g_job_rings_no++; break; -@@ -2398,6 +2398,8 @@ caam_jr_dev_init(const char *name, +@@ -2398,6 +2397,8 @@ caam_jr_dev_init(const char *name, static int cryptodev_caam_jr_probe(struct rte_vdev_device *vdev) { @@ -19739,7 +28625,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 struct rte_cryptodev_pmd_init_params init_params = { "", sizeof(struct sec_job_ring_t), -@@ -2414,6 +2416,12 @@ cryptodev_caam_jr_probe(struct rte_vdev_device *vdev) +@@ -2414,6 +2415,12 @@ cryptodev_caam_jr_probe(struct rte_vdev_device *vdev) input_args = rte_vdev_device_args(vdev); rte_cryptodev_pmd_parse_input_args(&init_params, input_args); @@ -19752,7 +28638,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 /* if sec device version is not configured */ if (!rta_get_sec_era()) { const struct device_node *caam_node; -@@ -2424,7 +2432,7 @@ cryptodev_caam_jr_probe(struct rte_vdev_device *vdev) +@@ -2424,7 +2431,7 @@ cryptodev_caam_jr_probe(struct rte_vdev_device *vdev) NULL); if (prop) { rta_set_sec_era( @@ -19761,7 +28647,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 break; } } -@@ -2460,6 +2468,15 @@ cryptodev_caam_jr_remove(struct rte_vdev_device *vdev) +@@ -2460,6 +2467,15 @@ cryptodev_caam_jr_remove(struct rte_vdev_device *vdev) return rte_cryptodev_pmd_destroy(cryptodev); } @@ -19777,7 +28663,7 @@ index 8aaa3d45f6..d6fa8cf7e8 100644 static struct rte_vdev_driver cryptodev_caam_jr_drv = { .probe = cryptodev_caam_jr_probe, .remove = cryptodev_caam_jr_remove -@@ -2474,6 +2491,12 @@ RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CAAM_JR_PMD, +@@ -2474,6 +2490,12 @@ RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CAAM_JR_PMD, RTE_PMD_REGISTER_CRYPTO_DRIVER(caam_jr_crypto_drv, cryptodev_caam_jr_drv.driver, cryptodev_driver_id); @@ -19954,22 +28840,19 @@ index b1bb44ca42..e4ee102344 100644 + for (i = 0; i < MAX_SEC_JOB_RINGS; i++) + g_uio_job_ring[i].uio_fd = -1; +} -diff --git a/dpdk/drivers/crypto/caam_jr/meson.build b/dpdk/drivers/crypto/caam_jr/meson.build -index 50132aebef..0dbfa2ee9c 100644 ---- a/dpdk/drivers/crypto/caam_jr/meson.build -+++ b/dpdk/drivers/crypto/caam_jr/meson.build -@@ -14,6 +14,11 @@ sources = files('caam_jr_capabilities.c', - - allow_experimental_apis = true +diff --git a/dpdk/drivers/crypto/ccp/ccp_crypto.c b/dpdk/drivers/crypto/ccp/ccp_crypto.c +index 4256734d16..1536b1a647 100644 +--- a/dpdk/drivers/crypto/ccp/ccp_crypto.c ++++ b/dpdk/drivers/crypto/ccp/ccp_crypto.c +@@ -2,6 +2,8 @@ + * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved. + */ -+# FIXME: temporary solution for Bugzilla 469 -+if (toolchain == 'gcc' and cc.version().version_compare('>=10.0.0')) -+ cflags += '-fcommon' -+endif ++#define OPENSSL_API_COMPAT 0x10100000L + - includes += include_directories('../../bus/dpaa/include/') - includes += include_directories('../../common/dpaax/') - includes += include_directories('../../common/dpaax/caamflib/') + #include + #include + #include diff --git a/dpdk/drivers/crypto/ccp/ccp_dev.c b/dpdk/drivers/crypto/ccp/ccp_dev.c index 80fe6a4533..7d98b2eb25 100644 --- a/dpdk/drivers/crypto/ccp/ccp_dev.c @@ -20009,26 +28892,8 @@ index 6f7217adbf..99c7684e50 100644 if not dep.found() build = false reason = 'missing dependency, "libcrypto"' -diff --git a/dpdk/drivers/crypto/dpaa2_sec/Makefile b/dpdk/drivers/crypto/dpaa2_sec/Makefile -index 96b9c78435..183e9412ae 100644 ---- a/dpdk/drivers/crypto/dpaa2_sec/Makefile -+++ b/dpdk/drivers/crypto/dpaa2_sec/Makefile -@@ -20,6 +20,13 @@ CFLAGS += -Wno-implicit-fallthrough - endif - endif - -+# FIXME: temporary solution for Bugzilla 469 -+ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) -+ifeq ($(shell test $(GCC_VERSION) -ge 100 && echo 1), 1) -+CFLAGS += -fcommon -+endif -+endif -+ - CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax - CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib - CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/ diff --git a/dpdk/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/dpdk/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c -index 6ed2701ab6..8df915e610 100644 +index 6ed2701ab6..00a421f6f0 100644 --- a/dpdk/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/dpdk/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -1,7 +1,7 @@ @@ -20040,7 +28905,16 @@ index 6ed2701ab6..8df915e610 100644 * */ -@@ -168,7 +168,8 @@ build_proto_compound_sg_fd(dpaa2_sec_session *sess, +@@ -56,8 +56,6 @@ + #define SEC_FLC_DHR_OUTBOUND -114 + #define SEC_FLC_DHR_INBOUND 0 + +-enum rta_sec_era rta_sec_era = RTA_SEC_ERA_8; +- + static uint8_t cryptodev_driver_id; + + int dpaa2_logtype_sec; +@@ -168,7 +166,8 @@ build_proto_compound_sg_fd(dpaa2_sec_session *sess, * mbuf priv after sym_op. */ if (sess->ctxt_type == DPAA2_SEC_PDCP && sess->pdcp.hfn_ovd) { @@ -20050,7 +28924,7 @@ index 6ed2701ab6..8df915e610 100644 /*enable HFN override override */ DPAA2_SET_FLE_INTERNAL_JD(ip_fle, hfn_ovd); DPAA2_SET_FLE_INTERNAL_JD(op_fle, hfn_ovd); -@@ -243,7 +244,8 @@ build_proto_compound_fd(dpaa2_sec_session *sess, +@@ -243,7 +242,8 @@ build_proto_compound_fd(dpaa2_sec_session *sess, * mbuf priv after sym_op. */ if (sess->ctxt_type == DPAA2_SEC_PDCP && sess->pdcp.hfn_ovd) { @@ -20060,7 +28934,45 @@ index 6ed2701ab6..8df915e610 100644 /*enable HFN override override */ DPAA2_SET_FLE_INTERNAL_JD(ip_fle, hfn_ovd); DPAA2_SET_FLE_INTERNAL_JD(op_fle, hfn_ovd); -@@ -1845,7 +1847,7 @@ dpaa2_sec_cipher_init(struct rte_cryptodev *dev, +@@ -1530,6 +1530,10 @@ sec_simple_fd_to_mbuf(const struct qbman_fd *fd) + int16_t diff = 0; + dpaa2_sec_session *sess_priv __rte_unused; + ++ if (unlikely(DPAA2_GET_FD_IVP(fd))) { ++ DPAA2_SEC_ERR("error: non inline buffer"); ++ return NULL; ++ } + struct rte_mbuf *mbuf = DPAA2_INLINE_MBUF_FROM_BUF( + DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)), + rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size); +@@ -1548,6 +1552,14 @@ sec_simple_fd_to_mbuf(const struct qbman_fd *fd) + else + mbuf->data_off += SEC_FLC_DHR_INBOUND; + ++ if (unlikely(fd->simple.frc)) { ++ DPAA2_SEC_ERR("SEC returned Error - %x", ++ fd->simple.frc); ++ op->status = RTE_CRYPTO_OP_STATUS_ERROR; ++ } else { ++ op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; ++ } ++ + return op; + } + #endif +@@ -1576,11 +1588,6 @@ sec_fd_to_mbuf(const struct qbman_fd *fd) + * We can have a better approach to use the inline Mbuf + */ + +- if (unlikely(DPAA2_GET_FD_IVP(fd))) { +- /* TODO complete it. */ +- DPAA2_SEC_ERR("error: non inline buffer"); +- return NULL; +- } + op = (struct rte_crypto_op *)DPAA2_GET_FLE_ADDR((fle - 1)); + + /* Prefeth op */ +@@ -1845,7 +1852,7 @@ dpaa2_sec_cipher_init(struct rte_cryptodev *dev, session->ctxt_type = DPAA2_SEC_CIPHER; session->cipher_key.data = rte_zmalloc(NULL, xform->cipher.key.length, RTE_CACHE_LINE_SIZE); @@ -20069,7 +28981,7 @@ index 6ed2701ab6..8df915e610 100644 DPAA2_SEC_ERR("No Memory for cipher key"); rte_free(priv); return -1; -@@ -2192,7 +2194,7 @@ dpaa2_sec_aead_init(struct rte_cryptodev *dev, +@@ -2192,7 +2199,7 @@ dpaa2_sec_aead_init(struct rte_cryptodev *dev, priv->flc_desc[0].desc[0] = aeaddata.keylen; err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, @@ -20078,7 +28990,7 @@ index 6ed2701ab6..8df915e610 100644 (unsigned int *)priv->flc_desc[0].desc, &priv->flc_desc[0].desc[1], 1); -@@ -2410,7 +2412,7 @@ dpaa2_sec_aead_chain_init(struct rte_cryptodev *dev, +@@ -2410,7 +2417,7 @@ dpaa2_sec_aead_chain_init(struct rte_cryptodev *dev, priv->flc_desc[0].desc[0] = cipherdata.keylen; priv->flc_desc[0].desc[1] = authdata.keylen; err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, @@ -20087,7 +28999,7 @@ index 6ed2701ab6..8df915e610 100644 (unsigned int *)priv->flc_desc[0].desc, &priv->flc_desc[0].desc[2], 2); -@@ -2744,12 +2746,6 @@ dpaa2_sec_ipsec_proto_init(struct rte_crypto_cipher_xform *cipher_xform, +@@ -2744,12 +2751,6 @@ dpaa2_sec_ipsec_proto_init(struct rte_crypto_cipher_xform *cipher_xform, return 0; } @@ -20100,7 +29012,18 @@ index 6ed2701ab6..8df915e610 100644 static int dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, struct rte_security_session_conf *conf, -@@ -3145,6 +3141,14 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, +@@ -2840,8 +2841,9 @@ dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev, + encap_pdb.options = (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) | + PDBOPTS_ESP_OIHI_PDB_INL | + PDBOPTS_ESP_IVSRC | +- PDBHMO_ESP_ENCAP_DTTL | + PDBHMO_ESP_SNR; ++ if (ipsec_xform->options.dec_ttl) ++ encap_pdb.options |= PDBHMO_ESP_ENCAP_DTTL; + if (ipsec_xform->options.esn) + encap_pdb.options |= PDBOPTS_ESP_ESN; + encap_pdb.spi = ipsec_xform->spi; +@@ -3145,6 +3147,14 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, goto out; } @@ -20115,7 +29038,41 @@ index 6ed2701ab6..8df915e610 100644 if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (session->dir == DIR_ENC) bufsize = cnstr_shdsc_pdcp_c_plane_encap( -@@ -3482,7 +3486,7 @@ void dpaa2_sec_stats_get(struct rte_cryptodev *dev, +@@ -3419,32 +3429,10 @@ dpaa2_sec_dev_stop(struct rte_cryptodev *dev) + } + + static int +-dpaa2_sec_dev_close(struct rte_cryptodev *dev) ++dpaa2_sec_dev_close(struct rte_cryptodev *dev __rte_unused) + { +- struct dpaa2_sec_dev_private *priv = dev->data->dev_private; +- struct fsl_mc_io *dpseci = (struct fsl_mc_io *)priv->hw; +- int ret; +- + PMD_INIT_FUNC_TRACE(); + +- /* Function is reverse of dpaa2_sec_dev_init. +- * It does the following: +- * 1. Detach a DPSECI from attached resources i.e. buffer pools, dpbp_id +- * 2. Close the DPSECI device +- * 3. Free the allocated resources. +- */ +- +- /*Close the device at underlying layer*/ +- ret = dpseci_close(dpseci, CMD_PRI_LOW, priv->token); +- if (ret) { +- DPAA2_SEC_ERR("Failure closing dpseci device: err(%d)", ret); +- return -1; +- } +- +- /*Free the allocated memory for ethernet private data and dpseci*/ +- priv->hw = NULL; +- rte_free(dpseci); +- + return 0; + } + +@@ -3482,7 +3470,7 @@ void dpaa2_sec_stats_get(struct rte_cryptodev *dev, return; } for (i = 0; i < dev->data->nb_queue_pairs; i++) { @@ -20124,43 +29081,64 @@ index 6ed2701ab6..8df915e610 100644 DPAA2_SEC_DEBUG("Uninitialised queue pair"); continue; } -diff --git a/dpdk/drivers/crypto/dpaa2_sec/meson.build b/dpdk/drivers/crypto/dpaa2_sec/meson.build -index ab9c8c8bf9..3f1dfd67da 100644 ---- a/dpdk/drivers/crypto/dpaa2_sec/meson.build -+++ b/dpdk/drivers/crypto/dpaa2_sec/meson.build -@@ -12,4 +12,9 @@ sources = files('dpaa2_sec_dpseci.c', +@@ -3700,11 +3688,31 @@ static const struct rte_security_ops dpaa2_sec_security_ops = { + static int + dpaa2_sec_uninit(const struct rte_cryptodev *dev) + { +- struct dpaa2_sec_dev_private *internals = dev->data->dev_private; ++ struct dpaa2_sec_dev_private *priv = dev->data->dev_private; ++ struct fsl_mc_io *dpseci = (struct fsl_mc_io *)priv->hw; ++ int ret; - allow_experimental_apis = true +- rte_free(dev->security_ctx); ++ PMD_INIT_FUNC_TRACE(); -+# FIXME: temporary solution for Bugzilla 469 -+if (toolchain == 'gcc' and cc.version().version_compare('>=10.0.0')) -+ cflags += '-fcommon' -+endif +- rte_mempool_free(internals->fle_pool); ++ /* Function is reverse of dpaa2_sec_dev_init. ++ * It does the following: ++ * 1. Detach a DPSECI from attached resources i.e. buffer pools, dpbp_id ++ * 2. Close the DPSECI device ++ * 3. Free the allocated resources. ++ */ + - includes += include_directories('mc', '../../common/dpaax', '../../common/dpaax/caamflib') -diff --git a/dpdk/drivers/crypto/dpaa_sec/Makefile b/dpdk/drivers/crypto/dpaa_sec/Makefile -index fbfd775855..b5a97b9f6e 100644 ---- a/dpdk/drivers/crypto/dpaa_sec/Makefile -+++ b/dpdk/drivers/crypto/dpaa_sec/Makefile -@@ -14,6 +14,13 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API - CFLAGS += -O3 - CFLAGS += $(WERROR_FLAGS) - -+# FIXME: temporary solution for Bugzilla 469 -+ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) -+ifeq ($(shell test $(GCC_VERSION) -ge 100 && echo 1), 1) -+CFLAGS += -fcommon -+endif -+endif ++ /*Close the device at underlying layer*/ ++ ret = dpseci_close(dpseci, CMD_PRI_LOW, priv->token); ++ if (ret) { ++ DPAA2_SEC_ERR("Failure closing dpseci device: err(%d)", ret); ++ return -1; ++ } + - CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa - CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include - CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/base/qbman ++ /*Free the allocated memory for ethernet private data and dpseci*/ ++ priv->hw = NULL; ++ rte_free(dpseci); ++ rte_free(dev->security_ctx); ++ rte_mempool_free(priv->fle_pool); + + DPAA2_SEC_INFO("Closing DPAA2_SEC device %s on numa socket %u", + dev->data->name, rte_socket_id()); +@@ -3862,6 +3870,8 @@ cryptodev_dpaa2_sec_probe(struct rte_dpaa2_driver *dpaa2_drv __rte_unused, + + if (dpaa2_svr_family == SVR_LX2160A) + rta_set_sec_era(RTA_SEC_ERA_10); ++ else ++ rta_set_sec_era(RTA_SEC_ERA_8); + + DPAA2_SEC_INFO("2-SEC ERA is %d", rta_get_sec_era()); + diff --git a/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.c b/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.c -index e0b307cecd..a650313cdb 100644 +index e0b307cecd..95dd58bfb3 100644 --- a/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.c -@@ -94,31 +94,6 @@ dpaa_sec_alloc_ctx(dpaa_sec_session *ses, int sg_count) +@@ -43,8 +43,6 @@ + #include + #include + +-enum rta_sec_era rta_sec_era; +- + int dpaa_logtype_sec; + + static uint8_t cryptodev_driver_id; +@@ -94,31 +92,6 @@ dpaa_sec_alloc_ctx(dpaa_sec_session *ses, int sg_count) return ctx; } @@ -20192,7 +29170,7 @@ index e0b307cecd..a650313cdb 100644 static void ern_sec_fq_handler(struct qman_portal *qm __rte_unused, struct qman_fq *fq, -@@ -183,7 +158,7 @@ dqrr_out_fq_cb_rx(struct qman_portal *qm __always_unused, +@@ -183,7 +156,7 @@ dqrr_out_fq_cb_rx(struct qman_portal *qm __always_unused, * sg[0] is for output * sg[1] for input */ @@ -20201,7 +29179,7 @@ index e0b307cecd..a650313cdb 100644 ctx = container_of(job, struct dpaa_sec_op_ctx, job); ctx->fd_status = fd->status; -@@ -262,7 +237,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) +@@ -262,7 +235,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) struct sec_cdb *cdb = &ses->cdb; struct alginfo *p_authdata = NULL; int32_t shared_desc_len = 0; @@ -20209,7 +29187,7 @@ index e0b307cecd..a650313cdb 100644 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN int swap = false; #else -@@ -276,10 +250,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) +@@ -276,10 +248,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) cipherdata.algtype = ses->cipher_key.alg; cipherdata.algmode = ses->cipher_key.algmode; @@ -20220,7 +29198,7 @@ index e0b307cecd..a650313cdb 100644 if (ses->auth_alg) { authdata.key = (size_t)ses->auth_key.data; authdata.keylen = ses->auth_key.length; -@@ -289,33 +259,17 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) +@@ -289,33 +257,17 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) authdata.algmode = ses->auth_key.algmode; p_authdata = &authdata; @@ -20260,7 +29238,7 @@ index e0b307cecd..a650313cdb 100644 if (ses->pdcp.domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (ses->dir == DIR_ENC) -@@ -394,7 +348,7 @@ dpaa_sec_prep_ipsec_cdb(dpaa_sec_session *ses) +@@ -394,7 +346,7 @@ dpaa_sec_prep_ipsec_cdb(dpaa_sec_session *ses) cdb->sh_desc[0] = cipherdata.keylen; cdb->sh_desc[1] = authdata.keylen; err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, @@ -20269,7 +29247,7 @@ index e0b307cecd..a650313cdb 100644 (unsigned int *)cdb->sh_desc, &cdb->sh_desc[2], 2); -@@ -405,14 +359,14 @@ dpaa_sec_prep_ipsec_cdb(dpaa_sec_session *ses) +@@ -405,14 +357,14 @@ dpaa_sec_prep_ipsec_cdb(dpaa_sec_session *ses) if (cdb->sh_desc[2] & 1) cipherdata.key_type = RTA_DATA_IMM; else { @@ -20286,7 +29264,7 @@ index e0b307cecd..a650313cdb 100644 (void *)(size_t)authdata.key); authdata.key_type = RTA_DATA_PTR; } -@@ -580,7 +534,7 @@ dpaa_sec_prep_cdb(dpaa_sec_session *ses) +@@ -580,7 +532,7 @@ dpaa_sec_prep_cdb(dpaa_sec_session *ses) cdb->sh_desc[0] = alginfo_c.keylen; cdb->sh_desc[1] = alginfo_a.keylen; err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, @@ -20295,7 +29273,7 @@ index e0b307cecd..a650313cdb 100644 (unsigned int *)cdb->sh_desc, &cdb->sh_desc[2], 2); -@@ -591,14 +545,14 @@ dpaa_sec_prep_cdb(dpaa_sec_session *ses) +@@ -591,14 +543,14 @@ dpaa_sec_prep_cdb(dpaa_sec_session *ses) if (cdb->sh_desc[2] & 1) alginfo_c.key_type = RTA_DATA_IMM; else { @@ -20312,7 +29290,7 @@ index e0b307cecd..a650313cdb 100644 (void *)(size_t)alginfo_a.key); alginfo_a.key_type = RTA_DATA_PTR; } -@@ -674,7 +628,7 @@ dpaa_sec_deq(struct dpaa_sec_qp *qp, struct rte_crypto_op **ops, int nb_ops) +@@ -674,7 +626,7 @@ dpaa_sec_deq(struct dpaa_sec_qp *qp, struct rte_crypto_op **ops, int nb_ops) * sg[0] is for output * sg[1] for input */ @@ -20321,7 +29299,7 @@ index e0b307cecd..a650313cdb 100644 ctx = container_of(job, struct dpaa_sec_op_ctx, job); ctx->fd_status = fd->status; -@@ -768,7 +722,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -768,7 +720,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) in_sg->extension = 1; in_sg->final = 1; in_sg->length = data_len; @@ -20330,7 +29308,7 @@ index e0b307cecd..a650313cdb 100644 /* 1st seg */ sg = in_sg + 1; -@@ -788,7 +742,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -788,7 +740,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) } else { sg->length = ses->iv.length; } @@ -20339,7 +29317,7 @@ index e0b307cecd..a650313cdb 100644 in_sg->length += sg->length; cpu_to_hw_sg(sg); sg++; -@@ -821,7 +775,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -821,7 +773,7 @@ build_auth_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) sg++; rte_memcpy(old_digest, sym->auth.digest.data, ses->digest_length); @@ -20348,7 +29326,7 @@ index e0b307cecd..a650313cdb 100644 qm_sg_entry_set64(sg, start_addr); sg->length = ses->digest_length; in_sg->length += ses->digest_length; -@@ -888,7 +842,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -888,7 +840,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) in_sg->extension = 1; in_sg->final = 1; in_sg->length = data_len; @@ -20357,7 +29335,7 @@ index e0b307cecd..a650313cdb 100644 sg = &cf->sg[2]; if (ses->iv.length) { -@@ -906,7 +860,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -906,7 +858,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) } else { sg->length = ses->iv.length; } @@ -20366,7 +29344,7 @@ index e0b307cecd..a650313cdb 100644 in_sg->length += sg->length; cpu_to_hw_sg(sg); sg++; -@@ -923,7 +877,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -923,7 +875,7 @@ build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) rte_memcpy(old_digest, sym->auth.digest.data, ses->digest_length); /* let's check digest by hw */ @@ -20375,7 +29353,7 @@ index e0b307cecd..a650313cdb 100644 sg++; qm_sg_entry_set64(sg, start_addr); sg->length = ses->digest_length; -@@ -987,7 +941,7 @@ build_cipher_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -987,7 +939,7 @@ build_cipher_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) out_sg = &cf->sg[0]; out_sg->extension = 1; out_sg->length = data_len; @@ -20384,7 +29362,7 @@ index e0b307cecd..a650313cdb 100644 cpu_to_hw_sg(out_sg); /* 1st seg */ -@@ -1016,11 +970,11 @@ build_cipher_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1016,11 +968,11 @@ build_cipher_only_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) in_sg->length = data_len + ses->iv.length; sg++; @@ -20398,7 +29376,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; cpu_to_hw_sg(sg); -@@ -1098,11 +1052,11 @@ build_cipher_only(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1098,11 +1050,11 @@ build_cipher_only(struct rte_crypto_op *op, dpaa_sec_session *ses) sg->extension = 1; sg->final = 1; sg->length = data_len + ses->iv.length; @@ -20412,7 +29390,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; cpu_to_hw_sg(sg); -@@ -1163,7 +1117,7 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1163,7 +1115,7 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) /* output sg entries */ sg = &cf->sg[2]; @@ -20421,7 +29399,7 @@ index e0b307cecd..a650313cdb 100644 cpu_to_hw_sg(out_sg); /* 1st seg */ -@@ -1206,18 +1160,18 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1206,18 +1158,18 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) /* input sg entries */ sg++; @@ -20443,7 +29421,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->auth_only_len; cpu_to_hw_sg(sg); } -@@ -1243,7 +1197,7 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1243,7 +1195,7 @@ build_cipher_auth_gcm_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) sg++; memcpy(ctx->digest, sym->aead.digest.data, ses->digest_length); @@ -20452,7 +29430,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->digest_length; } sg->final = 1; -@@ -1281,9 +1235,9 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1281,9 +1233,9 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) /* input */ rte_prefetch0(cf->sg); sg = &cf->sg[2]; @@ -20464,7 +29442,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; length += sg->length; cpu_to_hw_sg(sg); -@@ -1291,7 +1245,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1291,7 +1243,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) sg++; if (ses->auth_only_len) { qm_sg_entry_set64(sg, @@ -20473,7 +29451,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->auth_only_len; length += sg->length; cpu_to_hw_sg(sg); -@@ -1303,7 +1257,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1303,7 +1255,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) sg->final = 1; cpu_to_hw_sg(sg); } else { @@ -20482,7 +29460,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; length += sg->length; cpu_to_hw_sg(sg); -@@ -1311,7 +1265,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1311,7 +1263,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) sg++; if (ses->auth_only_len) { qm_sg_entry_set64(sg, @@ -20491,7 +29469,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->auth_only_len; length += sg->length; cpu_to_hw_sg(sg); -@@ -1326,7 +1280,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1326,7 +1278,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) ses->digest_length); sg++; @@ -20500,7 +29478,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->digest_length; length += sg->length; sg->final = 1; -@@ -1340,7 +1294,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1340,7 +1292,7 @@ build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) /* output */ sg++; @@ -20509,7 +29487,7 @@ index e0b307cecd..a650313cdb 100644 qm_sg_entry_set64(sg, dst_start_addr + sym->aead.data.offset); sg->length = sym->aead.data.length; -@@ -1409,7 +1363,7 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1409,7 +1361,7 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) /* output sg entries */ sg = &cf->sg[2]; @@ -20518,7 +29496,7 @@ index e0b307cecd..a650313cdb 100644 cpu_to_hw_sg(out_sg); /* 1st seg */ -@@ -1451,11 +1405,11 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1451,11 +1403,11 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) /* input sg entries */ sg++; @@ -20532,7 +29510,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; cpu_to_hw_sg(sg); -@@ -1481,7 +1435,7 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1481,7 +1433,7 @@ build_cipher_auth_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) sg++; memcpy(ctx->digest, sym->auth.digest.data, ses->digest_length); @@ -20541,7 +29519,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->digest_length; } sg->final = 1; -@@ -1518,9 +1472,9 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1518,9 +1470,9 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) /* input */ rte_prefetch0(cf->sg); sg = &cf->sg[2]; @@ -20553,7 +29531,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; length += sg->length; cpu_to_hw_sg(sg); -@@ -1532,7 +1486,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1532,7 +1484,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) sg->final = 1; cpu_to_hw_sg(sg); } else { @@ -20562,7 +29540,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->iv.length; length += sg->length; cpu_to_hw_sg(sg); -@@ -1548,7 +1502,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1548,7 +1500,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) ses->digest_length); sg++; @@ -20571,7 +29549,7 @@ index e0b307cecd..a650313cdb 100644 sg->length = ses->digest_length; length += sg->length; sg->final = 1; -@@ -1562,7 +1516,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1562,7 +1514,7 @@ build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) /* output */ sg++; @@ -20580,7 +29558,7 @@ index e0b307cecd..a650313cdb 100644 qm_sg_entry_set64(sg, dst_start_addr + sym->cipher.data.offset); sg->length = sym->cipher.data.length; length = sg->length; -@@ -1656,7 +1610,7 @@ build_proto_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1656,7 +1608,7 @@ build_proto_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) /* output */ out_sg = &cf->sg[0]; out_sg->extension = 1; @@ -20589,7 +29567,7 @@ index e0b307cecd..a650313cdb 100644 /* 1st seg */ sg = &cf->sg[2]; -@@ -1689,7 +1643,7 @@ build_proto_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) +@@ -1689,7 +1641,7 @@ build_proto_sg(struct rte_crypto_op *op, dpaa_sec_session *ses) in_len = mbuf->data_len; sg++; @@ -20598,7 +29576,21 @@ index e0b307cecd..a650313cdb 100644 /* 1st seg */ qm_sg_entry_set64(sg, rte_pktmbuf_mtophys(mbuf)); -@@ -1884,7 +1838,7 @@ dpaa_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops, +@@ -1736,6 +1688,13 @@ dpaa_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops, + uint32_t index, flags[DPAA_SEC_BURST] = {0}; + struct qman_fq *inq[DPAA_SEC_BURST]; + ++ if (unlikely(!RTE_PER_LCORE(dpaa_io))) { ++ if (rte_dpaa_portal_init((void *)0)) { ++ DPAA_SEC_ERR("Failure in affining portal"); ++ return 0; ++ } ++ } ++ + while (nb_ops) { + frames_to_send = (nb_ops > DPAA_SEC_BURST) ? + DPAA_SEC_BURST : nb_ops; +@@ -1884,7 +1843,7 @@ dpaa_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops, inq[loop] = ses->inq[rte_lcore_id() % MAX_DPAA_CORES]; fd->opaque_addr = 0; fd->cmd = 0; @@ -20607,7 +29599,21 @@ index e0b307cecd..a650313cdb 100644 fd->_format1 = qm_fd_compound; fd->length29 = 2 * sizeof(struct qm_sg_entry); -@@ -2349,7 +2303,7 @@ dpaa_sec_attach_sess_q(struct dpaa_sec_qp *qp, dpaa_sec_session *sess) +@@ -1936,6 +1895,13 @@ dpaa_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops, + uint16_t num_rx; + struct dpaa_sec_qp *dpaa_qp = (struct dpaa_sec_qp *)qp; + ++ if (unlikely(!RTE_PER_LCORE(dpaa_io))) { ++ if (rte_dpaa_portal_init((void *)0)) { ++ DPAA_SEC_ERR("Failure in affining portal"); ++ return 0; ++ } ++ } ++ + num_rx = dpaa_sec_deq(dpaa_qp, ops, nb_ops); + + dpaa_qp->rx_pkts += num_rx; +@@ -2349,7 +2315,7 @@ dpaa_sec_attach_sess_q(struct dpaa_sec_qp *qp, dpaa_sec_session *sess) } } ret = dpaa_sec_init_rx(sess->inq[rte_lcore_id() % MAX_DPAA_CORES], @@ -20616,7 +29622,23 @@ index e0b307cecd..a650313cdb 100644 qman_fq_fqid(&qp->outq)); if (ret) DPAA_SEC_ERR("Unable to init sec queue"); -@@ -3005,7 +2959,8 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev, +@@ -2815,12 +2781,14 @@ dpaa_sec_set_ipsec_session(__rte_unused struct rte_cryptodev *dev, + session->encap_pdb.ip_hdr_len = + sizeof(struct rte_ipv6_hdr); + } ++ + session->encap_pdb.options = + (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) | + PDBOPTS_ESP_OIHI_PDB_INL | + PDBOPTS_ESP_IVSRC | +- PDBHMO_ESP_ENCAP_DTTL | + PDBHMO_ESP_SNR; ++ if (ipsec_xform->options.dec_ttl) ++ session->encap_pdb.options |= PDBHMO_ESP_ENCAP_DTTL; + if (ipsec_xform->options.esn) + session->encap_pdb.options |= PDBOPTS_ESP_ESN; + session->encap_pdb.spi = ipsec_xform->spi; +@@ -3005,7 +2973,8 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev, session->pdcp.hfn = pdcp_xform->hfn; session->pdcp.hfn_threshold = pdcp_xform->hfn_threshold; session->pdcp.hfn_ovd = pdcp_xform->hfn_ovrd; @@ -20626,7 +29648,7 @@ index e0b307cecd..a650313cdb 100644 rte_spinlock_lock(&dev_priv->lock); for (i = 0; i < MAX_DPAA_CORES; i++) { -@@ -3149,7 +3104,7 @@ dpaa_sec_process_parallel_event(void *event, +@@ -3149,7 +3118,7 @@ dpaa_sec_process_parallel_event(void *event, * sg[0] is for output * sg[1] for input */ @@ -20635,7 +29657,7 @@ index e0b307cecd..a650313cdb 100644 ctx = container_of(job, struct dpaa_sec_op_ctx, job); ctx->fd_status = fd->status; -@@ -3204,7 +3159,7 @@ dpaa_sec_process_atomic_event(void *event, +@@ -3204,7 +3173,7 @@ dpaa_sec_process_atomic_event(void *event, * sg[0] is for output * sg[1] for input */ @@ -20644,11 +29666,77 @@ index e0b307cecd..a650313cdb 100644 ctx = container_of(job, struct dpaa_sec_op_ctx, job); ctx->fd_status = fd->status; +@@ -3455,23 +3424,24 @@ cryptodev_dpaa_sec_probe(struct rte_dpaa_driver *dpaa_drv __rte_unused, + + int retval; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return 0; ++ + snprintf(cryptodev_name, sizeof(cryptodev_name), "%s", dpaa_dev->name); + + cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id()); + if (cryptodev == NULL) + return -ENOMEM; + +- if (rte_eal_process_type() == RTE_PROC_PRIMARY) { +- cryptodev->data->dev_private = rte_zmalloc_socket( +- "cryptodev private structure", +- sizeof(struct dpaa_sec_dev_private), +- RTE_CACHE_LINE_SIZE, +- rte_socket_id()); ++ cryptodev->data->dev_private = rte_zmalloc_socket( ++ "cryptodev private structure", ++ sizeof(struct dpaa_sec_dev_private), ++ RTE_CACHE_LINE_SIZE, ++ rte_socket_id()); + +- if (cryptodev->data->dev_private == NULL) +- rte_panic("Cannot allocate memzone for private " +- "device data"); +- } ++ if (cryptodev->data->dev_private == NULL) ++ rte_panic("Cannot allocate memzone for private " ++ "device data"); + + dpaa_dev->crypto_dev = cryptodev; + cryptodev->device = &dpaa_dev->device; +@@ -3509,8 +3479,7 @@ cryptodev_dpaa_sec_probe(struct rte_dpaa_driver *dpaa_drv __rte_unused, + return 0; + + /* In case of error, cleanup is done */ +- if (rte_eal_process_type() == RTE_PROC_PRIMARY) +- rte_free(cryptodev->data->dev_private); ++ rte_free(cryptodev->data->dev_private); + + rte_cryptodev_pmd_release_device(cryptodev); + +diff --git a/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.h b/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.h +index 3ecc7eae51..4b07b7d5e7 100644 +--- a/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.h ++++ b/dpdk/drivers/crypto/dpaa_sec/dpaa_sec.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: BSD-3-Clause + * +- * Copyright 2016 NXP ++ * Copyright 2016-2022 NXP + * + */ + +@@ -207,7 +207,7 @@ struct dpaa_sec_job { + struct qm_sg_entry sg[MAX_JOB_SG_ENTRIES]; + }; + +-#define DPAA_MAX_NB_MAX_DIGEST 32 ++#define DPAA_MAX_NB_MAX_DIGEST 64 + struct dpaa_sec_op_ctx { + struct dpaa_sec_job job; + struct rte_crypto_op *op; diff --git a/dpdk/drivers/crypto/dpaa_sec/meson.build b/dpdk/drivers/crypto/dpaa_sec/meson.build -index 9f17d3a43e..e819f9cf1b 100644 +index 9f17d3a43e..71de819407 100644 --- a/dpdk/drivers/crypto/dpaa_sec/meson.build +++ b/dpdk/drivers/crypto/dpaa_sec/meson.build -@@ -6,11 +6,16 @@ if not is_linux +@@ -6,7 +6,7 @@ if not is_linux reason = 'only supported on linux' endif @@ -20657,15 +29745,6 @@ index 9f17d3a43e..e819f9cf1b 100644 sources = files('dpaa_sec.c') allow_experimental_apis = true - -+# FIXME: temporary solution for Bugzilla 469 -+if (toolchain == 'gcc' and cc.version().version_compare('>=10.0.0')) -+ cflags += '-fcommon' -+endif -+ - includes += include_directories('../../bus/dpaa/include') - includes += include_directories('../../common/dpaax') - includes += include_directories('../../common/dpaax/caamflib/') diff --git a/dpdk/drivers/crypto/kasumi/kasumi_pmd_private.h b/dpdk/drivers/crypto/kasumi/kasumi_pmd_private.h index 7ac19c5735..f0b83f2272 100644 --- a/dpdk/drivers/crypto/kasumi/kasumi_pmd_private.h @@ -20721,7 +29800,7 @@ index 09702b9e3e..e575330ef5 100644 #define MRVL_LOG(level, fmt, ...) \ rte_log(RTE_LOG_ ## level, mrvl_logtype_driver, \ diff --git a/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd.c b/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd.c -index 3c0fe216f0..63782ce974 100644 +index 3c0fe216f0..e335ca7ba1 100644 --- a/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd.c +++ b/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd.c @@ -19,6 +19,7 @@ @@ -20732,6 +29811,91 @@ index 3c0fe216f0..63782ce974 100644 static uint8_t cryptodev_driver_id; struct mrvl_pmd_init_params { +@@ -360,6 +361,14 @@ mrvl_crypto_set_aead_session_parameters(struct mrvl_crypto_session *sess, + sess->sam_sess_params.cipher_mode = + aead_map[aead_xform->aead.algo].cipher_mode; + ++ if (sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) { ++ /* IV must include nonce for all counter modes */ ++ sess->cipher_iv_offset = aead_xform->cipher.iv.offset; ++ ++ /* Set order of authentication then encryption to 0 in GCM */ ++ sess->sam_sess_params.u.basic.auth_then_encrypt = 0; ++ } ++ + /* Assume IV will be passed together with data. */ + sess->sam_sess_params.cipher_iv = NULL; + +@@ -916,14 +925,14 @@ mrvl_pmd_parse_input_args(struct mrvl_pmd_init_params *params, + ret = rte_kvargs_process(kvlist, + RTE_CRYPTODEV_PMD_NAME_ARG, + &parse_name_arg, +- ¶ms->common); ++ ¶ms->common.name); + if (ret < 0) + goto free_kvlist; + + ret = rte_kvargs_process(kvlist, + MRVL_PMD_MAX_NB_SESS_ARG, + &parse_integer_arg, +- params); ++ ¶ms->max_nb_sessions); + if (ret < 0) + goto free_kvlist; + +diff --git a/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c +index 2dfaa0b113..f92a97bd31 100644 +--- a/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c ++++ b/dpdk/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c +@@ -111,7 +111,7 @@ static const struct rte_cryptodev_capabilities + .increment = 1 + }, + .digest_size = { +- .min = 28, ++ .min = 12, + .max = 28, + .increment = 0 + }, +@@ -232,7 +232,7 @@ static const struct rte_cryptodev_capabilities + }, + .digest_size = { + .min = 12, +- .max = 48, ++ .max = 64, + .increment = 4 + }, + }, } +@@ -252,7 +252,7 @@ static const struct rte_cryptodev_capabilities + }, + .digest_size = { + .min = 12, +- .max = 48, ++ .max = 64, + .increment = 0 + }, + }, } +@@ -336,9 +336,9 @@ static const struct rte_cryptodev_capabilities + .increment = 0 + }, + .aad_size = { +- .min = 8, +- .max = 12, +- .increment = 4 ++ .min = 0, ++ .max = 64, ++ .increment = 1 + }, + .iv_size = { + .min = 12, +@@ -804,7 +804,7 @@ mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev, + MRVL_LOG(ERR, "Error while destroying session!"); + } + +- memset(sess, 0, sizeof(struct mrvl_crypto_session)); ++ memset(mrvl_sess, 0, sizeof(struct mrvl_crypto_session)); + struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); + set_sym_session_private_data(sess, index, NULL); + rte_mempool_put(sess_mp, sess_priv); diff --git a/dpdk/drivers/crypto/nitrox/nitrox_csr.h b/dpdk/drivers/crypto/nitrox/nitrox_csr.h index 8cd92e38be..de7a3c6713 100644 --- a/dpdk/drivers/crypto/nitrox/nitrox_csr.h @@ -20779,6 +29943,33 @@ index 56410c44d7..d1b32fec92 100644 ndev->rte_sym_dev.driver = &nitrox_rte_sym_drv; ndev->rte_sym_dev.numa_node = ndev->pdev->device.numa_node; ndev->rte_sym_dev.devargs = NULL; +diff --git a/dpdk/drivers/crypto/octeontx/otx_cryptodev.c b/dpdk/drivers/crypto/octeontx/otx_cryptodev.c +index ddece13118..adc6c5c042 100644 +--- a/dpdk/drivers/crypto/octeontx/otx_cryptodev.c ++++ b/dpdk/drivers/crypto/octeontx/otx_cryptodev.c +@@ -72,6 +72,7 @@ otx_cpt_pci_remove(struct rte_pci_device *pci_dev) + { + struct rte_cryptodev *cryptodev; + char name[RTE_CRYPTODEV_NAME_MAX_LEN]; ++ void *dev_priv; + + if (pci_dev == NULL) + return -EINVAL; +@@ -85,11 +86,13 @@ otx_cpt_pci_remove(struct rte_pci_device *pci_dev) + if (pci_dev->driver == NULL) + return -ENODEV; + ++ dev_priv = cryptodev->data->dev_private; ++ + /* free crypto device */ + rte_cryptodev_pmd_release_device(cryptodev); + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) +- rte_free(cryptodev->data->dev_private); ++ rte_free(dev_priv); + + cryptodev->device->driver = NULL; + cryptodev->device = NULL; diff --git a/dpdk/drivers/crypto/octeontx/otx_cryptodev_ops.c b/dpdk/drivers/crypto/octeontx/otx_cryptodev_ops.c index ba56b212b9..4eadb773ef 100644 --- a/dpdk/drivers/crypto/octeontx/otx_cryptodev_ops.c @@ -21006,10 +30197,19 @@ index 43ac3813df..b2054b3754 100644 rte_log(RTE_LOG_ ## level, openssl_logtype_driver, \ "%s() line %u: " fmt "\n", __func__, __LINE__, \ diff --git a/dpdk/drivers/crypto/openssl/rte_openssl_pmd.c b/dpdk/drivers/crypto/openssl/rte_openssl_pmd.c -index 91f028308c..c294f60b7d 100644 +index 91f028308c..aee8dea0c6 100644 --- a/dpdk/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/dpdk/drivers/crypto/openssl/rte_openssl_pmd.c -@@ -18,6 +18,7 @@ +@@ -2,6 +2,8 @@ + * Copyright(c) 2016-2017 Intel Corporation + */ + ++#define OPENSSL_API_COMPAT 0x10100000L ++ + #include + #include + #include +@@ -18,6 +20,7 @@ #define DES_BLOCK_SIZE 8 @@ -21017,7 +30217,7 @@ index 91f028308c..c294f60b7d 100644 static uint8_t cryptodev_driver_id; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) -@@ -762,10 +763,10 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op) +@@ -762,10 +765,10 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op) return NULL; /* provide internal session */ @@ -21030,7 +30230,25 @@ index 91f028308c..c294f60b7d 100644 return NULL; if (rte_mempool_get(qp->sess_mp_priv, -@@ -2037,6 +2038,26 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op, +@@ -1114,7 +1117,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset, + if (EVP_EncryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) + goto process_auth_encryption_ccm_err; + +- if (srclen > 0) ++ if (srclen >= 0) + if (process_openssl_encryption_update(mbuf_src, offset, &dst, + srclen, ctx, 0)) + goto process_auth_encryption_ccm_err; +@@ -1197,7 +1200,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset, + if (EVP_DecryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0) + goto process_auth_decryption_ccm_err; + +- if (srclen > 0) ++ if (srclen >= 0) + if (process_openssl_decryption_update(mbuf_src, offset, &dst, + srclen, ctx, 0)) + return -EFAULT; +@@ -2037,6 +2040,26 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op, return retval; } @@ -21057,7 +30275,7 @@ index 91f028308c..c294f60b7d 100644 /** Process crypto operation for mbuf */ static int process_op(struct openssl_qp *qp, struct rte_crypto_op *op, -@@ -2059,6 +2080,9 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op, +@@ -2059,6 +2082,9 @@ process_op(struct openssl_qp *qp, struct rte_crypto_op *op, break; case OPENSSL_CHAIN_CIPHER_AUTH: process_openssl_cipher_op(op, sess, msrc, mdst); @@ -21067,6 +30285,19 @@ index 91f028308c..c294f60b7d 100644 process_openssl_auth_op(qp, op, sess, mdst, mdst); break; case OPENSSL_CHAIN_AUTH_CIPHER: +diff --git a/dpdk/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/dpdk/drivers/crypto/openssl/rte_openssl_pmd_ops.c +index cbfb8149f9..4dda2e0c2f 100644 +--- a/dpdk/drivers/crypto/openssl/rte_openssl_pmd_ops.c ++++ b/dpdk/drivers/crypto/openssl/rte_openssl_pmd_ops.c +@@ -2,6 +2,8 @@ + * Copyright(c) 2016-2017 Intel Corporation + */ + ++#define OPENSSL_API_COMPAT 0x10100000L ++ + #include + + #include diff --git a/dpdk/drivers/crypto/qat/meson.build b/dpdk/drivers/crypto/qat/meson.build index fc65923a76..8d1e25a845 100644 --- a/dpdk/drivers/crypto/qat/meson.build @@ -21081,10 +30312,75 @@ index fc65923a76..8d1e25a845 100644 qat_deps += 'cryptodev' if dep.found() diff --git a/dpdk/drivers/crypto/qat/qat_asym.c b/dpdk/drivers/crypto/qat/qat_asym.c -index ae0dd79562..85973812a8 100644 +index ae0dd79562..217e84c1cf 100644 --- a/dpdk/drivers/crypto/qat/qat_asym.c +++ b/dpdk/drivers/crypto/qat/qat_asym.c -@@ -475,7 +475,7 @@ qat_asym_build_request(void *in_op, +@@ -65,27 +65,45 @@ static size_t max_of(int n, ...) + } + + static void qat_clear_arrays(struct qat_asym_op_cookie *cookie, +- int in_count, int out_count, int in_size, int out_size) ++ int in_count, int out_count, int alg_size) + { + int i; + + for (i = 0; i < in_count; i++) +- memset(cookie->input_array[i], 0x0, in_size); ++ memset(cookie->input_array[i], 0x0, alg_size); + for (i = 0; i < out_count; i++) +- memset(cookie->output_array[i], 0x0, out_size); ++ memset(cookie->output_array[i], 0x0, alg_size); ++} ++ ++static void qat_clear_arrays_crt(struct qat_asym_op_cookie *cookie, ++ int alg_size) ++{ ++ int i; ++ ++ memset(cookie->input_array[0], 0x0, alg_size); ++ for (i = 1; i < QAT_ASYM_RSA_QT_NUM_IN_PARAMS; i++) ++ memset(cookie->input_array[i], 0x0, alg_size / 2); ++ for (i = 0; i < QAT_ASYM_RSA_NUM_OUT_PARAMS; i++) ++ memset(cookie->output_array[i], 0x0, alg_size); + } + + static void qat_clear_arrays_by_alg(struct qat_asym_op_cookie *cookie, +- enum rte_crypto_asym_xform_type alg, int in_size, int out_size) ++ struct rte_crypto_asym_xform *xform, int alg_size) + { +- if (alg == RTE_CRYPTO_ASYM_XFORM_MODEX) ++ if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_MODEX) + qat_clear_arrays(cookie, QAT_ASYM_MODEXP_NUM_IN_PARAMS, +- QAT_ASYM_MODEXP_NUM_OUT_PARAMS, in_size, +- out_size); +- else if (alg == RTE_CRYPTO_ASYM_XFORM_MODINV) ++ QAT_ASYM_MODEXP_NUM_OUT_PARAMS, alg_size); ++ else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_MODINV) + qat_clear_arrays(cookie, QAT_ASYM_MODINV_NUM_IN_PARAMS, +- QAT_ASYM_MODINV_NUM_OUT_PARAMS, in_size, +- out_size); ++ QAT_ASYM_MODINV_NUM_OUT_PARAMS, alg_size); ++ else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { ++ if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_QT) ++ qat_clear_arrays_crt(cookie, alg_size); ++ else { ++ qat_clear_arrays(cookie, QAT_ASYM_RSA_NUM_IN_PARAMS, ++ QAT_ASYM_RSA_NUM_OUT_PARAMS, alg_size); ++ } ++ } + } + + static int qat_asym_check_nonzero(rte_crypto_param n) +@@ -352,7 +370,7 @@ qat_asym_fill_arrays(struct rte_crypto_asym_op *asym_op, + return -(EINVAL); + } + } +- if (xform->rsa.key_type == RTE_RSA_KET_TYPE_QT) { ++ if (xform->rsa.key_type == RTE_RSA_KEY_TYPE_QT) { + + qat_req->input_param_count = + QAT_ASYM_RSA_QT_NUM_IN_PARAMS; +@@ -475,7 +493,7 @@ qat_asym_build_request(void *in_op, if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { ctx = (struct qat_asym_session *) get_asym_session_private_data( @@ -21093,7 +30389,26 @@ index ae0dd79562..85973812a8 100644 if (unlikely(ctx == NULL)) { QAT_LOG(ERR, "Session has not been created for this device"); goto error; -@@ -693,7 +693,7 @@ qat_asym_process_response(void **op, uint8_t *resp, +@@ -629,6 +647,8 @@ static void qat_asym_collect_response(struct rte_crypto_op *rx_op, + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); ++ rx_op->status = ++ RTE_CRYPTO_OP_STATUS_SUCCESS; + break; + default: + QAT_LOG(ERR, "Padding not supported"); +@@ -655,8 +675,7 @@ static void qat_asym_collect_response(struct rte_crypto_op *rx_op, + } + } + } +- qat_clear_arrays_by_alg(cookie, xform->xform_type, alg_size_in_bytes, +- alg_size_in_bytes); ++ qat_clear_arrays_by_alg(cookie, xform, alg_size_in_bytes); + } + + void +@@ -693,7 +712,7 @@ qat_asym_process_response(void **op, uint8_t *resp, if (rx_op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { ctx = (struct qat_asym_session *)get_asym_session_private_data( @@ -21272,10 +30587,15 @@ index c8a52b669b..2b69b8ecf9 100644 - cryptodev_qat_asym_driver_id); + qat_asym_driver_id); diff --git a/dpdk/drivers/crypto/qat/qat_asym_pmd.h b/dpdk/drivers/crypto/qat/qat_asym_pmd.h -index 895d0f6d6a..3b5abddec8 100644 +index 895d0f6d6a..f6770bc4fb 100644 --- a/dpdk/drivers/crypto/qat/qat_asym_pmd.h +++ b/dpdk/drivers/crypto/qat/qat_asym_pmd.h -@@ -13,7 +13,7 @@ +@@ -9,11 +9,11 @@ + #include + #include "qat_device.h" + +-/** Intel(R) QAT Asymmetric Crypto PMD driver name */ ++/** Intel(R) QAT Asymmetric Crypto PMD name */ #define CRYPTODEV_NAME_QAT_ASYM_PMD crypto_qat_asym @@ -21305,10 +30625,27 @@ index 895d0f6d6a..3b5abddec8 100644 int qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev); diff --git a/dpdk/drivers/crypto/qat/qat_sym.c b/dpdk/drivers/crypto/qat/qat_sym.c -index 5c9904cbf9..fda20ad26d 100644 +index 5c9904cbf9..150c6a8b52 100644 --- a/dpdk/drivers/crypto/qat/qat_sym.c +++ b/dpdk/drivers/crypto/qat/qat_sym.c -@@ -179,7 +179,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, +@@ -2,6 +2,8 @@ + * Copyright(c) 2015-2019 Intel Corporation + */ + ++#define OPENSSL_API_COMPAT 0x10100000L ++ + #include + + #include +@@ -161,6 +163,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, + uint8_t do_sgl = 0; + uint8_t in_place = 1; + int alignment_adjustment = 0; ++ int oop_shift = 0; + struct rte_crypto_op *op = (struct rte_crypto_op *)in_op; + struct qat_sym_op_cookie *cookie = + (struct qat_sym_op_cookie *)op_cookie; +@@ -179,7 +182,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, } ctx = (struct qat_sym_session *)get_sym_session_private_data( @@ -21317,6 +30654,36 @@ index 5c9904cbf9..fda20ad26d 100644 if (unlikely(ctx == NULL)) { QAT_DP_LOG(ERR, "Session was not created for this device"); +@@ -309,8 +312,10 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, + } + min_ofs = auth_ofs; + +- auth_param->auth_res_addr = +- op->sym->auth.digest.phys_addr; ++ if (ctx->qat_hash_alg != ICP_QAT_HW_AUTH_ALGO_NULL || ++ ctx->auth_op == ICP_QAT_HW_AUTH_VERIFY) ++ auth_param->auth_res_addr = ++ op->sym->auth.digest.phys_addr; + + } + +@@ -447,6 +452,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, + rte_pktmbuf_iova_offset(op->sym->m_src, min_ofs); + dst_buf_start = + rte_pktmbuf_iova_offset(op->sym->m_dst, min_ofs); ++ oop_shift = min_ofs; + + } else { + /* In-place operation +@@ -507,7 +513,7 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg, + /* First find the end of the data */ + if (do_sgl) { + uint32_t remaining_off = auth_param->auth_off + +- auth_param->auth_len + alignment_adjustment; ++ auth_param->auth_len + alignment_adjustment + oop_shift; + struct rte_mbuf *sgl_buf = + (in_place ? + op->sym->m_src : op->sym->m_dst); diff --git a/dpdk/drivers/crypto/qat/qat_sym.h b/dpdk/drivers/crypto/qat/qat_sym.h index bc6426c327..758b06d865 100644 --- a/dpdk/drivers/crypto/qat/qat_sym.h @@ -21703,11 +31070,15 @@ index 71f21ceb25..31ed6a99aa 100644 - cryptodev_qat_driver_id); + qat_sym_driver_id); diff --git a/dpdk/drivers/crypto/qat/qat_sym_pmd.h b/dpdk/drivers/crypto/qat/qat_sym_pmd.h -index 7ddaf453e9..e2ed112cb1 100644 +index 7ddaf453e9..2fb0c998dd 100644 --- a/dpdk/drivers/crypto/qat/qat_sym_pmd.h +++ b/dpdk/drivers/crypto/qat/qat_sym_pmd.h -@@ -15,7 +15,11 @@ - /** Intel(R) QAT Symmetric Crypto PMD driver name */ +@@ -12,10 +12,14 @@ + #include "qat_sym_capabilities.h" + #include "qat_device.h" + +-/** Intel(R) QAT Symmetric Crypto PMD driver name */ ++/** Intel(R) QAT Symmetric Crypto PMD name */ #define CRYPTODEV_NAME_QAT_SYM_PMD crypto_qat -extern uint8_t cryptodev_qat_driver_id; @@ -21739,10 +31110,19 @@ index 7ddaf453e9..e2ed112cb1 100644 int qat_sym_dev_destroy(struct qat_pci_device *qat_pci_dev); diff --git a/dpdk/drivers/crypto/qat/qat_sym_session.c b/dpdk/drivers/crypto/qat/qat_sym_session.c -index 72290ba480..8545be2791 100644 +index 72290ba480..8c148c9cef 100644 --- a/dpdk/drivers/crypto/qat/qat_sym_session.c +++ b/dpdk/drivers/crypto/qat/qat_sym_session.c -@@ -19,6 +19,41 @@ +@@ -2,6 +2,8 @@ + * Copyright(c) 2015-2019 Intel Corporation + */ + ++#define OPENSSL_API_COMPAT 0x10100000L ++ + #include /* Needed to calculate pre-compute values */ + #include /* Needed to calculate pre-compute values */ + #include /* Needed to calculate pre-compute values */ +@@ -19,6 +21,41 @@ #include "qat_sym_session.h" #include "qat_sym_pmd.h" @@ -21784,7 +31164,19 @@ index 72290ba480..8545be2791 100644 /** Frees a context previously created * Depends on openssl libcrypto */ -@@ -416,6 +451,79 @@ qat_sym_session_configure(struct rte_cryptodev *dev, +@@ -60,8 +97,10 @@ bpi_cipher_ctx_init(enum rte_crypto_cipher_algorithm cryptodev_algo, + return 0; + + ctx_init_err: +- if (*ctx != NULL) ++ if (*ctx != NULL) { + EVP_CIPHER_CTX_free(*ctx); ++ *ctx = NULL; ++ } + return ret; + } + +@@ -416,6 +455,79 @@ qat_sym_session_configure(struct rte_cryptodev *dev, return 0; } @@ -21864,7 +31256,7 @@ index 72290ba480..8545be2791 100644 int qat_sym_session_set_parameters(struct rte_cryptodev *dev, struct rte_crypto_sym_xform *xform, void *session_private) -@@ -463,6 +571,8 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev, +@@ -463,6 +575,8 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev, xform, session); if (ret < 0) return ret; @@ -21873,7 +31265,7 @@ index 72290ba480..8545be2791 100644 } break; case ICP_QAT_FW_LA_CMD_HASH_CIPHER: -@@ -480,6 +590,8 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev, +@@ -480,6 +594,8 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev, xform, session); if (ret < 0) return ret; @@ -21882,7 +31274,7 @@ index 72290ba480..8545be2791 100644 } break; case ICP_QAT_FW_LA_CMD_TRNG_GET_RANDOM: -@@ -580,8 +692,29 @@ qat_sym_session_configure_auth(struct rte_cryptodev *dev, +@@ -580,8 +696,29 @@ qat_sym_session_configure_auth(struct rte_cryptodev *dev, const uint8_t *key_data = auth_xform->key.data; uint8_t key_length = auth_xform->key.length; session->aes_cmac = 0; @@ -21912,7 +31304,7 @@ index 72290ba480..8545be2791 100644 case RTE_CRYPTO_AUTH_SHA1_HMAC: session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA1; break; -@@ -635,11 +768,6 @@ qat_sym_session_configure_auth(struct rte_cryptodev *dev, +@@ -635,11 +772,6 @@ qat_sym_session_configure_auth(struct rte_cryptodev *dev, } session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3; break; @@ -21924,7 +31316,7 @@ index 72290ba480..8545be2791 100644 case RTE_CRYPTO_AUTH_MD5: case RTE_CRYPTO_AUTH_AES_CBC_MAC: QAT_LOG(ERR, "Crypto: Unsupported hash alg %u", -@@ -727,6 +855,8 @@ qat_sym_session_configure_aead(struct rte_cryptodev *dev, +@@ -727,6 +859,8 @@ qat_sym_session_configure_aead(struct rte_cryptodev *dev, session->cipher_iv.offset = xform->aead.iv.offset; session->cipher_iv.length = xform->aead.iv.length; @@ -21933,7 +31325,17 @@ index 72290ba480..8545be2791 100644 switch (aead_xform->algo) { case RTE_CRYPTO_AEAD_AES_GCM: if (qat_sym_validate_aes_key(aead_xform->key.length, -@@ -1524,7 +1654,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1034,6 +1168,9 @@ static int partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, + uint64_t *hash_state_out_be64; + int i; + ++ /* Initialize to avoid gcc warning */ ++ memset(digest, 0, sizeof(digest)); ++ + digest_size = qat_hash_get_digest_size(hash_alg); + if (digest_size <= 0) + return -EFAULT; +@@ -1524,7 +1661,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, (struct icp_qat_fw_la_auth_req_params *) ((char *)&req_tmpl->serv_specif_rqpars + ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET); @@ -21942,7 +31344,7 @@ index 72290ba480..8545be2791 100644 uint16_t hash_offset, cd_size; uint32_t *aad_len = NULL; uint32_t wordIndex = 0; -@@ -1574,10 +1704,11 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1574,10 +1711,11 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, hash = (struct icp_qat_hw_auth_setup *)cdesc->cd_cur_ptr; hash->auth_config.reserved = 0; hash->auth_config.config = @@ -21956,7 +31358,7 @@ index 72290ba480..8545be2791 100644 || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3 || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC -@@ -1600,6 +1731,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1600,6 +1738,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, */ switch (cdesc->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: @@ -21972,7 +31374,7 @@ index 72290ba480..8545be2791 100644 if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, cdesc->aes_cmac)) { -@@ -1609,6 +1749,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1609,6 +1756,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, state2_size = RTE_ALIGN_CEIL(ICP_QAT_HW_SHA1_STATE2_SZ, 8); break; case ICP_QAT_HW_AUTH_ALGO_SHA224: @@ -21988,7 +31390,7 @@ index 72290ba480..8545be2791 100644 if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, cdesc->aes_cmac)) { -@@ -1618,6 +1767,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1618,6 +1774,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, state2_size = ICP_QAT_HW_SHA224_STATE2_SZ; break; case ICP_QAT_HW_AUTH_ALGO_SHA256: @@ -22004,7 +31406,7 @@ index 72290ba480..8545be2791 100644 if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, cdesc->aes_cmac)) { -@@ -1627,6 +1785,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1627,6 +1792,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, state2_size = ICP_QAT_HW_SHA256_STATE2_SZ; break; case ICP_QAT_HW_AUTH_ALGO_SHA384: @@ -22020,7 +31422,7 @@ index 72290ba480..8545be2791 100644 if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, cdesc->aes_cmac)) { -@@ -1636,6 +1803,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1636,6 +1810,15 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, state2_size = ICP_QAT_HW_SHA384_STATE2_SZ; break; case ICP_QAT_HW_AUTH_ALGO_SHA512: @@ -22036,7 +31438,7 @@ index 72290ba480..8545be2791 100644 if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, cdesc->aes_cmac)) { -@@ -1700,7 +1876,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1700,7 +1883,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, memcpy(cipherconfig->key, authkey, authkeylen); memset(cipherconfig->key + authkeylen, 0, ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ); @@ -22045,7 +31447,7 @@ index 72290ba480..8545be2791 100644 authkeylen + ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ; auth_param->hash_state_sz = ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ >> 3; break; -@@ -1716,8 +1892,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1716,8 +1899,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, + ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ); memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); @@ -22055,7 +31457,7 @@ index 72290ba480..8545be2791 100644 auth_param->hash_state_sz = ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ >> 3; cdesc->min_qat_dev_gen = QAT_GEN2; -@@ -1803,7 +1978,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, +@@ -1803,7 +1985,7 @@ int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc, RTE_ALIGN_CEIL(hash_cd_ctrl->inner_state1_sz, 8)) >> 3); @@ -22089,6 +31491,20 @@ index c5ba2d6804..cb0f3a8ba9 100644 'rte_cryptodev_scheduler.h', 'rte_cryptodev_scheduler_operations.h', ) +diff --git a/dpdk/drivers/crypto/scheduler/scheduler_failover.c b/dpdk/drivers/crypto/scheduler/scheduler_failover.c +index 3a023b8ad3..b355fa04fd 100644 +--- a/dpdk/drivers/crypto/scheduler/scheduler_failover.c ++++ b/dpdk/drivers/crypto/scheduler/scheduler_failover.c +@@ -156,6 +156,9 @@ scheduler_start(struct rte_cryptodev *dev) + ((struct scheduler_qp_ctx *) + dev->data->queue_pairs[i])->private_qp_ctx; + ++ sched_ctx->slaves[PRIMARY_SLAVE_IDX].qp_id = i; ++ sched_ctx->slaves[SECONDARY_SLAVE_IDX].qp_id = i; ++ + rte_memcpy(&qp_ctx->primary_slave, + &sched_ctx->slaves[PRIMARY_SLAVE_IDX], + sizeof(struct scheduler_slave)); diff --git a/dpdk/drivers/crypto/scheduler/scheduler_pmd_private.h b/dpdk/drivers/crypto/scheduler/scheduler_pmd_private.h index 3ed480c183..d6870177b1 100644 --- a/dpdk/drivers/crypto/scheduler/scheduler_pmd_private.h @@ -22134,6 +31550,20 @@ index 1fe05eb567..1070800960 100644 #define SNOW3G_LOG(level, fmt, ...) \ rte_log(RTE_LOG_ ## level, snow3g_logtype_driver, \ +diff --git a/dpdk/drivers/crypto/virtio/virtio_rxtx.c b/dpdk/drivers/crypto/virtio/virtio_rxtx.c +index e9a63cb5a0..89e544e59c 100644 +--- a/dpdk/drivers/crypto/virtio/virtio_rxtx.c ++++ b/dpdk/drivers/crypto/virtio/virtio_rxtx.c +@@ -264,6 +264,9 @@ virtqueue_crypto_sym_enqueue_xmit( + if (cop->phys_addr) + desc[idx].addr = cop->phys_addr + session->iv.offset; + else { ++ if (session->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) ++ return -ENOMEM; ++ + rte_memcpy(crypto_op_cookie->iv, + rte_crypto_op_ctod_offset(cop, + uint8_t *, session->iv.offset), diff --git a/dpdk/drivers/crypto/zuc/rte_zuc_pmd.c b/dpdk/drivers/crypto/zuc/rte_zuc_pmd.c index 8e214cd50e..bc02d9d4af 100644 --- a/dpdk/drivers/crypto/zuc/rte_zuc_pmd.c @@ -22244,6 +31674,18 @@ index d71361666c..5ae76d4d9d 100644 } static int +diff --git a/dpdk/drivers/event/dpaa2/dpaa2_eventdev_logs.h b/dpdk/drivers/event/dpaa2/dpaa2_eventdev_logs.h +index 5da85c60f0..66c8c77274 100644 +--- a/dpdk/drivers/event/dpaa2/dpaa2_eventdev_logs.h ++++ b/dpdk/drivers/event/dpaa2/dpaa2_eventdev_logs.h +@@ -38,7 +38,5 @@ extern int dpaa2_logtype_event; + #define dpaa2_evdev_info(fmt, ...) DPAA2_EVENTDEV_LOG(INFO, fmt, ##__VA_ARGS__) + #define dpaa2_evdev_dbg(fmt, ...) DPAA2_EVENTDEV_LOG(DEBUG, fmt, ##__VA_ARGS__) + #define dpaa2_evdev_err(fmt, ...) DPAA2_EVENTDEV_LOG(ERR, fmt, ##__VA_ARGS__) +-#define dpaa2_evdev__func_trace dpaa2_evdev_dbg +-#define dpaa2_evdev_selftest dpaa2_evdev_info + + #endif /* _DPAA2_EVENTDEV_LOGS_H_ */ diff --git a/dpdk/drivers/event/dpaa2/dpaa2_eventdev_selftest.c b/dpdk/drivers/event/dpaa2/dpaa2_eventdev_selftest.c index ba4f4bd234..1f35807b21 100644 --- a/dpdk/drivers/event/dpaa2/dpaa2_eventdev_selftest.c @@ -22399,7 +31841,7 @@ index 61a66fabf3..0df9209e4f 100644 uint16_t dequeued = RTE_MIN(num, port->in_buffer_len); diff --git a/dpdk/drivers/event/octeontx2/otx2_evdev.c b/dpdk/drivers/event/octeontx2/otx2_evdev.c -index 2daeba42c7..5bdf23c362 100644 +index 2daeba42c7..6a0149b942 100644 --- a/dpdk/drivers/event/octeontx2/otx2_evdev.c +++ b/dpdk/drivers/event/octeontx2/otx2_evdev.c @@ -648,7 +648,36 @@ sso_lf_cfg(struct otx2_sso_evdev *dev, struct otx2_mbox *mbox, @@ -22540,7 +31982,7 @@ index 2daeba42c7..5bdf23c362 100644 event_dev->data->ports[i] = ws; } -@@ -788,19 +838,21 @@ sso_configure_ports(const struct rte_eventdev *event_dev) +@@ -788,31 +838,39 @@ sso_configure_ports(const struct rte_eventdev *event_dev) } for (i = 0; i < nb_lf; i++) { @@ -22548,30 +31990,40 @@ index 2daeba42c7..5bdf23c362 100644 struct otx2_ssogws *ws; uintptr_t base; - /* Free memory prior to re-allocation if needed */ +- /* Free memory prior to re-allocation if needed */ if (event_dev->data->ports[i] != NULL) { ws = event_dev->data->ports[i]; - rte_free(ws); -+ rte_free(ssogws_get_cookie(ws)); - ws = NULL; - } +- ws = NULL; +- } ++ } else { ++ /* Allocate event port memory */ ++ ws = rte_zmalloc_socket("otx2_sso_ws", ++ sizeof(struct otx2_ssogws) + ++ RTE_CACHE_LINE_SIZE, ++ RTE_CACHE_LINE_SIZE, ++ event_dev->data->socket_id); ++ if (ws == NULL) { ++ otx2_err("Failed to alloc memory for port=%d", ++ i); ++ rc = -ENOMEM; ++ break; ++ } - /* Allocate event port memory */ - ws = rte_zmalloc_socket("otx2_sso_ws", +- /* Allocate event port memory */ +- ws = rte_zmalloc_socket("otx2_sso_ws", - sizeof(struct otx2_ssogws), -+ sizeof(struct otx2_ssogws) + -+ RTE_CACHE_LINE_SIZE, - RTE_CACHE_LINE_SIZE, - event_dev->data->socket_id); - if (ws == NULL) { -@@ -809,10 +861,18 @@ sso_configure_ports(const struct rte_eventdev *event_dev) - break; +- RTE_CACHE_LINE_SIZE, +- event_dev->data->socket_id); +- if (ws == NULL) { +- otx2_err("Failed to alloc memory for port=%d", i); +- rc = -ENOMEM; +- break; ++ /* First cache line is reserved for cookie */ ++ ws = (struct otx2_ssogws *) ++ ((uint8_t *)ws + RTE_CACHE_LINE_SIZE); } -+ /* First cache line is reserved for cookie */ -+ ws = (struct otx2_ssogws *) -+ ((uint8_t *)ws + RTE_CACHE_LINE_SIZE); -+ ws->port = i; base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | i << 12); sso_set_port_ops(ws, base); @@ -22583,7 +32035,7 @@ index 2daeba42c7..5bdf23c362 100644 event_dev->data->ports[i] = ws; } -@@ -1057,8 +1117,8 @@ otx2_sso_configure(const struct rte_eventdev *event_dev) +@@ -1057,8 +1115,8 @@ otx2_sso_configure(const struct rte_eventdev *event_dev) goto teardown_hwggrp; } @@ -22661,6 +32113,19 @@ index 9d7c694ee6..74fcec8a07 100644 case RTE_EVENT_DEV_XSTATS_PORT: if (queue_port_id >= (signed int)dev->nb_event_ports) goto invalid_value; +diff --git a/dpdk/drivers/event/octeontx2/otx2_worker.h b/dpdk/drivers/event/octeontx2/otx2_worker.h +index 7d161c85ee..b35a9cf247 100644 +--- a/dpdk/drivers/event/octeontx2/otx2_worker.h ++++ b/dpdk/drivers/event/octeontx2/otx2_worker.h +@@ -270,7 +270,7 @@ otx2_ssogws_prepare_pkt(const struct otx2_eth_txq *txq, struct rte_mbuf *m, + uint64_t *cmd, const uint32_t flags) + { + otx2_lmt_mov(cmd, txq->cmd, otx2_nix_tx_ext_subs(flags)); +- otx2_nix_xmit_prepare(m, cmd, flags); ++ otx2_nix_xmit_prepare(m, cmd, flags, txq->lso_tun_fmt); + } + + static __rte_always_inline uint16_t diff --git a/dpdk/drivers/event/octeontx2/otx2_worker_dual.h b/dpdk/drivers/event/octeontx2/otx2_worker_dual.h index 5134e3d525..fb6a8cd0d5 100644 --- a/dpdk/drivers/event/octeontx2/otx2_worker_dual.h @@ -22679,6 +32144,26 @@ index 5134e3d525..fb6a8cd0d5 100644 /* Extracting tstamp, if PTP enabled. CGX will prepend the * timestamp at starting of packet data and it can be derieved * from WQE 9 dword which corresponds to SG iova. +diff --git a/dpdk/drivers/event/sw/sw_evdev.c b/dpdk/drivers/event/sw/sw_evdev.c +index fb8e8bebbb..d075108610 100644 +--- a/dpdk/drivers/event/sw/sw_evdev.c ++++ b/dpdk/drivers/event/sw/sw_evdev.c +@@ -717,7 +717,6 @@ sw_dump(struct rte_eventdev *dev, FILE *f) + continue; + } + int affinities_per_port[SW_PORTS_MAX] = {0}; +- uint32_t inflights = 0; + + fprintf(f, " Queue %d (%s)\n", i, q_type_strings[qid->type]); + fprintf(f, "\trx %"PRIu64"\tdrop %"PRIu64"\ttx %"PRIu64"\n", +@@ -738,7 +737,6 @@ sw_dump(struct rte_eventdev *dev, FILE *f) + for (flow = 0; flow < RTE_DIM(qid->fids); flow++) + if (qid->fids[flow].cq != -1) { + affinities_per_port[qid->fids[flow].cq]++; +- inflights += qid->fids[flow].pcount; + } + + uint32_t port; diff --git a/dpdk/drivers/mempool/dpaa2/meson.build b/dpdk/drivers/mempool/dpaa2/meson.build index d79fc31644..a4fe684fc4 100644 --- a/dpdk/drivers/mempool/dpaa2/meson.build @@ -22736,10 +32221,30 @@ index c97267db3c..e37b844842 100644 hdr.msg = FPA_DETACHAURA; hdr.vfid = gpool_index; diff --git a/dpdk/drivers/mempool/octeontx2/otx2_mempool_ops.c b/dpdk/drivers/mempool/octeontx2/otx2_mempool_ops.c -index ea4b1c45d2..18bdb0b4c4 100644 +index ea4b1c45d2..f4d50c29ca 100644 --- a/dpdk/drivers/mempool/octeontx2/otx2_mempool_ops.c +++ b/dpdk/drivers/mempool/octeontx2/otx2_mempool_ops.c -@@ -637,10 +637,10 @@ static int +@@ -533,7 +533,8 @@ npa_lf_aura_pool_pair_alloc(struct otx2_npa_lf *lf, const uint32_t block_size, + /* Update aura fields */ + aura->pool_addr = pool_id;/* AF will translate to associated poolctx */ + aura->ena = 1; +- aura->shift = __builtin_clz(block_count) - 8; ++ aura->shift = rte_log2_u32(block_count); ++ aura->shift = aura->shift < 8 ? 0 : aura->shift - 8; + aura->limit = block_count; + aura->pool_caching = 1; + aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER); +@@ -548,7 +549,8 @@ npa_lf_aura_pool_pair_alloc(struct otx2_npa_lf *lf, const uint32_t block_size, + pool->ena = 1; + pool->buf_size = block_size / OTX2_ALIGN; + pool->stack_max_pages = stack_size; +- pool->shift = __builtin_clz(block_count) - 8; ++ pool->shift = rte_log2_u32(block_count); ++ pool->shift = pool->shift < 8 ? 0 : pool->shift - 8; + pool->ptr_start = 0; + pool->ptr_end = ~0; + pool->stack_caching = 1; +@@ -637,10 +639,10 @@ static int otx2_npa_alloc(struct rte_mempool *mp) { uint32_t block_size, block_count; @@ -22752,7 +32257,7 @@ index ea4b1c45d2..18bdb0b4c4 100644 lf = otx2_npa_lf_obj_get(); diff --git a/dpdk/drivers/meson.build b/dpdk/drivers/meson.build -index 72eec46088..696079680b 100644 +index 72eec46088..44e3dbcb5c 100644 --- a/dpdk/drivers/meson.build +++ b/dpdk/drivers/meson.build @@ -9,8 +9,8 @@ endif @@ -22766,6 +32271,15 @@ index 72eec46088..696079680b 100644 'crypto', # depends on common, bus and mempool (net in future). 'compress', # depends on common, bus, mempool. 'event', # depends on common, bus, mempool and net. +@@ -116,7 +116,7 @@ foreach class:dpdk_driver_classes + include_directories: includes, + dependencies: static_deps, + c_args: cflags) +- objs += tmp_lib.extract_all_objects() ++ objs += tmp_lib.extract_all_objects(recursive: true) + sources = custom_target(out_filename, + command: [pmdinfo, tmp_lib.full_path(), + '@OUTPUT@', pmdinfogen], @@ -151,7 +151,7 @@ foreach class:dpdk_driver_classes version_map = '@0@/@1@/@2@_version.map'.format( meson.current_source_dir(), @@ -22792,20 +32306,44 @@ index 72eec46088..696079680b 100644 else lk_args = ['-Wl,--version-script=' + version_map] # on unix systems check the output of the -@@ -192,7 +198,7 @@ foreach class:dpdk_driver_classes - shared_dep = declare_dependency(link_with: shared_lib, - include_directories: includes, - dependencies: shared_deps) -- static_dep = declare_dependency(link_with: static_lib, -+ static_dep = declare_dependency( - include_directories: includes, - dependencies: static_deps) - diff --git a/dpdk/drivers/net/af_packet/rte_eth_af_packet.c b/dpdk/drivers/net/af_packet/rte_eth_af_packet.c -index f5806bf42c..00387ed0ac 100644 +index f5806bf42c..dbbe8e5deb 100644 --- a/dpdk/drivers/net/af_packet/rte_eth_af_packet.c +++ b/dpdk/drivers/net/af_packet/rte_eth_af_packet.c -@@ -604,6 +604,8 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, +@@ -213,8 +213,30 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + } + + /* point at the next incoming frame */ +- if ((ppd->tp_status != TP_STATUS_AVAILABLE) && +- (poll(&pfd, 1, -1) < 0)) ++ if (ppd->tp_status != TP_STATUS_AVAILABLE) { ++ if (poll(&pfd, 1, -1) < 0) ++ break; ++ ++ /* poll() can return POLLERR if the interface is down */ ++ if (pfd.revents & POLLERR) ++ break; ++ } ++ ++ /* ++ * poll() will almost always return POLLOUT, even if there ++ * are no extra buffers available ++ * ++ * This happens, because packet_poll() calls datagram_poll() ++ * which checks the space left in the socket buffer and, ++ * in the case of packet_mmap, the default socket buffer length ++ * doesn't match the requested size for the tx_ring. ++ * As such, there is almost always space left in socket buffer, ++ * which doesn't seem to be correlated to the requested size ++ * for the tx_ring in packet_mmap. ++ * ++ * This results in poll() returning POLLOUT. ++ */ ++ if (ppd->tp_status != TP_STATUS_AVAILABLE) + break; + + /* copy the tx frame data */ +@@ -604,6 +626,8 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, for (q = 0; q < nb_queues; q++) { (*internals)->rx_queue[q].map = MAP_FAILED; (*internals)->tx_queue[q].map = MAP_FAILED; @@ -22814,7 +32352,7 @@ index f5806bf42c..00387ed0ac 100644 } req = &((*internals)->req); -@@ -621,20 +623,20 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, +@@ -621,20 +645,20 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG(ERR, "%s: I/F name too long (%s)", name, pair->value); @@ -22839,7 +32377,7 @@ index f5806bf42c..00387ed0ac 100644 } memcpy(&(*internals)->eth_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); -@@ -658,7 +660,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, +@@ -658,7 +682,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG_ERRNO(ERR, "%s: could not open AF_PACKET socket", name); @@ -22848,7 +32386,7 @@ index f5806bf42c..00387ed0ac 100644 } tpver = TPACKET_V2; -@@ -802,15 +804,19 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, +@@ -802,15 +826,19 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, if (qsockfd != -1) close(qsockfd); for (q = 0; q < nb_queues; q++) { @@ -22885,7 +32423,7 @@ index 307aa0e388..a9007439fe 100644 bpf_dep = cc.find_library('bpf', required: false) endif diff --git a/dpdk/drivers/net/af_xdp/rte_eth_af_xdp.c b/dpdk/drivers/net/af_xdp/rte_eth_af_xdp.c -index 2b1245ee4f..ac253b1d81 100644 +index 2b1245ee4f..9b36d80335 100644 --- a/dpdk/drivers/net/af_xdp/rte_eth_af_xdp.c +++ b/dpdk/drivers/net/af_xdp/rte_eth_af_xdp.c @@ -34,6 +34,7 @@ @@ -23046,7 +32584,17 @@ index 2b1245ee4f..ac253b1d81 100644 } static void -@@ -737,12 +743,17 @@ eth_link_update(struct rte_eth_dev *dev __rte_unused, +@@ -699,6 +705,9 @@ eth_dev_close(struct rte_eth_dev *dev) + struct pkt_rx_queue *rxq; + int i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + AF_XDP_LOG(INFO, "Closing AF_XDP ethdev on numa socket %u\n", + rte_socket_id()); + +@@ -737,12 +746,17 @@ eth_link_update(struct rte_eth_dev *dev __rte_unused, } #if defined(XDP_UMEM_UNALIGNED_CHUNK_FLAG) @@ -23066,7 +32614,7 @@ index 2b1245ee4f..ac253b1d81 100644 } static struct -@@ -757,12 +768,15 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals __rte_unused, +@@ -757,29 +771,31 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals __rte_unused, .flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG}; void *base_addr = NULL; struct rte_mempool *mb_pool = rxq->mb_pool; @@ -23087,7 +32635,9 @@ index 2b1245ee4f..ac253b1d81 100644 umem = rte_zmalloc_socket("umem", sizeof(*umem), 0, rte_socket_id()); if (umem == NULL) { -@@ -771,12 +785,11 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals __rte_unused, +- AF_XDP_LOG(ERR, "Failed to allocate umem info"); ++ AF_XDP_LOG(ERR, "Failed to allocate umem info\n"); + return NULL; } umem->mb_pool = mb_pool; @@ -23103,8 +32653,12 @@ index 2b1245ee4f..ac253b1d81 100644 + &umem->fq, &umem->cq, &usr_config); if (ret) { - AF_XDP_LOG(ERR, "Failed to create umem"); -@@ -795,7 +808,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, +- AF_XDP_LOG(ERR, "Failed to create umem"); ++ AF_XDP_LOG(ERR, "Failed to create umem\n"); + goto err; + } + umem->buffer = base_addr; +@@ -795,7 +811,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, .fill_size = ETH_AF_XDP_DFLT_NUM_DESCS, .comp_size = ETH_AF_XDP_DFLT_NUM_DESCS, .frame_size = ETH_AF_XDP_FRAME_SIZE, @@ -23113,7 +32667,16 @@ index 2b1245ee4f..ac253b1d81 100644 char ring_name[RTE_RING_NAMESIZE]; char mz_name[RTE_MEMZONE_NAMESIZE]; int ret; -@@ -820,8 +833,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, +@@ -803,7 +819,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, + + umem = rte_zmalloc_socket("umem", sizeof(*umem), 0, rte_socket_id()); + if (umem == NULL) { +- AF_XDP_LOG(ERR, "Failed to allocate umem info"); ++ AF_XDP_LOG(ERR, "Failed to allocate umem info\n"); + return NULL; + } + +@@ -820,8 +836,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, for (i = 0; i < ETH_AF_XDP_NUM_BUFFERS; i++) rte_ring_enqueue(umem->buf_ring, @@ -23123,7 +32686,50 @@ index 2b1245ee4f..ac253b1d81 100644 snprintf(mz_name, sizeof(mz_name), "af_xdp_umem_%s_%u", internals->if_name, rxq->xsk_queue_idx); -@@ -930,7 +942,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, +@@ -840,7 +855,7 @@ xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals, + &usr_config); + + if (ret) { +- AF_XDP_LOG(ERR, "Failed to create umem"); ++ AF_XDP_LOG(ERR, "Failed to create umem\n"); + goto err; + } + umem->mz = mz; +@@ -883,25 +898,27 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq, + &txq->tx, &cfg); + if (ret) { + AF_XDP_LOG(ERR, "Failed to create xsk socket.\n"); +- goto err; ++ goto out_umem; + } + + #if defined(XDP_UMEM_UNALIGNED_CHUNK_FLAG) +- if (rte_pktmbuf_alloc_bulk(rxq->umem->mb_pool, fq_bufs, reserve_size)) { ++ ret = rte_pktmbuf_alloc_bulk(rxq->umem->mb_pool, fq_bufs, reserve_size); ++ if (ret) { + AF_XDP_LOG(DEBUG, "Failed to get enough buffers for fq.\n"); +- goto err; ++ goto out_xsk; + } + #endif + ret = reserve_fill_queue(rxq->umem, reserve_size, fq_bufs); + if (ret) { +- xsk_socket__delete(rxq->xsk); + AF_XDP_LOG(ERR, "Failed to reserve fill queue.\n"); +- goto err; ++ goto out_xsk; + } + + return 0; + +-err: ++out_xsk: ++ xsk_socket__delete(rxq->xsk); ++out_umem: + xdp_umem_destroy(rxq->umem); + + return ret; +@@ -930,7 +947,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, /* Now get the space available for data in the mbuf */ buf_size = rte_pktmbuf_data_room_size(mb_pool) - RTE_PKTMBUF_HEADROOM; @@ -23132,7 +32738,7 @@ index 2b1245ee4f..ac253b1d81 100644 if (data_size > buf_size) { AF_XDP_LOG(ERR, "%s: %d bytes will not fit in mbuf (%d bytes)\n", -@@ -1103,7 +1115,7 @@ xdp_get_channels_info(const char *if_name, int *max_queues, +@@ -1103,7 +1120,7 @@ xdp_get_channels_info(const char *if_name, int *max_queues, channels.cmd = ETHTOOL_GCHANNELS; ifr.ifr_data = (void *)&channels; @@ -23141,6 +32747,171 @@ index 2b1245ee4f..ac253b1d81 100644 ret = ioctl(fd, SIOCETHTOOL, &ifr); if (ret) { if (errno == EOPNOTSUPP) { +@@ -1289,16 +1306,11 @@ rte_pmd_af_xdp_probe(struct rte_vdev_device *dev) + rte_vdev_device_name(dev)); + + name = rte_vdev_device_name(dev); +- if (rte_eal_process_type() == RTE_PROC_SECONDARY && +- strlen(rte_vdev_device_args(dev)) == 0) { +- eth_dev = rte_eth_dev_attach_secondary(name); +- if (eth_dev == NULL) { +- AF_XDP_LOG(ERR, "Failed to probe %s\n", name); +- return -EINVAL; +- } +- eth_dev->dev_ops = &ops; +- rte_eth_dev_probing_finish(eth_dev); +- return 0; ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY) { ++ AF_XDP_LOG(ERR, "Failed to probe %s. " ++ "AF_XDP PMD does not support secondary processes.\n", ++ name); ++ return -ENOTSUP; + } + + kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_arguments); +diff --git a/dpdk/drivers/net/ark/ark_ethdev.c b/dpdk/drivers/net/ark/ark_ethdev.c +index c3642012dd..b3964839a2 100644 +--- a/dpdk/drivers/net/ark/ark_ethdev.c ++++ b/dpdk/drivers/net/ark/ark_ethdev.c +@@ -283,6 +283,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev) + ark->rqpacing = + (struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE); + ark->started = 0; ++ ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL; + + PMD_DEBUG_LOG(INFO, "Sys Ctrl Const = 0x%x HW Commit_ID: %08x\n", + ark->sysctrl.t32[4], +@@ -689,6 +690,9 @@ eth_ark_dev_close(struct rte_eth_dev *dev) + struct ark_adapter *ark = dev->data->dev_private; + uint16_t i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (ark->user_ext.dev_close) + ark->user_ext.dev_close(dev, + ark->user_data[dev->data->port_id]); +diff --git a/dpdk/drivers/net/ark/ark_ethdev_rx.c b/dpdk/drivers/net/ark/ark_ethdev_rx.c +index 6156730bb2..a3af847808 100644 +--- a/dpdk/drivers/net/ark/ark_ethdev_rx.c ++++ b/dpdk/drivers/net/ark/ark_ethdev_rx.c +@@ -25,9 +25,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue, + struct rte_mbuf *mbuf0, + uint32_t cons_index); + static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue); +-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue, +- uint32_t *pnb, +- struct rte_mbuf **mbufs); + + /* ************************************************************************* */ + struct ark_rx_queue { +@@ -53,7 +50,7 @@ struct ark_rx_queue { + /* The queue Index is used within the dpdk device structures */ + uint16_t queue_index; + +- uint32_t last_cons; ++ uint32_t unused; + + /* separate cache line */ + /* second cache line - fields only used in slow path */ +@@ -104,9 +101,8 @@ static inline void + eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index) + { + queue->cons_index = cons_index; +- eth_ark_rx_seed_mbufs(queue); +- if (((cons_index - queue->last_cons) >= 64U)) { +- queue->last_cons = cons_index; ++ if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) { ++ eth_ark_rx_seed_mbufs(queue); + ark_mpu_set_producer(queue->mpu, queue->seed_index); + } + } +@@ -317,9 +313,7 @@ eth_ark_recv_pkts(void *rx_queue, + break; + } + +- if (unlikely(nb != 0)) +- /* report next free to FPGA */ +- eth_ark_rx_update_cons_index(queue, cons_index); ++ eth_ark_rx_update_cons_index(queue, cons_index); + + return nb; + } +@@ -456,11 +450,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue) + int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb); + + if (unlikely(status != 0)) { +- /* Try to recover from lack of mbufs in pool */ +- status = eth_ark_rx_seed_recovery(queue, &nb, mbufs); +- if (unlikely(status != 0)) { +- return -1; +- } ++ PMD_DRV_LOG(NOTICE, ++ "Could not allocate %u mbufs from pool" ++ " for RX queue %u;" ++ " %u free buffers remaining in queue\n", ++ nb, queue->queue_index, ++ queue->seed_index - queue->cons_index); ++ return -1; + } + + if (ARK_RX_DEBUG) { /* DEBUG */ +@@ -509,29 +505,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue) + return 0; + } + +-int +-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue, +- uint32_t *pnb, +- struct rte_mbuf **mbufs) +-{ +- int status = -1; +- +- /* Ignore small allocation failures */ +- if (*pnb <= 64) +- return -1; +- +- *pnb = 64U; +- status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb); +- if (status != 0) { +- PMD_DRV_LOG(ERR, +- "ARK: Could not allocate %u mbufs from pool for RX queue %u;" +- " %u free buffers remaining in queue\n", +- *pnb, queue->queue_index, +- queue->seed_index - queue->cons_index); +- } +- return status; +-} +- + void + eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id, + const char *msg) +diff --git a/dpdk/drivers/net/ark/ark_pktdir.c b/dpdk/drivers/net/ark/ark_pktdir.c +index 1f2c8182ad..0bcc379f06 100644 +--- a/dpdk/drivers/net/ark/ark_pktdir.c ++++ b/dpdk/drivers/net/ark/ark_pktdir.c +@@ -22,7 +22,7 @@ ark_pktdir_init(void *base) + return inst; + } + inst->regs = (struct ark_pkt_dir_regs *)base; +- inst->regs->ctrl = 0x00110110; /* POR state */ ++ inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */ + return inst; + } + +diff --git a/dpdk/drivers/net/ark/ark_pktdir.h b/dpdk/drivers/net/ark/ark_pktdir.h +index 314e6dea9d..8e9f119855 100644 +--- a/dpdk/drivers/net/ark/ark_pktdir.h ++++ b/dpdk/drivers/net/ark/ark_pktdir.h +@@ -7,7 +7,7 @@ + + #include + +-#define ARK_PKTDIR_BASE_ADR 0xa0000 ++#define ARK_PKT_DIR_INIT_VAL 0x0110 + + typedef void *ark_pkt_dir_t; + diff --git a/dpdk/drivers/net/atlantic/rte_pmd_atlantic.h b/dpdk/drivers/net/atlantic/rte_pmd_atlantic.h index c0208569b6..0100fc16e5 100644 --- a/dpdk/drivers/net/atlantic/rte_pmd_atlantic.h @@ -23155,7 +32926,7 @@ index c0208569b6..0100fc16e5 100644 /** * @warning diff --git a/dpdk/drivers/net/avp/avp_ethdev.c b/dpdk/drivers/net/avp/avp_ethdev.c -index cd747b6beb..8de05ec16f 100644 +index cd747b6beb..cf4319dfb6 100644 --- a/dpdk/drivers/net/avp/avp_ethdev.c +++ b/dpdk/drivers/net/avp/avp_ethdev.c @@ -269,7 +269,7 @@ avp_dev_process_request(struct avp_dev *avp, struct rte_avp_request *request) @@ -23176,6 +32947,36 @@ index cd747b6beb..8de05ec16f 100644 struct avp_queue *txq = (struct avp_queue *)tx_queue; struct rte_avp_desc *tx_bufs[AVP_MAX_TX_BURST]; struct avp_dev *avp = txq->avp; +@@ -2111,6 +2111,9 @@ avp_dev_close(struct rte_eth_dev *eth_dev) + struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); + int ret; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + rte_spinlock_lock(&avp->lock); + if (avp->flags & AVP_F_DETACHED) { + PMD_DRV_LOG(ERR, "Operation not supported during VM live migration\n"); +diff --git a/dpdk/drivers/net/axgbe/axgbe_i2c.c b/dpdk/drivers/net/axgbe/axgbe_i2c.c +index 204ec36798..1b6094d6f0 100644 +--- a/dpdk/drivers/net/axgbe/axgbe_i2c.c ++++ b/dpdk/drivers/net/axgbe/axgbe_i2c.c +@@ -227,6 +227,7 @@ static int axgbe_i2c_xfer(struct axgbe_port *pdata, struct axgbe_i2c_op *op) + ret = axgbe_i2c_disable(pdata); + if (ret) { + PMD_DRV_LOG(ERR, "failed to disable i2c master\n"); ++ pthread_mutex_unlock(&pdata->i2c_mutex); + return ret; + } + +@@ -243,6 +244,7 @@ static int axgbe_i2c_xfer(struct axgbe_port *pdata, struct axgbe_i2c_op *op) + ret = axgbe_i2c_enable(pdata); + if (ret) { + PMD_DRV_LOG(ERR, "failed to enable i2c master\n"); ++ pthread_mutex_unlock(&pdata->i2c_mutex); + return ret; + } + diff --git a/dpdk/drivers/net/bnx2x/bnx2x.c b/dpdk/drivers/net/bnx2x/bnx2x.c index ed31335ac5..0b4030e2b9 100644 --- a/dpdk/drivers/net/bnx2x/bnx2x.c @@ -23233,7 +33034,7 @@ index ed31335ac5..0b4030e2b9 100644 le16toh(fp->fp_hc_idx), IGU_INT_ENABLE, 1); } diff --git a/dpdk/drivers/net/bnx2x/bnx2x.h b/dpdk/drivers/net/bnx2x/bnx2x.h -index 3383c76759..1dbc98197d 100644 +index 3383c76759..b6aa52a333 100644 --- a/dpdk/drivers/net/bnx2x/bnx2x.h +++ b/dpdk/drivers/net/bnx2x/bnx2x.h @@ -360,6 +360,9 @@ struct bnx2x_fastpath { @@ -23246,6 +33047,32 @@ index 3383c76759..1dbc98197d 100644 /* status block */ struct bnx2x_dma sb_dma; union bnx2x_host_hc_status_block status_block; +@@ -1899,18 +1902,19 @@ bnx2x_hc_ack_sb(struct bnx2x_softc *sc, uint8_t sb_id, uint8_t storm, + { + uint32_t hc_addr = (HC_REG_COMMAND_REG + SC_PORT(sc) * 32 + + COMMAND_REG_INT_ACK); +- struct igu_ack_register igu_ack; +- uint32_t *val = NULL; ++ union { ++ struct igu_ack_register igu_ack; ++ uint32_t val; ++ } val; + +- igu_ack.status_block_index = index; +- igu_ack.sb_id_and_flags = ++ val.igu_ack.status_block_index = index; ++ val.igu_ack.sb_id_and_flags = + ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) | + (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) | + (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | + (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); + +- val = (uint32_t *)&igu_ack; +- REG_WR(sc, hc_addr, *val); ++ REG_WR(sc, hc_addr, val.val); + + /* Make sure that ACK is written */ + mb(); diff --git a/dpdk/drivers/net/bnx2x/bnx2x_ethdev.c b/dpdk/drivers/net/bnx2x/bnx2x_ethdev.c index 20b045ff87..8a1a3fc7f9 100644 --- a/dpdk/drivers/net/bnx2x/bnx2x_ethdev.c @@ -23293,10 +33120,32 @@ index 20b045ff87..8a1a3fc7f9 100644 sc->pcie_bus = pci_dev->addr.bus; diff --git a/dpdk/drivers/net/bnx2x/bnx2x_rxtx.c b/dpdk/drivers/net/bnx2x/bnx2x_rxtx.c -index ae97dfee36..e201b68db8 100644 +index ae97dfee36..db4654dd51 100644 --- a/dpdk/drivers/net/bnx2x/bnx2x_rxtx.c +++ b/dpdk/drivers/net/bnx2x/bnx2x_rxtx.c -@@ -346,6 +346,8 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -321,14 +321,15 @@ static inline void + bnx2x_upd_rx_prod_fast(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, + uint16_t rx_bd_prod, uint16_t rx_cq_prod) + { +- struct ustorm_eth_rx_producers rx_prods = { 0 }; +- uint32_t *val = NULL; ++ union { ++ struct ustorm_eth_rx_producers rx_prods; ++ uint32_t val; ++ } val = { {0} }; + +- rx_prods.bd_prod = rx_bd_prod; +- rx_prods.cqe_prod = rx_cq_prod; ++ val.rx_prods.bd_prod = rx_bd_prod; ++ val.rx_prods.cqe_prod = rx_cq_prod; + +- val = (uint32_t *)&rx_prods; +- REG_WR(sc, fp->ustorm_rx_prods_offset, val[0]); ++ REG_WR(sc, fp->ustorm_rx_prods_offset, val.val); + } + + static uint16_t +@@ -346,6 +347,8 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) uint16_t len, pad; struct rte_mbuf *rx_mb = NULL; @@ -23305,7 +33154,7 @@ index ae97dfee36..e201b68db8 100644 hw_cq_cons = le16toh(*fp->rx_cq_cons_sb); if ((hw_cq_cons & USABLE_RCQ_ENTRIES_PER_PAGE) == USABLE_RCQ_ENTRIES_PER_PAGE) { -@@ -357,8 +359,10 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -357,8 +360,10 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) sw_cq_cons = rxq->rx_cq_head; sw_cq_prod = rxq->rx_cq_tail; @@ -23317,7 +33166,7 @@ index ae97dfee36..e201b68db8 100644 while (nb_rx < nb_pkts && sw_cq_cons != hw_cq_cons) { -@@ -414,7 +418,7 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -414,7 +419,7 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) */ if (cqe_fp->pars_flags.flags & PARSING_FLAGS_VLAN) { rx_mb->vlan_tci = cqe_fp->vlan_tag; @@ -23326,7 +33175,7 @@ index ae97dfee36..e201b68db8 100644 } rx_pkts[nb_rx] = rx_mb; -@@ -439,6 +443,8 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -439,6 +444,8 @@ bnx2x_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) bnx2x_upd_rx_prod_fast(sc, fp, bd_prod, sw_cq_prod); @@ -23335,6 +33184,19 @@ index ae97dfee36..e201b68db8 100644 return nb_rx; } +diff --git a/dpdk/drivers/net/bnx2x/elink.c b/dpdk/drivers/net/bnx2x/elink.c +index b65126d718..2093d8f373 100644 +--- a/dpdk/drivers/net/bnx2x/elink.c ++++ b/dpdk/drivers/net/bnx2x/elink.c +@@ -15013,7 +15013,7 @@ static void elink_check_kr2_wa(struct elink_params *params, + + /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery + * Since some switches tend to reinit the AN process and clear the +- * the advertised BP/NP after ~2 seconds causing the KR2 to be disabled ++ * advertised BP/NP after ~2 seconds causing the KR2 to be disabled + * and recovered many times + */ + if (vars->check_kr2_recovery_cnt > 0) { diff --git a/dpdk/drivers/net/bnx2x/meson.build b/dpdk/drivers/net/bnx2x/meson.build index 678708905e..f9749d3132 100644 --- a/dpdk/drivers/net/bnx2x/meson.build @@ -23349,7 +33211,7 @@ index 678708905e..f9749d3132 100644 reason = 'missing dependency, "zlib"' ext_deps += dep diff --git a/dpdk/drivers/net/bnxt/bnxt.h b/dpdk/drivers/net/bnxt/bnxt.h -index e259c8239d..0a0ecaafa8 100644 +index e259c8239d..5ddf60313d 100644 --- a/dpdk/drivers/net/bnxt/bnxt.h +++ b/dpdk/drivers/net/bnxt/bnxt.h @@ -117,6 +117,14 @@ @@ -23395,7 +33257,35 @@ index e259c8239d..0a0ecaafa8 100644 struct bnxt_link_info { uint32_t phy_flags; uint8_t mac_type; -@@ -342,7 +344,7 @@ struct bnxt_coal { +@@ -249,6 +251,7 @@ struct bnxt_link_info { + uint8_t phy_ver[PHY_VER_LEN]; + uint16_t link_speed; + uint16_t support_speeds; ++ uint16_t support_auto_speeds; + uint16_t auto_link_speed; + uint16_t force_link_speed; + uint16_t auto_link_speed_mask; +@@ -269,9 +272,11 @@ struct rte_flow { + struct bnxt_vnic_info *vnic; + }; + ++#define BNXT_PTP_RX_PND_CNT 10 + #define BNXT_PTP_FLAGS_PATH_TX 0x0 + #define BNXT_PTP_FLAGS_PATH_RX 0x1 + #define BNXT_PTP_FLAGS_CURRENT_TIME 0x2 ++#define BNXT_PTP_CURRENT_TIME_MASK 0xFFFF00000000ULL + + struct bnxt_ptp_cfg { + #define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400 +@@ -321,6 +326,7 @@ struct bnxt_ptp_cfg { + + /* On Thor, the Rx timestamp is present in the Rx completion record */ + uint64_t rx_timestamp; ++ uint64_t current_time; + }; + + struct bnxt_coal { +@@ -342,7 +348,7 @@ struct bnxt_coal { #define DBR_TYPE_NQ (0xaULL << 60) #define DBR_TYPE_NQ_ARM (0xbULL << 60) @@ -23404,7 +33294,7 @@ index e259c8239d..0a0ecaafa8 100644 #define BNXT_RSS_ENTRIES_PER_CTX_THOR 64 #define BNXT_MAX_RSS_CTXTS_THOR \ (BNXT_RSS_TBL_SIZE_THOR / BNXT_RSS_ENTRIES_PER_CTX_THOR) -@@ -461,6 +463,11 @@ struct bnxt_error_recovery_info { +@@ -461,6 +467,11 @@ struct bnxt_error_recovery_info { uint32_t last_reset_counter; }; @@ -23416,7 +33306,55 @@ index e259c8239d..0a0ecaafa8 100644 /* address space location of register */ #define BNXT_FW_STATUS_REG_TYPE_MASK 3 /* register is located in PCIe config space */ -@@ -485,7 +492,6 @@ struct bnxt { +@@ -481,11 +492,54 @@ struct bnxt_error_recovery_info { + #define BNXT_FW_STATUS_SHUTDOWN 0x100000 + + #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) ++ ++struct bnxt_ring_stats { ++ /* Number of transmitted unicast packets */ ++ uint64_t tx_ucast_pkts; ++ /* Number of transmitted multicast packets */ ++ uint64_t tx_mcast_pkts; ++ /* Number of transmitted broadcast packets */ ++ uint64_t tx_bcast_pkts; ++ /* Number of packets discarded in transmit path */ ++ uint64_t tx_discard_pkts; ++ /* Number of packets in transmit path with error */ ++ uint64_t tx_error_pkts; ++ /* Number of transmitted bytes for unicast traffic */ ++ uint64_t tx_ucast_bytes; ++ /* Number of transmitted bytes for multicast traffic */ ++ uint64_t tx_mcast_bytes; ++ /* Number of transmitted bytes for broadcast traffic */ ++ uint64_t tx_bcast_bytes; ++ /* Number of received unicast packets */ ++ uint64_t rx_ucast_pkts; ++ /* Number of received multicast packets */ ++ uint64_t rx_mcast_pkts; ++ /* Number of received broadcast packets */ ++ uint64_t rx_bcast_pkts; ++ /* Number of packets discarded in receive path */ ++ uint64_t rx_discard_pkts; ++ /* Number of packets in receive path with errors */ ++ uint64_t rx_error_pkts; ++ /* Number of received bytes for unicast traffic */ ++ uint64_t rx_ucast_bytes; ++ /* Number of received bytes for multicast traffic */ ++ uint64_t rx_mcast_bytes; ++ /* Number of received bytes for broadcast traffic */ ++ uint64_t rx_bcast_bytes; ++ /* Number of aggregated unicast packets */ ++ uint64_t rx_agg_pkts; ++ /* Number of aggregated unicast bytes */ ++ uint64_t rx_agg_bytes; ++ /* Number of aggregation events */ ++ uint64_t rx_agg_events; ++ /* Number of aborted aggregations */ ++ uint64_t rx_agg_aborts; ++}; ++ + struct bnxt { void *bar0; struct rte_eth_dev *eth_dev; @@ -23424,7 +33362,15 @@ index e259c8239d..0a0ecaafa8 100644 struct rte_pci_device *pdev; void *doorbell_base; -@@ -507,19 +513,17 @@ struct bnxt { +@@ -495,7 +549,6 @@ struct bnxt { + #define BNXT_FLAG_PORT_STATS BIT(2) + #define BNXT_FLAG_JUMBO BIT(3) + #define BNXT_FLAG_SHORT_CMD BIT(4) +-#define BNXT_FLAG_UPDATE_HASH BIT(5) + #define BNXT_FLAG_PTP_SUPPORTED BIT(6) + #define BNXT_FLAG_MULTI_HOST BIT(7) + #define BNXT_FLAG_EXT_RX_PORT_STATS BIT(8) +@@ -507,19 +560,19 @@ struct bnxt { #define BNXT_FLAG_STINGRAY BIT(14) #define BNXT_FLAG_FW_RESET BIT(15) #define BNXT_FLAG_FATAL_ERROR BIT(16) @@ -23446,6 +33392,8 @@ index e259c8239d..0a0ecaafa8 100644 +#define BNXT_FLAG_ADV_FLOW_MGMT BIT(23) +#define BNXT_FLAG_NPAR_PF BIT(24) +#define BNXT_FLAG_DFLT_MAC_SET BIT(26) ++#define BNXT_FLAGS_PTP_TIMESYNC_ENABLED BIT(27) ++#define BNXT_FLAGS_PTP_ALARM_SCHEDULED BIT(28) #define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF)) #define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF) -#define BNXT_NPAR(bp) ((bp)->port_partition_type) @@ -23453,24 +33401,42 @@ index e259c8239d..0a0ecaafa8 100644 #define BNXT_MH(bp) ((bp)->flags & BNXT_FLAG_MULTI_HOST) #define BNXT_SINGLE_PF(bp) (BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp)) #define BNXT_USE_CHIMP_MB 0 //For non-CFA commands, everything uses Chimp. -@@ -529,9 +533,14 @@ struct bnxt { +@@ -529,13 +582,23 @@ struct bnxt { #define BNXT_STINGRAY(bp) ((bp)->flags & BNXT_FLAG_STINGRAY) #define BNXT_HAS_NQ(bp) BNXT_CHIP_THOR(bp) #define BNXT_HAS_RING_GRPS(bp) (!BNXT_CHIP_THOR(bp)) +#define BNXT_HAS_DFLT_MAC_SET(bp) ((bp)->flags & BNXT_FLAG_DFLT_MAC_SET) ++#define BNXT_THOR_PTP_TIMESYNC_ENABLED(bp) \ ++ ((bp)->flags & BNXT_FLAGS_PTP_TIMESYNC_ENABLED) + + uint32_t fw_cap; +#define BNXT_FW_CAP_HOT_RESET BIT(0) +#define BNXT_FW_CAP_IF_CHANGE BIT(1) +#define BNXT_FW_CAP_ERROR_RECOVERY BIT(2) +#define BNXT_FW_CAP_ERR_RECOVER_RELOAD BIT(3) ++#define BNXT_FW_CAP_VLAN_TX_INSERT BIT(4) - uint32_t flow_flags; -#define BNXT_FLOW_FLAG_L2_HDR_SRC_FILTER_EN BIT(0) pthread_mutex_t flow_lock; uint32_t vnic_cap_flags; -@@ -584,12 +593,15 @@ struct bnxt { + #define BNXT_VNIC_CAP_COS_CLASSIFY BIT(0) ++#define BNXT_VNIC_CAP_VLAN_RX_STRIP BIT(1) ++#define BNXT_RX_VLAN_STRIP_EN(bp) ((bp)->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP) + unsigned int rx_nr_rings; + unsigned int rx_cp_nr_rings; + unsigned int rx_num_qs_per_vnic; +@@ -563,7 +626,7 @@ struct bnxt { + uint32_t max_ring_grps; + struct bnxt_ring_grp_info *grp_info; + +- unsigned int nr_vnics; ++ uint16_t nr_vnics; + + #define BNXT_GET_DEFAULT_VNIC(bp) (&(bp)->vnic_info[0]) + struct bnxt_vnic_info *vnic_info; +@@ -584,12 +647,15 @@ struct bnxt { rte_iova_t hwrm_short_cmd_req_dma_addr; rte_spinlock_t hwrm_lock; pthread_mutex_t def_cp_lock; @@ -23488,7 +33454,7 @@ index e259c8239d..0a0ecaafa8 100644 /* default HWRM request timeout value */ uint32_t hwrm_cmd_timeout; -@@ -603,18 +615,11 @@ struct bnxt { +@@ -603,18 +669,11 @@ struct bnxt { uint8_t max_q; uint16_t fw_fid; @@ -23507,7 +33473,7 @@ index e259c8239d..0a0ecaafa8 100644 uint16_t max_nq_rings; uint16_t max_l2_ctx; uint16_t max_rx_em_flows; -@@ -628,8 +633,6 @@ struct bnxt { +@@ -628,8 +687,6 @@ struct bnxt { #define BNXT_OUTER_TPID_BD_SHFT 16 uint32_t outer_tpid_bd; struct bnxt_pf_info pf; @@ -23516,8 +33482,20 @@ index e259c8239d..0a0ecaafa8 100644 uint8_t vxlan_port_cnt; uint8_t geneve_port_cnt; uint16_t vxlan_port; -@@ -652,8 +655,37 @@ struct bnxt { +@@ -650,10 +707,55 @@ struct bnxt { + + /* Struct to hold adapter error recovery related info */ struct bnxt_error_recovery_info *recovery_info; ++ struct bnxt_ring_stats *prev_rx_ring_stats; ++ struct bnxt_ring_stats *prev_tx_ring_stats; ++ ++#define BNXT_MAX_MC_ADDRS ((bp)->max_mcast_addr) ++ struct rte_ether_addr *mcast_addr_list; ++ rte_iova_t mc_list_dma_addr; ++ uint32_t nb_mc_addr; ++ uint32_t max_mcast_addr; /* maximum number of mcast filters supported */ ++ ++ struct rte_eth_rss_conf rss_conf; /* RSS configuration. */ }; +static @@ -23540,6 +33518,12 @@ index e259c8239d..0a0ecaafa8 100644 + bp->max_stat_ctx / 2U); + } + ++ /* RSS table size in Thor is 512. ++ * Cap max Rx rings to the same value for RSS. ++ */ ++ if (BNXT_CHIP_THOR(bp)) ++ max_rx_rings = RTE_MIN(max_rx_rings, BNXT_RSS_TBL_SIZE_THOR); ++ + max_tx_rings = RTE_MIN(max_tx_rings, max_rx_rings); + if (max_cp_rings > BNXT_NUM_ASYNC_CPR(bp)) + max_cp_rings -= BNXT_NUM_ASYNC_CPR(bp); @@ -23555,7 +33539,7 @@ index e259c8239d..0a0ecaafa8 100644 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg); int is_bnxt_in_error(struct bnxt *bp); uint16_t bnxt_rss_ctxts(const struct bnxt *bp); -@@ -664,6 +696,13 @@ void bnxt_schedule_fw_health_check(struct bnxt *bp); +@@ -664,6 +766,15 @@ void bnxt_schedule_fw_health_check(struct bnxt *bp); bool is_bnxt_supported(struct rte_eth_dev *dev); bool bnxt_stratus_device(struct bnxt *bp); @@ -23565,11 +33549,13 @@ index e259c8239d..0a0ecaafa8 100644 + uint16_t nb_pkts); +uint16_t bnxt_dummy_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts); -+ ++int bnxt_dev_start_op(struct rte_eth_dev *eth_dev); ++void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev); ++void bnxt_handle_vf_cfg_change(void *arg); extern const struct rte_flow_ops bnxt_flow_ops; #define bnxt_acquire_flow_lock(bp) \ pthread_mutex_lock(&(bp)->flow_lock) -@@ -671,11 +710,23 @@ extern const struct rte_flow_ops bnxt_flow_ops; +@@ -671,11 +782,23 @@ extern const struct rte_flow_ops bnxt_flow_ops; #define bnxt_release_flow_lock(bp) \ pthread_mutex_unlock(&(bp)->flow_lock) @@ -23595,7 +33581,7 @@ index e259c8239d..0a0ecaafa8 100644 + PMD_DRV_LOG_RAW(level, fmt, ## args) #endif diff --git a/dpdk/drivers/net/bnxt/bnxt_cpr.c b/dpdk/drivers/net/bnxt/bnxt_cpr.c -index e6f30fecbf..26c7dae88f 100644 +index e6f30fecbf..d59f87a74f 100644 --- a/dpdk/drivers/net/bnxt/bnxt_cpr.c +++ b/dpdk/drivers/net/bnxt/bnxt_cpr.c @@ -21,7 +21,7 @@ void bnxt_wait_for_device_shutdown(struct bnxt *bp) @@ -23607,7 +33593,46 @@ index e6f30fecbf..26c7dae88f 100644 return; /* Driver has to wait for fw_reset_max_msecs or shutdown bit which comes -@@ -76,6 +76,18 @@ void bnxt_handle_async_event(struct bnxt *bp, +@@ -46,6 +46,22 @@ void bnxt_wait_for_device_shutdown(struct bnxt *bp) + } while (timeout); + } + ++void bnxt_handle_vf_cfg_change(void *arg) ++{ ++ struct bnxt *bp = arg; ++ struct rte_eth_dev *eth_dev = bp->eth_dev; ++ int rc; ++ ++ /* Free and recreate filters with default VLAN */ ++ if (eth_dev->data->dev_started) { ++ bnxt_dev_stop_op(eth_dev); ++ ++ rc = bnxt_dev_start_op(eth_dev); ++ if (rc != 0) ++ PMD_DRV_LOG(ERR, "Failed to start Port:%u\n", eth_dev->data->port_id); ++ } ++} ++ + /* + * Async event handling + */ +@@ -64,6 +80,8 @@ void bnxt_handle_async_event(struct bnxt *bp, + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE: + /* FALLTHROUGH */ + bnxt_link_update_op(bp->eth_dev, 0); ++ _rte_eth_dev_callback_process(bp->eth_dev, ++ RTE_ETH_EVENT_INTR_LSC, NULL); + break; + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD: + PMD_DRV_LOG(INFO, "Async event: PF driver unloaded\n"); +@@ -71,11 +89,25 @@ void bnxt_handle_async_event(struct bnxt *bp, + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE: + PMD_DRV_LOG(INFO, "Async event: VF config changed\n"); + bnxt_hwrm_func_qcfg(bp, NULL); ++ if (BNXT_VF(bp)) ++ rte_eal_alarm_set(1, bnxt_handle_vf_cfg_change, (void *)bp); + break; + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED: PMD_DRV_LOG(INFO, "Port conn async event\n"); break; case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: @@ -23626,7 +33651,7 @@ index e6f30fecbf..26c7dae88f 100644 event_data = rte_le_to_cpu_32(async_cmp->event_data1); /* timestamp_lo/hi values are in units of 100ms */ bp->fw_reset_max_msecs = async_cmp->timestamp_hi ? -@@ -276,3 +288,9 @@ bool bnxt_is_recovery_enabled(struct bnxt *bp) +@@ -276,3 +308,9 @@ bool bnxt_is_recovery_enabled(struct bnxt *bp) return false; } @@ -23637,10 +33662,40 @@ index e6f30fecbf..26c7dae88f 100644 + bp->eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts; +} diff --git a/dpdk/drivers/net/bnxt/bnxt_cpr.h b/dpdk/drivers/net/bnxt/bnxt_cpr.h -index c2880783f6..ff9697f4c8 100644 +index c2880783f6..26cbf97fbf 100644 --- a/dpdk/drivers/net/bnxt/bnxt_cpr.h +++ b/dpdk/drivers/net/bnxt/bnxt_cpr.h -@@ -64,9 +64,9 @@ struct bnxt_db_info; +@@ -8,17 +8,10 @@ + #include + + #include ++#include "hsi_struct_def_dpdk.h" + + struct bnxt_db_info; + +-#define CMP_VALID(cmp, raw_cons, ring) \ +- (!!(rte_le_to_cpu_32(((struct cmpl_base *)(cmp))->info3_v) & \ +- CMPL_BASE_V) == !((raw_cons) & ((ring)->ring_size))) +- +-#define CMPL_VALID(cmp, v) \ +- (!!(rte_le_to_cpu_32(((struct cmpl_base *)(cmp))->info3_v) & \ +- CMPL_BASE_V) == !(v)) +- + #define NQ_CMP_VALID(nqcmp, raw_cons, ring) \ + (!!((nqcmp)->v & rte_cpu_to_le_32(NQ_CN_V)) == \ + !((raw_cons) & ((ring)->ring_size))) +@@ -26,6 +19,10 @@ struct bnxt_db_info; + #define CMP_TYPE(cmp) \ + (((struct cmpl_base *)cmp)->type & CMPL_BASE_TYPE_MASK) + ++/* Get completion length from completion type, in 16-byte units. */ ++#define CMP_LEN(cmp_type) (((cmp_type) & 1) + 1) ++ ++ + #define ADV_RAW_CMP(idx, n) ((idx) + (n)) + #define NEXT_RAW_CMP(idx) ADV_RAW_CMP(idx, 1) + #define RING_CMP(ring, idx) ((idx) & (ring)->ring_mask) +@@ -64,9 +61,9 @@ struct bnxt_db_info; (cons)); \ } while (0) #define B_CP_DIS_DB(cpr, raw_cons) \ @@ -23653,17 +33708,63 @@ index c2880783f6..ff9697f4c8 100644 #define B_CP_DB(cpr, raw_cons, ring_mask) \ rte_write32((DB_CP_FLAGS | \ -@@ -126,4 +126,5 @@ void bnxt_wait_for_device_shutdown(struct bnxt *bp); +@@ -126,4 +123,36 @@ void bnxt_wait_for_device_shutdown(struct bnxt *bp); bool bnxt_is_recovery_enabled(struct bnxt *bp); bool bnxt_is_master_func(struct bnxt *bp); +void bnxt_stop_rxtx(struct bnxt *bp); ++ ++/** ++ * Check validity of a completion ring entry. If the entry is valid, include a ++ * C11 __ATOMIC_ACQUIRE fence to ensure that subsequent loads of fields in the ++ * completion are not hoisted by the compiler or by the CPU to come before the ++ * loading of the "valid" field. ++ * ++ * Note: the caller must not access any fields in the specified completion ++ * entry prior to calling this function. ++ * ++ * @param cmpl ++ * Pointer to an entry in the completion ring. ++ * @param raw_cons ++ * Raw consumer index of entry in completion ring. ++ * @param ring_size ++ * Size of completion ring. ++ */ ++static __rte_always_inline bool ++bnxt_cpr_cmp_valid(const void *cmpl, uint32_t raw_cons, uint32_t ring_size) ++{ ++ const struct cmpl_base *c = cmpl; ++ bool expected, valid; ++ ++ expected = !(raw_cons & ring_size); ++ valid = !!(rte_le_to_cpu_32(c->info3_v) & CMPL_BASE_V); ++ if (valid == expected) { ++ rte_smp_rmb(); ++ return true; ++ } ++ return false; ++} #endif diff --git a/dpdk/drivers/net/bnxt/bnxt_ethdev.c b/dpdk/drivers/net/bnxt/bnxt_ethdev.c -index 41848f36f8..06843d8ddb 100644 +index 41848f36f8..1f50a449d9 100644 --- a/dpdk/drivers/net/bnxt/bnxt_ethdev.c +++ b/dpdk/drivers/net/bnxt/bnxt_ethdev.c -@@ -119,6 +119,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = { +@@ -100,8 +100,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = { + ETH_RSS_NONFRAG_IPV6_TCP | \ + ETH_RSS_NONFRAG_IPV6_UDP) + +-#define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_VLAN_INSERT | \ +- DEV_TX_OFFLOAD_IPV4_CKSUM | \ ++#define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_IPV4_CKSUM | \ + DEV_TX_OFFLOAD_TCP_CKSUM | \ + DEV_TX_OFFLOAD_UDP_CKSUM | \ + DEV_TX_OFFLOAD_TCP_TSO | \ +@@ -114,11 +113,11 @@ static const struct rte_pci_id bnxt_pci_id_map[] = { + DEV_TX_OFFLOAD_MULTI_SEGS) + + #define BNXT_DEV_RX_OFFLOAD_SUPPORT (DEV_RX_OFFLOAD_VLAN_FILTER | \ +- DEV_RX_OFFLOAD_VLAN_STRIP | \ + DEV_RX_OFFLOAD_IPV4_CKSUM | \ DEV_RX_OFFLOAD_UDP_CKSUM | \ DEV_RX_OFFLOAD_TCP_CKSUM | \ DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | \ @@ -23671,16 +33772,17 @@ index 41848f36f8..06843d8ddb 100644 DEV_RX_OFFLOAD_JUMBO_FRAME | \ DEV_RX_OFFLOAD_KEEP_CRC | \ DEV_RX_OFFLOAD_VLAN_EXTEND | \ -@@ -132,6 +133,8 @@ static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); +@@ -132,6 +131,9 @@ static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev); static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev); static void bnxt_cancel_fw_health_check(struct bnxt *bp); +static int bnxt_restore_vlan_filters(struct bnxt *bp); +static void bnxt_dev_recover(void *arg); ++static int bnxt_check_fw_ready(struct bnxt *bp); int is_bnxt_in_error(struct bnxt *bp) { -@@ -151,12 +154,15 @@ int is_bnxt_in_error(struct bnxt *bp) +@@ -151,12 +153,15 @@ int is_bnxt_in_error(struct bnxt *bp) uint16_t bnxt_rss_ctxts(const struct bnxt *bp) { @@ -23698,7 +33800,16 @@ index 41848f36f8..06843d8ddb 100644 } static uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp) -@@ -228,14 +234,109 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) +@@ -205,7 +210,7 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) + if (rc) + goto alloc_mem_err; + +- rc = bnxt_alloc_vnic_attributes(bp); ++ rc = bnxt_alloc_vnic_attributes(bp, reconfig); + if (rc) + goto alloc_mem_err; + +@@ -228,14 +233,144 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) return rc; } @@ -23727,12 +33838,13 @@ index 41848f36f8..06843d8ddb 100644 + if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) { + int j, nr_ctxs = bnxt_rss_ctxts(bp); + ++ /* RSS table size in Thor is 512. ++ * Cap max Rx rings to same value ++ */ + if (bp->rx_nr_rings > BNXT_RSS_TBL_SIZE_THOR) { + PMD_DRV_LOG(ERR, "RxQ cnt %d > reta_size %d\n", + bp->rx_nr_rings, BNXT_RSS_TBL_SIZE_THOR); -+ PMD_DRV_LOG(ERR, -+ "Only queues 0-%d will be in RSS table\n", -+ BNXT_RSS_TBL_SIZE_THOR - 1); ++ goto err_out; + } + + rc = 0; @@ -23789,10 +33901,11 @@ index 41848f36f8..06843d8ddb 100644 + + bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); + -+ if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) -+ bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1); -+ else -+ bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0); ++ rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic, ++ (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) ? ++ true : false); ++ if (rc) ++ goto err_out; + + return 0; +err_out: @@ -23801,6 +33914,39 @@ index 41848f36f8..06843d8ddb 100644 + return rc; +} + ++static void bnxt_free_prev_ring_stats(struct bnxt *bp) ++{ ++ rte_free(bp->prev_rx_ring_stats); ++ rte_free(bp->prev_tx_ring_stats); ++ ++ bp->prev_rx_ring_stats = NULL; ++ bp->prev_tx_ring_stats = NULL; ++} ++ ++static int bnxt_alloc_prev_ring_stats(struct bnxt *bp) ++{ ++ bp->prev_rx_ring_stats = rte_zmalloc("bnxt_prev_rx_ring_stats", ++ sizeof(struct bnxt_ring_stats) * ++ bp->rx_cp_nr_rings, ++ 0); ++ if (bp->prev_rx_ring_stats == NULL) ++ return -ENOMEM; ++ ++ bp->prev_tx_ring_stats = rte_zmalloc("bnxt_prev_tx_ring_stats", ++ sizeof(struct bnxt_ring_stats) * ++ bp->tx_cp_nr_rings, ++ 0); ++ if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats == NULL) ++ goto error; ++ ++ return 0; ++ ++error: ++ bnxt_free_prev_ring_stats(bp); ++ return -ENOMEM; ++} ++ ++ +static int bnxt_init_chip(struct bnxt *bp) +{ struct rte_eth_link new; @@ -23811,7 +33957,7 @@ index 41848f36f8..06843d8ddb 100644 uint32_t intr_vector = 0; uint32_t queue_id, base = BNXT_MISC_VEC_ID; uint32_t vec = BNXT_MISC_VEC_ID; -@@ -303,93 +404,11 @@ static int bnxt_init_chip(struct bnxt *bp) +@@ -303,93 +438,21 @@ static int bnxt_init_chip(struct bnxt *bp) /* VNIC configuration */ for (i = 0; i < bp->nr_vnics; i++) { @@ -23822,7 +33968,8 @@ index 41848f36f8..06843d8ddb 100644 + rc = bnxt_setup_one_vnic(bp, i); if (rc) goto err_out; -- ++ } + - PMD_DRV_LOG(DEBUG, "vnic[%d] = %p vnic->fw_grp_ids = %p\n", - i, vnic, vnic->fw_grp_ids); - @@ -23883,10 +34030,16 @@ index 41848f36f8..06843d8ddb 100644 - PMD_DRV_LOG(DEBUG, - "rxq[%d]->vnic=%p vnic->fw_grp_ids=%p\n", - j, rxq->vnic, rxq->vnic->fw_grp_ids); -- ++ for (j = 0; j < bp->tx_nr_rings; j++) { ++ struct bnxt_tx_queue *txq = bp->tx_queues[j]; + - if (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start) - rxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID; -- } ++ if (!txq->tx_deferred_start) { ++ bp->eth_dev->data->tx_queue_state[j] = ++ RTE_ETH_QUEUE_STATE_STARTED; ++ txq->tx_started = true; + } - - rc = bnxt_vnic_rss_configure(bp, vnic); - if (rc) { @@ -23907,19 +34060,62 @@ index 41848f36f8..06843d8ddb 100644 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL); if (rc) { PMD_DRV_LOG(ERR, -@@ -439,8 +458,11 @@ static int bnxt_init_chip(struct bnxt *bp) +@@ -422,7 +485,7 @@ static int bnxt_init_chip(struct bnxt *bp) + PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues" + " intr_vec", bp->eth_dev->data->nb_rx_queues); + rc = -ENOMEM; +- goto err_disable; ++ goto err_out; + } + PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p " + "intr_handle->nb_efd = %d intr_handle->max_intr = %d\n", +@@ -439,13 +502,16 @@ static int bnxt_init_chip(struct bnxt *bp) /* enable uio/vfio intr/eventfd mapping */ rc = rte_intr_enable(intr_handle); +#ifndef RTE_EXEC_ENV_FREEBSD + /* In FreeBSD OS, nic_uio driver does not support interrupts */ if (rc) - goto err_free; +- goto err_free; ++ goto err_out; +#endif rc = bnxt_get_hwrm_link_config(bp, &new); if (rc) { -@@ -505,7 +527,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, + PMD_DRV_LOG(ERR, "HWRM Get link config failure rc: %x\n", rc); +- goto err_free; ++ goto err_out; + } + + if (!bp->link_info.link_up) { +@@ -453,17 +519,13 @@ static int bnxt_init_chip(struct bnxt *bp) + if (rc) { + PMD_DRV_LOG(ERR, + "HWRM link config failure rc: %x\n", rc); +- goto err_free; ++ goto err_out; + } + } + bnxt_print_link_info(bp->eth_dev); + + return 0; + +-err_free: +- rte_free(intr_handle->intr_vec); +-err_disable: +- rte_intr_efd_disable(intr_handle); + err_out: + /* Some of the error status returned by FW may not be from errno.h */ + if (rc > 0) +@@ -498,19 +560,19 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, + return rc; + + /* MAC Specifics */ +- dev_info->max_mac_addrs = bp->max_l2_ctx; ++ dev_info->max_mac_addrs = RTE_MIN(bp->max_l2_ctx, ETH_NUM_RECEIVE_MAC_ADDR); + dev_info->max_hash_mac_addrs = 0; + + /* PF/VF specifics */ if (BNXT_PF(bp)) dev_info->max_vfs = pdev->max_vfs; @@ -23928,7 +34124,28 @@ index 41848f36f8..06843d8ddb 100644 /* For the sake of symmetry, max_rx_queues = max_tx_queues */ dev_info->max_rx_queues = max_rx_rings; dev_info->max_tx_queues = max_rx_rings; -@@ -535,8 +557,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, + dev_info->reta_size = bnxt_rss_hash_tbl_size(bp); +- dev_info->hash_key_size = 40; ++ dev_info->hash_key_size = HW_HASH_KEY_SIZE; + max_vnics = bp->max_vnics; + + /* MTU specifics */ +@@ -524,10 +586,13 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, + dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT; + if (bp->flags & BNXT_FLAG_PTP_SUPPORTED) + dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP; ++ if (bp->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP) ++ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_VLAN_STRIP; + dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT; ++ if (bp->fw_cap & BNXT_FW_CAP_VLAN_TX_INSERT) ++ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT; + dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; + +- /* *INDENT-OFF* */ + dev_info->default_rxconf = (struct rte_eth_rxconf) { + .rx_thresh = { + .pthresh = 8, +@@ -535,8 +600,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, .wthresh = 0, }, .rx_free_thresh = 32, @@ -23938,7 +34155,48 @@ index 41848f36f8..06843d8ddb 100644 }; dev_info->default_txconf = (struct rte_eth_txconf) { -@@ -758,6 +779,7 @@ bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev) +@@ -550,14 +614,11 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, + }; + eth_dev->data->dev_conf.intr_conf.lsc = 1; + +- eth_dev->data->dev_conf.intr_conf.rxq = 1; + dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC; + dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC; + dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC; + dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC; + +- /* *INDENT-ON* */ +- + /* + * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim + * need further investigation. +@@ -597,6 +658,7 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) + { + struct bnxt *bp = eth_dev->data->dev_private; + uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; ++ struct rte_eth_rss_conf *rss_conf = ð_dev->data->dev_conf.rx_adv_conf.rss_conf; + int rc; + + bp->rx_queues = (void *)eth_dev->data->rx_queues; +@@ -678,6 +740,17 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) + rx_offloads |= DEV_RX_OFFLOAD_RSS_HASH; + eth_dev->data->dev_conf.rxmode.offloads = rx_offloads; + ++ /* application provides the hash key to program */ ++ if (rss_conf->rss_key != NULL) { ++ if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) ++ PMD_DRV_LOG(WARNING, "port %u RSS key len must be %d bytes long", ++ eth_dev->data->port_id, HW_HASH_KEY_SIZE); ++ else ++ memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE); ++ } ++ bp->rss_conf.rss_key_len = HW_HASH_KEY_SIZE; ++ bp->rss_conf.rss_hf = rss_conf->rss_hf; ++ + if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { + eth_dev->data->mtu = + eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - +@@ -758,6 +831,7 @@ bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev) DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM | DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | @@ -23946,16 +34204,39 @@ index 41848f36f8..06843d8ddb 100644 DEV_RX_OFFLOAD_RSS_HASH | DEV_RX_OFFLOAD_VLAN_FILTER))) { PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n", -@@ -827,7 +849,7 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) +@@ -815,6 +889,11 @@ static int bnxt_handle_if_change_status(struct bnxt *bp) + + /* clear fatal flag so that re-init happens */ + bp->flags &= ~BNXT_FLAG_FATAL_ERROR; ++ ++ rc = bnxt_check_fw_ready(bp); ++ if (rc) ++ return rc; ++ + rc = bnxt_init_resources(bp, true); + + bp->flags &= ~BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE; +@@ -822,17 +901,12 @@ static int bnxt_handle_if_change_status(struct bnxt *bp) + return rc; + } + +-static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) ++int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) + { struct bnxt *bp = eth_dev->data->dev_private; uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; int vlan_mask = 0; - int rc; +- +- if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) { +- PMD_DRV_LOG(ERR, "Queues are not configured yet!\n"); +- return -EINVAL; +- } + int rc, retry_cnt = BNXT_IF_CHANGE_RETRY_COUNT; - if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) { - PMD_DRV_LOG(ERR, "Queues are not configured yet!\n"); -@@ -840,14 +862,23 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) + if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) { + PMD_DRV_LOG(ERR, +@@ -840,21 +914,35 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS); } @@ -23986,15 +34267,19 @@ index 41848f36f8..06843d8ddb 100644 bnxt_enable_int(bp); rc = bnxt_init_chip(bp); -@@ -855,6 +886,7 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) + if (rc) goto error; ++ rc = bnxt_alloc_prev_ring_stats(bp); ++ if (rc) ++ goto error; ++ eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev); + eth_dev->data->dev_started = 1; bnxt_link_update_op(eth_dev, 1); -@@ -869,19 +901,16 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) +@@ -869,19 +957,17 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev); eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev); @@ -24013,11 +34298,106 @@ index 41848f36f8..06843d8ddb 100644 bnxt_free_tx_mbufs(bp); bnxt_free_rx_mbufs(bp); + bnxt_hwrm_if_change(bp, false); ++ bnxt_free_prev_ring_stats(bp); + eth_dev->data->dev_started = 0; return rc; } -@@ -916,6 +945,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) +@@ -890,6 +976,9 @@ static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev) + struct bnxt *bp = eth_dev->data->dev_private; + int rc = 0; + ++ if (!BNXT_SINGLE_PF(bp)) ++ return -ENOTSUP; ++ + if (!bp->link_info.link_up) + rc = bnxt_set_hwrm_link_config(bp, true); + if (!rc) +@@ -903,6 +992,9 @@ static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) + { + struct bnxt *bp = eth_dev->data->dev_private; + ++ if (!BNXT_SINGLE_PF(bp)) ++ return -ENOTSUP; ++ + eth_dev->data->dev_link.link_status = 0; + bnxt_set_hwrm_link_config(bp, false); + bp->link_info.link_up = 0; +@@ -910,12 +1002,80 @@ static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) + return 0; + } + ++static void bnxt_ptp_get_current_time(void *arg) ++{ ++ struct bnxt *bp = arg; ++ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; ++ int rc; ++ ++ rc = is_bnxt_in_error(bp); ++ if (rc) ++ return; ++ ++ if (!ptp) ++ return; ++ ++ bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, ++ &ptp->current_time); ++ ++ rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp); ++ if (rc != 0) { ++ PMD_DRV_LOG(ERR, "Failed to re-schedule PTP alarm\n"); ++ bp->flags &= ~BNXT_FLAGS_PTP_ALARM_SCHEDULED; ++ } ++} ++ ++static int bnxt_schedule_ptp_alarm(struct bnxt *bp) ++{ ++ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; ++ int rc; ++ ++ if (bp->flags & BNXT_FLAGS_PTP_ALARM_SCHEDULED) ++ return 0; ++ ++ bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, ++ &ptp->current_time); ++ ++ rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp); ++ return rc; ++} ++ ++static void bnxt_cancel_ptp_alarm(struct bnxt *bp) ++{ ++ if (bp->flags & BNXT_FLAGS_PTP_ALARM_SCHEDULED) { ++ rte_eal_alarm_cancel(bnxt_ptp_get_current_time, (void *)bp); ++ bp->flags &= ~BNXT_FLAGS_PTP_ALARM_SCHEDULED; ++ } ++} ++ ++static void bnxt_ptp_stop(struct bnxt *bp) ++{ ++ bnxt_cancel_ptp_alarm(bp); ++ bp->flags &= ~BNXT_FLAGS_PTP_TIMESYNC_ENABLED; ++} ++ ++static int bnxt_ptp_start(struct bnxt *bp) ++{ ++ int rc; ++ ++ rc = bnxt_schedule_ptp_alarm(bp); ++ if (rc != 0) { ++ PMD_DRV_LOG(ERR, "Failed to schedule PTP alarm\n"); ++ } else { ++ bp->flags |= BNXT_FLAGS_PTP_TIMESYNC_ENABLED; ++ bp->flags |= BNXT_FLAGS_PTP_ALARM_SCHEDULED; ++ } ++ ++ return rc; ++} ++ + /* Unload the driver, release resources */ +-static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) ++void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) + { struct bnxt *bp = eth_dev->data->dev_private; struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; @@ -24025,7 +34405,7 @@ index 41848f36f8..06843d8ddb 100644 eth_dev->data->dev_started = 0; /* Prevent crashes when queues are still in use */ -@@ -929,18 +959,16 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) +@@ -929,18 +1089,19 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) bnxt_cancel_fw_health_check(bp); @@ -24033,6 +34413,16 @@ index 41848f36f8..06843d8ddb 100644 - if (bp->eth_dev->data->dev_started) { - /* TBD: STOP HW queues DMA */ - eth_dev->data->dev_link.link_status = 0; +- } +- bnxt_dev_set_link_down_op(eth_dev); ++ if (BNXT_THOR_PTP_TIMESYNC_ENABLED(bp)) ++ bnxt_cancel_ptp_alarm(bp); + +- /* Wait for link to be reset and the async notification to process. +- * During reset recovery, there is no need to wait +- */ +- if (!is_bnxt_in_error(bp)) +- rte_delay_ms(BNXT_LINK_WAIT_INTERVAL * 2); + /* Do not bring link down during reset recovery */ + if (!is_bnxt_in_error(bp)) { + bnxt_dev_set_link_down_op(eth_dev); @@ -24042,41 +34432,56 @@ index 41848f36f8..06843d8ddb 100644 + /* clear the recorded link status */ + memset(&link, 0, sizeof(link)); + rte_eth_linkstatus_set(eth_dev, &link); - } -- bnxt_dev_set_link_down_op(eth_dev); -- -- /* Wait for link to be reset and the async notification to process. -- * During reset recovery, there is no need to wait -- */ -- if (!is_bnxt_in_error(bp)) -- rte_delay_ms(BNXT_LINK_WAIT_INTERVAL * 2); ++ } /* Clean queue intr-vector mapping */ rte_intr_efd_disable(intr_handle); -@@ -955,8 +983,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) +@@ -955,8 +1116,8 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) /* Process any remaining notifications in default completion queue */ bnxt_int_handler(eth_dev); bnxt_shutdown_nic(bp); - bnxt_hwrm_if_change(bp, 0); - bp->dev_stopped = 1; + bnxt_hwrm_if_change(bp, false); ++ bnxt_free_prev_ring_stats(bp); bp->rx_cosq_cnt = 0; } -@@ -964,7 +991,11 @@ static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) +@@ -964,7 +1125,15 @@ static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; - if (bp->dev_stopped == 0) ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + /* cancel the recovery handler before remove dev */ + rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp); + rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp); ++ rte_eal_alarm_cancel(bnxt_handle_vf_cfg_change, (void *)bp); + + if (eth_dev->data->dev_started) bnxt_dev_stop_op(eth_dev); if (eth_dev->data->mac_addrs != NULL) { -@@ -1074,7 +1105,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, +@@ -1007,8 +1176,6 @@ static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, + STAILQ_REMOVE(&vnic->filter, filter, + bnxt_filter_info, next); + bnxt_hwrm_clear_l2_filter(bp, filter); +- filter->mac_index = INVALID_MAC_INDEX; +- memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN); + bnxt_free_filter(bp, filter); + } + filter = temp_filter; +@@ -1055,7 +1222,6 @@ static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic, + else + STAILQ_INSERT_TAIL(&vnic->filter, filter, next); + } else { +- memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN); + bnxt_free_filter(bp, filter); + } + +@@ -1074,7 +1240,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, if (rc) return rc; @@ -24085,7 +34490,7 @@ index 41848f36f8..06843d8ddb 100644 PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n"); return -ENOTSUP; } -@@ -1084,6 +1115,10 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, +@@ -1084,6 +1250,10 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, return -EINVAL; } @@ -24096,7 +34501,7 @@ index 41848f36f8..06843d8ddb 100644 rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index, pool); return rc; -@@ -1094,7 +1129,8 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) +@@ -1094,7 +1264,8 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) int rc = 0; struct bnxt *bp = eth_dev->data->dev_private; struct rte_eth_link new; @@ -24106,7 +34511,7 @@ index 41848f36f8..06843d8ddb 100644 rc = is_bnxt_in_error(bp); if (rc) -@@ -1118,6 +1154,12 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) +@@ -1118,16 +1289,17 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) rte_delay_ms(BNXT_LINK_WAIT_INTERVAL); } while (cnt--); @@ -24119,7 +34524,17 @@ index 41848f36f8..06843d8ddb 100644 out: /* Timed out or success */ if (new.link_status != eth_dev->data->dev_link.link_status || -@@ -1145,6 +1187,10 @@ static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) + new.link_speed != eth_dev->data->dev_link.link_speed) { + rte_eth_linkstatus_set(eth_dev, &new); +- +- _rte_eth_dev_callback_process(eth_dev, +- RTE_ETH_EVENT_INTR_LSC, +- NULL); +- + bnxt_print_link_info(eth_dev); + } + +@@ -1145,6 +1317,10 @@ static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) if (rc) return rc; @@ -24130,7 +34545,7 @@ index 41848f36f8..06843d8ddb 100644 if (bp->vnic_info == NULL) return 0; -@@ -1170,6 +1216,10 @@ static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) +@@ -1170,6 +1346,10 @@ static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) if (rc) return rc; @@ -24141,7 +34556,7 @@ index 41848f36f8..06843d8ddb 100644 if (bp->vnic_info == NULL) return 0; -@@ -1195,6 +1245,10 @@ static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) +@@ -1195,6 +1375,10 @@ static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) if (rc) return rc; @@ -24152,7 +34567,7 @@ index 41848f36f8..06843d8ddb 100644 if (bp->vnic_info == NULL) return 0; -@@ -1220,6 +1274,10 @@ static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) +@@ -1220,6 +1404,10 @@ static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) if (rc) return rc; @@ -24163,7 +34578,7 @@ index 41848f36f8..06843d8ddb 100644 if (bp->vnic_info == NULL) return 0; -@@ -1319,8 +1377,8 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, +@@ -1319,8 +1507,8 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, } } @@ -24174,20 +34589,55 @@ index 41848f36f8..06843d8ddb 100644 } static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, -@@ -1399,7 +1457,9 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, +@@ -1337,7 +1525,6 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, + if (rc) + return rc; + +- /* Retrieve from the default VNIC */ + if (!vnic) + return -EINVAL; + if (!vnic->rss_table) +@@ -1371,6 +1558,9 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, + } } - bp->flags |= BNXT_FLAG_UPDATE_HASH; -- memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf)); -+ memcpy(ð_dev->data->dev_conf.rx_adv_conf.rss_conf, -+ rss_conf, -+ sizeof(*rss_conf)); ++ if (BNXT_THOR_PTP_TIMESYNC_ENABLED(bp)) ++ bnxt_schedule_ptp_alarm(bp); ++ + return 0; + } + +@@ -1398,13 +1588,13 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, + return -EINVAL; + } +- bp->flags |= BNXT_FLAG_UPDATE_HASH; +- memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf)); +- /* Update the default RSS VNIC(s) */ vnic = &bp->vnic_info[0]; -@@ -1420,8 +1480,8 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, + vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf); + ++ /* Cache the hash function */ ++ bp->rss_conf.rss_hf = rss_conf->rss_hf; ++ + /* + * If hashkey is not specified, use the previously configured + * hashkey +@@ -1414,14 +1604,18 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, + + if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) { + PMD_DRV_LOG(ERR, +- "Invalid hashkey length, should be 16 bytes\n"); ++ "Invalid hashkey length, should be %d bytes\n", ++ HW_HASH_KEY_SIZE); + return -EINVAL; + } memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len); ++ /* Cache the hash key */ ++ memcpy(bp->rss_conf.rss_key, rss_conf->rss_key, HW_HASH_KEY_SIZE); ++ rss_config: - bnxt_hwrm_vnic_rss_cfg(bp, vnic); - return 0; @@ -24196,7 +34646,7 @@ index 41848f36f8..06843d8ddb 100644 } static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, -@@ -1476,7 +1536,7 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, +@@ -1476,7 +1670,7 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, } if (hash_types) { PMD_DRV_LOG(ERR, @@ -24205,7 +34655,62 @@ index 41848f36f8..06843d8ddb 100644 vnic->hash_type); return -ENOTSUP; } -@@ -1808,6 +1868,11 @@ static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, +@@ -1532,8 +1726,9 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, + if (rc) + return rc; + +- if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { +- PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n"); ++ if (!BNXT_SINGLE_PF(bp)) { ++ PMD_DRV_LOG(ERR, ++ "Flow Control Settings cannot be modified on VF or on shared PF\n"); + return -ENOTSUP; + } + +@@ -1608,7 +1803,6 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, + } + tunnel_type = + HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN; +- bp->vxlan_port_cnt++; + break; + case RTE_TUNNEL_TYPE_GENEVE: + if (bp->geneve_port_cnt) { +@@ -1623,7 +1817,6 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, + } + tunnel_type = + HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE; +- bp->geneve_port_cnt++; + break; + default: + PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); +@@ -1631,6 +1824,18 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, + } + rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port, + tunnel_type); ++ ++ if (rc != 0) ++ return rc; ++ ++ if (tunnel_type == ++ HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN) ++ bp->vxlan_port_cnt++; ++ ++ if (tunnel_type == ++ HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE) ++ bp->geneve_port_cnt++; ++ + return rc; + } + +@@ -1781,7 +1986,6 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id) + /* Free the newly allocated filter as we were + * not able to create the filter in hardware. + */ +- filter->fw_l2_filter_id = UINT64_MAX; + bnxt_free_filter(bp, filter); + return rc; + } +@@ -1808,6 +2012,11 @@ static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, if (rc) return rc; @@ -24217,7 +34722,15 @@ index 41848f36f8..06843d8ddb 100644 /* These operations apply to ALL existing MAC/VLAN filters */ if (on) return bnxt_add_vlan_filter(bp, vlan_id); -@@ -1841,18 +1906,12 @@ static int bnxt_del_dflt_mac_filter(struct bnxt *bp, +@@ -1831,7 +2040,6 @@ static int bnxt_del_dflt_mac_filter(struct bnxt *bp, + STAILQ_REMOVE(&vnic->filter, filter, + bnxt_filter_info, next); + bnxt_free_filter(bp, filter); +- filter->fw_l2_filter_id = UINT64_MAX; + } + return rc; + } +@@ -1841,18 +2049,12 @@ static int bnxt_del_dflt_mac_filter(struct bnxt *bp, } static int @@ -24237,7 +34750,7 @@ index 41848f36f8..06843d8ddb 100644 vnic = BNXT_GET_DEFAULT_VNIC(bp); if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) { /* Remove any VLAN filters programmed */ -@@ -1876,18 +1935,102 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) +@@ -1876,18 +2078,106 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n", !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)); @@ -24258,6 +34771,10 @@ index 41848f36f8..06843d8ddb 100644 + } + bnxt_del_dflt_mac_filter(bp, vnic); + ++ rc = bnxt_hwrm_vnic_ctx_free(bp, vnic); ++ if (rc) ++ return rc; ++ + rc = bnxt_hwrm_vnic_free(bp, vnic); + if (rc) + return rc; @@ -24350,7 +34867,7 @@ index 41848f36f8..06843d8ddb 100644 } if (mask & ETH_VLAN_EXTEND_MASK) { -@@ -1965,7 +2108,6 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, +@@ -1965,7 +2255,6 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct bnxt *bp = dev->data->dev_private; /* Default Filter is tied to VNIC 0 */ struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; @@ -24358,7 +34875,7 @@ index 41848f36f8..06843d8ddb 100644 int rc; rc = is_bnxt_in_error(bp); -@@ -1978,32 +2120,27 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, +@@ -1978,32 +2267,27 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, if (rte_is_zero_ether_addr(addr)) return -EINVAL; @@ -24407,7 +34924,45 @@ index 41848f36f8..06843d8ddb 100644 } static int -@@ -2053,10 +2190,11 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) +@@ -2012,9 +2296,8 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, + uint32_t nb_mc_addr) + { + struct bnxt *bp = eth_dev->data->dev_private; +- char *mc_addr_list = (char *)mc_addr_set; + struct bnxt_vnic_info *vnic; +- uint32_t off = 0, i = 0; ++ uint32_t i = 0; + int rc; + + rc = is_bnxt_in_error(bp); +@@ -2023,6 +2306,8 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, + + vnic = BNXT_GET_DEFAULT_VNIC(bp); + ++ bp->nb_mc_addr = nb_mc_addr; ++ + if (nb_mc_addr > BNXT_MAX_MC_ADDRS) { + vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; + goto allmulti; +@@ -2030,14 +2315,10 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, + + /* TODO Check for Duplicate mcast addresses */ + vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; +- for (i = 0; i < nb_mc_addr; i++) { +- memcpy(vnic->mc_list + off, &mc_addr_list[i], +- RTE_ETHER_ADDR_LEN); +- off += RTE_ETHER_ADDR_LEN; +- } ++ for (i = 0; i < nb_mc_addr; i++) ++ rte_ether_addr_copy(&mc_addr_set[i], &bp->mcast_addr_list[i]); + +- vnic->mc_addr_cnt = i; +- if (vnic->mc_addr_cnt) ++ if (bp->nb_mc_addr) + vnic->flags |= BNXT_VNIC_INFO_MCAST; + else + vnic->flags &= ~BNXT_VNIC_INFO_MCAST; +@@ -2053,10 +2334,11 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) uint8_t fw_major = (bp->fw_ver >> 24) & 0xff; uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff; uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff; @@ -24421,7 +34976,7 @@ index 41848f36f8..06843d8ddb 100644 ret += 1; /* add the size of '\0' */ if (fw_size < (uint32_t)ret) -@@ -2082,8 +2220,9 @@ bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, +@@ -2082,8 +2364,9 @@ bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, qinfo->nb_desc = rxq->nb_rx_desc; qinfo->conf.rx_free_thresh = rxq->rx_free_thresh; @@ -24432,7 +34987,7 @@ index 41848f36f8..06843d8ddb 100644 } static void -@@ -2107,6 +2246,7 @@ bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, +@@ -2107,6 +2390,7 @@ bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, qinfo->conf.tx_free_thresh = txq->tx_free_thresh; qinfo->conf.tx_rs_thresh = 0; qinfo->conf.tx_deferred_start = txq->tx_deferred_start; @@ -24440,7 +34995,475 @@ index 41848f36f8..06843d8ddb 100644 } int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) -@@ -3500,9 +3640,9 @@ bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) +@@ -2144,6 +2428,10 @@ int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) + } + #endif + ++ /* Is there a change in mtu setting? */ ++ if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size) ++ return rc; ++ + if (new_mtu > RTE_ETHER_MTU) { + bp->flags |= BNXT_FLAG_JUMBO; + bp->eth_dev->data->dev_conf.rxmode.offloads |= +@@ -2154,10 +2442,6 @@ int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) + bp->flags &= ~BNXT_FLAG_JUMBO; + } + +- /* Is there a change in mtu setting? */ +- if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size) +- return rc; +- + for (i = 0; i < bp->nr_vnics; i++) { + struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; + uint16_t size = 0; +@@ -2196,9 +2480,8 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on) + if (rc) + return rc; + +- if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { +- PMD_DRV_LOG(ERR, +- "PVID cannot be modified for this function\n"); ++ if (!BNXT_SINGLE_PF(bp)) { ++ PMD_DRV_LOG(ERR, "PVID cannot be modified on VF or on shared PF\n"); + return -ENOTSUP; + } + bp->vlan = on ? pvid : 0; +@@ -2239,8 +2522,8 @@ static uint32_t + bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) + { + struct bnxt *bp = (struct bnxt *)dev->data->dev_private; +- uint32_t desc = 0, raw_cons = 0, cons; + struct bnxt_cp_ring_info *cpr; ++ uint32_t desc = 0, raw_cons, cp_ring_size; + struct bnxt_rx_queue *rxq; + struct rx_pkt_cmpl *rxcmp; + int rc; +@@ -2249,20 +2532,48 @@ bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) + if (rc) + return rc; + +- rxq = dev->data->rx_queues[rx_queue_id]; +- cpr = rxq->cp_ring; +- raw_cons = cpr->cp_raw_cons; ++ rxq = dev->data->rx_queues[rx_queue_id]; ++ cpr = rxq->cp_ring; ++ raw_cons = cpr->cp_raw_cons; ++ cp_ring_size = cpr->cp_ring_struct->ring_size; ++ ++ while (1) { ++ uint32_t agg_cnt, cons, cmpl_type; ++ ++ cons = RING_CMP(cpr->cp_ring_struct, raw_cons); ++ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; ++ ++ if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size)) ++ break; ++ ++ cmpl_type = CMP_TYPE(rxcmp); ++ ++ switch (cmpl_type) { ++ case CMPL_BASE_TYPE_RX_L2: ++ agg_cnt = BNXT_RX_L2_AGG_BUFS(rxcmp); ++ raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt; ++ desc++; ++ break; ++ ++ case CMPL_BASE_TYPE_RX_TPA_END: ++ if (BNXT_CHIP_THOR(rxq->bp)) { ++ struct rx_tpa_v2_end_cmpl_hi *p5_tpa_end; ++ ++ p5_tpa_end = (void *)rxcmp; ++ agg_cnt = BNXT_TPA_END_AGG_BUFS_TH(p5_tpa_end); ++ } else { ++ struct rx_tpa_end_cmpl *tpa_end; + +- while (1) { +- cons = RING_CMP(cpr->cp_ring_struct, raw_cons); +- rte_prefetch0(&cpr->cp_desc_ring[cons]); +- rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; ++ tpa_end = (void *)rxcmp; ++ agg_cnt = BNXT_TPA_END_AGG_BUFS(tpa_end); ++ } + +- if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) { +- break; +- } else { +- raw_cons++; ++ raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt; + desc++; ++ break; ++ ++ default: ++ raw_cons += CMP_LEN(cmpl_type); + } + } + +@@ -2272,42 +2583,78 @@ bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) + static int + bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset) + { +- struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue; +- struct bnxt_rx_ring_info *rxr; ++ struct bnxt_rx_queue *rxq = rx_queue; + struct bnxt_cp_ring_info *cpr; + struct bnxt_sw_rx_bd *rx_buf; ++ struct bnxt_rx_ring_info *rxr; ++ uint32_t desc, raw_cons, cp_ring_size; ++ struct bnxt *bp = rxq->bp; + struct rx_pkt_cmpl *rxcmp; +- uint32_t cons, cp_cons; + int rc; + +- if (!rxq) +- return -EINVAL; +- +- rc = is_bnxt_in_error(rxq->bp); ++ rc = is_bnxt_in_error(bp); + if (rc) + return rc; + +- cpr = rxq->cp_ring; +- rxr = rxq->rx_ring; +- + if (offset >= rxq->nb_rx_desc) + return -EINVAL; + +- cons = RING_CMP(cpr->cp_ring_struct, offset); +- cp_cons = cpr->cp_raw_cons; +- rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; ++ rxr = rxq->rx_ring; ++ cpr = rxq->cp_ring; ++ cp_ring_size = cpr->cp_ring_struct->ring_size; + +- if (cons > cp_cons) { +- if (CMPL_VALID(rxcmp, cpr->valid)) +- return RTE_ETH_RX_DESC_DONE; +- } else { +- if (CMPL_VALID(rxcmp, !cpr->valid)) +- return RTE_ETH_RX_DESC_DONE; +- } +- rx_buf = &rxr->rx_buf_ring[cons]; +- if (rx_buf->mbuf == NULL) +- return RTE_ETH_RX_DESC_UNAVAIL; ++ raw_cons = cpr->cp_raw_cons; ++ desc = 0; ++ while (1) { ++ uint32_t agg_cnt, cons, cmpl_type; ++ ++ cons = RING_CMP(cpr->cp_ring_struct, raw_cons); ++ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; ++ ++ if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size)) ++ break; + ++ cmpl_type = CMP_TYPE(rxcmp); ++ ++ switch (cmpl_type) { ++ case CMPL_BASE_TYPE_RX_L2: ++ if (desc == offset) { ++ cons = rxcmp->opaque; ++ rx_buf = &rxr->rx_buf_ring[cons]; ++ if (rx_buf->mbuf != NULL) ++ return RTE_ETH_RX_DESC_DONE; ++ else ++ return RTE_ETH_RX_DESC_UNAVAIL; ++ } ++ agg_cnt = BNXT_RX_L2_AGG_BUFS(rxcmp); ++ raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt; ++ desc++; ++ break; ++ ++ case CMPL_BASE_TYPE_RX_TPA_END: ++ if (desc == offset) ++ return RTE_ETH_RX_DESC_DONE; ++ ++ if (BNXT_CHIP_THOR(rxq->bp)) { ++ struct rx_tpa_v2_end_cmpl_hi *p5_tpa_end; ++ ++ p5_tpa_end = (void *)rxcmp; ++ agg_cnt = BNXT_TPA_END_AGG_BUFS_TH(p5_tpa_end); ++ } else { ++ struct rx_tpa_end_cmpl *tpa_end; ++ ++ tpa_end = (void *)rxcmp; ++ agg_cnt = BNXT_TPA_END_AGG_BUFS(tpa_end); ++ } ++ ++ raw_cons = raw_cons + CMP_LEN(cmpl_type) + agg_cnt; ++ desc++; ++ break; ++ ++ default: ++ raw_cons += CMP_LEN(cmpl_type); ++ } ++ } + + return RTE_ETH_RX_DESC_AVAIL; + } +@@ -2316,41 +2663,47 @@ static int + bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset) + { + struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; +- struct bnxt_tx_ring_info *txr; +- struct bnxt_cp_ring_info *cpr; +- struct bnxt_sw_tx_bd *tx_buf; +- struct tx_pkt_cmpl *txcmp; +- uint32_t cons, cp_cons; ++ struct bnxt_cp_ring_info *cpr = txq->cp_ring; ++ uint32_t ring_mask, raw_cons, nb_tx_pkts = 0; ++ struct cmpl_base *cp_desc_ring; + int rc; + +- if (!txq) +- return -EINVAL; +- + rc = is_bnxt_in_error(txq->bp); + if (rc) + return rc; + +- cpr = txq->cp_ring; +- txr = txq->tx_ring; +- + if (offset >= txq->nb_tx_desc) + return -EINVAL; + +- cons = RING_CMP(cpr->cp_ring_struct, offset); +- txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; +- cp_cons = cpr->cp_raw_cons; ++ /* Return "desc done" if descriptor is available for use. */ ++ if (bnxt_tx_bds_in_hw(txq) <= offset) ++ return RTE_ETH_TX_DESC_DONE; + +- if (cons > cp_cons) { +- if (CMPL_VALID(txcmp, cpr->valid)) +- return RTE_ETH_TX_DESC_UNAVAIL; +- } else { +- if (CMPL_VALID(txcmp, !cpr->valid)) +- return RTE_ETH_TX_DESC_UNAVAIL; ++ raw_cons = cpr->cp_raw_cons; ++ cp_desc_ring = cpr->cp_desc_ring; ++ ring_mask = cpr->cp_ring_struct->ring_mask; ++ ++ /* Check to see if hw has posted a completion for the descriptor. */ ++ while (1) { ++ struct tx_cmpl *txcmp; ++ uint32_t cons; ++ ++ cons = RING_CMPL(ring_mask, raw_cons); ++ txcmp = (struct tx_cmpl *)&cp_desc_ring[cons]; ++ ++ if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1)) ++ break; ++ ++ if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2) ++ nb_tx_pkts += rte_le_to_cpu_32(txcmp->opaque); ++ ++ if (nb_tx_pkts > offset) ++ return RTE_ETH_TX_DESC_DONE; ++ ++ raw_cons = NEXT_RAW_CMP(raw_cons); + } +- tx_buf = &txr->tx_buf_ring[cons]; +- if (tx_buf->mbuf == NULL) +- return RTE_ETH_TX_DESC_DONE; + ++ /* Descriptor is pending transmit, not yet completed by hardware. */ + return RTE_ETH_TX_DESC_FULL; + } + +@@ -2705,14 +3058,11 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp, + + STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next); + bnxt_free_filter(bp, mfilter); +- mfilter->fw_l2_filter_id = -1; + bnxt_free_filter(bp, bfilter); +- bfilter->fw_l2_filter_id = -1; + } + + return 0; + free_filter: +- bfilter->fw_l2_filter_id = -1; + bnxt_free_filter(bp, bfilter); + return ret; + } +@@ -3110,7 +3460,6 @@ bnxt_fdir_filter(struct rte_eth_dev *dev, + STAILQ_REMOVE(&vnic->filter, match, + bnxt_filter_info, next); + bnxt_free_filter(bp, match); +- filter->fw_l2_filter_id = -1; + bnxt_free_filter(bp, filter); + } + break; +@@ -3143,7 +3492,6 @@ bnxt_fdir_filter(struct rte_eth_dev *dev, + return ret; + + free_filter: +- filter->fw_l2_filter_id = -1; + bnxt_free_filter(bp, filter); + return ret; + } +@@ -3287,19 +3635,49 @@ static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts) + ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L])); + *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32; ++ rte_read32((uint8_t *)bp->bar0 + ptp->tx_mapped_regs[BNXT_PTP_TX_SEQ]); + + return 0; + } + +-static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) ++static int bnxt_clr_rx_ts(struct bnxt *bp, uint64_t *last_ts) + { + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + struct bnxt_pf_info *pf = &bp->pf; + uint16_t port_id; ++ int i = 0; + uint32_t fifo; + +- if (!ptp) +- return -ENODEV; ++ if (!ptp || BNXT_CHIP_THOR(bp)) ++ return -EINVAL; ++ ++ port_id = pf->port_id; ++ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + ++ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); ++ while ((fifo & BNXT_PTP_RX_FIFO_PENDING) && (i < BNXT_PTP_RX_PND_CNT)) { ++ rte_write32(1 << port_id, (uint8_t *)bp->bar0 + ++ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]); ++ fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + ++ ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); ++ *last_ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + ++ ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L])); ++ *last_ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + ++ ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32; ++ i++; ++ } ++ ++ if (i >= BNXT_PTP_RX_PND_CNT) ++ return -EBUSY; ++ ++ return 0; ++} ++ ++static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) ++{ ++ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; ++ struct bnxt_pf_info *pf = &bp->pf; ++ uint16_t port_id; ++ uint32_t fifo; + + fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); +@@ -3312,10 +3690,8 @@ static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) + + fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); +- if (fifo & BNXT_PTP_RX_FIFO_PENDING) { +-/* bnxt_clr_rx_ts(bp); TBD */ +- return -EBUSY; +- } ++ if (fifo & BNXT_PTP_RX_FIFO_PENDING) ++ return bnxt_clr_rx_ts(bp, ts); + + *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L])); +@@ -3333,11 +3709,13 @@ bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + ns = rte_timespec_to_ns(ts); + /* Set the timecounters to a new value. */ + ptp->tc.nsec = ns; ++ ptp->tx_tstamp_tc.nsec = ns; ++ ptp->rx_tstamp_tc.nsec = ns; + + return 0; + } +@@ -3351,7 +3729,7 @@ bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) + int rc = 0; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + if (BNXT_CHIP_THOR(bp)) + rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, +@@ -3373,7 +3751,7 @@ bnxt_timesync_enable(struct rte_eth_dev *dev) + int rc; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + ptp->rx_filter = 1; + ptp->tx_tstamp_en = 1; +@@ -3401,8 +3779,10 @@ bnxt_timesync_enable(struct rte_eth_dev *dev) + + if (!BNXT_CHIP_THOR(bp)) + bnxt_map_ptp_regs(bp); ++ else ++ rc = bnxt_ptp_start(bp); + +- return 0; ++ return rc; + } + + static int +@@ -3412,7 +3792,7 @@ bnxt_timesync_disable(struct rte_eth_dev *dev) + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + ptp->rx_filter = 0; + ptp->tx_tstamp_en = 0; +@@ -3422,6 +3802,8 @@ bnxt_timesync_disable(struct rte_eth_dev *dev) + + if (!BNXT_CHIP_THOR(bp)) + bnxt_unmap_ptp_regs(bp); ++ else ++ bnxt_ptp_stop(bp); + + return 0; + } +@@ -3437,7 +3819,7 @@ bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev, + uint64_t ns; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + if (BNXT_CHIP_THOR(bp)) + rx_tstamp_cycles = ptp->rx_timestamp; +@@ -3460,7 +3842,7 @@ bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev, + int rc = 0; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + if (BNXT_CHIP_THOR(bp)) + rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX, +@@ -3481,9 +3863,11 @@ bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + + if (!ptp) +- return 0; ++ return -ENOTSUP; + + ptp->tc.nsec += delta; ++ ptp->tx_tstamp_tc.nsec += delta; ++ ptp->rx_tstamp_tc.nsec += delta; + + return 0; + } +@@ -3500,9 +3884,9 @@ bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) if (rc) return rc; @@ -24453,7 +35476,7 @@ index 41848f36f8..06843d8ddb 100644 rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length); if (rc != 0) -@@ -3524,10 +3664,10 @@ bnxt_get_eeprom_op(struct rte_eth_dev *dev, +@@ -3524,10 +3908,10 @@ bnxt_get_eeprom_op(struct rte_eth_dev *dev, if (rc) return rc; @@ -24468,7 +35491,7 @@ index 41848f36f8..06843d8ddb 100644 if (in_eeprom->offset == 0) /* special offset value to get directory */ return bnxt_get_nvram_directory(bp, in_eeprom->length, -@@ -3600,10 +3740,10 @@ bnxt_set_eeprom_op(struct rte_eth_dev *dev, +@@ -3600,10 +3984,10 @@ bnxt_set_eeprom_op(struct rte_eth_dev *dev, if (rc) return rc; @@ -24483,7 +35506,7 @@ index 41848f36f8..06843d8ddb 100644 if (!BNXT_PF(bp)) { PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n"); -@@ -3688,8 +3828,6 @@ static const struct eth_dev_ops bnxt_dev_ops = { +@@ -3688,8 +4072,6 @@ static const struct eth_dev_ops bnxt_dev_ops = { .txq_info_get = bnxt_txq_info_get_op, .dev_led_on = bnxt_dev_led_on_op, .dev_led_off = bnxt_dev_led_off_op, @@ -24492,7 +35515,28 @@ index 41848f36f8..06843d8ddb 100644 .rx_queue_count = bnxt_rx_queue_count_op, .rx_descriptor_status = bnxt_rx_descriptor_status_op, .tx_descriptor_status = bnxt_tx_descriptor_status_op, -@@ -3788,24 +3926,100 @@ static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) +@@ -3765,13 +4147,19 @@ static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) + uint32_t val = info->reset_reg_val[index]; + uint32_t reg = info->reset_reg[index]; + uint32_t type, offset; ++ int ret; + + type = BNXT_FW_STATUS_REG_TYPE(reg); + offset = BNXT_FW_STATUS_REG_OFF(reg); + + switch (type) { + case BNXT_FW_STATUS_REG_TYPE_CFG: +- rte_pci_write_config(bp->pdev, &val, sizeof(val), offset); ++ ret = rte_pci_write_config(bp->pdev, &val, sizeof(val), offset); ++ if (ret < 0) { ++ PMD_DRV_LOG(ERR, "Failed to write %#x at PCI offset %#x", ++ val, offset); ++ return; ++ } + break; + case BNXT_FW_STATUS_REG_TYPE_GRC: + offset = bnxt_map_reset_regs(bp, offset); +@@ -3788,50 +4176,167 @@ static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) static void bnxt_dev_cleanup(struct bnxt *bp) { @@ -24506,6 +35550,32 @@ index 41848f36f8..06843d8ddb 100644 bnxt_uninit_resources(bp, true); } ++static int ++bnxt_check_fw_reset_done(struct bnxt *bp) ++{ ++ int timeout = bp->fw_reset_max_msecs; ++ uint16_t val = 0; ++ int rc; ++ ++ do { ++ rc = rte_pci_read_config(bp->pdev, &val, sizeof(val), PCI_SUBSYSTEM_ID_OFFSET); ++ if (rc < 0) { ++ PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", PCI_SUBSYSTEM_ID_OFFSET); ++ return rc; ++ } ++ if (val != 0xffff) ++ break; ++ rte_delay_ms(1); ++ } while (timeout--); ++ ++ if (val == 0xffff) { ++ PMD_DRV_LOG(ERR, "Firmware reset aborted, PCI config space invalid\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ +static int bnxt_restore_vlan_filters(struct bnxt *bp) +{ + struct rte_eth_dev *dev = bp->eth_dev; @@ -24536,7 +35606,7 @@ index 41848f36f8..06843d8ddb 100644 + struct rte_ether_addr *addr; + uint64_t pool_mask; + uint32_t pool = 0; -+ uint16_t i; ++ uint32_t i; + int rc; + + if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) @@ -24597,16 +35667,58 @@ index 41848f36f8..06843d8ddb 100644 /* TODO restore other filters as well */ return ret; } -@@ -3820,7 +4034,7 @@ static void bnxt_dev_recover(void *arg) - bp->flags &= ~BNXT_FLAG_FATAL_ERROR; +-static void bnxt_dev_recover(void *arg) ++static int bnxt_check_fw_ready(struct bnxt *bp) + { +- struct bnxt *bp = arg; +- int timeout = bp->fw_reset_max_msecs; ++ int timeout = bp->fw_reset_max_msecs ? : BNXT_MAX_FW_RESET_TIMEOUT; + int rc = 0; + +- /* Clear Error flag so that device re-init should happen */ +- bp->flags &= ~BNXT_FLAG_FATAL_ERROR; +- do { - rc = bnxt_hwrm_ver_get(bp); -+ rc = bnxt_hwrm_ver_get(bp, SHORT_HWRM_CMD_TIMEOUT); ++ rc = bnxt_hwrm_poll_ver_get(bp); if (rc == 0) break; rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL); -@@ -3844,15 +4058,17 @@ static void bnxt_dev_recover(void *arg) + timeout -= BNXT_FW_READY_WAIT_INTERVAL; +- } while (rc && timeout); ++ } while (rc && timeout > 0); + +- if (rc) { ++ if (rc) + PMD_DRV_LOG(ERR, "FW is not Ready after reset\n"); +- goto err; ++ ++ return rc; ++} ++ ++static void bnxt_dev_recover(void *arg) ++{ ++ struct bnxt *bp = arg; ++ int rc = 0; ++ ++ if (!bp->fw_reset_min_msecs) { ++ rc = bnxt_check_fw_reset_done(bp); ++ if (rc) ++ goto err; + } + ++ /* Clear Error flag so that device re-init should happen */ ++ bp->flags &= ~BNXT_FLAG_FATAL_ERROR; ++ ++ rc = bnxt_check_fw_ready(bp); ++ if (rc) ++ goto err; ++ + rc = bnxt_init_resources(bp, true); + if (rc) { + PMD_DRV_LOG(ERR, +@@ -3844,32 +4349,57 @@ static void bnxt_dev_recover(void *arg) rc = bnxt_dev_start_op(bp->eth_dev); if (rc) { PMD_DRV_LOG(ERR, "Failed to start port after reset\n"); @@ -24626,7 +35738,77 @@ index 41848f36f8..06843d8ddb 100644 err: bp->flags |= BNXT_FLAG_FATAL_ERROR; bnxt_uninit_resources(bp, false); -@@ -4006,17 +4222,22 @@ void bnxt_schedule_fw_health_check(struct bnxt *bp) ++ if (bp->eth_dev->data->dev_conf.intr_conf.rmv) ++ _rte_eth_dev_callback_process(bp->eth_dev, ++ RTE_ETH_EVENT_INTR_RMV, ++ NULL); + PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n"); + } + + void bnxt_dev_reset_and_resume(void *arg) + { + struct bnxt *bp = arg; ++ uint32_t us = US_PER_MS * bp->fw_reset_min_msecs; ++ uint16_t val = 0; + int rc; + + bnxt_dev_cleanup(bp); + + bnxt_wait_for_device_shutdown(bp); + +- rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs, +- bnxt_dev_recover, (void *)bp); ++ /* During some fatal firmware error conditions, the PCI config space ++ * register 0x2e which normally contains the subsystem ID will become ++ * 0xffff. This register will revert back to the normal value after ++ * the chip has completed core reset. If we detect this condition, ++ * we can poll this config register immediately for the value to revert. ++ */ ++ if (bp->flags & BNXT_FLAG_FATAL_ERROR) { ++ rc = rte_pci_read_config(bp->pdev, &val, sizeof(val), PCI_SUBSYSTEM_ID_OFFSET); ++ if (rc < 0) { ++ PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", PCI_SUBSYSTEM_ID_OFFSET); ++ return; ++ } ++ if (val == 0xffff) { ++ bp->fw_reset_min_msecs = 0; ++ us = 1; ++ } ++ } ++ ++ rc = rte_eal_alarm_set(us, bnxt_dev_recover, (void *)bp); + if (rc) + PMD_DRV_LOG(ERR, "Error setting recovery alarm"); + } +@@ -3879,13 +4409,17 @@ uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t reg = info->status_regs[index]; + uint32_t type, offset, val = 0; ++ int ret = 0; + + type = BNXT_FW_STATUS_REG_TYPE(reg); + offset = BNXT_FW_STATUS_REG_OFF(reg); + + switch (type) { + case BNXT_FW_STATUS_REG_TYPE_CFG: +- rte_pci_read_config(bp->pdev, &val, sizeof(val), offset); ++ ret = rte_pci_read_config(bp->pdev, &val, sizeof(val), offset); ++ if (ret < 0) ++ PMD_DRV_LOG(ERR, "Failed to read PCI offset %#x", ++ offset); + break; + case BNXT_FW_STATUS_REG_TYPE_GRC: + offset = info->mapped_status_regs[index]; +@@ -3991,6 +4525,8 @@ static void bnxt_check_fw_health(void *arg) + bp->flags |= BNXT_FLAG_FATAL_ERROR; + bp->flags |= BNXT_FLAG_FW_RESET; + ++ bnxt_stop_rxtx(bp); ++ + PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); + + if (bnxt_is_master_func(bp)) +@@ -4006,24 +4542,26 @@ void bnxt_schedule_fw_health_check(struct bnxt *bp) { uint32_t polling_freq; @@ -24651,7 +35833,23 @@ index 41848f36f8..06843d8ddb 100644 } static void bnxt_cancel_fw_health_check(struct bnxt *bp) -@@ -4138,18 +4359,6 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, + { +- if (!bnxt_is_recovery_enabled(bp)) +- return; +- + rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp); + bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; + } +@@ -4127,7 +4665,7 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, + if (!mz) { + mz = rte_memzone_reserve_aligned(mz_name, + rmem->nr_pages * 8, +- SOCKET_ID_ANY, ++ bp->eth_dev->device->numa_node, + RTE_MEMZONE_2MB | + RTE_MEMZONE_SIZE_HINT_ONLY | + RTE_MEMZONE_IOVA_CONTIG, +@@ -4138,18 +4676,6 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; @@ -24670,7 +35868,16 @@ index 41848f36f8..06843d8ddb 100644 rmem->pg_tbl = mz->addr; rmem->pg_tbl_map = mz_phys_addr; -@@ -4173,22 +4382,8 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, +@@ -4162,7 +4688,7 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, + if (!mz) { + mz = rte_memzone_reserve_aligned(mz_name, + mem_size, +- SOCKET_ID_ANY, ++ bp->eth_dev->device->numa_node, + RTE_MEMZONE_1GB | + RTE_MEMZONE_SIZE_HINT_ONLY | + RTE_MEMZONE_IOVA_CONTIG, +@@ -4173,22 +4699,8 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; @@ -24693,7 +35900,7 @@ index 41848f36f8..06843d8ddb 100644 rmem->pg_arr[i] = ((char *)mz->addr) + sz; rmem->dma_arr[i] = mz_phys_addr + sz; -@@ -4365,18 +4560,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) +@@ -4365,18 +4877,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) } memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; @@ -24712,7 +35919,7 @@ index 41848f36f8..06843d8ddb 100644 bp->rx_mem_zone = (const void *)mz; bp->hw_rx_port_stats = mz->addr; -@@ -4403,17 +4586,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) +@@ -4403,17 +4903,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) } memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; @@ -24730,7 +35937,24 @@ index 41848f36f8..06843d8ddb 100644 bp->tx_mem_zone = (const void *)mz; bp->hw_tx_port_stats = mz->addr; -@@ -4461,7 +4633,7 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) +@@ -4450,18 +4939,22 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) + static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) + { + struct bnxt *bp = eth_dev->data->dev_private; ++ size_t max_mac_addr = RTE_MIN(bp->max_l2_ctx, ETH_NUM_RECEIVE_MAC_ADDR); + int rc = 0; + ++ if (bp->max_l2_ctx > ETH_NUM_RECEIVE_MAC_ADDR) ++ PMD_DRV_LOG(INFO, "Max number of MAC addrs supported is %d, but will be limited to %d\n", ++ bp->max_l2_ctx, ETH_NUM_RECEIVE_MAC_ADDR); ++ + eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", +- RTE_ETHER_ADDR_LEN * +- bp->max_l2_ctx, ++ RTE_ETHER_ADDR_LEN * max_mac_addr, + 0); + if (eth_dev->data->mac_addrs == NULL) { + PMD_DRV_LOG(ERR, "Failed to alloc MAC addr tbl\n"); return -ENOMEM; } @@ -24739,7 +35963,7 @@ index 41848f36f8..06843d8ddb 100644 if (BNXT_PF(bp)) return -EINVAL; -@@ -4474,14 +4646,11 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) +@@ -4474,16 +4967,30 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]); rc = bnxt_hwrm_set_mac(bp); @@ -24755,8 +35979,27 @@ index 41848f36f8..06843d8ddb 100644 - memcpy(bp->mac_addr, bp->dflt_mac_addr, RTE_ETHER_ADDR_LEN); memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN); ++ /* ++ * Allocate memory to hold multicast mac addresses added. ++ * Used to restore them during reset recovery ++ */ ++ bp->mcast_addr_list = rte_zmalloc("bnxt_mcast_addr_tbl", ++ sizeof(struct rte_ether_addr) * ++ BNXT_MAX_MC_ADDRS, 0); ++ if (bp->mcast_addr_list == NULL) { ++ PMD_DRV_LOG(ERR, "Failed to allocate multicast addr table\n"); ++ return -ENOMEM; ++ } ++ bp->mc_list_dma_addr = rte_malloc_virt2iova(bp->mcast_addr_list); ++ if (bp->mc_list_dma_addr == RTE_BAD_IOVA) { ++ PMD_DRV_LOG(ERR, "Fail to map mcast_addr_list to physical memory\n"); ++ return -ENOMEM; ++ } ++ return rc; -@@ -4492,7 +4661,7 @@ static int bnxt_restore_dflt_mac(struct bnxt *bp) + } + +@@ -4492,7 +4999,7 @@ static int bnxt_restore_dflt_mac(struct bnxt *bp) int rc = 0; /* MAC is already configured in FW */ @@ -24765,7 +36008,7 @@ index 41848f36f8..06843d8ddb 100644 return 0; /* Restore the old MAC configured */ -@@ -4546,7 +4715,9 @@ static int bnxt_init_fw(struct bnxt *bp) +@@ -4546,7 +5053,9 @@ static int bnxt_init_fw(struct bnxt *bp) uint16_t mtu; int rc = 0; @@ -24776,7 +36019,7 @@ index 41848f36f8..06843d8ddb 100644 if (rc) return rc; -@@ -4574,14 +4745,10 @@ static int bnxt_init_fw(struct bnxt *bp) +@@ -4574,17 +5083,15 @@ static int bnxt_init_fw(struct bnxt *bp) if (rc) return rc; @@ -24792,7 +36035,12 @@ index 41848f36f8..06843d8ddb 100644 bnxt_hwrm_port_led_qcaps(bp); -@@ -4600,8 +4767,14 @@ bnxt_init_locks(struct bnxt *bp) ++ bnxt_hwrm_port_phy_qcaps(bp); ++ + return 0; + } + +@@ -4600,8 +5107,14 @@ bnxt_init_locks(struct bnxt *bp) } err = pthread_mutex_init(&bp->def_cp_lock, NULL); @@ -24808,7 +36056,24 @@ index 41848f36f8..06843d8ddb 100644 return err; } -@@ -4693,8 +4866,6 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) +@@ -4648,6 +5161,16 @@ static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev) + } + } + ++ if (!reconfig_dev) { ++ bp->rss_conf.rss_key = rte_zmalloc("bnxt_rss_key", ++ HW_HASH_KEY_SIZE, 0); ++ if (bp->rss_conf.rss_key == NULL) { ++ PMD_DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory", ++ bp->eth_dev->data->port_id); ++ return -ENOMEM; ++ } ++ } ++ + rc = bnxt_alloc_mem(bp, reconfig_dev); + if (rc) + return rc; +@@ -4693,8 +5216,6 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) bp = eth_dev->data->dev_private; @@ -24817,7 +36082,26 @@ index 41848f36f8..06843d8ddb 100644 if (bnxt_vf_pciid(pci_dev->id.device_id)) bp->flags |= BNXT_FLAG_VF; -@@ -4745,6 +4916,7 @@ bnxt_uninit_locks(struct bnxt *bp) +@@ -4717,7 +5238,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) + rc = bnxt_alloc_hwrm_resources(bp); + if (rc) { + PMD_DRV_LOG(ERR, +- "Failed to allocate hwrm resource rc: %x\n", rc); ++ "Failed to allocate response buffer rc: %x\n", rc); + goto error_free; + } + rc = bnxt_init_resources(bp, false); +@@ -4729,7 +5250,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) + goto error_free; + + PMD_DRV_LOG(INFO, +- DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n", ++ "Found %s device at mem %" PRIX64 ", node addr %pM\n", ++ DRV_MODULE_NAME, + pci_dev->mem_resource[0].phys_addr, + pci_dev->mem_resource[0].addr); + +@@ -4745,6 +5267,7 @@ bnxt_uninit_locks(struct bnxt *bp) { pthread_mutex_destroy(&bp->flow_lock); pthread_mutex_destroy(&bp->def_cp_lock); @@ -24825,7 +36109,27 @@ index 41848f36f8..06843d8ddb 100644 } static int -@@ -4796,10 +4968,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) +@@ -4755,7 +5278,7 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) + bnxt_free_int(bp); + bnxt_free_mem(bp, reconfig_dev); + bnxt_hwrm_func_buf_unrgtr(bp); +- rc = bnxt_hwrm_func_driver_unregister(bp, 0); ++ rc = bnxt_hwrm_func_driver_unregister(bp); + bp->flags &= ~BNXT_FLAG_REGISTERED; + bnxt_free_ctx_mem(bp); + if (!reconfig_dev) { +@@ -4765,6 +5288,10 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) + rte_free(bp->recovery_info); + bp->recovery_info = NULL; + } ++ rte_free(bp->mcast_addr_list); ++ bp->mcast_addr_list = NULL; ++ rte_free(bp->rss_conf.rss_key); ++ bp->rss_conf.rss_key = NULL; + } + + bnxt_uninit_locks(bp); +@@ -4796,10 +5323,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) bp->rx_mem_zone = NULL; } @@ -24834,12 +36138,22 @@ index 41848f36f8..06843d8ddb 100644 bnxt_dev_close_op(eth_dev); - if (bp->pf.vf_info) - rte_free(bp->pf.vf_info); -+ bnxt_hwrm_free_vf_info(bp); ++ bnxt_free_vf_info(bp); eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; +@@ -4825,7 +5351,8 @@ static int bnxt_pci_remove(struct rte_pci_device *pci_dev) + + static struct rte_pci_driver bnxt_rte_pmd = { + .id_table = bnxt_pci_id_map, +- .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, ++ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC | ++ RTE_PCI_DRV_INTR_RMV, + .probe = bnxt_pci_probe, + .remove = bnxt_pci_remove, + }; diff --git a/dpdk/drivers/net/bnxt/bnxt_filter.c b/dpdk/drivers/net/bnxt/bnxt_filter.c -index da1a6c24a9..f4b18d5b84 100644 +index da1a6c24a9..d8b2b68c56 100644 --- a/dpdk/drivers/net/bnxt/bnxt_filter.c +++ b/dpdk/drivers/net/bnxt/bnxt_filter.c @@ -26,22 +26,20 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp) @@ -24884,7 +36198,13 @@ index da1a6c24a9..f4b18d5b84 100644 for (i = 0; i < bp->nr_vnics; i++) { vnic = &bp->vnic_info[i]; filter = STAILQ_FIRST(&vnic->filter); -@@ -96,12 +103,6 @@ void bnxt_free_all_filters(struct bnxt *bp) +@@ -92,16 +99,12 @@ void bnxt_free_all_filters(struct bnxt *bp) + bnxt_filter_info, next); + STAILQ_INSERT_TAIL(&bp->free_filter_list, + filter, next); ++ if (filter->vnic) ++ filter->vnic = NULL; + filter = temp_filter; } STAILQ_INIT(&vnic->filter); } @@ -24897,6 +36217,17 @@ index da1a6c24a9..f4b18d5b84 100644 } void bnxt_free_filter_mem(struct bnxt *bp) +@@ -192,5 +195,10 @@ struct bnxt_filter_info *bnxt_get_unused_filter(struct bnxt *bp) + + void bnxt_free_filter(struct bnxt *bp, struct bnxt_filter_info *filter) + { ++ memset(filter, 0, sizeof(*filter)); ++ filter->mac_index = INVALID_MAC_INDEX; ++ filter->fw_l2_filter_id = UINT64_MAX; ++ filter->fw_ntuple_filter_id = UINT64_MAX; ++ filter->fw_em_filter_id = UINT64_MAX; + STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next); + } diff --git a/dpdk/drivers/net/bnxt/bnxt_filter.h b/dpdk/drivers/net/bnxt/bnxt_filter.h index 9db3e74877..fc40f112ba 100644 --- a/dpdk/drivers/net/bnxt/bnxt_filter.h @@ -24913,10 +36244,114 @@ index 9db3e74877..fc40f112ba 100644 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp); diff --git a/dpdk/drivers/net/bnxt/bnxt_flow.c b/dpdk/drivers/net/bnxt/bnxt_flow.c -index 76e9584da7..f069e5f56a 100644 +index 76e9584da7..29b59eca41 100644 --- a/dpdk/drivers/net/bnxt/bnxt_flow.c +++ b/dpdk/drivers/net/bnxt/bnxt_flow.c -@@ -746,10 +746,9 @@ bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf) +@@ -185,11 +185,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + PMD_DRV_LOG(DEBUG, "Parse inner header\n"); + break; + case RTE_FLOW_ITEM_TYPE_ETH: +- if (!item->spec || !item->mask) ++ if (!item->spec) + break; + + eth_spec = item->spec; +- eth_mask = item->mask; ++ ++ if (item->mask) ++ eth_mask = item->mask; ++ else ++ eth_mask = &rte_flow_item_eth_mask; + + /* Source MAC address mask cannot be partially set. + * Should be All 0's or all 1's. +@@ -278,7 +282,12 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + vlan_spec = item->spec; +- vlan_mask = item->mask; ++ ++ if (item->mask) ++ vlan_mask = item->mask; ++ else ++ vlan_mask = &rte_flow_item_vlan_mask; ++ + if (en & en_ethertype) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, +@@ -321,11 +330,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + case RTE_FLOW_ITEM_TYPE_IPV4: + /* If mask is not involved, we could use EM filters. */ + ipv4_spec = item->spec; +- ipv4_mask = item->mask; + +- if (!item->spec || !item->mask) ++ if (!item->spec) + break; + ++ if (item->mask) ++ ipv4_mask = item->mask; ++ else ++ ipv4_mask = &rte_flow_item_ipv4_mask; ++ + /* Only IP DST and SRC fields are maskable. */ + if (ipv4_mask->hdr.version_ihl || + ipv4_mask->hdr.type_of_service || +@@ -382,11 +395,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + ipv6_spec = item->spec; +- ipv6_mask = item->mask; + +- if (!item->spec || !item->mask) ++ if (!item->spec) + break; + ++ if (item->mask) ++ ipv6_mask = item->mask; ++ else ++ ipv6_mask = &rte_flow_item_ipv6_mask; ++ + /* Only IP DST and SRC fields are maskable. */ + if (ipv6_mask->hdr.vtc_flow || + ipv6_mask->hdr.payload_len || +@@ -434,11 +451,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + break; + case RTE_FLOW_ITEM_TYPE_TCP: + tcp_spec = item->spec; +- tcp_mask = item->mask; + +- if (!item->spec || !item->mask) ++ if (!item->spec) + break; + ++ if (item->mask) ++ tcp_mask = item->mask; ++ else ++ tcp_mask = &rte_flow_item_tcp_mask; ++ + /* Check TCP mask. Only DST & SRC ports are maskable */ + if (tcp_mask->hdr.sent_seq || + tcp_mask->hdr.recv_ack || +@@ -479,11 +500,15 @@ bnxt_validate_and_parse_flow_type(struct bnxt *bp, + break; + case RTE_FLOW_ITEM_TYPE_UDP: + udp_spec = item->spec; +- udp_mask = item->mask; + +- if (!item->spec || !item->mask) ++ if (!item->spec) + break; + ++ if (item->mask) ++ udp_mask = item->mask; ++ else ++ udp_mask = &rte_flow_item_udp_mask; ++ + if (udp_mask->hdr.dgram_len || + udp_mask->hdr.dgram_cksum) { + rte_flow_error_set(error, +@@ -746,10 +771,9 @@ bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf) { struct bnxt_filter_info *mf, *f0; struct bnxt_vnic_info *vnic0; @@ -24928,7 +36363,7 @@ index 76e9584da7..f069e5f56a 100644 f0 = STAILQ_FIRST(&vnic0->filter); /* This flow has same DST MAC as the port/l2 filter. */ -@@ -762,8 +761,7 @@ bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf) +@@ -762,8 +786,7 @@ bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf) if (vnic->fw_vnic_id == INVALID_VNIC_ID) continue; @@ -24938,7 +36373,7 @@ index 76e9584da7..f069e5f56a 100644 if (mf->matching_l2_fltr_ptr) continue; -@@ -798,6 +796,8 @@ bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, +@@ -798,6 +821,8 @@ bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, if (filter1 == NULL) return NULL; @@ -24947,7 +36382,7 @@ index 76e9584da7..f069e5f56a 100644 filter1->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_XDP_DISABLE; filter1->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX; if (nf->valid_flags & BNXT_FLOW_L2_SRC_VALID_FLAG || -@@ -867,7 +867,6 @@ bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, +@@ -867,7 +892,6 @@ bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, bnxt_free_filter(bp, filter1); return NULL; } @@ -24955,7 +36390,7 @@ index 76e9584da7..f069e5f56a 100644 return filter1; } -@@ -880,11 +879,14 @@ bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, +@@ -880,42 +904,71 @@ bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf, l2_filter = bnxt_find_matching_l2_filter(bp, nf); if (l2_filter) { l2_filter->l2_ref_cnt++; @@ -24972,7 +36407,105 @@ index 76e9584da7..f069e5f56a 100644 return l2_filter; } -@@ -1054,16 +1056,9 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, + +-static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic) ++static void bnxt_vnic_cleanup(struct bnxt *bp, struct bnxt_vnic_info *vnic) ++{ ++ if (vnic->rx_queue_cnt > 1) ++ bnxt_hwrm_vnic_ctx_free(bp, vnic); ++ ++ bnxt_hwrm_vnic_free(bp, vnic); ++ ++ rte_free(vnic->fw_grp_ids); ++ vnic->fw_grp_ids = NULL; ++ ++ vnic->rx_queue_cnt = 0; ++} ++ ++static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic, ++ const struct rte_flow_action *act, ++ struct rte_flow_error *error) + { + struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; + uint64_t rx_offloads = dev_conf->rxmode.offloads; + int rc; + ++ if (bp->nr_vnics > bp->max_vnics - 1) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ATTR_GROUP, ++ NULL, ++ "Group id is invalid"); ++ + rc = bnxt_vnic_grp_alloc(bp, vnic); + if (rc) +- goto ret; ++ return rte_flow_error_set(error, -rc, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ act, ++ "Failed to alloc VNIC group"); + + rc = bnxt_hwrm_vnic_alloc(bp, vnic); + if (rc) { +- PMD_DRV_LOG(ERR, "HWRM vnic alloc failure rc: %x\n", rc); ++ rte_flow_error_set(error, -rc, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ act, ++ "Failed to alloc VNIC"); + goto ret; + } +- bp->nr_vnics++; + + /* RSS context is required only when there is more than one RSS ring */ + if (vnic->rx_queue_cnt > 1) { +- rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0 /* ctx_idx 0 */); ++ rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0); + if (rc) { +- PMD_DRV_LOG(ERR, +- "HWRM vnic ctx alloc failure: %x\n", rc); ++ rte_flow_error_set(error, -rc, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ act, ++ "Failed to alloc VNIC context"); + goto ret; + } +- } else { +- PMD_DRV_LOG(DEBUG, "No RSS context required\n"); + } + + if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) +@@ -924,12 +977,29 @@ static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic) + vnic->vlan_strip = false; + + rc = bnxt_hwrm_vnic_cfg(bp, vnic); +- if (rc) ++ if (rc) { ++ rte_flow_error_set(error, -rc, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ act, ++ "Failed to configure VNIC"); + goto ret; ++ } ++ ++ rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); ++ if (rc) { ++ rte_flow_error_set(error, -rc, ++ RTE_FLOW_ERROR_TYPE_ACTION, ++ act, ++ "Failed to configure VNIC plcmode"); ++ goto ret; ++ } ++ ++ bp->nr_vnics++; + +- bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); ++ return 0; + + ret: ++ bnxt_vnic_cleanup(bp, vnic); + return rc; + } + +@@ -1054,16 +1124,9 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, vnic_id = act_q->index; } @@ -24991,7 +36524,26 @@ index 76e9584da7..f069e5f56a 100644 if (vnic->rx_queue_cnt) { if (vnic->start_grp_id != act_q->index) { PMD_DRV_LOG(ERR, -@@ -1126,7 +1121,16 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, +@@ -1106,16 +1169,9 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, + + PMD_DRV_LOG(DEBUG, "VNIC found\n"); + +- rc = bnxt_vnic_prep(bp, vnic); +- if (rc) { +- rte_flow_error_set(error, +- EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION, +- act, +- "VNIC prep fail"); +- rc = -rte_errno; ++ rc = bnxt_vnic_prep(bp, vnic, act, error); ++ if (rc) + goto ret; +- } + + PMD_DRV_LOG(DEBUG, + "vnic[%d] = %p vnic->fw_grp_ids = %p\n", +@@ -1126,7 +1182,16 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, PMD_DRV_LOG(DEBUG, "Setting vnic ff_idx %d\n", vnic->ff_pool_idx); filter->dst_id = vnic->fw_vnic_id; @@ -25009,7 +36561,7 @@ index 76e9584da7..f069e5f56a 100644 if (filter1 == NULL) { rte_flow_error_set(error, ENOSPC, -@@ -1252,28 +1256,10 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, +@@ -1252,28 +1317,10 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, rss = (const struct rte_flow_action_rss *)act->conf; vnic_id = attr->group; @@ -25040,7 +36592,37 @@ index 76e9584da7..f069e5f56a 100644 /* Check if requested RSS config matches RSS config of VNIC * only if it is not a fresh VNIC configuration. -@@ -1420,11 +1406,6 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, +@@ -1334,16 +1381,9 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, + vnic->end_grp_id = rss->queue[rss->queue_num - 1]; + vnic->func_default = 0; //This is not a default VNIC. + +- rc = bnxt_vnic_prep(bp, vnic); +- if (rc) { +- rte_flow_error_set(error, +- EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION, +- act, +- "VNIC prep fail"); +- rc = -rte_errno; ++ rc = bnxt_vnic_prep(bp, vnic, act, error); ++ if (rc) + goto ret; +- } + + PMD_DRV_LOG(DEBUG, + "vnic[%d] = %p vnic->fw_grp_ids = %p\n", +@@ -1377,8 +1417,8 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, + /* If hash key has not been specified, + * use random hash key. + */ +- prandom_bytes(vnic->rss_hash_key, +- HW_HASH_KEY_SIZE); ++ bnxt_prandom_bytes(vnic->rss_hash_key, ++ HW_HASH_KEY_SIZE); + } else { + if (rss->key_len > HW_HASH_KEY_SIZE) + memcpy(vnic->rss_hash_key, +@@ -1420,11 +1460,6 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, goto ret; } @@ -25052,7 +36634,7 @@ index 76e9584da7..f069e5f56a 100644 done: act = bnxt_flow_non_void_action(++act); if (act->type != RTE_FLOW_ACTION_TYPE_END) { -@@ -1448,7 +1429,7 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, +@@ -1448,7 +1483,7 @@ bnxt_validate_and_parse_flow(struct rte_eth_dev *dev, if (rxq && !vnic->rx_queue_cnt) rxq->vnic = &bp->vnic_info[0]; } @@ -25061,7 +36643,42 @@ index 76e9584da7..f069e5f56a 100644 } static -@@ -1537,10 +1518,13 @@ bnxt_update_filter(struct bnxt *bp, struct bnxt_filter_info *old_filter, +@@ -1491,9 +1526,11 @@ bnxt_flow_validate(struct rte_eth_dev *dev, + + filter = bnxt_get_unused_filter(bp); + if (filter == NULL) { +- PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n"); ++ rte_flow_error_set(error, ENOSPC, ++ RTE_FLOW_ERROR_TYPE_HANDLE, NULL, ++ "Not enough resources for a new flow"); + bnxt_release_flow_lock(bp); +- return -ENOMEM; ++ return -ENOSPC; + } + + ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr, +@@ -1504,10 +1541,8 @@ bnxt_flow_validate(struct rte_eth_dev *dev, + vnic = find_matching_vnic(bp, filter); + if (vnic) { + if (STAILQ_EMPTY(&vnic->filter)) { +- rte_free(vnic->fw_grp_ids); +- bnxt_hwrm_vnic_ctx_free(bp, vnic); +- bnxt_hwrm_vnic_free(bp, vnic); +- vnic->rx_queue_cnt = 0; ++ bnxt_vnic_cleanup(bp, vnic); ++ bp->nr_vnics--; + PMD_DRV_LOG(DEBUG, "Free VNIC\n"); + } + } +@@ -1521,7 +1556,6 @@ bnxt_flow_validate(struct rte_eth_dev *dev, + + exit: + /* No need to hold on to this filter if we are just validating flow */ +- filter->fw_l2_filter_id = UINT64_MAX; + bnxt_free_filter(bp, filter); + bnxt_release_flow_lock(bp); + +@@ -1537,10 +1571,13 @@ bnxt_update_filter(struct bnxt *bp, struct bnxt_filter_info *old_filter, * filter which points to the new destination queue and so we clear * the previous L2 filter. For ntuple filters, we are going to reuse * the old L2 filter and create new NTUPLE filter with this new @@ -25077,7 +36694,7 @@ index 76e9584da7..f069e5f56a 100644 bnxt_hwrm_set_l2_filter(bp, new_filter->dst_id, new_filter); } else { if (new_filter->filter_type == HWRM_CFA_EM_FILTER) -@@ -1663,7 +1647,9 @@ bnxt_flow_create(struct rte_eth_dev *dev, +@@ -1663,7 +1700,9 @@ bnxt_flow_create(struct rte_eth_dev *dev, filter = bnxt_get_unused_filter(bp); if (filter == NULL) { @@ -25088,7 +36705,7 @@ index 76e9584da7..f069e5f56a 100644 goto free_flow; } -@@ -1729,12 +1715,24 @@ bnxt_flow_create(struct rte_eth_dev *dev, +@@ -1729,12 +1768,24 @@ bnxt_flow_create(struct rte_eth_dev *dev, filter->enables |= HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID; ret = bnxt_hwrm_set_em_filter(bp, filter->dst_id, filter); @@ -25113,7 +36730,7 @@ index 76e9584da7..f069e5f56a 100644 } vnic = find_matching_vnic(bp, filter); -@@ -1748,9 +1746,9 @@ bnxt_flow_create(struct rte_eth_dev *dev, +@@ -1748,9 +1799,9 @@ bnxt_flow_create(struct rte_eth_dev *dev, } STAILQ_INSERT_TAIL(&vnic->filter, filter, next); @@ -25124,7 +36741,7 @@ index 76e9584da7..f069e5f56a 100644 return flow; } -@@ -1765,7 +1763,7 @@ bnxt_flow_create(struct rte_eth_dev *dev, +@@ -1765,7 +1816,7 @@ bnxt_flow_create(struct rte_eth_dev *dev, rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_NONE, NULL, "Flow with pattern exists, updating destination queue"); @@ -25133,7 +36750,28 @@ index 76e9584da7..f069e5f56a 100644 rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to create flow."); -@@ -1817,57 +1815,31 @@ static int bnxt_handle_tunnel_redirect_destroy(struct bnxt *bp, +@@ -1806,68 +1857,50 @@ static int bnxt_handle_tunnel_redirect_destroy(struct bnxt *bp, + /* Tunnel doesn't belong to this VF, so don't send HWRM + * cmd, just delete the flow from driver + */ +- if (bp->fw_fid != (tun_dst_fid + bp->first_vf_id)) ++ if (bp->fw_fid != (tun_dst_fid + bp->first_vf_id)) { + PMD_DRV_LOG(ERR, + "Tunnel does not belong to this VF, skip hwrm_tunnel_redirect_free\n"); +- else ++ } else { + ret = bnxt_hwrm_tunnel_redirect_free(bp, + filter->tunnel_type); ++ if (ret) { ++ rte_flow_error_set(error, -ret, ++ RTE_FLOW_ERROR_TYPE_HANDLE, ++ NULL, ++ "Unable to free tunnel redirection"); ++ return ret; ++ } ++ } + } + return ret; } static int @@ -25198,7 +36836,22 @@ index 76e9584da7..f069e5f56a 100644 done: if (!ret) { -@@ -1903,7 +1875,36 @@ bnxt_flow_destroy(struct rte_eth_dev *dev, +@@ -1890,12 +1923,8 @@ bnxt_flow_destroy(struct rte_eth_dev *dev, + */ + if (vnic && !vnic->func_default && + STAILQ_EMPTY(&vnic->flow_list)) { +- rte_free(vnic->fw_grp_ids); +- if (vnic->rx_queue_cnt > 1) +- bnxt_hwrm_vnic_ctx_free(bp, vnic); +- +- bnxt_hwrm_vnic_free(bp, vnic); +- vnic->rx_queue_cnt = 0; ++ bnxt_vnic_cleanup(bp, vnic); ++ bp->nr_vnics--; + } + } else { + rte_flow_error_set(error, -ret, +@@ -1903,7 +1932,36 @@ bnxt_flow_destroy(struct rte_eth_dev *dev, "Failed to destroy flow."); } @@ -25235,7 +36888,7 @@ index 76e9584da7..f069e5f56a 100644 return ret; } -@@ -1911,7 +1912,6 @@ static int +@@ -1911,7 +1969,6 @@ static int bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) { struct bnxt *bp = dev->data->dev_private; @@ -25243,7 +36896,7 @@ index 76e9584da7..f069e5f56a 100644 struct bnxt_vnic_info *vnic; struct rte_flow *flow; unsigned int i; -@@ -1925,66 +1925,17 @@ bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) +@@ -1925,66 +1982,17 @@ bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) while (!STAILQ_EMPTY(&vnic->flow_list)) { flow = STAILQ_FIRST(&vnic->flow_list); @@ -25317,7 +36970,7 @@ index 76e9584da7..f069e5f56a 100644 } diff --git a/dpdk/drivers/net/bnxt/bnxt_hwrm.c b/dpdk/drivers/net/bnxt/bnxt_hwrm.c -index 41730089b1..8025d5ad78 100644 +index 41730089b1..4ae1682920 100644 --- a/dpdk/drivers/net/bnxt/bnxt_hwrm.c +++ b/dpdk/drivers/net/bnxt/bnxt_hwrm.c @@ -52,7 +52,7 @@ static int page_getenum(size_t size) @@ -25383,7 +37036,15 @@ index 41730089b1..8025d5ad78 100644 else if (rc > 0) \ rc = -EIO; \ return rc; \ -@@ -309,8 +314,8 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, +@@ -303,14 +308,14 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, + mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; + } else if (vnic->flags & BNXT_VNIC_INFO_MCAST) { + mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST; +- req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt); +- req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr); ++ req.num_mc_entries = rte_cpu_to_le_32(bp->nb_mc_addr); ++ req.mc_tbl_addr = rte_cpu_to_le_64(bp->mc_list_dma_addr); + } if (vlan_table) { if (!(mask & HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN)) mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY; @@ -25460,14 +37121,34 @@ index 41730089b1..8025d5ad78 100644 return rc; } -@@ -567,6 +589,20 @@ static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp) +@@ -529,9 +551,13 @@ static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp) + + HWRM_CHECK_RESULT(); + +- if (!BNXT_CHIP_THOR(bp) && +- !(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS)) +- return 0; ++ if (BNXT_CHIP_THOR(bp)) { ++ if (!(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_HWRM_ACCESS)) ++ return 0; ++ } else { ++ if (!(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS)) ++ return 0; ++ } + + if (resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_ONE_STEP_TX_TS) + bp->flags |= BNXT_FLAG_FW_CAP_ONE_STEP_TX_TS; +@@ -567,6 +593,67 @@ static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp) return 0; } -+void bnxt_hwrm_free_vf_info(struct bnxt *bp) ++void bnxt_free_vf_info(struct bnxt *bp) +{ + uint16_t i; + ++ if (bp->pf.vf_info == NULL) ++ return; ++ + for (i = 0; i < bp->pf.max_vfs; i++) { + rte_free(bp->pf.vf_info[i].vlan_table); + bp->pf.vf_info[i].vlan_table = NULL; @@ -25478,27 +37159,100 @@ index 41730089b1..8025d5ad78 100644 + bp->pf.vf_info = NULL; +} + ++static int bnxt_alloc_vf_info(struct bnxt *bp, uint16_t max_vfs) ++{ ++ struct bnxt_child_vf_info *vf_info = bp->pf.vf_info; ++ int i; ++ ++ if (vf_info) ++ bnxt_free_vf_info(bp); ++ ++ vf_info = rte_zmalloc("bnxt_vf_info", sizeof(*vf_info) * max_vfs, 0); ++ if (vf_info == NULL) { ++ PMD_DRV_LOG(ERR, "Failed to alloc vf info\n"); ++ return -ENOMEM; ++ } ++ ++ bp->pf.max_vfs = max_vfs; ++ for (i = 0; i < max_vfs; i++) { ++ vf_info[i].fid = bp->pf.first_vf_id + i; ++ vf_info[i].vlan_table = rte_zmalloc("VF VLAN table", ++ getpagesize(), getpagesize()); ++ if (vf_info[i].vlan_table == NULL) { ++ PMD_DRV_LOG(ERR, "Failed to alloc VLAN table for VF %d\n", i); ++ goto err; ++ } ++ rte_mem_lock_page(vf_info[i].vlan_table); ++ ++ vf_info[i].vlan_as_table = rte_zmalloc("VF VLAN AS table", ++ getpagesize(), getpagesize()); ++ if (vf_info[i].vlan_as_table == NULL) { ++ PMD_DRV_LOG(ERR, "Failed to alloc VLAN AS table for VF %d\n", i); ++ goto err; ++ } ++ rte_mem_lock_page(vf_info[i].vlan_as_table); ++ ++ STAILQ_INIT(&vf_info[i].filter); ++ } ++ ++ bp->pf.vf_info = vf_info; ++ ++ return 0; ++err: ++ bnxt_free_vf_info(bp); ++ return -ENOMEM; ++} ++ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) { int rc = 0; -@@ -593,9 +629,14 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) +@@ -574,7 +661,6 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) + struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr; + uint16_t new_max_vfs; + uint32_t flags; +- int i; + + HWRM_PREP(req, FUNC_QCAPS, BNXT_USE_CHIMP_MB); + +@@ -592,42 +678,19 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) + bp->pf.total_vfs = rte_le_to_cpu_16(resp->max_vfs); new_max_vfs = bp->pdev->max_vfs; if (new_max_vfs != bp->pf.max_vfs) { - if (bp->pf.vf_info) +- if (bp->pf.vf_info) - rte_free(bp->pf.vf_info); - bp->pf.vf_info = rte_malloc("bnxt_vf_info", -+ bnxt_hwrm_free_vf_info(bp); -+ bp->pf.vf_info = rte_zmalloc("bnxt_vf_info", - sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0); -+ if (bp->pf.vf_info == NULL) { -+ PMD_DRV_LOG(ERR, "Alloc vf info fail\n"); -+ HWRM_UNLOCK(); -+ return -ENOMEM; -+ } - bp->pf.max_vfs = new_max_vfs; - for (i = 0; i < new_max_vfs; i++) { - bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i; -@@ -627,7 +668,12 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) +- sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0); +- bp->pf.max_vfs = new_max_vfs; +- for (i = 0; i < new_max_vfs; i++) { +- bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i; +- bp->pf.vf_info[i].vlan_table = +- rte_zmalloc("VF VLAN table", +- getpagesize(), +- getpagesize()); +- if (bp->pf.vf_info[i].vlan_table == NULL) +- PMD_DRV_LOG(ERR, +- "Fail to alloc VLAN table for VF %d\n", +- i); +- else +- rte_mem_lock_page( +- bp->pf.vf_info[i].vlan_table); +- bp->pf.vf_info[i].vlan_as_table = +- rte_zmalloc("VF VLAN AS table", +- getpagesize(), +- getpagesize()); +- if (bp->pf.vf_info[i].vlan_as_table == NULL) +- PMD_DRV_LOG(ERR, +- "Alloc VLAN AS table for VF %d fail\n", +- i); +- else +- rte_mem_lock_page( +- bp->pf.vf_info[i].vlan_as_table); +- STAILQ_INIT(&bp->pf.vf_info[i].filter); +- } ++ rc = bnxt_alloc_vf_info(bp, new_max_vfs); ++ if (rc) ++ goto unlock; + } } bp->fw_fid = rte_le_to_cpu_32(resp->fid); @@ -25512,7 +37266,16 @@ index 41730089b1..8025d5ad78 100644 bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings); bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings); -@@ -661,16 +707,15 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) +@@ -647,6 +710,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) + bp->max_vnics = 1; + } + bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx); ++ bp->max_mcast_addr = rte_le_to_cpu_32(resp->max_mcast_filters); ++ + if (BNXT_PF(bp)) { + bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics); + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED) { +@@ -661,17 +726,21 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->flags |= BNXT_FLAG_EXT_STATS_SUPPORTED; if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE) { @@ -25532,9 +37295,38 @@ index 41730089b1..8025d5ad78 100644 + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_HOT_RESET_CAPABLE) + bp->fw_cap |= BNXT_FW_CAP_HOT_RESET; ++ if (!(flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VLAN_ACCELERATION_TX_DISABLED)) { ++ bp->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT; ++ PMD_DRV_LOG(DEBUG, "VLAN acceleration for TX is enabled\n"); ++ } ++unlock: HWRM_UNLOCK(); -@@ -756,8 +801,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) + return rc; +@@ -682,6 +751,9 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp) + int rc; + + rc = __bnxt_hwrm_func_qcaps(bp); ++ if (rc == -ENOMEM) ++ return rc; ++ + if (!rc && bp->hwrm_spec_code >= HWRM_SPEC_CODE_1_8_3) { + rc = bnxt_alloc_ctx_mem(bp); + if (rc) +@@ -721,6 +793,12 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp) + PMD_DRV_LOG(INFO, "CoS assignment capability enabled\n"); + } + ++ if (rte_le_to_cpu_32(resp->flags) & ++ HWRM_VNIC_QCAPS_OUTPUT_FLAGS_VLAN_STRIP_CAP) { ++ bp->vnic_cap_flags |= BNXT_VNIC_CAP_VLAN_RX_STRIP; ++ PMD_DRV_LOG(DEBUG, "Rx VLAN strip capability enabled\n"); ++ } ++ + bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported); + + HWRM_UNLOCK(); +@@ -756,8 +834,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) if (bp->flags & BNXT_FLAG_REGISTERED) return 0; @@ -25546,7 +37338,20 @@ index 41730089b1..8025d5ad78 100644 flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ERROR_RECOVERY_SUPPORT; /* PFs and trusted VFs should indicate the support of the -@@ -797,7 +843,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) +@@ -769,9 +848,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) + HWRM_PREP(req, FUNC_DRV_RGTR, BNXT_USE_CHIMP_MB); + req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER | + HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD); +- req.ver_maj = RTE_VER_YEAR; +- req.ver_min = RTE_VER_MONTH; +- req.ver_upd = RTE_VER_MINOR; ++ req.ver_maj_8b = RTE_VER_YEAR; ++ req.ver_min_8b = RTE_VER_MONTH; ++ req.ver_upd_8b = RTE_VER_MINOR; + + if (BNXT_PF(bp)) { + req.enables |= rte_cpu_to_le_32( +@@ -797,7 +876,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE | ASYNC_CMPL_EVENT_ID_LINK_SPEED_CHANGE | ASYNC_CMPL_EVENT_ID_RESET_NOTIFY); @@ -25555,7 +37360,7 @@ index 41730089b1..8025d5ad78 100644 req.async_event_fwd[0] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_ERROR_RECOVERY); req.async_event_fwd[1] |= -@@ -810,7 +856,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) +@@ -810,7 +889,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) flags = rte_le_to_cpu_32(resp->flags); if (flags & HWRM_FUNC_DRV_RGTR_OUTPUT_FLAGS_IF_CHANGE_SUPPORTED) @@ -25564,7 +37369,7 @@ index 41730089b1..8025d5ad78 100644 HWRM_UNLOCK(); -@@ -934,7 +980,7 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp) +@@ -934,7 +1013,7 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp) return rc; } @@ -25573,7 +37378,7 @@ index 41730089b1..8025d5ad78 100644 { int rc = 0; struct hwrm_ver_get_input req = {.req_type = 0 }; -@@ -945,6 +991,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) +@@ -945,6 +1024,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) uint32_t dev_caps_cfg; bp->max_req_len = HWRM_MAX_REQ_LEN; @@ -25581,7 +37386,7 @@ index 41730089b1..8025d5ad78 100644 HWRM_PREP(req, VER_GET, BNXT_USE_CHIMP_MB); req.hwrm_intf_maj = HWRM_VERSION_MAJOR; -@@ -958,10 +1005,11 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) +@@ -958,13 +1038,14 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) else HWRM_CHECK_RESULT(); @@ -25590,12 +37395,18 @@ index 41730089b1..8025d5ad78 100644 resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, resp->hwrm_intf_upd_8b, resp->hwrm_fw_maj_8b, - resp->hwrm_fw_min_8b, resp->hwrm_fw_bld_8b); +- bp->fw_ver = (resp->hwrm_fw_maj_8b << 24) | +- (resp->hwrm_fw_min_8b << 16) | +- (resp->hwrm_fw_bld_8b << 8) | + resp->hwrm_fw_min_8b, resp->hwrm_fw_bld_8b, + resp->hwrm_fw_rsvd_8b); - bp->fw_ver = (resp->hwrm_fw_maj_8b << 24) | - (resp->hwrm_fw_min_8b << 16) | - (resp->hwrm_fw_bld_8b << 8) | -@@ -979,7 +1027,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) ++ bp->fw_ver = ((uint32_t)resp->hwrm_fw_maj_8b << 24) | ++ ((uint32_t)resp->hwrm_fw_min_8b << 16) | ++ ((uint32_t)resp->hwrm_fw_bld_8b << 8) | + resp->hwrm_fw_rsvd_8b; + PMD_DRV_LOG(INFO, "Driver HWRM version: %d.%d.%d\n", + HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE); +@@ -979,7 +1060,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) /* convert timeout to usec */ bp->hwrm_cmd_timeout *= 1000; if (!bp->hwrm_cmd_timeout) @@ -25604,18 +37415,47 @@ index 41730089b1..8025d5ad78 100644 if (resp->hwrm_intf_maj_8b != HWRM_VERSION_MAJOR) { PMD_DRV_LOG(ERR, "Unsupported firmware API version\n"); -@@ -1011,9 +1059,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) - rc = -ENOMEM; - goto error; - } +@@ -990,6 +1071,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) + if (bp->max_req_len > resp->max_req_win_len) { + PMD_DRV_LOG(ERR, "Unsupported request length\n"); + rc = -EINVAL; ++ goto error; + } + bp->max_req_len = rte_le_to_cpu_16(resp->max_req_win_len); + bp->hwrm_max_ext_req_len = rte_le_to_cpu_16(resp->max_ext_req_len); +@@ -999,29 +1081,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) + max_resp_len = rte_le_to_cpu_16(resp->max_resp_len); + dev_caps_cfg = rte_le_to_cpu_32(resp->dev_caps_cfg); + +- if (bp->max_resp_len != max_resp_len) { +- sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", +- bp->pdev->addr.domain, bp->pdev->addr.bus, +- bp->pdev->addr.devid, bp->pdev->addr.function); +- +- rte_free(bp->hwrm_cmd_resp_addr); +- +- bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0); +- if (bp->hwrm_cmd_resp_addr == NULL) { +- rc = -ENOMEM; +- goto error; +- } - rte_mem_lock_page(bp->hwrm_cmd_resp_addr); - bp->hwrm_cmd_resp_dma_addr = +- bp->hwrm_cmd_resp_dma_addr = - rte_mem_virt2iova(bp->hwrm_cmd_resp_addr); -+ rte_malloc_virt2iova(bp->hwrm_cmd_resp_addr); - if (bp->hwrm_cmd_resp_dma_addr == RTE_BAD_IOVA) { - PMD_DRV_LOG(ERR, - "Unable to map response buffer to physical memory.\n"); -@@ -1048,9 +1095,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) +- if (bp->hwrm_cmd_resp_dma_addr == RTE_BAD_IOVA) { +- PMD_DRV_LOG(ERR, +- "Unable to map response buffer to physical memory.\n"); +- rc = -ENOMEM; +- goto error; +- } +- bp->max_resp_len = max_resp_len; +- } ++ RTE_VERIFY(max_resp_len <= bp->max_resp_len); ++ bp->max_resp_len = max_resp_len; + + if ((dev_caps_cfg & + HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) && +@@ -1048,9 +1109,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) rc = -ENOMEM; goto error; } @@ -25626,7 +37466,32 @@ index 41730089b1..8025d5ad78 100644 if (bp->hwrm_short_cmd_req_dma_addr == RTE_BAD_IOVA) { rte_free(bp->hwrm_short_cmd_req_addr); PMD_DRV_LOG(ERR, -@@ -1210,6 +1256,35 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, +@@ -1078,7 +1138,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) + return rc; + } + +-int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags) ++int bnxt_hwrm_func_driver_unregister(struct bnxt *bp) + { + int rc; + struct hwrm_func_drv_unrgtr_input req = {.req_type = 0 }; +@@ -1088,7 +1148,6 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags) + return 0; + + HWRM_PREP(req, FUNC_DRV_UNRGTR, BNXT_USE_CHIMP_MB); +- req.flags = flags; + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + +@@ -1190,6 +1249,7 @@ 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->auto_link_speed_mask = rte_le_to_cpu_16(resp->auto_link_speed_mask); + 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; +@@ -1210,6 +1270,35 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, return rc; } @@ -25662,7 +37527,7 @@ index 41730089b1..8025d5ad78 100644 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp) { int rc = 0; -@@ -1269,14 +1344,13 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp) +@@ -1269,14 +1358,13 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp) bp->tx_cos_queue[i].id; } } else { @@ -25684,7 +37549,72 @@ index 41730089b1..8025d5ad78 100644 } } -@@ -2072,8 +2146,8 @@ int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp, +@@ -1480,6 +1568,10 @@ int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx) + struct hwrm_ring_grp_alloc_input req = {.req_type = 0 }; + struct hwrm_ring_grp_alloc_output *resp = bp->hwrm_cmd_resp_addr; + ++ /* Don't attempt to re-create the ring group if it is already created */ ++ if (bp->grp_info[idx].fw_grp_id != INVALID_HW_RING_ID) ++ return 0; ++ + HWRM_PREP(req, RING_GRP_ALLOC, BNXT_USE_CHIMP_MB); + + req.cr = rte_cpu_to_le_16(bp->grp_info[idx].cp_fw_ring_id); +@@ -1504,6 +1596,9 @@ int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned int idx) + struct hwrm_ring_grp_free_input req = {.req_type = 0 }; + struct hwrm_ring_grp_free_output *resp = bp->hwrm_cmd_resp_addr; + ++ if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) ++ return 0; ++ + HWRM_PREP(req, RING_GRP_FREE, BNXT_USE_CHIMP_MB); + + req.ring_group_id = rte_cpu_to_le_16(bp->grp_info[idx].fw_grp_id); +@@ -1538,8 +1633,7 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) + return rc; + } + +-int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, +- unsigned int idx __rte_unused) ++static int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) + { + int rc; + struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 }; +@@ -1562,8 +1656,7 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, + return rc; + } + +-int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, +- unsigned int idx __rte_unused) ++static int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) + { + int rc; + struct hwrm_stat_ctx_free_input req = {.req_type = 0 }; +@@ -1771,12 +1864,6 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) + if (vnic->bd_stall) + req.flags |= + rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE); +- if (vnic->roce_dual) +- req.flags |= rte_cpu_to_le_32( +- HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE); +- if (vnic->roce_only) +- req.flags |= rte_cpu_to_le_32( +- HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE); + if (vnic->rss_dflt_cr) + req.flags |= rte_cpu_to_le_32( + HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE); +@@ -1824,10 +1911,6 @@ int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic, + HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE; + vnic->bd_stall = rte_le_to_cpu_32(resp->flags) & + HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE; +- vnic->roce_dual = rte_le_to_cpu_32(resp->flags) & +- HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE; +- vnic->roce_only = rte_le_to_cpu_32(resp->flags) & +- HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE; + vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) & + HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE; + +@@ -2072,8 +2155,8 @@ int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp, HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO | HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN | HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ); @@ -25695,7 +37625,25 @@ index 41730089b1..8025d5ad78 100644 req.min_agg_len = rte_cpu_to_le_32(512); } req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id); -@@ -2325,13 +2399,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index) +@@ -2229,7 +2312,7 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp) + 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); ++ rc = bnxt_hwrm_stat_ctx_free(bp, cpr); + cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE; + if (rc) + return rc; +@@ -2256,7 +2339,7 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp) + cpr = rxq->cp_ring; + } + +- rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i); ++ rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr); + + if (rc) + return rc; +@@ -2325,13 +2408,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index) if (BNXT_HAS_RING_GRPS(bp)) bp->grp_info[queue_index].rx_fw_ring_id = INVALID_HW_RING_ID; @@ -25709,7 +37657,7 @@ index 41730089b1..8025d5ad78 100644 } ring = rxr->ag_ring_struct; if (ring->fw_ring_id != INVALID_HW_RING_ID) { -@@ -2339,11 +2406,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index) +@@ -2339,11 +2415,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index) BNXT_CHIP_THOR(bp) ? HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG : HWRM_RING_FREE_INPUT_RING_TYPE_RX); @@ -25721,9 +37669,12 @@ index 41730089b1..8025d5ad78 100644 if (BNXT_HAS_RING_GRPS(bp)) bp->grp_info[queue_index].ag_fw_ring_id = INVALID_HW_RING_ID; -@@ -2430,11 +2492,10 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp) +@@ -2428,13 +2499,12 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp) + + sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain, pdev->addr.bus, pdev->addr.devid, pdev->addr.function); - bp->max_resp_len = HWRM_MAX_RESP_LEN; +- bp->max_resp_len = HWRM_MAX_RESP_LEN; ++ bp->max_resp_len = BNXT_PAGE_SIZE; bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0); - rte_mem_lock_page(bp->hwrm_cmd_resp_addr); if (bp->hwrm_cmd_resp_addr == NULL) @@ -25734,7 +37685,7 @@ index 41730089b1..8025d5ad78 100644 if (bp->hwrm_cmd_resp_dma_addr == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); -@@ -2445,18 +2506,32 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp) +@@ -2445,24 +2515,57 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp) return 0; } @@ -25773,7 +37724,32 @@ index 41730089b1..8025d5ad78 100644 STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next); bnxt_free_filter(bp, filter); } -@@ -2474,12 +2549,7 @@ bnxt_clear_hwrm_vnic_flows(struct bnxt *bp, struct bnxt_vnic_info *vnic) + return rc; + } + ++int bnxt_hwrm_rx_ring_reset(struct bnxt *bp, int queue_index) ++{ ++ int rc; ++ struct hwrm_ring_reset_input req = {.req_type = 0 }; ++ struct hwrm_ring_reset_output *resp = bp->hwrm_cmd_resp_addr; ++ ++ HWRM_PREP(req, RING_RESET, BNXT_USE_CHIMP_MB); ++ ++ req.ring_type = HWRM_RING_RESET_INPUT_RING_TYPE_RX_RING_GRP; ++ req.ring_id = rte_cpu_to_le_16(bp->grp_info[queue_index].fw_grp_id); ++ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); ++ ++ HWRM_CHECK_RESULT(); ++ ++ HWRM_UNLOCK(); ++ ++ return rc; ++} ++ + static int + bnxt_clear_hwrm_vnic_flows(struct bnxt *bp, struct bnxt_vnic_info *vnic) + { +@@ -2474,12 +2577,7 @@ bnxt_clear_hwrm_vnic_flows(struct bnxt *bp, struct bnxt_vnic_info *vnic) flow = STAILQ_FIRST(&vnic->flow_list); filter = flow->filter; PMD_DRV_LOG(DEBUG, "filter type %d\n", filter->filter_type); @@ -25787,7 +37763,44 @@ index 41730089b1..8025d5ad78 100644 STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next); rte_free(flow); -@@ -2914,10 +2984,10 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) +@@ -2824,15 +2922,8 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) + + speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds); + link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY; +- /* Autoneg can be done only when the FW allows. +- * When user configures fixed speed of 40G and later changes to +- * any other speed, auto_link_speed/force_link_speed is still set +- * to 40G until link comes up at new speed. +- */ +- if (autoneg == 1 && +- !(!BNXT_CHIP_THOR(bp) && +- (bp->link_info.auto_link_speed || +- bp->link_info.force_link_speed))) { ++ /* Autoneg can be done only when the FW allows. */ ++ if (autoneg == 1 && bp->link_info.support_auto_speeds) { + link_req.phy_flags |= + HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG; + link_req.auto_link_speed_mask = +@@ -2873,7 +2964,6 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) + return rc; + } + +-/* JIRA 22088 */ + int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) + { + struct hwrm_func_qcfg_input req = {0}; +@@ -2888,8 +2978,8 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) + + HWRM_CHECK_RESULT(); + +- /* Hard Coded.. 0xfff VLAN ID mask */ +- bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff; ++ bp->vlan = rte_le_to_cpu_16(resp->vlan) & ETH_VLAN_ID_MAX; ++ + flags = rte_le_to_cpu_16(resp->flags); + if (BNXT_PF(bp) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST)) + bp->flags |= BNXT_FLAG_MULTI_HOST; +@@ -2914,10 +3004,10 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5: case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0: /* FALLTHROUGH */ @@ -25800,7 +37813,7 @@ index 41730089b1..8025d5ad78 100644 break; } -@@ -3053,9 +3123,9 @@ static void add_random_mac_if_needed(struct bnxt *bp, +@@ -3053,9 +3143,9 @@ static void add_random_mac_if_needed(struct bnxt *bp, } } @@ -25813,7 +37826,7 @@ index 41730089b1..8025d5ad78 100644 { struct hwrm_func_qcaps_input req = {0}; struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr; -@@ -3089,6 +3159,8 @@ static void reserve_resources_from_vf(struct bnxt *bp, +@@ -3089,6 +3179,8 @@ static void reserve_resources_from_vf(struct bnxt *bp, bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps); HWRM_UNLOCK(); @@ -25822,7 +37835,7 @@ index 41730089b1..8025d5ad78 100644 } int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf) -@@ -3297,17 +3369,19 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port, +@@ -3297,17 +3389,19 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port, HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC, BNXT_USE_CHIMP_MB); req.tunnel_type = tunnel_type; @@ -25845,7 +37858,7 @@ index 41730089b1..8025d5ad78 100644 bp->geneve_port = port; break; default: -@@ -3382,7 +3456,7 @@ int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp) +@@ -3382,7 +3476,7 @@ int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp) page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN)); req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN); req.req_buf_page_addr0 = @@ -25854,7 +37867,127 @@ index 41730089b1..8025d5ad78 100644 if (req.req_buf_page_addr0 == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, "unable to map buffer address to physical memory\n"); -@@ -3812,11 +3886,11 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data) +@@ -3612,8 +3706,20 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id, + return rc; + } + +-int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx, +- struct rte_eth_stats *stats, uint8_t rx) ++static void bnxt_update_prev_stat(uint64_t *cntr, uint64_t *prev_cntr) ++{ ++ /* One of the HW stat values that make up this counter was zero as ++ * returned by HW in this iteration, so use the previous ++ * iteration's counter value ++ */ ++ if (*prev_cntr && *cntr == 0) ++ *cntr = *prev_cntr; ++ else ++ *prev_cntr = *cntr; ++} ++ ++int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx, ++ struct bnxt_ring_stats *ring_stats, bool rx) + { + int rc = 0; + struct hwrm_stat_ctx_query_input req = {.req_type = 0}; +@@ -3628,21 +3734,82 @@ int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx, + HWRM_CHECK_RESULT(); + + if (rx) { +- stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts); +- stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts); +- stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts); +- stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes); +- stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes); +- stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes); +- stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts); +- stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts); ++ struct bnxt_ring_stats *prev_stats = &bp->prev_rx_ring_stats[idx]; ++ ++ ring_stats->rx_ucast_pkts = rte_le_to_cpu_64(resp->rx_ucast_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_ucast_pkts, ++ &prev_stats->rx_ucast_pkts); ++ ++ ring_stats->rx_mcast_pkts = rte_le_to_cpu_64(resp->rx_mcast_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_mcast_pkts, ++ &prev_stats->rx_mcast_pkts); ++ ++ ring_stats->rx_bcast_pkts = rte_le_to_cpu_64(resp->rx_bcast_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_bcast_pkts, ++ &prev_stats->rx_bcast_pkts); ++ ++ ring_stats->rx_ucast_bytes = rte_le_to_cpu_64(resp->rx_ucast_bytes); ++ bnxt_update_prev_stat(&ring_stats->rx_ucast_bytes, ++ &prev_stats->rx_ucast_bytes); ++ ++ ring_stats->rx_mcast_bytes = rte_le_to_cpu_64(resp->rx_mcast_bytes); ++ bnxt_update_prev_stat(&ring_stats->rx_mcast_bytes, ++ &prev_stats->rx_mcast_bytes); ++ ++ ring_stats->rx_bcast_bytes = rte_le_to_cpu_64(resp->rx_bcast_bytes); ++ bnxt_update_prev_stat(&ring_stats->rx_bcast_bytes, ++ &prev_stats->rx_bcast_bytes); ++ ++ ring_stats->rx_error_pkts = rte_le_to_cpu_64(resp->rx_err_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_error_pkts, ++ &prev_stats->rx_error_pkts); ++ ++ ring_stats->rx_discard_pkts = rte_le_to_cpu_64(resp->rx_drop_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_discard_pkts, ++ &prev_stats->rx_discard_pkts); ++ ++ ring_stats->rx_agg_pkts = rte_le_to_cpu_64(resp->rx_agg_pkts); ++ bnxt_update_prev_stat(&ring_stats->rx_agg_pkts, ++ &prev_stats->rx_agg_pkts); ++ ++ ring_stats->rx_agg_bytes = rte_le_to_cpu_64(resp->rx_agg_bytes); ++ bnxt_update_prev_stat(&ring_stats->rx_agg_bytes, ++ &prev_stats->rx_agg_bytes); ++ ++ ring_stats->rx_agg_events = rte_le_to_cpu_64(resp->rx_agg_events); ++ bnxt_update_prev_stat(&ring_stats->rx_agg_events, ++ &prev_stats->rx_agg_events); ++ ++ ring_stats->rx_agg_aborts = rte_le_to_cpu_64(resp->rx_agg_aborts); ++ bnxt_update_prev_stat(&ring_stats->rx_agg_aborts, ++ &prev_stats->rx_agg_aborts); + } else { +- stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts); +- stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts); +- stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts); +- stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes); +- stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes); +- stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes); ++ struct bnxt_ring_stats *prev_stats = &bp->prev_tx_ring_stats[idx]; ++ ++ ring_stats->tx_ucast_pkts = rte_le_to_cpu_64(resp->tx_ucast_pkts); ++ bnxt_update_prev_stat(&ring_stats->tx_ucast_pkts, ++ &prev_stats->tx_ucast_pkts); ++ ++ ring_stats->tx_mcast_pkts = rte_le_to_cpu_64(resp->tx_mcast_pkts); ++ bnxt_update_prev_stat(&ring_stats->tx_mcast_pkts, ++ &prev_stats->tx_mcast_pkts); ++ ++ ring_stats->tx_bcast_pkts = rte_le_to_cpu_64(resp->tx_bcast_pkts); ++ bnxt_update_prev_stat(&ring_stats->tx_bcast_pkts, ++ &prev_stats->tx_bcast_pkts); ++ ++ ring_stats->tx_ucast_bytes = rte_le_to_cpu_64(resp->tx_ucast_bytes); ++ bnxt_update_prev_stat(&ring_stats->tx_ucast_bytes, ++ &prev_stats->tx_ucast_bytes); ++ ++ ring_stats->tx_mcast_bytes = rte_le_to_cpu_64(resp->tx_mcast_bytes); ++ bnxt_update_prev_stat(&ring_stats->tx_mcast_bytes, ++ &prev_stats->tx_mcast_bytes); ++ ++ ring_stats->tx_bcast_bytes = rte_le_to_cpu_64(resp->tx_bcast_bytes); ++ bnxt_update_prev_stat(&ring_stats->tx_bcast_bytes, ++ &prev_stats->tx_bcast_bytes); ++ + } + + HWRM_UNLOCK(); +@@ -3812,11 +3979,11 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data) buflen = dir_entries * entry_length; buf = rte_malloc("nvm_dir", buflen, 0); @@ -25868,7 +38001,7 @@ index 41730089b1..8025d5ad78 100644 PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; -@@ -3846,12 +3920,12 @@ int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index, +@@ -3846,12 +4013,12 @@ int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index, struct hwrm_nvm_read_output *resp = bp->hwrm_cmd_resp_addr; buf = rte_malloc("nvm_item", length, 0); @@ -25883,7 +38016,7 @@ index 41730089b1..8025d5ad78 100644 PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; -@@ -3900,12 +3974,12 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type, +@@ -3900,12 +4067,12 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type, uint8_t *buf; buf = rte_malloc("nvm_write", data_len, 0); @@ -25898,7 +38031,7 @@ index 41730089b1..8025d5ad78 100644 PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; -@@ -3967,7 +4041,7 @@ static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf, +@@ -3967,7 +4134,7 @@ static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf, req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf); req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics); @@ -25907,7 +38040,7 @@ index 41730089b1..8025d5ad78 100644 if (req.vnic_id_tbl_addr == RTE_BAD_IOVA) { HWRM_UNLOCK(); -@@ -4391,37 +4465,35 @@ int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic) +@@ -4391,37 +4558,35 @@ int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic) { unsigned int rss_idx, fw_idx, i; @@ -25965,7 +38098,7 @@ index 41730089b1..8025d5ad78 100644 } static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, -@@ -4831,7 +4903,6 @@ int bnxt_hwrm_set_mac(struct bnxt *bp) +@@ -4831,7 +4996,6 @@ int bnxt_hwrm_set_mac(struct bnxt *bp) HWRM_CHECK_RESULT(); @@ -25973,7 +38106,7 @@ index 41730089b1..8025d5ad78 100644 HWRM_UNLOCK(); return rc; -@@ -4844,7 +4915,7 @@ int bnxt_hwrm_if_change(struct bnxt *bp, bool up) +@@ -4844,7 +5008,7 @@ int bnxt_hwrm_if_change(struct bnxt *bp, bool up) uint32_t flags; int rc; @@ -25982,7 +38115,7 @@ index 41730089b1..8025d5ad78 100644 return 0; /* Do not issue FUNC_DRV_IF_CHANGE during reset recovery. -@@ -4887,7 +4958,7 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) +@@ -4887,7 +5051,7 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) int rc; /* Older FW does not have error recovery support */ @@ -25991,47 +38124,116 @@ index 41730089b1..8025d5ad78 100644 return 0; if (!info) { -@@ -5034,35 +5105,3 @@ int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path, uint64_t *timestamp) +@@ -5034,34 +5198,78 @@ int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path, uint64_t *timestamp) return rc; } - -int bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(struct bnxt *bp) --{ ++int bnxt_hwrm_poll_ver_get(struct bnxt *bp) + { - struct hwrm_cfa_adv_flow_mgnt_qcaps_output *resp = - bp->hwrm_cmd_resp_addr; - struct hwrm_cfa_adv_flow_mgnt_qcaps_input req = {0}; - uint32_t flags = 0; -- int rc = 0; -- ++ struct hwrm_ver_get_input req = {.req_type = 0 }; ++ struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr; + int rc = 0; + - if (!(bp->flags & BNXT_FLAG_ADV_FLOW_MGMT)) - return rc; -- ++ bp->max_req_len = HWRM_MAX_REQ_LEN; ++ bp->max_resp_len = BNXT_PAGE_SIZE; ++ bp->hwrm_cmd_timeout = SHORT_HWRM_CMD_TIMEOUT; + - if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) { - PMD_DRV_LOG(DEBUG, - "Not a PF or trusted VF. Command not supported\n"); -- return 0; ++ HWRM_PREP(req, VER_GET, BNXT_USE_CHIMP_MB); ++ req.hwrm_intf_maj = HWRM_VERSION_MAJOR; ++ req.hwrm_intf_min = HWRM_VERSION_MINOR; ++ req.hwrm_intf_upd = HWRM_VERSION_UPDATE; ++ ++ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); ++ ++ HWRM_CHECK_RESULT_SILENT(); ++ HWRM_UNLOCK(); ++ ++ return rc; ++} ++ ++int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp) ++{ ++ int rc = 0; ++ struct hwrm_port_phy_qcaps_input req = {0}; ++ struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr; ++ struct bnxt_link_info *link_info = &bp->link_info; ++ ++ if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) + return 0; - } -- + - HWRM_PREP(req, CFA_ADV_FLOW_MGNT_QCAPS, BNXT_USE_KONG(bp)); - rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp)); -- -- HWRM_CHECK_RESULT(); ++ HWRM_PREP(req, PORT_PHY_QCAPS, BNXT_USE_CHIMP_MB); ++ ++ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + + HWRM_CHECK_RESULT(); - flags = rte_le_to_cpu_32(resp->flags); -- HWRM_UNLOCK(); -- ++ ++ if (resp->supported_speeds_auto_mode) ++ link_info->support_auto_speeds = ++ rte_le_to_cpu_16(resp->supported_speeds_auto_mode); ++ ++ /* Older firmware does not have supported_auto_speeds, so assume ++ * that all supported speeds can be autonegotiated. ++ */ ++ if (link_info->auto_link_speed_mask && !link_info->support_auto_speeds) ++ link_info->support_auto_speeds = link_info->support_speeds; ++ + HWRM_UNLOCK(); + - if (flags & HWRM_CFA_ADV_FLOW_MGNT_QCAPS_L2_HDR_SRC_FILTER_EN) { - bp->flow_flags |= BNXT_FLOW_FLAG_L2_HDR_SRC_FILTER_EN; - PMD_DRV_LOG(INFO, "Source L2 header filtering enabled\n"); -- } -- -- return rc; --} ++ return 0; ++} ++ ++int ++bnxt_vnic_rss_clear_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) ++{ ++ struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr; ++ struct hwrm_vnic_rss_cfg_input req = {0}; ++ int nr_ctxs = vnic->num_lb_ctxts; ++ int i, rc = 0; ++ ++ for (i = 0; i < nr_ctxs; i++) { ++ HWRM_PREP(req, VNIC_RSS_CFG, BNXT_USE_CHIMP_MB); ++ ++ req.rss_ctx_idx = rte_cpu_to_le_16(vnic->fw_grp_ids[i]); ++ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id); ++ ++ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); ++ ++ HWRM_CHECK_RESULT(); ++ HWRM_UNLOCK(); + } + + return rc; diff --git a/dpdk/drivers/net/bnxt/bnxt_hwrm.h b/dpdk/drivers/net/bnxt/bnxt_hwrm.h -index abe5de9db6..8ceaeb59c0 100644 +index abe5de9db6..bb1762d27b 100644 --- a/dpdk/drivers/net/bnxt/bnxt_hwrm.h +++ b/dpdk/drivers/net/bnxt/bnxt_hwrm.h -@@ -35,6 +35,9 @@ struct bnxt_cp_ring_info; +@@ -13,7 +13,6 @@ struct bnxt; + struct bnxt_filter_info; + struct bnxt_cp_ring_info; + +-#define HWRM_SEQ_ID_INVALID -1U + /* Convert Bit field location to value */ + #define ASYNC_CMPL_EVENT_ID_LINK_STATUS_CHANGE \ + (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE) +@@ -35,6 +34,9 @@ struct bnxt_cp_ring_info; #define HWRM_QUEUE_SERVICE_PROFILE_LOSSY \ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY @@ -26041,36 +38243,83 @@ index abe5de9db6..8ceaeb59c0 100644 #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC \ HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MAXIMAL \ -@@ -86,6 +89,7 @@ int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp); +@@ -86,8 +88,9 @@ int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp); int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp); int bnxt_hwrm_func_driver_register(struct bnxt *bp); int bnxt_hwrm_func_qcaps(struct bnxt *bp); -+void bnxt_hwrm_free_vf_info(struct bnxt *bp); ++void bnxt_free_vf_info(struct bnxt *bp); int bnxt_hwrm_func_reset(struct bnxt *bp); - int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags); +-int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags); ++int bnxt_hwrm_func_driver_unregister(struct bnxt *bp); int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid, -@@ -117,7 +121,7 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, - int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx, - struct rte_eth_stats *stats, uint8_t rx); - + struct rte_eth_stats *stats); + int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid, +@@ -110,14 +113,7 @@ int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx); + int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned int idx); + + int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr); +-int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, +- struct bnxt_cp_ring_info *cpr, unsigned int idx); +-int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, +- struct bnxt_cp_ring_info *cpr, unsigned int idx); +-int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx, +- struct rte_eth_stats *stats, uint8_t rx); +- -int bnxt_hwrm_ver_get(struct bnxt *bp); +int bnxt_hwrm_ver_get(struct bnxt *bp, uint32_t timeout); int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic); int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic); -@@ -226,5 +230,6 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp); +@@ -226,5 +222,12 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp); int bnxt_hwrm_fw_reset(struct bnxt *bp); int bnxt_hwrm_port_ts_query(struct bnxt *bp, uint8_t path, uint64_t *timestamp); -int bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(struct bnxt *bp); +int bnxt_clear_one_vnic_filter(struct bnxt *bp, + struct bnxt_filter_info *filter); ++int bnxt_hwrm_poll_ver_get(struct bnxt *bp); ++int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp); ++int bnxt_hwrm_rx_ring_reset(struct bnxt *bp, int queue_index); ++int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx, ++ struct bnxt_ring_stats *stats, bool rx); ++int bnxt_vnic_rss_clear_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic); #endif diff --git a/dpdk/drivers/net/bnxt/bnxt_irq.c b/dpdk/drivers/net/bnxt/bnxt_irq.c -index 846325ea96..40e1b0c980 100644 +index 846325ea96..f442edacca 100644 --- a/dpdk/drivers/net/bnxt/bnxt_irq.c +++ b/dpdk/drivers/net/bnxt/bnxt_irq.c -@@ -181,5 +181,13 @@ int bnxt_request_int(struct bnxt *bp) +@@ -21,15 +21,18 @@ void bnxt_int_handler(void *param) + { + struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param; + struct bnxt *bp = eth_dev->data->dev_private; +- struct bnxt_cp_ring_info *cpr = bp->async_cp_ring; ++ uint32_t cons, raw_cons, cp_ring_size; ++ struct bnxt_cp_ring_info *cpr; + struct cmpl_base *cmp; +- uint32_t raw_cons; +- uint32_t cons; + ++ if (bp == NULL) ++ return; ++ cpr = bp->async_cp_ring; + if (cpr == NULL) + return; + + raw_cons = cpr->cp_raw_cons; ++ cp_ring_size = cpr->cp_ring_struct->ring_size; + pthread_mutex_lock(&bp->def_cp_lock); + while (1) { + if (!cpr || !cpr->cp_ring_struct || !cpr->cp_db.doorbell) { +@@ -45,7 +48,7 @@ void bnxt_int_handler(void *param) + cons = RING_CMP(cpr->cp_ring_struct, raw_cons); + cmp = &cpr->cp_desc_ring[cons]; + +- if (!CMP_VALID(cmp, raw_cons, cpr->cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(cmp, raw_cons, cp_ring_size)) + break; + + bnxt_event_hwrm_resp_handler(bp, cmp); +@@ -181,5 +184,13 @@ int bnxt_request_int(struct bnxt *bp) irq->requested = 1; } @@ -26085,9 +38334,18 @@ index 846325ea96..40e1b0c980 100644 return rc; } diff --git a/dpdk/drivers/net/bnxt/bnxt_ring.c b/dpdk/drivers/net/bnxt/bnxt_ring.c -index ea46fa9bc0..bb60f8ab0f 100644 +index ea46fa9bc0..b56313a6a9 100644 --- a/dpdk/drivers/net/bnxt/bnxt_ring.c +++ b/dpdk/drivers/net/bnxt/bnxt_ring.c +@@ -94,7 +94,7 @@ int bnxt_alloc_ring_grps(struct bnxt *bp) + * tx bd ring - Only non-zero length if tx_ring_info is not NULL + * rx bd ring - Only non-zero length if rx_ring_info is not NULL + */ +-int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, ++int bnxt_alloc_rings(struct bnxt *bp, unsigned int socket_id, uint16_t qidx, + struct bnxt_tx_queue *txq, + struct bnxt_rx_queue *rxq, + struct bnxt_cp_ring_info *cp_ring_info, @@ -110,9 +110,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, uint64_t rx_offloads = bp->eth_dev->data->dev_conf.rxmode.offloads; const struct rte_memzone *mz = NULL; @@ -26098,6 +38356,15 @@ index ea46fa9bc0..bb60f8ab0f 100644 int stats_len = (tx_ring_info || rx_ring_info) ? RTE_CACHE_LINE_ROUNDUP(sizeof(struct hwrm_stat_ctx_query_output) - +@@ -205,7 +203,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, + mz = rte_memzone_lookup(mz_name); + if (!mz) { + mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len, +- SOCKET_ID_ANY, ++ socket_id, + RTE_MEMZONE_2MB | + RTE_MEMZONE_SIZE_HINT_ONLY | + RTE_MEMZONE_IOVA_CONTIG, @@ -214,22 +212,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, return -ENOMEM; } @@ -26121,14 +38388,48 @@ index ea46fa9bc0..bb60f8ab0f 100644 if (tx_ring_info) { txq->mz = mz; -@@ -468,6 +451,7 @@ int bnxt_alloc_rxtx_nq_ring(struct bnxt *bp) +@@ -439,24 +422,23 @@ int bnxt_alloc_rxtx_nq_ring(struct bnxt *bp) + struct bnxt_cp_ring_info *nqr; + struct bnxt_ring *ring; + int ring_index = BNXT_NUM_ASYNC_CPR(bp); +- unsigned int socket_id; + uint8_t ring_type; + int rc = 0; + + if (!BNXT_HAS_NQ(bp) || bp->rxtx_nq_ring) + return 0; + +- socket_id = rte_lcore_to_socket_id(rte_get_master_lcore()); +- + nqr = rte_zmalloc_socket("nqr", + sizeof(struct bnxt_cp_ring_info), +- RTE_CACHE_LINE_SIZE, socket_id); ++ RTE_CACHE_LINE_SIZE, ++ bp->eth_dev->device->numa_node); + if (nqr == NULL) + return -ENOMEM; + + ring = rte_zmalloc_socket("bnxt_cp_ring_struct", + sizeof(struct bnxt_ring), +- RTE_CACHE_LINE_SIZE, socket_id); ++ RTE_CACHE_LINE_SIZE, ++ bp->eth_dev->device->numa_node); + if (ring == NULL) { + rte_free(nqr); + return -ENOMEM; +@@ -468,9 +450,11 @@ int bnxt_alloc_rxtx_nq_ring(struct bnxt *bp) ring->ring_mask = ring->ring_size - 1; ring->vmem_size = 0; ring->vmem = NULL; + ring->fw_ring_id = INVALID_HW_RING_ID; nqr->cp_ring_struct = ring; - rc = bnxt_alloc_rings(bp, 0, NULL, NULL, nqr, NULL, "l2_nqr"); +- rc = bnxt_alloc_rings(bp, 0, NULL, NULL, nqr, NULL, "l2_nqr"); ++ rc = bnxt_alloc_rings(bp, bp->eth_dev->device->numa_node, 0, NULL, ++ NULL, nqr, NULL, "l2_nqr"); + if (rc) { + rte_free(ring); + rte_free(nqr); @@ -615,7 +599,7 @@ int bnxt_alloc_hwrm_rx_ring(struct bnxt *bp, int queue_index) if (rxq->rx_started) { @@ -26138,8 +38439,50 @@ index ea46fa9bc0..bb60f8ab0f 100644 "bnxt_init_one_rx_ring failed!\n"); bnxt_rx_queue_release_op(rxq); rc = -ENOMEM; +@@ -831,22 +815,21 @@ int bnxt_alloc_async_ring_struct(struct bnxt *bp) + { + struct bnxt_cp_ring_info *cpr = NULL; + struct bnxt_ring *ring = NULL; +- unsigned int socket_id; + + if (BNXT_NUM_ASYNC_CPR(bp) == 0) + return 0; + +- socket_id = rte_lcore_to_socket_id(rte_get_master_lcore()); +- + cpr = rte_zmalloc_socket("cpr", + sizeof(struct bnxt_cp_ring_info), +- RTE_CACHE_LINE_SIZE, socket_id); ++ RTE_CACHE_LINE_SIZE, ++ bp->eth_dev->device->numa_node); + if (cpr == NULL) + return -ENOMEM; + + ring = rte_zmalloc_socket("bnxt_cp_ring_struct", + sizeof(struct bnxt_ring), +- RTE_CACHE_LINE_SIZE, socket_id); ++ RTE_CACHE_LINE_SIZE, ++ bp->eth_dev->device->numa_node); + if (ring == NULL) { + rte_free(cpr); + return -ENOMEM; +@@ -858,11 +841,11 @@ int bnxt_alloc_async_ring_struct(struct bnxt *bp) + ring->ring_mask = ring->ring_size - 1; + ring->vmem_size = 0; + ring->vmem = NULL; ++ ring->fw_ring_id = INVALID_HW_RING_ID; + + bp->async_cp_ring = cpr; + cpr->cp_ring_struct = ring; + +- return bnxt_alloc_rings(bp, 0, NULL, NULL, +- bp->async_cp_ring, NULL, +- "def_cp"); ++ return bnxt_alloc_rings(bp, bp->eth_dev->device->numa_node, 0, NULL, ++ NULL, bp->async_cp_ring, NULL, "def_cp"); + } diff --git a/dpdk/drivers/net/bnxt/bnxt_ring.h b/dpdk/drivers/net/bnxt/bnxt_ring.h -index 48a39d7884..0a4685d167 100644 +index 48a39d7884..201b3919ed 100644 --- a/dpdk/drivers/net/bnxt/bnxt_ring.h +++ b/dpdk/drivers/net/bnxt/bnxt_ring.h @@ -27,7 +27,7 @@ @@ -26151,6 +38494,15 @@ index 48a39d7884..0a4685d167 100644 #define AGG_RING_MULTIPLIER 2 /* These assume 4k pages */ +@@ -66,7 +66,7 @@ struct bnxt_rx_ring_info; + struct bnxt_cp_ring_info; + void bnxt_free_ring(struct bnxt_ring *ring); + int bnxt_alloc_ring_grps(struct bnxt *bp); +-int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, ++int bnxt_alloc_rings(struct bnxt *bp, unsigned int socket_id, uint16_t qidx, + struct bnxt_tx_queue *txq, + struct bnxt_rx_queue *rxq, + struct bnxt_cp_ring_info *cp_ring_info, @@ -83,7 +83,7 @@ void bnxt_free_rxtx_nq_ring(struct bnxt *bp); static inline void bnxt_db_write(struct bnxt_db_info *db, uint32_t idx) { @@ -26201,22 +38553,72 @@ index 48a39d7884..0a4685d167 100644 #endif diff --git a/dpdk/drivers/net/bnxt/bnxt_rxq.c b/dpdk/drivers/net/bnxt/bnxt_rxq.c -index 457ebede0e..df00191c09 100644 +index 457ebede0e..616a0d2360 100644 --- a/dpdk/drivers/net/bnxt/bnxt_rxq.c +++ b/dpdk/drivers/net/bnxt/bnxt_rxq.c -@@ -168,10 +168,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp) - if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { - struct rte_eth_rss_conf *rss = &dev_conf->rx_adv_conf.rss_conf; +@@ -40,35 +40,6 @@ int bnxt_mq_rx_configure(struct bnxt *bp) + + bp->nr_vnics = 0; + +- /* Single queue mode */ +- if (bp->rx_cp_nr_rings < 2) { +- vnic = &bp->vnic_info[0]; +- if (!vnic) { +- PMD_DRV_LOG(ERR, "VNIC alloc failed\n"); +- rc = -ENOMEM; +- goto err_out; +- } +- vnic->flags |= BNXT_VNIC_INFO_BCAST; +- bp->nr_vnics++; +- +- rxq = bp->eth_dev->data->rx_queues[0]; +- rxq->vnic = vnic; +- +- vnic->func_default = true; +- vnic->start_grp_id = 0; +- vnic->end_grp_id = vnic->start_grp_id; +- filter = bnxt_alloc_filter(bp); +- if (!filter) { +- PMD_DRV_LOG(ERR, "L2 filter alloc failed\n"); +- rc = -ENOMEM; +- goto err_out; +- } +- filter->mac_index = 0; +- filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; +- STAILQ_INSERT_TAIL(&vnic->filter, filter, next); +- goto out; +- } +- + /* Multi-queue mode */ + if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_DCB_RSS) { + /* VMDq ONLY, VMDq+RSS, VMDq+DCB, VMDq+DCB+RSS */ +@@ -106,7 +77,6 @@ int bnxt_mq_rx_configure(struct bnxt *bp) + + pools = RTE_MIN(pools, bp->rx_cp_nr_rings); + nb_q_per_grp = bp->rx_cp_nr_rings / pools; +- bp->rx_num_qs_per_vnic = nb_q_per_grp; + PMD_DRV_LOG(DEBUG, "pools = %u nb_q_per_grp = %u\n", + pools, nb_q_per_grp); + start_grp_id = 0; +@@ -164,14 +134,10 @@ int bnxt_mq_rx_configure(struct bnxt *bp) + end_grp_id += nb_q_per_grp; + } + +-out: +- if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { +- struct rte_eth_rss_conf *rss = &dev_conf->rx_adv_conf.rss_conf; ++ bp->rx_num_qs_per_vnic = nb_q_per_grp; - if (bp->flags & BNXT_FLAG_UPDATE_HASH) { - rss = &bp->rss_conf; -+ if (bp->flags & BNXT_FLAG_UPDATE_HASH) - bp->flags &= ~BNXT_FLAG_UPDATE_HASH; +- bp->flags &= ~BNXT_FLAG_UPDATE_HASH; - } ++ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { ++ struct rte_eth_rss_conf *rss = &bp->rss_conf; for (i = 0; i < bp->nr_vnics; i++) { vnic = &bp->vnic_info[i]; -@@ -203,11 +201,9 @@ void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq) +@@ -203,11 +169,9 @@ void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq) struct bnxt_tpa_info *tpa_info; uint16_t i; @@ -26229,7 +38631,7 @@ index 457ebede0e..df00191c09 100644 sw_ring = rxq->rx_ring->rx_buf_ring; if (sw_ring) { for (i = 0; -@@ -243,7 +239,6 @@ void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq) +@@ -243,7 +207,6 @@ void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq) } } @@ -26237,7 +38639,7 @@ index 457ebede0e..df00191c09 100644 } void bnxt_free_rx_mbufs(struct bnxt *bp) -@@ -268,12 +263,21 @@ void bnxt_rx_queue_release_op(void *rx_queue) +@@ -268,12 +231,21 @@ void bnxt_rx_queue_release_op(void *rx_queue) bnxt_rx_queue_release_mbufs(rxq); /* Free RX ring hardware descriptors */ @@ -26264,7 +38666,7 @@ index 457ebede0e..df00191c09 100644 bnxt_free_rxq_stats(rxq); rte_memzone_free(rxq->mz); -@@ -300,7 +304,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -300,7 +272,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, if (rc) return rc; @@ -26273,7 +38675,7 @@ index 457ebede0e..df00191c09 100644 PMD_DRV_LOG(ERR, "Cannot create Rx ring %d. Only %d rings available\n", queue_idx, bp->max_rx_rings); -@@ -309,8 +313,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -309,8 +281,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) { PMD_DRV_LOG(ERR, "nb_desc %d is invalid\n", nb_desc); @@ -26283,7 +38685,7 @@ index 457ebede0e..df00191c09 100644 } if (eth_dev->data->rx_queues) { -@@ -322,19 +325,26 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -322,19 +293,26 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, RTE_CACHE_LINE_SIZE, socket_id); if (!rxq) { PMD_DRV_LOG(ERR, "bnxt_rx_queue allocation failed!\n"); @@ -26314,14 +38716,14 @@ index 457ebede0e..df00191c09 100644 PMD_DRV_LOG(DEBUG, "RX Buf size is %d\n", rxq->rx_buf_size); rxq->queue_id = queue_idx; -@@ -346,13 +356,12 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -346,13 +324,12 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, eth_dev->data->rx_queues[queue_idx] = rxq; /* Allocate RX ring hardware descriptors */ - if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq, rxq->cp_ring, NULL, - "rxr")) { -+ rc = bnxt_alloc_rings(bp, queue_idx, NULL, rxq, rxq->cp_ring, NULL, -+ "rxr"); ++ rc = bnxt_alloc_rings(bp, socket_id, queue_idx, NULL, rxq, rxq->cp_ring, ++ NULL, "rxr"); + if (rc) { PMD_DRV_LOG(ERR, - "ring_dma_zone_reserve for rx_ring failed!\n"); @@ -26333,15 +38735,15 @@ index 457ebede0e..df00191c09 100644 } rte_atomic64_init(&rxq->rx_mbuf_alloc_fail); -@@ -370,13 +379,14 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -370,13 +347,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, rxq->rx_started = true; } eth_dev->data->rx_queue_state[queue_idx] = queue_state; - rte_spinlock_init(&rxq->lock); - - /* Configure mtu if it is different from what was configured before */ - if (!queue_idx) - bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu); +- +- /* Configure mtu if it is different from what was configured before */ +- if (!queue_idx) +- bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu); -out: + return 0; @@ -26350,7 +38752,7 @@ index 457ebede0e..df00191c09 100644 return rc; } -@@ -540,12 +550,12 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +@@ -540,12 +514,12 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) rc = bnxt_vnic_rss_configure(bp, vnic); } @@ -26368,7 +38770,17 @@ index 457ebede0e..df00191c09 100644 /* * For Thor, we need to ensure that the VNIC default receive * ring corresponds to an active receive queue. When no queue -@@ -565,6 +575,22 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +@@ -557,6 +531,9 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) + if (active_queue_cnt == 0) { + uint16_t saved_mru = vnic->mru; + ++ /* clear RSS setting on vnic. */ ++ bnxt_vnic_rss_clear_p5(bp, vnic); ++ + vnic->mru = 0; + /* Reconfigure default receive ring and MRU. */ + bnxt_hwrm_vnic_cfg(bp, vnic); +@@ -565,6 +542,22 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) /* Reconfigure default receive ring. */ bnxt_hwrm_vnic_cfg(bp, vnic); } @@ -26392,7 +38804,7 @@ index 457ebede0e..df00191c09 100644 if (rc == 0) diff --git a/dpdk/drivers/net/bnxt/bnxt_rxq.h b/dpdk/drivers/net/bnxt/bnxt_rxq.h -index 4f5182d9e9..ae3badb7a0 100644 +index 4f5182d9e9..6942af9d41 100644 --- a/dpdk/drivers/net/bnxt/bnxt_rxq.h +++ b/dpdk/drivers/net/bnxt/bnxt_rxq.h @@ -6,13 +6,13 @@ @@ -26412,19 +38824,101 @@ index 4f5182d9e9..ae3badb7a0 100644 struct rte_mempool *mb_pool; /* mbuf pool for RX ring */ struct rte_mbuf *pkt_first_seg; /* 1st seg of pkt */ struct rte_mbuf *pkt_last_seg; /* Last seg of pkt */ -@@ -31,6 +31,7 @@ struct bnxt_rx_queue { +@@ -31,6 +31,8 @@ struct bnxt_rx_queue { uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */ uint8_t rx_deferred_start; /* not in global dev start */ uint8_t rx_started; /* RX queue is started */ + uint8_t drop_en; /* Drop when rx desc not available. */ ++ uint8_t in_reset; /* Rx ring is scheduled for reset */ struct bnxt *bp; int index; diff --git a/dpdk/drivers/net/bnxt/bnxt_rxr.c b/dpdk/drivers/net/bnxt/bnxt_rxr.c -index 3b713c2427..1cf8f3e17c 100644 +index 3b713c2427..3355e00c85 100644 --- a/dpdk/drivers/net/bnxt/bnxt_rxr.c +++ b/dpdk/drivers/net/bnxt/bnxt_rxr.c -@@ -145,6 +145,7 @@ static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, +@@ -10,15 +10,14 @@ + #include + #include + #include ++#include + + #include "bnxt.h" + #include "bnxt_ring.h" + #include "bnxt_rxr.h" + #include "bnxt_rxq.h" + #include "hsi_struct_def_dpdk.h" +-#ifdef RTE_LIBRTE_IEEE1588 + #include "bnxt_hwrm.h" +-#endif + + /* + * RX Ring handling +@@ -122,6 +121,50 @@ struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr, + return mbuf; + } + ++static void bnxt_rx_ring_reset(void *arg) ++{ ++ struct bnxt *bp = arg; ++ int i, rc = 0; ++ struct bnxt_rx_queue *rxq; ++ ++ ++ for (i = 0; i < (int)bp->rx_nr_rings; i++) { ++ struct bnxt_rx_ring_info *rxr; ++ ++ rxq = bp->rx_queues[i]; ++ if (!rxq || !rxq->in_reset) ++ continue; ++ ++ rxr = rxq->rx_ring; ++ /* Disable and flush TPA before resetting the RX ring */ ++ if (rxr->tpa_info) ++ bnxt_hwrm_vnic_tpa_cfg(bp, rxq->vnic, false); ++ rc = bnxt_hwrm_rx_ring_reset(bp, i); ++ if (rc) { ++ PMD_DRV_LOG(ERR, "Rx ring%d reset failed\n", i); ++ continue; ++ } ++ ++ bnxt_rx_queue_release_mbufs(rxq); ++ rxr->rx_prod = 0; ++ rxr->ag_prod = 0; ++ rxr->rx_next_cons = 0; ++ bnxt_init_one_rx_ring(rxq); ++ bnxt_db_write(&rxr->rx_db, rxr->rx_prod); ++ bnxt_db_write(&rxr->ag_db, rxr->ag_prod); ++ if (rxr->tpa_info) ++ bnxt_hwrm_vnic_tpa_cfg(bp, rxq->vnic, true); ++ ++ rxq->in_reset = 0; ++ } ++} ++ ++static void bnxt_sched_ring_reset(struct bnxt_rx_queue *rxq) ++{ ++ rxq->in_reset = 1; ++ rte_eal_alarm_set(1, bnxt_rx_ring_reset, (void *)rxq->bp); ++} ++ + static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, + struct rx_tpa_start_cmpl *tpa_start, + struct rx_tpa_start_cmpl_hi *tpa_start1) +@@ -136,6 +179,12 @@ static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, + + data_cons = tpa_start->opaque; + tpa_info = &rxr->tpa_info[agg_id]; ++ if (unlikely(data_cons != rxr->rx_next_cons)) { ++ PMD_DRV_LOG(ERR, "TPA cons %x, expected cons %x\n", ++ data_cons, rxr->rx_next_cons); ++ bnxt_sched_ring_reset(rxq); ++ return; ++ } + + mbuf = bnxt_consume_rx_buf(rxr, data_cons); + +@@ -145,6 +194,7 @@ static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, tpa_info->mbuf = mbuf; tpa_info->len = rte_le_to_cpu_32(tpa_start->len); @@ -26432,7 +38926,38 @@ index 3b713c2427..1cf8f3e17c 100644 mbuf->nb_segs = 1; mbuf->next = NULL; mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len); -@@ -261,6 +262,7 @@ static int bnxt_rx_pages(struct bnxt_rx_queue *rxq, +@@ -159,8 +209,9 @@ static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, + mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code); + mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID; + } +- if (tpa_start1->flags2 & +- rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) { ++ if (BNXT_RX_VLAN_STRIP_EN(rxq->bp) && ++ (tpa_start1->flags2 & ++ rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN))) { + mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata); + mbuf->ol_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED; + } +@@ -171,6 +222,8 @@ static void bnxt_tpa_start(struct bnxt_rx_queue *rxq, + /* recycle next mbuf */ + data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons); + bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons)); ++ ++ rxr->rx_next_cons = RING_NEXT(rxr->rx_ring_struct, data_cons); + } + + static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr, +@@ -185,7 +238,8 @@ static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr, + cpr->valid = FLIP_VALID(raw_cp_cons, + cpr->cp_ring_struct->ring_mask, + cpr->valid); +- return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct); ++ return bnxt_cpr_cmp_valid(agg_cmpl, raw_cp_cons, ++ cpr->cp_ring_struct->ring_size); + } + + /* TPA consume agg buffer out of order, allocate connected data only */ +@@ -261,10 +315,39 @@ static int bnxt_rx_pages(struct bnxt_rx_queue *rxq, */ rte_bitmap_set(rxr->ag_bitmap, ag_cons); } @@ -26440,7 +38965,53 @@ index 3b713c2427..1cf8f3e17c 100644 bnxt_prod_ag_mbuf(rxq); return 0; } -@@ -300,7 +302,6 @@ static inline struct rte_mbuf *bnxt_tpa_end( + ++static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, ++ uint32_t *raw_cons, void *cmp) ++{ ++ struct rx_pkt_cmpl *rxcmp = cmp; ++ uint32_t tmp_raw_cons = *raw_cons; ++ uint8_t cmp_type, agg_bufs = 0; ++ ++ cmp_type = CMP_TYPE(rxcmp); ++ ++ if (cmp_type == CMPL_BASE_TYPE_RX_L2) { ++ agg_bufs = BNXT_RX_L2_AGG_BUFS(rxcmp); ++ } else if (cmp_type == RX_TPA_END_CMPL_TYPE_RX_TPA_END) { ++ struct rx_tpa_end_cmpl *tpa_end = cmp; ++ ++ if (BNXT_CHIP_THOR(bp)) ++ return 0; ++ ++ agg_bufs = BNXT_TPA_END_AGG_BUFS(tpa_end); ++ } ++ ++ if (agg_bufs) { ++ if (!bnxt_agg_bufs_valid(cpr, agg_bufs, tmp_raw_cons)) ++ return -EBUSY; ++ } ++ *raw_cons = tmp_raw_cons; ++ return 0; ++} ++ + static inline struct rte_mbuf *bnxt_tpa_end( + struct bnxt_rx_queue *rxq, + uint32_t *raw_cp_cons, +@@ -279,6 +362,13 @@ static inline struct rte_mbuf *bnxt_tpa_end( + uint8_t payload_offset; + struct bnxt_tpa_info *tpa_info; + ++ if (unlikely(rxq->in_reset)) { ++ PMD_DRV_LOG(ERR, "rxq->in_reset: raw_cp_cons:%d\n", ++ *raw_cp_cons); ++ bnxt_discard_rx(rxq->bp, cpr, raw_cp_cons, tpa_end); ++ return NULL; ++ } ++ + if (BNXT_CHIP_THOR(rxq->bp)) { + struct rx_tpa_v2_end_cmpl *th_tpa_end; + struct rx_tpa_v2_end_cmpl_hi *th_tpa_end1; +@@ -300,7 +390,6 @@ static inline struct rte_mbuf *bnxt_tpa_end( mbuf = tpa_info->mbuf; RTE_ASSERT(mbuf != NULL); @@ -26448,7 +39019,70 @@ index 3b713c2427..1cf8f3e17c 100644 if (agg_bufs) { bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs, tpa_info); } -@@ -474,8 +475,6 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt, +@@ -379,9 +468,11 @@ bnxt_parse_pkt_type(struct rx_pkt_cmpl *rxcmp, struct rx_pkt_cmpl_hi *rxcmp1) + static void + bnxt_get_rx_ts_thor(struct bnxt *bp, uint32_t rx_ts_cmpl) + { +- uint64_t systime_cycles = 0; ++ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; ++ uint64_t last_hwrm_time; ++ uint64_t pkt_time = 0; + +- if (!BNXT_CHIP_THOR(bp)) ++ if (!BNXT_CHIP_THOR(bp) || !ptp) + return; + + /* On Thor, Rx timestamps are provided directly in the +@@ -392,10 +483,13 @@ bnxt_get_rx_ts_thor(struct bnxt *bp, uint32_t rx_ts_cmpl) + * from the HWRM response with the lower 32 bits in the + * Rx completion to produce the 48 bit timestamp for the Rx packet + */ +- bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, +- &systime_cycles); +- bp->ptp_cfg->rx_timestamp = (systime_cycles & 0xFFFF00000000); +- bp->ptp_cfg->rx_timestamp |= rx_ts_cmpl; ++ last_hwrm_time = ptp->current_time; ++ pkt_time = (last_hwrm_time & BNXT_PTP_CURRENT_TIME_MASK) | rx_ts_cmpl; ++ if (rx_ts_cmpl < (uint32_t)last_hwrm_time) { ++ /* timer has rolled over */ ++ pkt_time += (1ULL << 32); ++ } ++ ptp->rx_timestamp = pkt_time; + } + #endif + +@@ -437,7 +531,8 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt, + cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons); + rxcmp1 = (struct rx_pkt_cmpl_hi *)&cpr->cp_desc_ring[cp_cons]; + +- if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(rxcmp1, tmp_raw_cons, ++ cpr->cp_ring_struct->ring_size)) + return -EBUSY; + + cpr->valid = FLIP_VALID(cp_cons, +@@ -462,20 +557,25 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt, + goto next_rx; + } + +- agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) +- >> RX_PKT_CMPL_AGG_BUFS_SFT; ++ agg_buf = BNXT_RX_L2_AGG_BUFS(rxcmp); + if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons)) + return -EBUSY; + + prod = rxr->rx_prod; + + cons = rxcmp->opaque; ++ if (unlikely(cons != rxr->rx_next_cons)) { ++ bnxt_discard_rx(rxq->bp, cpr, &tmp_raw_cons, rxcmp); ++ PMD_DRV_LOG(ERR, "RX cons %x != expected cons %x\n", ++ cons, rxr->rx_next_cons); ++ bnxt_sched_ring_reset(rxq); ++ rc = -EBUSY; ++ goto next_rx; ++ } + mbuf = bnxt_consume_rx_buf(rxr, cons); if (mbuf == NULL) return -EBUSY; @@ -26457,7 +39091,31 @@ index 3b713c2427..1cf8f3e17c 100644 mbuf->data_off = RTE_PKTMBUF_HEADROOM; mbuf->nb_segs = 1; mbuf->next = NULL; -@@ -606,6 +605,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -502,7 +602,8 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt, + if (agg_buf) + bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf, NULL); + +- if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) { ++ if (BNXT_RX_VLAN_STRIP_EN(rxq->bp) && ++ (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN)) { + mbuf->vlan_tci = rxcmp1->metadata & + (RX_PKT_CMPL_METADATA_VID_MASK | + RX_PKT_CMPL_METADATA_DE | +@@ -585,11 +686,12 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt, + goto rx; + } + rxr->rx_prod = prod; ++rx: ++ rxr->rx_next_cons = RING_NEXT(rxr->rx_ring_struct, cons); + /* + * All MBUFs are allocated with the same size under DPDK, + * no optimization for rx_copy_thresh + */ +-rx: + *rx_pkt = mbuf; + + next_rx: +@@ -606,6 +708,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, struct bnxt_cp_ring_info *cpr = rxq->cp_ring; struct bnxt_rx_ring_info *rxr = rxq->rx_ring; uint32_t raw_cons = cpr->cp_raw_cons; @@ -26465,7 +39123,7 @@ index 3b713c2427..1cf8f3e17c 100644 uint32_t cons; int nb_rx_pkts = 0; struct rx_pkt_cmpl *rxcmp; -@@ -618,14 +618,12 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -618,17 +721,16 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, return 0; /* If Rx Q was stopped return */ @@ -26480,8 +39138,13 @@ index 3b713c2427..1cf8f3e17c 100644 - rte_prefetch0(&cpr->cp_desc_ring[cons]); rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; - if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) -@@ -637,10 +635,14 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +- if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, ++ cpr->cp_ring_struct->ring_size)) + break; + cpr->valid = FLIP_VALID(cons, + cpr->cp_ring_struct->ring_mask, +@@ -637,10 +739,14 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, /* TODO: Avoid magic numbers... */ if ((CMP_TYPE(rxcmp) & 0x30) == 0x10) { rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons); @@ -26498,7 +39161,17 @@ index 3b713c2427..1cf8f3e17c 100644 } else if (!BNXT_NUM_ASYNC_CPR(rxq->bp)) { evt = bnxt_event_hwrm_resp_handler(rxq->bp, -@@ -667,6 +669,10 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -653,9 +759,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, + raw_cons = NEXT_RAW_CMP(raw_cons); + if (nb_rx_pkts == nb_pkts || evt) + break; +- /* Post some Rx buf early in case of larger burst processing */ +- if (nb_rx_pkts == BNXT_RX_POST_THRESH) +- bnxt_db_write(&rxr->rx_db, rxr->rx_prod); + } + + cpr->cp_raw_cons = raw_cons; +@@ -667,6 +770,10 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, goto done; } @@ -26509,7 +39182,7 @@ index 3b713c2427..1cf8f3e17c 100644 if (prod != rxr->rx_prod) bnxt_db_write(&rxr->rx_db, rxr->rx_prod); -@@ -674,23 +680,23 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -674,23 +781,23 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, if (ag_prod != rxr->ag_prod) bnxt_db_write(&rxr->ag_db, rxr->ag_prod); @@ -26542,7 +39215,7 @@ index 3b713c2427..1cf8f3e17c 100644 bnxt_db_write(&rxr->rx_db, rxr->rx_prod); } else { PMD_DRV_LOG(ERR, "Alloc mbuf failed\n"); -@@ -700,8 +706,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -700,8 +807,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, } done: @@ -26551,7 +39224,17 @@ index 3b713c2427..1cf8f3e17c 100644 return nb_rx_pkts; } -@@ -778,6 +782,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) +@@ -746,6 +851,9 @@ void bnxt_free_rx_rings(struct bnxt *bp) + rte_free(rxq->cp_ring->cp_ring_struct); + rte_free(rxq->cp_ring); + ++ rte_memzone_free(rxq->mz); ++ rxq->mz = NULL; ++ + rte_free(rxq); + bp->rx_queues[i] = NULL; + } +@@ -778,6 +886,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) ring->bd_dma = rxr->rx_desc_mapping; ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd); ring->vmem = (void **)&rxr->rx_buf_ring; @@ -26559,7 +39242,7 @@ index 3b713c2427..1cf8f3e17c 100644 cpr = rte_zmalloc_socket("bnxt_rx_ring", sizeof(struct bnxt_cp_ring_info), -@@ -799,6 +804,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) +@@ -799,6 +908,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) ring->bd_dma = cpr->cp_desc_mapping; ring->vmem_size = 0; ring->vmem = NULL; @@ -26567,7 +39250,7 @@ index 3b713c2427..1cf8f3e17c 100644 /* Allocate Aggregator rings */ ring = rte_zmalloc_socket("bnxt_rx_ring_struct", -@@ -814,6 +820,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) +@@ -814,6 +924,7 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id) ring->bd_dma = rxr->ag_desc_mapping; ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd); ring->vmem = (void **)&rxr->ag_buf_ring; @@ -26575,7 +39258,7 @@ index 3b713c2427..1cf8f3e17c 100644 return 0; } -@@ -844,7 +851,7 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) +@@ -844,7 +955,7 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; size = RTE_MIN(BNXT_MAX_PKT_LEN, size); @@ -26584,7 +39267,7 @@ index 3b713c2427..1cf8f3e17c 100644 rxr = rxq->rx_ring; ring = rxr->rx_ring_struct; -@@ -852,11 +859,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) +@@ -852,11 +963,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) prod = rxr->rx_prod; for (i = 0; i < ring->ring_size; i++) { @@ -26603,7 +39286,7 @@ index 3b713c2427..1cf8f3e17c 100644 } rxr->rx_prod = prod; prod = RING_NEXT(rxr->rx_ring_struct, prod); -@@ -868,11 +877,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) +@@ -868,11 +981,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) prod = rxr->ag_prod; for (i = 0; i < ring->ring_size; i++) { @@ -26622,7 +39305,7 @@ index 3b713c2427..1cf8f3e17c 100644 } rxr->ag_prod = prod; prod = RING_NEXT(rxr->ag_ring_struct, prod); -@@ -883,11 +894,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) +@@ -883,15 +998,20 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq) unsigned int max_aggs = BNXT_TPA_MAX_AGGS(rxq->bp); for (i = 0; i < max_aggs; i++) { @@ -26641,11 +39324,46 @@ index 3b713c2427..1cf8f3e17c 100644 } } } + PMD_DRV_LOG(DEBUG, "TPA alloc Done!\n"); + ++ /* Explicitly reset this driver internal tracker on a ring init */ ++ rxr->rx_next_cons = 0; ++ + return 0; + } diff --git a/dpdk/drivers/net/bnxt/bnxt_rxr.h b/dpdk/drivers/net/bnxt/bnxt_rxr.h -index 76bf88d707..410b46016b 100644 +index 76bf88d707..f53bdde1e4 100644 --- a/dpdk/drivers/net/bnxt/bnxt_rxr.h +++ b/dpdk/drivers/net/bnxt/bnxt_rxr.h -@@ -212,8 +212,6 @@ struct bnxt_rx_ring_info { +@@ -147,6 +147,10 @@ static inline uint16_t bnxt_tpa_start_agg_id(struct bnxt *bp, + #define RX_CMP_L4_CS_UNKNOWN(rxcmp1) \ + !((rxcmp1)->flags2 & RX_CMP_L4_CS_BITS) + ++#define BNXT_RX_L2_AGG_BUFS(cmp) \ ++ (((cmp)->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK) >> \ ++ RX_PKT_CMPL_AGG_BUFS_SFT) ++ + #define RX_CMP_T_L4_CS_BITS \ + rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC) + +@@ -165,8 +169,6 @@ static inline uint16_t bnxt_tpa_start_agg_id(struct bnxt *bp, + ((rxcmp1)->errors_v2 & \ + rte_cpu_to_le_32(RX_PKT_CMPL_ERRORS_L4_CS_ERROR)) + +-#define BNXT_RX_POST_THRESH 32 +- + enum pkt_hash_types { + PKT_HASH_TYPE_NONE, /* Undefined type */ + PKT_HASH_TYPE_L2, /* Input: src_MAC, dest_MAC */ +@@ -188,6 +190,7 @@ struct bnxt_sw_rx_bd { + struct bnxt_rx_ring_info { + uint16_t rx_prod; + uint16_t ag_prod; ++ uint16_t rx_next_cons; + struct bnxt_db_info rx_db; + struct bnxt_db_info ag_db; + +@@ -212,8 +215,6 @@ struct bnxt_rx_ring_info { uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); @@ -26655,13 +39373,34 @@ index 76bf88d707..410b46016b 100644 int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id); int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq); diff --git a/dpdk/drivers/net/bnxt/bnxt_rxtx_vec_sse.c b/dpdk/drivers/net/bnxt/bnxt_rxtx_vec_sse.c -index 22d9f9e84a..7529d0316b 100644 +index 22d9f9e84a..3d2081b1c0 100644 --- a/dpdk/drivers/net/bnxt/bnxt_rxtx_vec_sse.c +++ b/dpdk/drivers/net/bnxt/bnxt_rxtx_vec_sse.c -@@ -233,8 +233,13 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, - /* Return no more than RTE_BNXT_MAX_RX_BURST per call. */ - nb_pkts = RTE_MIN(nb_pkts, RTE_BNXT_MAX_RX_BURST); +@@ -203,14 +203,14 @@ bnxt_parse_csum(struct rte_mbuf *mbuf, struct rx_pkt_cmpl_hi *rxcmp1) + } + } + +-uint16_t +-bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +- uint16_t nb_pkts) ++static uint16_t ++recv_burst_vec_sse(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + { + struct bnxt_rx_queue *rxq = rx_queue; + struct bnxt_cp_ring_info *cpr = rxq->cp_ring; + struct bnxt_rx_ring_info *rxr = rxq->rx_ring; + uint32_t raw_cons = cpr->cp_raw_cons; ++ uint32_t cp_ring_size; + uint32_t cons; + int nb_rx_pkts = 0; + struct rx_pkt_cmpl *rxcmp; +@@ -230,11 +230,15 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + if (rxq->rxrearm_nb >= RTE_BNXT_RXQ_REARM_THRESH) + bnxt_rxq_rearm(rxq, rxr); +- /* Return no more than RTE_BNXT_MAX_RX_BURST per call. */ +- nb_pkts = RTE_MIN(nb_pkts, RTE_BNXT_MAX_RX_BURST); +- - /* Make nb_pkts an integer multiple of RTE_BNXT_DESCS_PER_LOOP */ + /* + * Make nb_pkts an integer multiple of RTE_BNXT_DESCS_PER_LOOP. @@ -26670,10 +39409,41 @@ index 22d9f9e84a..7529d0316b 100644 nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_BNXT_DESCS_PER_LOOP); + if (!nb_pkts) + return 0; ++ ++ cp_ring_size = cpr->cp_ring_struct->ring_size; /* Handle RX burst request */ while (1) { -@@ -289,7 +294,8 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -242,7 +246,7 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + + rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; + +- if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(rxcmp, raw_cons, cp_ring_size)) + break; + + if (likely(CMP_TYPE(rxcmp) == RX_PKT_CMPL_TYPE_RX_L2)) { +@@ -257,8 +261,8 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + rxcmp1 = (struct rx_pkt_cmpl_hi *) + &cpr->cp_desc_ring[cp_cons]; + +- if (!CMP_VALID(rxcmp1, tmp_raw_cons, +- cpr->cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(rxcmp1, tmp_raw_cons, ++ cp_ring_size)) + break; + + raw_cons = tmp_raw_cons; +@@ -283,13 +287,15 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + if (rxcmp->flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) + mbuf->ol_flags |= PKT_RX_RSS_HASH; + +- if (rxcmp1->flags2 & +- RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) { ++ if (BNXT_RX_VLAN_STRIP_EN(rxq->bp) && ++ (rxcmp1->flags2 & ++ RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN)) { + mbuf->vlan_tci = rxcmp1->metadata & (RX_PKT_CMPL_METADATA_VID_MASK | RX_PKT_CMPL_METADATA_DE | RX_PKT_CMPL_METADATA_PRI_MASK); @@ -26692,11 +39462,98 @@ index 22d9f9e84a..7529d0316b 100644 tx_buf->mbuf = NULL; if (blk && mbuf->pool != free[0]->pool) { +@@ -346,6 +354,27 @@ bnxt_tx_cmp_vec(struct bnxt_tx_queue *txq, int nr_pkts) + txr->tx_cons = cons; + } + ++uint16_t ++bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) ++{ ++ uint16_t cnt = 0; ++ ++ while (nb_pkts > RTE_BNXT_MAX_RX_BURST) { ++ uint16_t burst; ++ ++ burst = recv_burst_vec_sse(rx_queue, rx_pkts + cnt, ++ RTE_BNXT_MAX_RX_BURST); ++ ++ cnt += burst; ++ nb_pkts -= burst; ++ ++ if (burst < RTE_BNXT_MAX_RX_BURST) ++ return cnt; ++ } ++ ++ return cnt + recv_burst_vec_sse(rx_queue, rx_pkts + cnt, nb_pkts); ++} ++ + static void + bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq) + { +@@ -362,7 +391,7 @@ bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq) + cons = RING_CMPL(ring_mask, raw_cons); + txcmp = (struct tx_cmpl *)&cp_desc_ring[cons]; + +- if (!CMP_VALID(txcmp, raw_cons, cp_ring_struct)) ++ if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1)) + break; + + if (likely(CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)) diff --git a/dpdk/drivers/net/bnxt/bnxt_stats.c b/dpdk/drivers/net/bnxt/bnxt_stats.c -index 14d355fd08..84011fc3ea 100644 +index 14d355fd08..bc181db3b6 100644 --- a/dpdk/drivers/net/bnxt/bnxt_stats.c +++ b/dpdk/drivers/net/bnxt/bnxt_stats.c -@@ -389,11 +389,8 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, +@@ -377,8 +377,48 @@ void bnxt_free_stats(struct bnxt *bp) + } + } + ++static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats, ++ struct bnxt_ring_stats *ring_stats, ++ unsigned int i, bool rx) ++{ ++ if (rx) { ++ stats->q_ipackets[i] = ring_stats->rx_ucast_pkts; ++ stats->q_ipackets[i] += ring_stats->rx_mcast_pkts; ++ stats->q_ipackets[i] += ring_stats->rx_bcast_pkts; ++ ++ stats->ipackets += stats->q_ipackets[i]; ++ ++ stats->q_ibytes[i] = ring_stats->rx_ucast_bytes; ++ stats->q_ibytes[i] += ring_stats->rx_mcast_bytes; ++ stats->q_ibytes[i] += ring_stats->rx_bcast_bytes; ++ ++ stats->ibytes += stats->q_ibytes[i]; ++ ++ stats->q_errors[i] = ring_stats->rx_discard_pkts; ++ stats->q_errors[i] += ring_stats->rx_error_pkts; ++ ++ stats->imissed += ring_stats->rx_discard_pkts; ++ stats->ierrors += ring_stats->rx_error_pkts; ++ stats->ierrors += ring_stats->rx_discard_pkts; ++ } else { ++ stats->q_opackets[i] = ring_stats->tx_ucast_pkts; ++ stats->q_opackets[i] += ring_stats->tx_mcast_pkts; ++ stats->q_opackets[i] += ring_stats->tx_bcast_pkts; ++ ++ stats->opackets += stats->q_opackets[i]; ++ ++ stats->q_obytes[i] = ring_stats->tx_ucast_bytes; ++ stats->q_obytes[i] += ring_stats->tx_mcast_bytes; ++ stats->q_obytes[i] += ring_stats->tx_bcast_bytes; ++ ++ stats->obytes += stats->q_obytes[i]; ++ ++ stats->oerrors += ring_stats->tx_discard_pkts; ++ } ++} ++ + int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, +- struct rte_eth_stats *bnxt_stats) ++ struct rte_eth_stats *bnxt_stats) + { + int rc = 0; + unsigned int i; +@@ -389,11 +429,8 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, if (rc) return rc; @@ -26709,7 +39566,63 @@ index 14d355fd08..84011fc3ea 100644 num_q_stats = RTE_MIN(bp->rx_cp_nr_rings, (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS); -@@ -437,7 +434,7 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev) +@@ -401,11 +438,17 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, + for (i = 0; i < num_q_stats; i++) { + struct bnxt_rx_queue *rxq = bp->rx_queues[i]; + struct bnxt_cp_ring_info *cpr = rxq->cp_ring; ++ struct bnxt_ring_stats ring_stats = {0}; ++ ++ if (!rxq->rx_started) ++ continue; + +- rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, +- bnxt_stats, 1); ++ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i, ++ &ring_stats, true); + if (unlikely(rc)) + return rc; ++ ++ bnxt_fill_rte_eth_stats(bnxt_stats, &ring_stats, i, true); + bnxt_stats->rx_nombuf += + rte_atomic64_read(&rxq->rx_mbuf_alloc_fail); + } +@@ -416,17 +459,32 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, + for (i = 0; i < num_q_stats; i++) { + struct bnxt_tx_queue *txq = bp->tx_queues[i]; + struct bnxt_cp_ring_info *cpr = txq->cp_ring; ++ struct bnxt_ring_stats ring_stats = {0}; ++ ++ if (!txq->tx_started) ++ continue; + +- rc = bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, +- bnxt_stats, 0); ++ rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i, ++ &ring_stats, false); + if (unlikely(rc)) + return rc; ++ ++ bnxt_fill_rte_eth_stats(bnxt_stats, &ring_stats, i, false); + } + +- rc = bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats); + return rc; + } + ++static void bnxt_clear_prev_stat(struct bnxt *bp) ++{ ++ /* ++ * Clear the cached values of stats returned by HW in the previous ++ * get operation. ++ */ ++ memset(bp->prev_rx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->rx_cp_nr_rings); ++ memset(bp->prev_tx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->tx_cp_nr_rings); ++} ++ + int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev) + { + struct bnxt *bp = eth_dev->data->dev_private; +@@ -437,7 +495,7 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev) if (ret) return ret; @@ -26718,10 +39631,144 @@ index 14d355fd08..84011fc3ea 100644 PMD_DRV_LOG(ERR, "Device Initialization not complete!\n"); return -EINVAL; } -@@ -620,70 +617,3 @@ int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev) +@@ -449,6 +507,8 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev) + rte_atomic64_clear(&rxq->rx_mbuf_alloc_fail); + } ++ bnxt_clear_prev_stat(bp); ++ return ret; } + +@@ -468,10 +528,13 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev, + if (rc) + return rc; + +- if (xstats == NULL) +- return 0; ++ stat_count = RTE_DIM(bnxt_rx_stats_strings) + ++ RTE_DIM(bnxt_tx_stats_strings) + 1/* For tx_drop_pkts */ + ++ RTE_DIM(bnxt_rx_ext_stats_strings) + ++ RTE_DIM(bnxt_tx_ext_stats_strings); + +- memset(xstats, 0, sizeof(*xstats)); ++ if (n < stat_count || xstats == NULL) ++ return stat_count; + + bnxt_hwrm_port_qstats(bp); + bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts); +@@ -483,14 +546,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev, + (bp->fw_tx_port_stats_ext_size / + stat_size)); + +- count = RTE_DIM(bnxt_rx_stats_strings) + +- RTE_DIM(bnxt_tx_stats_strings) + 1/* For tx_drop_pkts */ + +- RTE_DIM(bnxt_rx_ext_stats_strings) + +- RTE_DIM(bnxt_tx_ext_stats_strings); +- stat_count = count; +- +- if (n < count) +- return count; ++ memset(xstats, 0, sizeof(*xstats) * n); + + count = 0; + for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) { +@@ -541,7 +597,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev, + + int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev, + struct rte_eth_xstat_name *xstats_names, +- __rte_unused unsigned int limit) ++ unsigned int size) + { + /* Account for the Tx drop pkts aka the Anti spoof counter */ + const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) + +@@ -549,52 +605,49 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev, + RTE_DIM(bnxt_rx_ext_stats_strings) + + RTE_DIM(bnxt_tx_ext_stats_strings); + struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; +- unsigned int i, count; ++ unsigned int i, count = 0; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + +- if (xstats_names != NULL) { +- count = 0; +- +- for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) { +- strlcpy(xstats_names[count].name, +- bnxt_rx_stats_strings[i].name, +- sizeof(xstats_names[count].name)); +- count++; +- } +- +- for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) { +- strlcpy(xstats_names[count].name, +- bnxt_tx_stats_strings[i].name, +- sizeof(xstats_names[count].name)); +- count++; +- } ++ if (xstats_names == NULL || size < stat_cnt) ++ return stat_cnt; + ++ for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) { + strlcpy(xstats_names[count].name, +- bnxt_func_stats_strings[4].name, ++ bnxt_rx_stats_strings[i].name, + sizeof(xstats_names[count].name)); + count++; ++ } + +- for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) { +- strlcpy(xstats_names[count].name, +- bnxt_rx_ext_stats_strings[i].name, +- sizeof(xstats_names[count].name)); +- +- count++; +- } ++ for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) { ++ strlcpy(xstats_names[count].name, ++ bnxt_tx_stats_strings[i].name, ++ sizeof(xstats_names[count].name)); ++ count++; ++ } + +- for (i = 0; i < RTE_DIM(bnxt_tx_ext_stats_strings); i++) { +- strlcpy(xstats_names[count].name, +- bnxt_tx_ext_stats_strings[i].name, +- sizeof(xstats_names[count].name)); ++ strlcpy(xstats_names[count].name, ++ bnxt_func_stats_strings[4].name, ++ sizeof(xstats_names[count].name)); ++ count++; + +- count++; +- } ++ for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) { ++ strlcpy(xstats_names[count].name, ++ bnxt_rx_ext_stats_strings[i].name, ++ sizeof(xstats_names[count].name)); ++ count++; ++ } + ++ for (i = 0; i < RTE_DIM(bnxt_tx_ext_stats_strings); i++) { ++ strlcpy(xstats_names[count].name, ++ bnxt_tx_ext_stats_strings[i].name, ++ sizeof(xstats_names[count].name)); ++ count++; + } ++ + return stat_cnt; + } + +@@ -618,72 +671,7 @@ int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev) + PMD_DRV_LOG(ERR, "Failed to reset xstats: %s\n", + strerror(-ret)); + +- return ret; +-} - -int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids, - uint64_t *values, unsigned int limit) @@ -26740,7 +39787,8 @@ index 14d355fd08..84011fc3ea 100644 - rc = is_bnxt_in_error(bp); - if (rc) - return rc; -- ++ bnxt_clear_prev_stat(bp); + - if (!ids) - return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt); - @@ -26788,9 +39836,33 @@ index 14d355fd08..84011fc3ea 100644 - xstats_names_copy[ids[i]].name); - } - return stat_cnt; --} ++ return ret; + } +diff --git a/dpdk/drivers/net/bnxt/bnxt_stats.h b/dpdk/drivers/net/bnxt/bnxt_stats.h +index 3cf2a1b822..591c55c406 100644 +--- a/dpdk/drivers/net/bnxt/bnxt_stats.h ++++ b/dpdk/drivers/net/bnxt/bnxt_stats.h +@@ -12,17 +12,12 @@ void bnxt_free_stats(struct bnxt *bp); + int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, + struct rte_eth_stats *bnxt_stats); + int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev); +-int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev, ++int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned int limit); + int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev, + struct rte_eth_xstat *xstats, unsigned int n); + int bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev); +-int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids, +- uint64_t *values, unsigned int limit); +-int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev, +- struct rte_eth_xstat_name *xstats_names, +- const uint64_t *ids, unsigned int limit); + + struct bnxt_xstats_name_off { + char name[RTE_ETH_XSTATS_NAME_SIZE]; diff --git a/dpdk/drivers/net/bnxt/bnxt_txq.c b/dpdk/drivers/net/bnxt/bnxt_txq.c -index 2d7645eeb0..78625eef60 100644 +index 2d7645eeb0..129bd5b541 100644 --- a/dpdk/drivers/net/bnxt/bnxt_txq.c +++ b/dpdk/drivers/net/bnxt/bnxt_txq.c @@ -27,7 +27,7 @@ static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq) @@ -26863,7 +39935,7 @@ index 2d7645eeb0..78625eef60 100644 } txq->bp = bp; txq->nb_tx_desc = nb_desc; -@@ -134,7 +139,7 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, +@@ -134,33 +139,29 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, rc = bnxt_init_tx_ring_struct(txq, socket_id); if (rc) @@ -26872,9 +39944,12 @@ index 2d7645eeb0..78625eef60 100644 txq->queue_id = queue_idx; txq->port_id = eth_dev->data->port_id; -@@ -143,16 +148,14 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, - if (bnxt_alloc_rings(bp, queue_idx, txq, NULL, txq->cp_ring, NULL, - "txr")) { + + /* Allocate TX ring hardware descriptors */ +- if (bnxt_alloc_rings(bp, queue_idx, txq, NULL, txq->cp_ring, NULL, +- "txr")) { ++ if (bnxt_alloc_rings(bp, socket_id, queue_idx, txq, NULL, txq->cp_ring, ++ NULL, "txr")) { PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for tx_ring failed!"); - bnxt_tx_queue_release_op(txq); rc = -ENOMEM; @@ -26891,22 +39966,32 @@ index 2d7645eeb0..78625eef60 100644 } eth_dev->data->tx_queues[queue_idx] = txq; -@@ -161,6 +164,9 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, - txq->tx_started = false; - else - txq->tx_started = true; + +- if (txq->tx_deferred_start) +- txq->tx_started = false; +- else +- txq->tx_started = true; -out: -+ + return 0; +err: + bnxt_tx_queue_release_op(txq); return rc; } diff --git a/dpdk/drivers/net/bnxt/bnxt_txr.c b/dpdk/drivers/net/bnxt/bnxt_txr.c -index 16021407e8..9a18e8f6f7 100644 +index 16021407e8..78c3f2918c 100644 --- a/dpdk/drivers/net/bnxt/bnxt_txr.c +++ b/dpdk/drivers/net/bnxt/bnxt_txr.c -@@ -78,6 +78,7 @@ int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id) +@@ -37,6 +37,9 @@ void bnxt_free_tx_rings(struct bnxt *bp) + rte_free(txq->cp_ring->cp_ring_struct); + rte_free(txq->cp_ring); + ++ rte_memzone_free(txq->mz); ++ txq->mz = NULL; ++ + rte_free(txq); + bp->tx_queues[i] = NULL; + } +@@ -78,6 +81,7 @@ int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id) ring->bd_dma = txr->tx_desc_mapping; ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_tx_bd); ring->vmem = (void **)&txr->tx_buf_ring; @@ -26914,7 +39999,7 @@ index 16021407e8..9a18e8f6f7 100644 cpr = rte_zmalloc_socket("bnxt_tx_ring", sizeof(struct bnxt_cp_ring_info), -@@ -98,6 +99,7 @@ int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id) +@@ -98,6 +102,7 @@ int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id) ring->bd_dma = cpr->cp_desc_mapping; ring->vmem_size = 0; ring->vmem = NULL; @@ -26922,6 +40007,67 @@ index 16021407e8..9a18e8f6f7 100644 return 0; } +@@ -174,7 +179,7 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt, + txbd->flags_type |= TX_BD_SHORT_FLAGS_COAL_NOW; + txbd->flags_type |= TX_BD_LONG_FLAGS_NO_CMPL; + txbd->len = tx_pkt->data_len; +- if (tx_pkt->pkt_len >= 2014) ++ if (tx_pkt->pkt_len >= 2048) + txbd->flags_type |= TX_BD_LONG_FLAGS_LHINT_GTE2K; + else + txbd->flags_type |= lhint_arr[tx_pkt->pkt_len >> 9]; +@@ -396,30 +401,26 @@ static void bnxt_tx_cmp(struct bnxt_tx_queue *txq, int nr_pkts) + + static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq) + { ++ uint32_t nb_tx_pkts = 0, cons, ring_mask, opaque; + struct bnxt_cp_ring_info *cpr = txq->cp_ring; + uint32_t raw_cons = cpr->cp_raw_cons; +- uint32_t cons; +- uint32_t nb_tx_pkts = 0; ++ struct bnxt_ring *cp_ring_struct; + struct tx_cmpl *txcmp; +- struct cmpl_base *cp_desc_ring = cpr->cp_desc_ring; +- struct bnxt_ring *cp_ring_struct = cpr->cp_ring_struct; +- uint32_t ring_mask = cp_ring_struct->ring_mask; +- uint32_t opaque = 0; + + if (bnxt_tx_bds_in_hw(txq) < txq->tx_free_thresh) + return 0; + ++ cp_ring_struct = cpr->cp_ring_struct; ++ ring_mask = cp_ring_struct->ring_mask; ++ + do { + cons = RING_CMPL(ring_mask, raw_cons); + txcmp = (struct tx_cmpl *)&cpr->cp_desc_ring[cons]; +- rte_prefetch_non_temporal(&cp_desc_ring[(cons + 2) & +- ring_mask]); + +- if (!CMPL_VALID(txcmp, cpr->valid)) ++ if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1)) + break; +- opaque = rte_cpu_to_le_32(txcmp->opaque); +- NEXT_CMPL(cpr, cons, cpr->valid, 1); +- rte_prefetch0(&cp_desc_ring[cons]); ++ ++ opaque = rte_le_to_cpu_32(txcmp->opaque); + + if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2) + nb_tx_pkts += opaque; +@@ -427,9 +428,11 @@ static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq) + RTE_LOG_DP(ERR, PMD, + "Unhandled CMP type %02x\n", + CMP_TYPE(txcmp)); +- raw_cons = cons; ++ raw_cons = NEXT_RAW_CMP(raw_cons); + } while (nb_tx_pkts < ring_mask); + ++ cpr->valid = !!(raw_cons & cp_ring_struct->ring_size); ++ + if (nb_tx_pkts) { + bnxt_tx_cmp(txq, nb_tx_pkts); + cpr->cp_raw_cons = raw_cons; diff --git a/dpdk/drivers/net/bnxt/bnxt_txr.h b/dpdk/drivers/net/bnxt/bnxt_txr.h index e7f43f9d1d..08fd2e0142 100644 --- a/dpdk/drivers/net/bnxt/bnxt_txr.h @@ -26935,10 +40081,32 @@ index e7f43f9d1d..08fd2e0142 100644 #ifdef RTE_ARCH_X86 uint16_t bnxt_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +diff --git a/dpdk/drivers/net/bnxt/bnxt_util.h b/dpdk/drivers/net/bnxt/bnxt_util.h +index a15b3a1a95..68665196c3 100644 +--- a/dpdk/drivers/net/bnxt/bnxt_util.h ++++ b/dpdk/drivers/net/bnxt/bnxt_util.h +@@ -10,6 +10,8 @@ + #define BIT(n) (1UL << (n)) + #endif /* BIT */ + ++#define PCI_SUBSYSTEM_ID_OFFSET 0x2e ++ + int bnxt_check_zero_bytes(const uint8_t *bytes, int len); + void bnxt_eth_hw_addr_random(uint8_t *mac_addr); + diff --git a/dpdk/drivers/net/bnxt/bnxt_vnic.c b/dpdk/drivers/net/bnxt/bnxt_vnic.c -index 104342e13b..ef07721148 100644 +index 104342e13b..d64c4136a8 100644 --- a/dpdk/drivers/net/bnxt/bnxt_vnic.c +++ b/dpdk/drivers/net/bnxt/bnxt_vnic.c +@@ -16,7 +16,7 @@ + * VNIC Functions + */ + +-void prandom_bytes(void *dest_ptr, size_t len) ++void bnxt_prandom_bytes(void *dest_ptr, size_t len) + { + char *dest = (char *)dest_ptr; + uint64_t rb; @@ -78,6 +78,9 @@ void bnxt_free_all_vnics(struct bnxt *bp) struct bnxt_vnic_info *vnic; unsigned int i; @@ -26949,10 +40117,69 @@ index 104342e13b..ef07721148 100644 for (i = 0; i < bp->max_vnics; i++) { vnic = &bp->vnic_info[i]; STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next); -@@ -150,17 +153,6 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp) - return -ENOMEM; +@@ -95,23 +98,16 @@ void bnxt_free_vnic_attributes(struct bnxt *bp) + + for (i = 0; i < bp->max_vnics; i++) { + vnic = &bp->vnic_info[i]; +- if (vnic->rss_table) { +- /* 'Unreserve' the rss_table */ +- /* N/A */ +- +- vnic->rss_table = NULL; +- } +- +- if (vnic->rss_hash_key) { +- /* 'Unreserve' the rss_hash_key */ +- /* N/A */ +- ++ if (vnic->rss_mz != NULL) { ++ rte_memzone_free(vnic->rss_mz); ++ vnic->rss_mz = NULL; + vnic->rss_hash_key = NULL; ++ vnic->rss_table = NULL; + } } - mz_phys_addr = mz->iova; + } + +-int bnxt_alloc_vnic_attributes(struct bnxt *bp) ++int bnxt_alloc_vnic_attributes(struct bnxt *bp, bool reconfig) + { + struct bnxt_vnic_info *vnic; + struct rte_pci_device *pdev = bp->pdev; +@@ -119,12 +115,10 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp) + char mz_name[RTE_MEMZONE_NAMESIZE]; + uint32_t entry_length; + size_t rss_table_size; +- uint16_t max_vnics; + int i; + rte_iova_t mz_phys_addr; + +- entry_length = HW_HASH_KEY_SIZE + +- BNXT_MAX_MC_ADDRS * RTE_ETHER_ADDR_LEN; ++ entry_length = HW_HASH_KEY_SIZE; + + if (BNXT_CHIP_THOR(bp)) + rss_table_size = BNXT_RSS_TBL_SIZE_THOR * +@@ -134,53 +128,43 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp) + + entry_length = RTE_CACHE_LINE_ROUNDUP(entry_length + rss_table_size); + +- max_vnics = bp->max_vnics; +- snprintf(mz_name, RTE_MEMZONE_NAMESIZE, +- "bnxt_%04x:%02x:%02x:%02x_vnicattr", pdev->addr.domain, +- pdev->addr.bus, pdev->addr.devid, pdev->addr.function); +- mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; +- mz = rte_memzone_lookup(mz_name); +- if (!mz) { +- mz = rte_memzone_reserve(mz_name, +- entry_length * max_vnics, SOCKET_ID_ANY, +- RTE_MEMZONE_2MB | +- RTE_MEMZONE_SIZE_HINT_ONLY | +- RTE_MEMZONE_IOVA_CONTIG); +- if (!mz) +- return -ENOMEM; +- } +- mz_phys_addr = mz->iova; - if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(DEBUG, - "Memzone physical address same as virtual.\n"); @@ -26964,9 +40191,144 @@ index 104342e13b..ef07721148 100644 - return -ENOMEM; - } - } - - for (i = 0; i < max_vnics; i++) { +- +- for (i = 0; i < max_vnics; i++) { ++ for (i = 0; i < bp->max_vnics; i++) { vnic = &bp->vnic_info[i]; + ++ snprintf(mz_name, RTE_MEMZONE_NAMESIZE, ++ "bnxt_%04x:%02x:%02x:%02x_vnicattr_%d", pdev->addr.domain, ++ pdev->addr.bus, pdev->addr.devid, pdev->addr.function, i); ++ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; ++ mz = rte_memzone_lookup(mz_name); ++ if (mz == NULL) { ++ mz = rte_memzone_reserve(mz_name, ++ entry_length, ++ bp->eth_dev->device->numa_node, ++ RTE_MEMZONE_2MB | ++ RTE_MEMZONE_SIZE_HINT_ONLY | ++ RTE_MEMZONE_IOVA_CONTIG); ++ if (mz == NULL) { ++ PMD_DRV_LOG(ERR, "Cannot allocate bnxt vnic_attributes memory\n"); ++ return -ENOMEM; ++ } ++ } ++ vnic->rss_mz = mz; ++ mz_phys_addr = mz->iova; ++ + /* Allocate rss table and hash key */ +- vnic->rss_table = +- (void *)((char *)mz->addr + (entry_length * i)); ++ vnic->rss_table = (void *)((char *)mz->addr); ++ vnic->rss_table_dma_addr = mz_phys_addr; + memset(vnic->rss_table, -1, entry_length); + +- vnic->rss_table_dma_addr = mz_phys_addr + (entry_length * i); +- vnic->rss_hash_key = (void *)((char *)vnic->rss_table + +- rss_table_size); +- +- vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + +- rss_table_size; +- vnic->mc_list = (void *)((char *)vnic->rss_hash_key + +- HW_HASH_KEY_SIZE); +- vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr + +- HW_HASH_KEY_SIZE; +- prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE); ++ vnic->rss_hash_key = (void *)((char *)vnic->rss_table + rss_table_size); ++ vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + rss_table_size; ++ ++ if (!reconfig) { ++ bnxt_prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE); ++ memcpy(bp->rss_conf.rss_key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); ++ } else { ++ memcpy(vnic->rss_hash_key, bp->rss_conf.rss_key, HW_HASH_KEY_SIZE); ++ } + } + + return 0; +diff --git a/dpdk/drivers/net/bnxt/bnxt_vnic.h b/dpdk/drivers/net/bnxt/bnxt_vnic.h +index a372b899bc..6fb5ec2809 100644 +--- a/dpdk/drivers/net/bnxt/bnxt_vnic.h ++++ b/dpdk/drivers/net/bnxt/bnxt_vnic.h +@@ -25,14 +25,11 @@ struct bnxt_vnic_info { + uint16_t mru; + uint16_t hash_type; + uint8_t hash_mode; ++ const struct rte_memzone *rss_mz; + rte_iova_t rss_table_dma_addr; + uint16_t *rss_table; + rte_iova_t rss_hash_key_dma_addr; + void *rss_hash_key; +- rte_iova_t mc_list_dma_addr; +- char *mc_list; +- uint32_t mc_addr_cnt; +-#define BNXT_MAX_MC_ADDRS 16 + uint32_t flags; + #define BNXT_VNIC_INFO_PROMISC (1 << 0) + #define BNXT_VNIC_INFO_ALLMULTI (1 << 1) +@@ -49,8 +46,6 @@ struct bnxt_vnic_info { + bool vlan_strip; + bool func_default; + bool bd_stall; +- bool roce_dual; +- bool roce_only; + bool rss_dflt_cr; + + STAILQ_HEAD(, bnxt_filter_info) filter; +@@ -63,10 +58,10 @@ int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic, + struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp); + void bnxt_free_all_vnics(struct bnxt *bp); + void bnxt_free_vnic_attributes(struct bnxt *bp); +-int bnxt_alloc_vnic_attributes(struct bnxt *bp); ++int bnxt_alloc_vnic_attributes(struct bnxt *bp, bool reconfig); + void bnxt_free_vnic_mem(struct bnxt *bp); + int bnxt_alloc_vnic_mem(struct bnxt *bp); + int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic); +-void prandom_bytes(void *dest_ptr, size_t len); ++void bnxt_prandom_bytes(void *dest_ptr, size_t len); + uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type); + #endif +diff --git a/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h b/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h +index c2bae0f675..0935eb75bd 100644 +--- a/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h ++++ b/dpdk/drivers/net/bnxt/hsi_struct_def_dpdk.h +@@ -7441,6 +7441,9 @@ struct hwrm_func_qcaps_output { + */ + #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_NOTIFY_VF_DEF_VNIC_CHNG_SUPPORTED \ + UINT32_C(0x4000000) ++ /* If set to 1, then the vlan acceleration for TX is disabled. */ ++ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VLAN_ACCELERATION_TX_DISABLED \ ++ UINT32_C(0x8000000) + /* + * This value is current MAC address configured for this + * function. A value of 00-00-00-00-00-00 indicates no +@@ -9644,7 +9647,7 @@ struct hwrm_func_resource_qcaps_output { + #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL \ + UINT32_C(0x1) + /* +- * The PF driver should not reserve any resources for each VF until the ++ * The PF driver should not reserve any resources for each VF until + * the VF interface is brought up. + */ + #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC \ +@@ -24388,8 +24391,15 @@ struct hwrm_ring_reset_input { + #define HWRM_RING_RESET_INPUT_RING_TYPE_RX UINT32_C(0x2) + /* RoCE Notification Completion Ring (ROCE_CR) */ + #define HWRM_RING_RESET_INPUT_RING_TYPE_ROCE_CMPL UINT32_C(0x3) +- #define HWRM_RING_RESET_INPUT_RING_TYPE_LAST \ +- HWRM_RING_RESET_INPUT_RING_TYPE_ROCE_CMPL ++ /* ++ * Rx Ring Group. This is to reset rx and aggregation in an atomic ++ * operation. Completion ring associated with this ring group is ++ * not reset. ++ */ ++ #define HWRM_RING_RESET_INPUT_RING_TYPE_RX_RING_GRP UINT32_C(0x6) ++ #define HWRM_RING_RESET_INPUT_RING_TYPE_LAST \ ++ HWRM_RING_RESET_INPUT_RING_TYPE_RX_RING_GRP ++ + uint8_t unused_0; + /* Physical number of the ring. */ + uint16_t ring_id; diff --git a/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h b/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h index 2e893cc7bf..81d0d0e032 100644 --- a/dpdk/drivers/net/bnxt/rte_pmd_bnxt.h @@ -27003,7 +40365,7 @@ index 6e44ffdb1c..9b5738afee 100644 /* Additional port parameters not listed in documentation */ /** State machine flags */ diff --git a/dpdk/drivers/net/bonding/eth_bond_private.h b/dpdk/drivers/net/bonding/eth_bond_private.h -index c9b2d0fe46..af92a4c52a 100644 +index c9b2d0fe46..98933be3b0 100644 --- a/dpdk/drivers/net/bonding/eth_bond_private.h +++ b/dpdk/drivers/net/bonding/eth_bond_private.h @@ -50,6 +50,8 @@ extern const struct rte_flow_ops bond_flow_ops; @@ -27023,8 +40385,26 @@ index c9b2d0fe46..af92a4c52a 100644 uint16_t active_slave_count; /**< Number of active slaves */ uint16_t active_slaves[RTE_MAX_ETHPORTS]; /**< Active slave list */ +@@ -211,7 +212,7 @@ int + valid_bonded_port_id(uint16_t port_id); + + int +-valid_slave_port_id(uint16_t port_id, uint8_t mode); ++valid_slave_port_id(struct bond_dev_private *internals, uint16_t port_id); + + void + deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id); +@@ -239,7 +240,7 @@ slave_remove_mac_addresses(struct rte_eth_dev *bonded_eth_dev, + uint16_t slave_port_id); + + int +-bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode); ++bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, uint8_t mode); + + int + slave_configure(struct rte_eth_dev *bonded_eth_dev, diff --git a/dpdk/drivers/net/bonding/rte_eth_bond_8023ad.c b/dpdk/drivers/net/bonding/rte_eth_bond_8023ad.c -index b77a37ddb3..5fe004e551 100644 +index b77a37ddb3..478c28afee 100644 --- a/dpdk/drivers/net/bonding/rte_eth_bond_8023ad.c +++ b/dpdk/drivers/net/bonding/rte_eth_bond_8023ad.c @@ -356,16 +356,28 @@ rx_machine(struct bond_dev_private *internals, uint16_t slave_id, @@ -27060,17 +40440,89 @@ index b77a37ddb3..5fe004e551 100644 } } -@@ -798,7 +810,8 @@ rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id, +@@ -792,24 +804,61 @@ rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id, + struct rte_mbuf *lacp_pkt) { + struct lacpdu_header *lacp; + struct lacpdu_actor_partner_params *partner; ++ struct port *port, *agg; + + if (lacp_pkt != NULL) { + lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *); RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP); partner = &lacp->lacpdu.partner; - if (rte_is_same_ether_addr(&partner->port_params.system, +- &internals->mode4.mac_addr)) { ++ port = &bond_mode_8023ad_ports[slave_id]; ++ agg = &bond_mode_8023ad_ports[port->aggregator_port_id]; ++ + if (rte_is_zero_ether_addr(&partner->port_params.system) || + rte_is_same_ether_addr(&partner->port_params.system, - &internals->mode4.mac_addr)) { ++ &agg->actor.system)) { /* This LACP frame is sending to the bonding port * so pass it to rx_machine. -@@ -1020,6 +1033,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, + */ + rx_machine(internals, slave_id, &lacp->lacpdu); ++ } else { ++ char preferred_system_name[RTE_ETHER_ADDR_FMT_SIZE]; ++ char self_system_name[RTE_ETHER_ADDR_FMT_SIZE]; ++ ++ rte_ether_format_addr(preferred_system_name, ++ RTE_ETHER_ADDR_FMT_SIZE, &partner->port_params.system); ++ rte_ether_format_addr(self_system_name, ++ RTE_ETHER_ADDR_FMT_SIZE, &agg->actor.system); ++ MODE4_DEBUG("preferred partner system %s " ++ "is not equal with self system: %s\n", ++ preferred_system_name, self_system_name); + } + rte_pktmbuf_free(lacp_pkt); + } else + rx_machine(internals, slave_id, NULL); + } + ++static void ++bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private *internals, ++ uint16_t slave_id) ++{ ++#define DEDICATED_QUEUE_BURST_SIZE 32 ++ struct rte_mbuf *lacp_pkt[DEDICATED_QUEUE_BURST_SIZE]; ++ uint16_t rx_count = rte_eth_rx_burst(slave_id, ++ internals->mode4.dedicated_queues.rx_qid, ++ lacp_pkt, DEDICATED_QUEUE_BURST_SIZE); ++ ++ if (rx_count) { ++ uint16_t i; ++ ++ for (i = 0; i < rx_count; i++) ++ bond_mode_8023ad_handle_slow_pkt(internals, slave_id, ++ lacp_pkt[i]); ++ } else { ++ rx_machine_update(internals, slave_id, NULL); ++ } ++} ++ + static void + bond_mode_8023ad_periodic_cb(void *arg) + { +@@ -898,15 +947,8 @@ bond_mode_8023ad_periodic_cb(void *arg) + + rx_machine_update(internals, slave_id, lacp_pkt); + } else { +- uint16_t rx_count = rte_eth_rx_burst(slave_id, +- internals->mode4.dedicated_queues.rx_qid, +- &lacp_pkt, 1); +- +- if (rx_count == 1) +- bond_mode_8023ad_handle_slow_pkt(internals, +- slave_id, lacp_pkt); +- else +- rx_machine_update(internals, slave_id, NULL); ++ bond_mode_8023ad_dedicated_rxq_process(internals, ++ slave_id); + } + + periodic_machine(internals, slave_id); +@@ -1020,6 +1062,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, port->actor.port_number = rte_cpu_to_be_16(slave_id + 1); memcpy(&port->partner, &initial, sizeof(struct port_params)); @@ -27078,7 +40530,7 @@ index b77a37ddb3..5fe004e551 100644 /* default states */ port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED; -@@ -1043,7 +1057,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, +@@ -1043,7 +1086,7 @@ bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev, RTE_ASSERT(port->tx_ring == NULL); socket_id = rte_eth_dev_socket_id(slave_id); @@ -27087,7 +40539,7 @@ index b77a37ddb3..5fe004e551 100644 socket_id = rte_socket_id(); element_size = sizeof(struct slow_protocol_frame) + -@@ -1320,8 +1334,7 @@ bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals, +@@ -1320,8 +1363,7 @@ bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals, rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr); if (internals->mode4.dedicated_queues.enabled == 0) { @@ -27097,7 +40549,7 @@ index b77a37ddb3..5fe004e551 100644 /* reset timer */ port->rx_marker_timer = 0; wrn = WRN_TX_QUEUE_FULL; -@@ -1341,8 +1354,7 @@ bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals, +@@ -1341,8 +1383,7 @@ bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals, } } else if (likely(subtype == SLOW_SUBTYPE_LACP)) { if (internals->mode4.dedicated_queues.enabled == 0) { @@ -27107,7 +40559,7 @@ index b77a37ddb3..5fe004e551 100644 /* If RX fing full free lacpdu message and drop packet */ wrn = WRN_RX_QUEUE_FULL; goto free_out; -@@ -1675,9 +1687,6 @@ rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port) +@@ -1675,9 +1716,6 @@ rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port) dev = &rte_eth_devices[port]; internals = dev->data->dev_private; @@ -27117,7 +40569,7 @@ index b77a37ddb3..5fe004e551 100644 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0) return -1; -@@ -1704,9 +1713,6 @@ rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port) +@@ -1704,9 +1742,6 @@ rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port) dev = &rte_eth_devices[port]; internals = dev->data->dev_private; @@ -27128,10 +40580,41 @@ index b77a37ddb3..5fe004e551 100644 if (dev->data->dev_started) return -1; diff --git a/dpdk/drivers/net/bonding/rte_eth_bond_api.c b/dpdk/drivers/net/bonding/rte_eth_bond_api.c -index f38eb3b47f..a4007fe07c 100644 +index f38eb3b47f..7ae865c2cf 100644 --- a/dpdk/drivers/net/bonding/rte_eth_bond_api.c +++ b/dpdk/drivers/net/bonding/rte_eth_bond_api.c -@@ -129,12 +129,6 @@ deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id) +@@ -56,19 +56,25 @@ check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev) + } + + int +-valid_slave_port_id(uint16_t port_id, uint8_t mode) ++valid_slave_port_id(struct bond_dev_private *internals, uint16_t slave_port_id) + { +- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); ++ RTE_ETH_VALID_PORTID_OR_ERR_RET(slave_port_id, -1); + +- /* Verify that port_id refers to a non bonded port */ +- if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0 && +- mode == BONDING_MODE_8023AD) { ++ /* Verify that slave_port_id refers to a non bonded port */ ++ if (check_for_bonded_ethdev(&rte_eth_devices[slave_port_id]) == 0 && ++ internals->mode == BONDING_MODE_8023AD) { + RTE_BOND_LOG(ERR, "Cannot add slave to bonded device in 802.3ad" + " mode as slave is also a bonded device, only " + "physical devices can be support in this mode."); + return -1; + } + ++ if (internals->port_id == slave_port_id) { ++ RTE_BOND_LOG(ERR, ++ "Cannot add the bonded device itself as its slave."); ++ return -1; ++ } ++ + return 0; + } + +@@ -129,12 +135,6 @@ deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id) RTE_ASSERT(active_count < RTE_DIM(internals->active_slaves)); internals->active_slave_count = active_count; @@ -27144,7 +40627,7 @@ index f38eb3b47f..a4007fe07c 100644 if (eth_dev->data->dev_started) { if (internals->mode == BONDING_MODE_8023AD) { bond_mode_8023ad_start(eth_dev); -@@ -167,7 +161,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) +@@ -167,7 +167,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) ret = rte_vdev_init(name, devargs); if (ret) @@ -27153,7 +40636,71 @@ index f38eb3b47f..a4007fe07c 100644 ret = rte_eth_dev_get_port_by_name(name, &port_id); RTE_ASSERT(!ret); -@@ -698,6 +692,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, +@@ -285,6 +285,7 @@ eth_bond_slave_inherit_dev_info_rx_first(struct bond_dev_private *internals, + struct rte_eth_rxconf *rxconf_i = &internals->default_rxconf; + + internals->reta_size = di->reta_size; ++ internals->rss_key_len = di->hash_key_size; + + /* Inherit Rx offload capabilities from the first slave device */ + internals->rx_offload_capa = di->rx_offload_capa; +@@ -380,6 +381,11 @@ eth_bond_slave_inherit_dev_info_rx_next(struct bond_dev_private *internals, + */ + if (internals->reta_size > di->reta_size) + internals->reta_size = di->reta_size; ++ if (internals->rss_key_len > di->hash_key_size) { ++ RTE_BOND_LOG(WARNING, "slave has different rss key size, " ++ "configuring rss may fail"); ++ internals->rss_key_len = di->hash_key_size; ++ } + + if (!internals->max_rx_pktlen && + di->max_rx_pktlen < internals->candidate_max_rx_pktlen) +@@ -457,7 +463,7 @@ __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) != 0) ++ if (valid_slave_port_id(internals, slave_port_id) != 0) + return -1; + + slave_eth_dev = &rte_eth_devices[slave_port_id]; +@@ -606,13 +612,15 @@ rte_eth_bond_slave_add(uint16_t bonded_port_id, uint16_t slave_port_id) + + int retval; + +- /* Verify that port id's are valid bonded and slave ports */ + if (valid_bonded_port_id(bonded_port_id) != 0) + return -1; + + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + ++ if (valid_slave_port_id(internals, slave_port_id) != 0) ++ return -1; ++ + rte_spinlock_lock(&internals->lock); + + retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id); +@@ -636,7 +644,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, + bonded_eth_dev = &rte_eth_devices[bonded_port_id]; + internals = bonded_eth_dev->data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) < 0) ++ if (valid_slave_port_id(internals, slave_port_id) < 0) + return -1; + + /* first remove from active slave list */ +@@ -655,7 +663,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, + } + + if (slave_idx < 0) { +- RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %d", ++ RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %u", + internals->slave_count); + return -1; + } +@@ -698,6 +706,7 @@ __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, internals->current_primary_port = internals->slaves[0].port_id; else internals->primary_port = 0; @@ -27161,8 +40708,17 @@ index f38eb3b47f..a4007fe07c 100644 } if (internals->active_slave_count < 1) { +@@ -783,7 +792,7 @@ rte_eth_bond_primary_set(uint16_t bonded_port_id, uint16_t slave_port_id) + + internals = rte_eth_devices[bonded_port_id].data->dev_private; + +- if (valid_slave_port_id(slave_port_id, internals->mode) != 0) ++ if (valid_slave_port_id(internals, slave_port_id) != 0) + return -1; + + internals->user_defined_primary_port = 1; diff --git a/dpdk/drivers/net/bonding/rte_eth_bond_args.c b/dpdk/drivers/net/bonding/rte_eth_bond_args.c -index abdf552610..8c5f90dc63 100644 +index abdf552610..764b1b8c8e 100644 --- a/dpdk/drivers/net/bonding/rte_eth_bond_args.c +++ b/dpdk/drivers/net/bonding/rte_eth_bond_args.c @@ -22,23 +22,37 @@ const char *pmd_bond_init_valid_arguments[] = { @@ -27266,8 +40822,33 @@ index abdf552610..8c5f90dc63 100644 return -1; } return port_id; +@@ -209,20 +200,20 @@ int + bond_ethdev_parse_socket_id_kvarg(const char *key __rte_unused, + const char *value, void *extra_args) + { +- int socket_id; ++ long socket_id; + char *endptr; + + if (value == NULL || extra_args == NULL) + return -1; + + errno = 0; +- socket_id = (uint8_t)strtol(value, &endptr, 10); ++ socket_id = strtol(value, &endptr, 10); + if (*endptr != 0 || errno != 0) + return -1; + + /* validate socket id value */ +- if (socket_id >= 0) { +- *(uint8_t *)extra_args = (uint8_t)socket_id; ++ if (socket_id >= 0 && socket_id < RTE_MAX_NUMA_NODES) { ++ *(int *)extra_args = (int)socket_id; + return 0; + } + return -1; diff --git a/dpdk/drivers/net/bonding/rte_eth_bond_pmd.c b/dpdk/drivers/net/bonding/rte_eth_bond_pmd.c -index 707a0f3cdd..e7cb418053 100644 +index 707a0f3cdd..d6dbd2fb8a 100644 --- a/dpdk/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/dpdk/drivers/net/bonding/rte_eth_bond_pmd.c @@ -69,7 +69,7 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) @@ -27324,6 +40905,15 @@ index 707a0f3cdd..e7cb418053 100644 struct rte_ether_hdr *eth_h; uint16_t ether_type, offset; uint16_t nb_recv_pkts; +@@ -1322,7 +1322,7 @@ bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs, + + /* Increment reference count on mbufs */ + for (i = 0; i < nb_pkts; i++) +- rte_mbuf_refcnt_update(bufs[i], num_of_slaves - 1); ++ rte_pktmbuf_refcnt_update(bufs[i], num_of_slaves - 1); + + /* Transmit burst on each active slave */ + for (i = 0; i < num_of_slaves; i++) { @@ -1502,6 +1502,7 @@ int mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) { @@ -27351,7 +40941,7 @@ index 707a0f3cdd..e7cb418053 100644 } } else { if (rte_eth_dev_default_mac_addr_set( -@@ -1545,10 +1547,11 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) +@@ -1545,17 +1547,18 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) &internals->slaves[i].persisted_mac_addr)) { RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address", internals->slaves[i].port_id); @@ -27364,15 +40954,205 @@ index 707a0f3cdd..e7cb418053 100644 } return 0; -@@ -2873,6 +2876,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, + } + + int +-bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode) ++bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, uint8_t mode) + { + struct bond_dev_private *internals; + +@@ -1699,19 +1702,22 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, + + /* If RSS is enabled for bonding, try to enable it for slaves */ + if (bonded_eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { +- if (internals->rss_key_len != 0) { +- slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len = ++ /* rss_key won't be empty if RSS is configured in bonded dev */ ++ slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len = + internals->rss_key_len; +- slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = ++ slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = + internals->rss_key; +- } else { +- slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; +- } + + slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = + bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; + slave_eth_dev->data->dev_conf.rxmode.mq_mode = + bonded_eth_dev->data->dev_conf.rxmode.mq_mode; ++ } else { ++ slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len = 0; ++ slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; ++ slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; ++ slave_eth_dev->data->dev_conf.rxmode.mq_mode = ++ bonded_eth_dev->data->dev_conf.rxmode.mq_mode; + } + + if (bonded_eth_dev->data->dev_conf.rxmode.offloads & +@@ -1788,12 +1794,13 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, + != 0) + return errval; + +- if (bond_ethdev_8023ad_flow_verify(bonded_eth_dev, +- slave_eth_dev->data->port_id) != 0) { ++ errval = bond_ethdev_8023ad_flow_verify(bonded_eth_dev, ++ slave_eth_dev->data->port_id); ++ if (errval != 0) { + RTE_BOND_LOG(ERR, +- "rte_eth_tx_queue_setup: port=%d queue_id %d, err (%d)", +- slave_eth_dev->data->port_id, q_id, errval); +- return -1; ++ "bond_ethdev_8023ad_flow_verify: port=%d, err (%d)", ++ slave_eth_dev->data->port_id, errval); ++ return errval; + } + + if (internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id] != NULL) +@@ -1801,8 +1808,14 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev, + internals->mode4.dedicated_queues.flow[slave_eth_dev->data->port_id], + &flow_error); + +- bond_ethdev_8023ad_flow_set(bonded_eth_dev, ++ errval = bond_ethdev_8023ad_flow_set(bonded_eth_dev, + slave_eth_dev->data->port_id); ++ if (errval != 0) { ++ RTE_BOND_LOG(ERR, ++ "bond_ethdev_8023ad_flow_set: port=%d, err (%d)", ++ slave_eth_dev->data->port_id, errval); ++ return errval; ++ } + } + + /* Start device */ +@@ -2082,13 +2095,14 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev) + internals->link_status_polling_enabled = 0; + for (i = 0; i < internals->slave_count; i++) { + uint16_t slave_id = internals->slaves[i].port_id; ++ ++ internals->slaves[i].last_link_status = 0; ++ rte_eth_dev_stop(slave_id); ++ /* active slaves need to be deactivated. */ + if (find_slave_by_id(internals->active_slaves, + internals->active_slave_count, slave_id) != +- internals->active_slave_count) { +- internals->slaves[i].last_link_status = 0; +- rte_eth_dev_stop(slave_id); ++ internals->active_slave_count) + deactivate_slave(eth_dev, slave_id); +- } + } + } + +@@ -2204,6 +2218,7 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads; + + dev_info->reta_size = internals->reta_size; ++ dev_info->hash_key_size = internals->rss_key_len; + + return 0; + } +@@ -2643,6 +2658,39 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev) + return ret; + } + ++static int ++bond_ethdev_promiscuous_update(struct rte_eth_dev *dev) ++{ ++ struct bond_dev_private *internals = dev->data->dev_private; ++ uint16_t port_id = internals->current_primary_port; ++ ++ switch (internals->mode) { ++ case BONDING_MODE_ROUND_ROBIN: ++ case BONDING_MODE_BALANCE: ++ case BONDING_MODE_BROADCAST: ++ case BONDING_MODE_8023AD: ++ /* As promiscuous mode is propagated to all slaves for these ++ * mode, no need to update for bonding device. ++ */ ++ break; ++ case BONDING_MODE_ACTIVE_BACKUP: ++ case BONDING_MODE_TLB: ++ case BONDING_MODE_ALB: ++ default: ++ /* As promiscuous mode is propagated only to primary slave ++ * for these mode. When active/standby switchover, promiscuous ++ * mode should be set to new primary slave according to bonding ++ * device. ++ */ ++ if (rte_eth_promiscuous_get(internals->port_id) == 1) ++ rte_eth_promiscuous_enable(port_id); ++ else ++ rte_eth_promiscuous_disable(port_id); ++ } ++ ++ return 0; ++} ++ + static int + bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev) + { +@@ -2756,6 +2804,39 @@ bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev) + return ret; + } + ++static int ++bond_ethdev_allmulticast_update(struct rte_eth_dev *dev) ++{ ++ struct bond_dev_private *internals = dev->data->dev_private; ++ uint16_t port_id = internals->current_primary_port; ++ ++ switch (internals->mode) { ++ case BONDING_MODE_ROUND_ROBIN: ++ case BONDING_MODE_BALANCE: ++ case BONDING_MODE_BROADCAST: ++ case BONDING_MODE_8023AD: ++ /* As allmulticast mode is propagated to all slaves for these ++ * mode, no need to update for bonding device. ++ */ ++ break; ++ case BONDING_MODE_ACTIVE_BACKUP: ++ case BONDING_MODE_TLB: ++ case BONDING_MODE_ALB: ++ default: ++ /* As allmulticast mode is propagated only to primary slave ++ * for these mode. When active/standby switchover, allmulticast ++ * mode should be set to new primary slave according to bonding ++ * device. ++ */ ++ if (rte_eth_allmulticast_get(internals->port_id) == 1) ++ rte_eth_allmulticast_enable(port_id); ++ else ++ rte_eth_allmulticast_disable(port_id); ++ } ++ ++ return 0; ++} ++ + static void + bond_ethdev_delayed_lsc_propagation(void *arg) + { +@@ -2845,6 +2926,8 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, + lsc_flag = 1; + + mac_address_slaves_update(bonded_eth_dev); ++ bond_ethdev_promiscuous_update(bonded_eth_dev); ++ bond_ethdev_allmulticast_update(bonded_eth_dev); + } + + activate_slave(bonded_eth_dev, port_id); +@@ -2873,6 +2956,9 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, internals->active_slaves[0]); else internals->current_primary_port = internals->primary_port; + mac_address_slaves_update(bonded_eth_dev); ++ bond_ethdev_promiscuous_update(bonded_eth_dev); ++ bond_ethdev_allmulticast_update(bonded_eth_dev); } } -@@ -2931,7 +2935,8 @@ bond_ethdev_rss_reta_update(struct rte_eth_dev *dev, +@@ -2931,7 +3017,8 @@ bond_ethdev_rss_reta_update(struct rte_eth_dev *dev, return -EINVAL; /* Copy RETA table */ @@ -27382,11 +41162,146 @@ index 707a0f3cdd..e7cb418053 100644 for (i = 0; i < reta_count; i++) { internals->reta_conf[i].mask = reta_conf[i].mask; +@@ -2991,13 +3078,15 @@ bond_ethdev_rss_hash_update(struct rte_eth_dev *dev, + if (bond_rss_conf.rss_hf != 0) + dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = bond_rss_conf.rss_hf; + +- if (bond_rss_conf.rss_key && bond_rss_conf.rss_key_len < +- sizeof(internals->rss_key)) { +- if (bond_rss_conf.rss_key_len == 0) +- bond_rss_conf.rss_key_len = 40; +- internals->rss_key_len = bond_rss_conf.rss_key_len; ++ if (bond_rss_conf.rss_key) { ++ if (bond_rss_conf.rss_key_len < internals->rss_key_len) ++ return -EINVAL; ++ else if (bond_rss_conf.rss_key_len > internals->rss_key_len) ++ RTE_BOND_LOG(WARNING, "rss_key will be truncated"); ++ + memcpy(internals->rss_key, bond_rss_conf.rss_key, + internals->rss_key_len); ++ bond_rss_conf.rss_key_len = internals->rss_key_len; + } + + for (i = 0; i < internals->slave_count; i++) { +@@ -3250,7 +3339,7 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode) + /* Set mode 4 default configuration */ + bond_mode_8023ad_setup(eth_dev, NULL); + if (bond_ethdev_mode_set(eth_dev, mode)) { +- RTE_BOND_LOG(ERR, "Failed to set bonded device %d mode to %d", ++ RTE_BOND_LOG(ERR, "Failed to set bonded device %u mode to %u", + eth_dev->data->port_id, mode); + goto err; + } +@@ -3292,8 +3381,9 @@ bond_probe(struct rte_vdev_device *dev) + const char *name; + struct bond_dev_private *internals; + struct rte_kvargs *kvlist; +- uint8_t bonding_mode, socket_id/*, agg_mode*/; +- int arg_count, port_id; ++ uint8_t bonding_mode; ++ int arg_count, port_id; ++ int socket_id; + uint8_t agg_mode; + struct rte_eth_dev *eth_dev; + +@@ -3442,6 +3532,8 @@ bond_remove(struct rte_vdev_device *dev) + rte_bitmap_free(internals->vlan_filter_bmp); + rte_free(internals->vlan_filter_bmpmem); + ++ if (internals->kvlist != NULL) ++ rte_kvargs_free(internals->kvlist); + rte_eth_dev_release_port(eth_dev); + + return 0; +@@ -3455,6 +3547,7 @@ bond_ethdev_configure(struct rte_eth_dev *dev) + const char *name = dev->device->name; + struct bond_dev_private *internals = dev->data->dev_private; + struct rte_kvargs *kvlist = internals->kvlist; ++ uint64_t offloads; + int arg_count; + uint16_t port_id = dev - rte_eth_devices; + uint8_t agg_mode; +@@ -3470,20 +3563,40 @@ bond_ethdev_configure(struct rte_eth_dev *dev) + + /* + * If RSS is enabled, fill table with default values and +- * set key to the the value specified in port RSS configuration. ++ * set key to the value specified in port RSS configuration. + * Fall back to default RSS key if the key is not specified + */ + if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) { +- if (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key != NULL) { +- internals->rss_key_len = +- dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len; +- memcpy(internals->rss_key, +- dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key, +- internals->rss_key_len); +- } else { ++ struct rte_eth_rss_conf *rss_conf = ++ &dev->data->dev_conf.rx_adv_conf.rss_conf; ++ ++ if (internals->rss_key_len == 0) { + internals->rss_key_len = sizeof(default_rss_key); +- memcpy(internals->rss_key, default_rss_key, ++ } ++ ++ if (rss_conf->rss_key != NULL) { ++ if (internals->rss_key_len > rss_conf->rss_key_len) { ++ RTE_BOND_LOG(ERR, "Invalid rss key length(%u)", ++ rss_conf->rss_key_len); ++ return -EINVAL; ++ } ++ ++ memcpy(internals->rss_key, rss_conf->rss_key, + internals->rss_key_len); ++ } else { ++ if (internals->rss_key_len > sizeof(default_rss_key)) { ++ /* ++ * If the rss_key includes standard_rss_key and ++ * extended_hash_key, the rss key length will be ++ * larger than default rss key length, so it should ++ * re-calculate the hash key. ++ */ ++ for (i = 0; i < internals->rss_key_len; i++) ++ internals->rss_key[i] = (uint8_t)rte_rand(); ++ } else { ++ memcpy(internals->rss_key, default_rss_key, ++ internals->rss_key_len); ++ } + } + + for (i = 0; i < RTE_DIM(internals->reta_conf); i++) { +@@ -3495,6 +3608,16 @@ bond_ethdev_configure(struct rte_eth_dev *dev) + } + } + ++ offloads = dev->data->dev_conf.txmode.offloads; ++ if ((offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) && ++ (internals->mode == BONDING_MODE_8023AD || ++ internals->mode == BONDING_MODE_BROADCAST)) { ++ RTE_BOND_LOG(WARNING, ++ "bond mode broadcast & 8023AD don't support MBUF_FAST_FREE offload, force disable it."); ++ offloads &= ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; ++ dev->data->dev_conf.txmode.offloads = offloads; ++ } ++ + /* set the max_rx_pktlen */ + internals->max_rx_pktlen = internals->candidate_max_rx_pktlen; + diff --git a/dpdk/drivers/net/cxgbe/base/adapter.h b/dpdk/drivers/net/cxgbe/base/adapter.h -index db654ad9cd..eabd70a213 100644 +index db654ad9cd..33aecd8dd4 100644 --- a/dpdk/drivers/net/cxgbe/base/adapter.h +++ b/dpdk/drivers/net/cxgbe/base/adapter.h -@@ -816,6 +816,7 @@ int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_rspq *rq); +@@ -286,8 +286,6 @@ struct sge { + u32 fl_starve_thres; /* Free List starvation threshold */ + }; + +-#define T4_OS_NEEDS_MBOX_LOCKING 1 +- + /* + * OS Lock/List primitives for those interfaces in the Common Code which + * need this. +@@ -816,6 +814,7 @@ int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_rspq *rq); int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_rspq *rq); void t4_sge_eth_rxq_release(struct adapter *adap, struct sge_eth_rxq *rxq); void t4_sge_eth_clear_queues(struct port_info *pi); @@ -27394,6 +41309,314 @@ index db654ad9cd..eabd70a213 100644 int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us, unsigned int cnt); int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts, +diff --git a/dpdk/drivers/net/cxgbe/base/common.h b/dpdk/drivers/net/cxgbe/base/common.h +index 6047642c5c..fe944d61eb 100644 +--- a/dpdk/drivers/net/cxgbe/base/common.h ++++ b/dpdk/drivers/net/cxgbe/base/common.h +@@ -12,10 +12,6 @@ + #include "t4_chip_type.h" + #include "t4fw_interface.h" + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + #define CXGBE_PAGE_SIZE RTE_PGSIZE_4K + + #define T4_MEMORY_WRITE 0 +@@ -198,15 +194,15 @@ struct rss_params { + unsigned int mode; /* RSS mode */ + union { + struct { +- uint synmapen:1; /* SYN Map Enable */ +- uint syn4tupenipv6:1; /* en 4-tuple IPv6 SYNs hash */ +- uint syn2tupenipv6:1; /* en 2-tuple IPv6 SYNs hash */ +- uint syn4tupenipv4:1; /* en 4-tuple IPv4 SYNs hash */ +- uint syn2tupenipv4:1; /* en 2-tuple IPv4 SYNs hash */ +- uint ofdmapen:1; /* Offload Map Enable */ +- uint tnlmapen:1; /* Tunnel Map Enable */ +- uint tnlalllookup:1; /* Tunnel All Lookup */ +- uint hashtoeplitz:1; /* use Toeplitz hash */ ++ unsigned int synmapen:1; /* SYN Map Enable */ ++ unsigned int syn4tupenipv6:1; /* en 4-tuple IPv6 SYNs hash */ ++ unsigned int syn2tupenipv6:1; /* en 2-tuple IPv6 SYNs hash */ ++ unsigned int syn4tupenipv4:1; /* en 4-tuple IPv4 SYNs hash */ ++ unsigned int syn2tupenipv4:1; /* en 2-tuple IPv4 SYNs hash */ ++ unsigned int ofdmapen:1; /* Offload Map Enable */ ++ unsigned int tnlmapen:1; /* Tunnel Map Enable */ ++ unsigned int tnlalllookup:1; /* Tunnel All Lookup */ ++ unsigned int hashtoeplitz:1; /* use Toeplitz hash */ + } basicvirtual; + } u; + }; +diff --git a/dpdk/drivers/net/cxgbe/base/t4_hw.c b/dpdk/drivers/net/cxgbe/base/t4_hw.c +index 71ad1cb0f2..baca2bc9e0 100644 +--- a/dpdk/drivers/net/cxgbe/base/t4_hw.c ++++ b/dpdk/drivers/net/cxgbe/base/t4_hw.c +@@ -264,17 +264,6 @@ static void fw_asrt(struct adapter *adap, u32 mbox_addr) + + #define X_CIM_PF_NOACCESS 0xeeeeeeee + +-/* +- * If the Host OS Driver needs locking arround accesses to the mailbox, this +- * can be turned on via the T4_OS_NEEDS_MBOX_LOCKING CPP define ... +- */ +-/* makes single-statement usage a bit cleaner ... */ +-#ifdef T4_OS_NEEDS_MBOX_LOCKING +-#define T4_OS_MBOX_LOCKING(x) x +-#else +-#define T4_OS_MBOX_LOCKING(x) do {} while (0) +-#endif +- + /** + * t4_wr_mbox_meat_timeout - send a command to FW through the given mailbox + * @adap: the adapter +@@ -315,28 +304,17 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + 1, 1, 3, 5, 10, 10, 20, 50, 100 + }; + +- u32 v; +- u64 res; +- int i, ms; +- unsigned int delay_idx; +- __be64 *temp = (__be64 *)malloc(size * sizeof(char)); +- __be64 *p = temp; + u32 data_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_DATA); + u32 ctl_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_CTRL); +- u32 ctl; +- struct mbox_entry entry; +- u32 pcie_fw = 0; +- +- if (!temp) +- return -ENOMEM; ++ struct mbox_entry *entry; ++ u32 v, ctl, pcie_fw = 0; ++ unsigned int delay_idx; ++ const __be64 *p; ++ int i, ms, ret; ++ u64 res; + +- if ((size & 15) || size > MBOX_LEN) { +- free(temp); ++ if ((size & 15) != 0 || size > MBOX_LEN) + return -EINVAL; +- } +- +- memset(p, 0, size); +- memcpy(p, (const __be64 *)cmd, size); + + /* + * If we have a negative timeout, that implies that we can't sleep. +@@ -346,14 +324,17 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + timeout = -timeout; + } + +-#ifdef T4_OS_NEEDS_MBOX_LOCKING ++ entry = t4_os_alloc(sizeof(*entry)); ++ if (entry == NULL) ++ return -ENOMEM; ++ + /* + * Queue ourselves onto the mailbox access list. When our entry is at + * the front of the list, we have rights to access the mailbox. So we + * wait [for a while] till we're at the front [or bail out with an + * EBUSY] ... + */ +- t4_os_atomic_add_tail(&entry, &adap->mbox_list, &adap->mbox_lock); ++ t4_os_atomic_add_tail(entry, &adap->mbox_list, &adap->mbox_lock); + + delay_idx = 0; + ms = delay[0]; +@@ -368,18 +349,18 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + */ + pcie_fw = t4_read_reg(adap, A_PCIE_FW); + if (i > 4 * timeout || (pcie_fw & F_PCIE_FW_ERR)) { +- t4_os_atomic_list_del(&entry, &adap->mbox_list, ++ t4_os_atomic_list_del(entry, &adap->mbox_list, + &adap->mbox_lock); + t4_report_fw_error(adap); +- free(temp); +- return (pcie_fw & F_PCIE_FW_ERR) ? -ENXIO : -EBUSY; ++ ret = ((pcie_fw & F_PCIE_FW_ERR) != 0) ? -ENXIO : -EBUSY; ++ goto out_free; + } + + /* + * If we're at the head, break out and start the mailbox + * protocol. + */ +- if (t4_os_list_first_entry(&adap->mbox_list) == &entry) ++ if (t4_os_list_first_entry(&adap->mbox_list) == entry) + break; + + /* +@@ -394,7 +375,6 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + rte_delay_ms(ms); + } + } +-#endif /* T4_OS_NEEDS_MBOX_LOCKING */ + + /* + * Attempt to gain access to the mailbox. +@@ -411,12 +391,11 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + * mailbox atomic access list and report the error to our caller. + */ + if (v != X_MBOWNER_PL) { +- T4_OS_MBOX_LOCKING(t4_os_atomic_list_del(&entry, +- &adap->mbox_list, +- &adap->mbox_lock)); ++ t4_os_atomic_list_del(entry, &adap->mbox_list, ++ &adap->mbox_lock); + t4_report_fw_error(adap); +- free(temp); +- return (v == X_MBOWNER_FW ? -EBUSY : -ETIMEDOUT); ++ ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT; ++ goto out_free; + } + + /* +@@ -442,7 +421,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + /* + * Copy in the new mailbox command and send it on its way ... + */ +- for (i = 0; i < size; i += 8, p++) ++ for (i = 0, p = cmd; i < size; i += 8, p++) + t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p)); + + CXGBE_DEBUG_MBOX(adap, "%s: mbox %u: %016llx %016llx %016llx %016llx " +@@ -513,11 +492,10 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + get_mbox_rpl(adap, rpl, size / 8, data_reg); + } + t4_write_reg(adap, ctl_reg, V_MBOWNER(X_MBOWNER_NONE)); +- T4_OS_MBOX_LOCKING( +- t4_os_atomic_list_del(&entry, &adap->mbox_list, +- &adap->mbox_lock)); +- free(temp); +- return -G_FW_CMD_RETVAL((int)res); ++ t4_os_atomic_list_del(entry, &adap->mbox_list, ++ &adap->mbox_lock); ++ ret = -G_FW_CMD_RETVAL((int)res); ++ goto out_free; + } + } + +@@ -528,12 +506,13 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, + */ + dev_err(adap, "command %#x in mailbox %d timed out\n", + *(const u8 *)cmd, mbox); +- T4_OS_MBOX_LOCKING(t4_os_atomic_list_del(&entry, +- &adap->mbox_list, +- &adap->mbox_lock)); ++ t4_os_atomic_list_del(entry, &adap->mbox_list, &adap->mbox_lock); + t4_report_fw_error(adap); +- free(temp); +- return (pcie_fw & F_PCIE_FW_ERR) ? -ENXIO : -ETIMEDOUT; ++ ret = ((pcie_fw & F_PCIE_FW_ERR) != 0) ? -ENXIO : -ETIMEDOUT; ++ ++out_free: ++ t4_os_free(entry); ++ return ret; + } + + int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, +diff --git a/dpdk/drivers/net/cxgbe/base/t4vf_hw.c b/dpdk/drivers/net/cxgbe/base/t4vf_hw.c +index 649bacfb25..7e323d9b66 100644 +--- a/dpdk/drivers/net/cxgbe/base/t4vf_hw.c ++++ b/dpdk/drivers/net/cxgbe/base/t4vf_hw.c +@@ -83,7 +83,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + + u32 mbox_ctl = T4VF_CIM_BASE_ADDR + A_CIM_VF_EXT_MAILBOX_CTRL; + __be64 cmd_rpl[MBOX_LEN / 8]; +- struct mbox_entry entry; ++ struct mbox_entry *entry; + unsigned int delay_idx; + u32 v, mbox_data; + const __be64 *p; +@@ -106,13 +106,17 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4) + return -EINVAL; + ++ entry = t4_os_alloc(sizeof(*entry)); ++ if (entry == NULL) ++ return -ENOMEM; ++ + /* + * Queue ourselves onto the mailbox access list. When our entry is at + * the front of the list, we have rights to access the mailbox. So we + * wait [for a while] till we're at the front [or bail out with an + * EBUSY] ... + */ +- t4_os_atomic_add_tail(&entry, &adapter->mbox_list, &adapter->mbox_lock); ++ t4_os_atomic_add_tail(entry, &adapter->mbox_list, &adapter->mbox_lock); + + delay_idx = 0; + ms = delay[0]; +@@ -125,17 +129,17 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + * contend on access to the mailbox ... + */ + if (i > (2 * FW_CMD_MAX_TIMEOUT)) { +- t4_os_atomic_list_del(&entry, &adapter->mbox_list, ++ t4_os_atomic_list_del(entry, &adapter->mbox_list, + &adapter->mbox_lock); + ret = -EBUSY; +- return ret; ++ goto out_free; + } + + /* + * If we're at the head, break out and start the mailbox + * protocol. + */ +- if (t4_os_list_first_entry(&adapter->mbox_list) == &entry) ++ if (t4_os_list_first_entry(&adapter->mbox_list) == entry) + break; + + /* +@@ -160,10 +164,10 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + v = G_MBOWNER(t4_read_reg(adapter, mbox_ctl)); + + if (v != X_MBOWNER_PL) { +- t4_os_atomic_list_del(&entry, &adapter->mbox_list, ++ t4_os_atomic_list_del(entry, &adapter->mbox_list, + &adapter->mbox_lock); + ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT; +- return ret; ++ goto out_free; + } + + /* +@@ -224,7 +228,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + get_mbox_rpl(adapter, cmd_rpl, size / 8, mbox_data); + t4_write_reg(adapter, mbox_ctl, + V_MBOWNER(X_MBOWNER_NONE)); +- t4_os_atomic_list_del(&entry, &adapter->mbox_list, ++ t4_os_atomic_list_del(entry, &adapter->mbox_list, + &adapter->mbox_lock); + + /* return value in high-order host-endian word */ +@@ -236,7 +240,8 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + & F_FW_CMD_REQUEST) == 0); + memcpy(rpl, cmd_rpl, size); + } +- return -((int)G_FW_CMD_RETVAL(v)); ++ ret = -((int)G_FW_CMD_RETVAL(v)); ++ goto out_free; + } + } + +@@ -246,8 +251,11 @@ int t4vf_wr_mbox_core(struct adapter *adapter, + dev_err(adapter, "command %#x timed out\n", + *(const u8 *)cmd); + dev_err(adapter, " Control = %#x\n", t4_read_reg(adapter, mbox_ctl)); +- t4_os_atomic_list_del(&entry, &adapter->mbox_list, &adapter->mbox_lock); ++ t4_os_atomic_list_del(entry, &adapter->mbox_list, &adapter->mbox_lock); + ret = -ETIMEDOUT; ++ ++out_free: ++ t4_os_free(entry); + return ret; + } + diff --git a/dpdk/drivers/net/cxgbe/cxgbe.h b/dpdk/drivers/net/cxgbe/cxgbe.h index 6c1f73ac4b..8b8babc5e4 100644 --- a/dpdk/drivers/net/cxgbe/cxgbe.h @@ -27420,7 +41643,7 @@ index 6c1f73ac4b..8b8babc5e4 100644 #define CXGBE_RX_OFFLOADS (DEV_RX_OFFLOAD_VLAN_STRIP | \ DEV_RX_OFFLOAD_IPV4_CKSUM | \ diff --git a/dpdk/drivers/net/cxgbe/cxgbe_ethdev.c b/dpdk/drivers/net/cxgbe/cxgbe_ethdev.c -index 51b63ef574..352b47fdfb 100644 +index 51b63ef574..ed92b560c6 100644 --- a/dpdk/drivers/net/cxgbe/cxgbe_ethdev.c +++ b/dpdk/drivers/net/cxgbe/cxgbe_ethdev.c @@ -74,6 +74,9 @@ uint16_t cxgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, @@ -27450,7 +41673,14 @@ index 51b63ef574..352b47fdfb 100644 eth_dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else -@@ -329,12 +333,7 @@ void cxgbe_dev_close(struct rte_eth_dev *eth_dev) +@@ -325,16 +329,14 @@ void cxgbe_dev_close(struct rte_eth_dev *eth_dev) + + CXGBE_FUNC_TRACE(); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (!(adapter->flags & FULL_INIT_DONE)) return; cxgbe_down(pi); @@ -27464,8 +41694,13 @@ index 51b63ef574..352b47fdfb 100644 } /* Start the device. -@@ -649,7 +648,7 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev, - rxq->fl.size = temp_nb_desc; +@@ -645,11 +647,10 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev, + } + + rxq->rspq.size = temp_nb_desc; +- if ((&rxq->fl) != NULL) +- rxq->fl.size = temp_nb_desc; ++ rxq->fl.size = temp_nb_desc; /* Set to jumbo mode if necessary */ - if (pkt_len > RTE_ETHER_MAX_LEN) @@ -27775,10 +42010,119 @@ index 5302d1343d..6e5fae9928 100644 * will be different from the user provided value only if user * provided value is -1 diff --git a/dpdk/drivers/net/cxgbe/sge.c b/dpdk/drivers/net/cxgbe/sge.c -index aba85a2090..7587c46aab 100644 +index aba85a2090..f3ff576cfd 100644 --- a/dpdk/drivers/net/cxgbe/sge.c +++ b/dpdk/drivers/net/cxgbe/sge.c -@@ -1421,16 +1421,49 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) +@@ -793,9 +793,9 @@ static inline void txq_advance(struct sge_txq *q, unsigned int n) + + #define MAX_COALESCE_LEN 64000 + +-static inline int wraps_around(struct sge_txq *q, int ndesc) ++static inline bool wraps_around(struct sge_txq *q, int ndesc) + { +- return (q->pidx + ndesc) > q->size ? 1 : 0; ++ return (q->pidx + ndesc) > q->size ? true : false; + } + + static void tx_timer_cb(void *data) +@@ -846,7 +846,6 @@ static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap, + + /* fill the pkts WR header */ + wr = (void *)&q->desc[q->pidx]; +- wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR)); + vmwr = (void *)&q->desc[q->pidx]; + + wr_mid = V_FW_WR_LEN16(DIV_ROUND_UP(q->coalesce.flits, 2)); +@@ -856,8 +855,11 @@ static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap, + wr->npkt = q->coalesce.idx; + wr->r3 = 0; + if (is_pf4(adap)) { +- wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR)); + wr->type = q->coalesce.type; ++ if (likely(wr->type != 0)) ++ wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR)); ++ else ++ wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_WR)); + } else { + wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_VM_WR)); + vmwr->r4 = 0; +@@ -936,13 +938,16 @@ static inline int should_tx_packet_coalesce(struct sge_eth_txq *txq, + ndesc = DIV_ROUND_UP(q->coalesce.flits + flits, 8); + credits = txq_avail(q) - ndesc; + ++ if (unlikely(wraps_around(q, ndesc))) ++ return 0; ++ + /* If we are wrapping or this is last mbuf then, send the + * already coalesced mbufs and let the non-coalesce pass + * handle the mbuf. + */ +- if (unlikely(credits < 0 || wraps_around(q, ndesc))) { ++ if (unlikely(credits < 0)) { + ship_tx_pkt_coalesce_wr(adap, txq); +- return 0; ++ return -EBUSY; + } + + /* If the max coalesce len or the max WR len is reached +@@ -966,8 +971,12 @@ static inline int should_tx_packet_coalesce(struct sge_eth_txq *txq, + ndesc = flits_to_desc(q->coalesce.flits + flits); + credits = txq_avail(q) - ndesc; + +- if (unlikely(credits < 0 || wraps_around(q, ndesc))) ++ if (unlikely(wraps_around(q, ndesc))) + return 0; ++ ++ if (unlikely(credits < 0)) ++ return -EBUSY; ++ + q->coalesce.flits += wr_size / sizeof(__be64); + q->coalesce.type = type; + q->coalesce.ptr = (unsigned char *)&q->desc[q->pidx] + +@@ -1110,7 +1119,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, + unsigned int flits, ndesc, cflits; + int l3hdr_len, l4hdr_len, eth_xtra_len; + int len, last_desc; +- int credits; ++ int should_coal, credits; + u32 wr_mid; + u64 cntrl, *end; + bool v6; +@@ -1141,9 +1150,9 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, + /* align the end of coalesce WR to a 512 byte boundary */ + txq->q.coalesce.max = (8 - (txq->q.pidx & 7)) * 8; + +- if (!((m->ol_flags & PKT_TX_TCP_SEG) || +- m->pkt_len > RTE_ETHER_MAX_LEN)) { +- if (should_tx_packet_coalesce(txq, mbuf, &cflits, adap)) { ++ if ((m->ol_flags & PKT_TX_TCP_SEG) == 0) { ++ should_coal = should_tx_packet_coalesce(txq, mbuf, &cflits, adap); ++ if (should_coal > 0) { + if (unlikely(map_mbuf(mbuf, addr) < 0)) { + dev_warn(adap, "%s: mapping err for coalesce\n", + __func__); +@@ -1152,8 +1161,8 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, + } + return tx_do_packet_coalesce(txq, mbuf, cflits, adap, + pi, addr, nb_pkts); +- } else { +- return -EBUSY; ++ } else if (should_coal < 0) { ++ return should_coal; + } + } + +@@ -1200,8 +1209,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf, + end = (u64 *)vmwr + flits; + } + +- len = 0; +- len += sizeof(*cpl); ++ len = sizeof(*cpl); + + /* Coalescing skipped and we send through normal path */ + if (!(m->ol_flags & PKT_TX_TCP_SEG)) { +@@ -1421,16 +1429,49 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) return ctrl_xmit(q, mbuf); } @@ -27831,7 +42175,7 @@ index aba85a2090..7587c46aab 100644 * * Allocates resources for an SGE descriptor ring, such as Tx queues, * free buffer lists, or response queues. Each SGE ring requires -@@ -1440,39 +1473,34 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) +@@ -1440,39 +1481,34 @@ int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf) * of the function), the bus address of the HW ring, and the address * of the SW ring. */ @@ -27881,7 +42225,7 @@ index aba85a2090..7587c46aab 100644 memset(tz->addr, 0, len); if (sw_size) { s = rte_zmalloc_socket(z_name_sw, nelem * sw_size, -@@ -1788,21 +1816,15 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, +@@ -1788,21 +1824,15 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, struct fw_iq_cmd c; struct sge *s = &adap->sge; struct port_info *pi = eth_dev->data->dev_private; @@ -27906,7 +42250,7 @@ index aba85a2090..7587c46aab 100644 if (!iq->desc) return -ENOMEM; -@@ -1860,18 +1882,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, +@@ -1860,18 +1890,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, fl->size = s->fl_starve_thres - 1 + 2 * 8; fl->size = cxgbe_roundup(fl->size, 8); @@ -27932,7 +42276,16 @@ index aba85a2090..7587c46aab 100644 flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc); c.iqns_to_fl0congen |= -@@ -1991,8 +2009,6 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, +@@ -1921,7 +1947,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, + iq->stat = (void *)&iq->desc[iq->size * 8]; + iq->eth_dev = eth_dev; + iq->handler = hnd; +- iq->port_id = pi->pidx; ++ iq->port_id = eth_dev->data->port_id; + iq->mb_pool = mp; + + /* set offset to -1 to distinguish ingress queues without FL */ +@@ -1991,8 +2017,6 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, refill_fl_err: t4_iq_free(adap, adap->mbox, adap->pf, 0, FW_IQ_TYPE_FL_INT_CAP, iq->cntxt_id, fl->cntxt_id, 0xffff); @@ -27941,7 +42294,7 @@ index aba85a2090..7587c46aab 100644 err: iq->cntxt_id = 0; iq->abs_id = 0; -@@ -2058,21 +2074,15 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, +@@ -2058,21 +2082,15 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, struct fw_eq_eth_cmd c; struct sge *s = &adap->sge; struct port_info *pi = eth_dev->data->dev_private; @@ -27967,7 +42320,7 @@ index aba85a2090..7587c46aab 100644 if (!txq->q.desc) return -ENOMEM; -@@ -2137,20 +2147,13 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, +@@ -2137,20 +2155,13 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, struct fw_eq_ctrl_cmd c; struct sge *s = &adap->sge; struct port_info *pi = eth_dev->data->dev_private; @@ -27991,7 +42344,7 @@ index aba85a2090..7587c46aab 100644 if (!txq->q.desc) return -ENOMEM; -@@ -2262,6 +2265,36 @@ void t4_sge_eth_txq_release(struct adapter *adap, struct sge_eth_txq *txq) +@@ -2262,6 +2273,36 @@ void t4_sge_eth_txq_release(struct adapter *adap, struct sge_eth_txq *txq) } } @@ -28028,7 +42381,7 @@ index aba85a2090..7587c46aab 100644 void t4_sge_tx_monitor_start(struct adapter *adap) { rte_eal_alarm_set(50, tx_timer_cb, (void *)adap); -@@ -2281,21 +2314,6 @@ void t4_sge_tx_monitor_stop(struct adapter *adap) +@@ -2281,21 +2322,6 @@ void t4_sge_tx_monitor_stop(struct adapter *adap) void t4_free_sge_resources(struct adapter *adap) { unsigned int i; @@ -28050,7 +42403,7 @@ index aba85a2090..7587c46aab 100644 /* clean up control Tx queues */ for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) { -@@ -2305,12 +2323,17 @@ void t4_free_sge_resources(struct adapter *adap) +@@ -2305,12 +2331,17 @@ void t4_free_sge_resources(struct adapter *adap) reclaim_completed_tx_imm(&cq->q); t4_ctrl_eq_free(adap, adap->mbox, adap->pf, 0, cq->q.cntxt_id); @@ -28070,7 +42423,7 @@ index aba85a2090..7587c46aab 100644 /** diff --git a/dpdk/drivers/net/dpaa/dpaa_ethdev.c b/dpdk/drivers/net/dpaa/dpaa_ethdev.c -index 26805f17b7..4d5946103a 100644 +index 26805f17b7..37dce2146f 100644 --- a/dpdk/drivers/net/dpaa/dpaa_ethdev.c +++ b/dpdk/drivers/net/dpaa/dpaa_ethdev.c @@ -173,8 +173,8 @@ dpaa_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) @@ -28084,7 +42437,35 @@ index 26805f17b7..4d5946103a 100644 DEV_RX_OFFLOAD_JUMBO_FRAME; else dev->data->dev_conf.rxmode.offloads &= -@@ -881,8 +881,8 @@ dpaa_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) +@@ -811,23 +811,17 @@ int + dpaa_eth_eventq_detach(const struct rte_eth_dev *dev, + int eth_rx_queue_id) + { +- struct qm_mcc_initfq opts; ++ struct qm_mcc_initfq opts = {0}; + int ret; + u32 flags = 0; + struct dpaa_if *dpaa_intf = dev->data->dev_private; + struct qman_fq *rxq = &dpaa_intf->rx_queues[eth_rx_queue_id]; + +- dpaa_poll_queue_default_config(&opts); +- +- if (dpaa_intf->cgr_rx) { +- opts.we_mask |= QM_INITFQ_WE_CGID; +- opts.fqd.cgid = dpaa_intf->cgr_rx[eth_rx_queue_id].cgrid; +- opts.fqd.fq_ctrl |= QM_FQCTRL_CGE; +- } +- ++ qman_retire_fq(rxq, NULL); ++ qman_oos_fq(rxq); + ret = qman_init_fq(rxq, flags, &opts); + if (ret) { +- DPAA_PMD_ERR("init rx fqid %d failed with ret: %d", ++ DPAA_PMD_ERR("detach rx fqid %d failed with ret: %d", + rxq->fqid, ret); + } + +@@ -881,8 +875,8 @@ dpaa_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) PMD_INIT_FUNC_TRACE(); if (qman_query_fq_frm_cnt(rxq, &frm_cnt) == 0) { @@ -28095,7 +42476,7 @@ index 26805f17b7..4d5946103a 100644 } return frm_cnt; } -@@ -996,8 +996,7 @@ dpaa_dev_add_mac_addr(struct rte_eth_dev *dev, +@@ -996,8 +990,7 @@ dpaa_dev_add_mac_addr(struct rte_eth_dev *dev, ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, index); if (ret) @@ -28105,7 +42486,7 @@ index 26805f17b7..4d5946103a 100644 return 0; } -@@ -1023,7 +1022,7 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev, +@@ -1023,7 +1016,7 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev, ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0); if (ret) @@ -28114,7 +42495,7 @@ index 26805f17b7..4d5946103a 100644 return ret; } -@@ -1121,7 +1120,7 @@ is_dpaa_supported(struct rte_eth_dev *dev) +@@ -1121,7 +1114,7 @@ is_dpaa_supported(struct rte_eth_dev *dev) } int @@ -28123,7 +42504,7 @@ index 26805f17b7..4d5946103a 100644 { struct rte_eth_dev *dev; struct dpaa_if *dpaa_intf; -@@ -1306,6 +1305,7 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) +@@ -1306,6 +1299,7 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) struct fman_if *fman_intf; struct fman_if_bpool *bp, *tmp_bp; uint32_t cgrid[DPAA_MAX_NUM_PCD_QUEUES]; @@ -28131,7 +42512,7 @@ index 26805f17b7..4d5946103a 100644 PMD_INIT_FUNC_TRACE(); -@@ -1457,15 +1457,9 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) +@@ -1457,15 +1451,9 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev) /* copy the primary mac address */ rte_ether_addr_copy(&fman_intf->mac_addr, ð_dev->data->mac_addrs[0]); @@ -28149,7 +42530,7 @@ index 26805f17b7..4d5946103a 100644 /* Disable RX mode */ fman_if_discard_rx_errors(fman_intf); -@@ -1578,8 +1572,7 @@ rte_dpaa_probe(struct rte_dpaa_driver *dpaa_drv __rte_unused, +@@ -1578,8 +1566,7 @@ rte_dpaa_probe(struct rte_dpaa_driver *dpaa_drv __rte_unused, if (!is_global_init && (rte_eal_process_type() == RTE_PROC_PRIMARY)) { if (access("/tmp/fmc.bin", F_OK) == -1) { @@ -28209,10 +42590,19 @@ index 37eea9b032..ec45633ba2 100644 #endif /* _PMD_DPAA_H_ */ diff --git a/dpdk/drivers/net/dpaa2/dpaa2_ethdev.c b/dpdk/drivers/net/dpaa2/dpaa2_ethdev.c -index 2cde55e7cc..5b7529690b 100644 +index 2cde55e7cc..acdff22521 100644 --- a/dpdk/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/dpdk/drivers/net/dpaa2/dpaa2_ethdev.c -@@ -147,7 +147,7 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -31,6 +31,8 @@ + + #define DRIVER_LOOPBACK_MODE "drv_loopback" + #define DRIVER_NO_PREFETCH_MODE "drv_no_prefetch" ++#define CHECK_INTERVAL 100 /* 100ms */ ++#define MAX_REPEAT_TIME 90 /* 9s (90 * 100ms) in total */ + + /* Supported Rx offloads */ + static uint64_t dev_rx_offloads_sup = +@@ -147,7 +149,7 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) { struct dpaa2_dev_priv *priv = dev->data->dev_private; struct fsl_mc_io *dpni = dev->process_private; @@ -28221,7 +42611,7 @@ index 2cde55e7cc..5b7529690b 100644 PMD_INIT_FUNC_TRACE(); -@@ -155,7 +155,7 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -155,7 +157,7 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) /* VLAN Filter not avaialble */ if (!priv->max_vlan_filters) { DPAA2_PMD_INFO("VLAN filter not available"); @@ -28230,7 +42620,7 @@ index 2cde55e7cc..5b7529690b 100644 } if (dev->data->dev_conf.rxmode.offloads & -@@ -168,14 +168,8 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -168,14 +170,8 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) if (ret < 0) DPAA2_PMD_INFO("Unable to set vlan filter = %d", ret); } @@ -28246,7 +42636,7 @@ index 2cde55e7cc..5b7529690b 100644 } static int -@@ -255,8 +249,6 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) +@@ -255,8 +251,6 @@ dpaa2_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) PMD_INIT_FUNC_TRACE(); @@ -28255,7 +42645,7 @@ index 2cde55e7cc..5b7529690b 100644 dev_info->max_mac_addrs = priv->max_mac_filters; dev_info->max_rx_pktlen = DPAA2_MAX_RX_PKT_LEN; dev_info->min_rx_bufsize = DPAA2_MIN_RX_BUF_SIZE; -@@ -553,9 +545,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) +@@ -553,9 +547,6 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); @@ -28265,7 +42655,7 @@ index 2cde55e7cc..5b7529690b 100644 return 0; } -@@ -663,7 +652,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, +@@ -663,7 +654,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, DPNI_CP_CONGESTION_GROUP, DPNI_QUEUE_RX, dpaa2_q->tc_index, @@ -28274,7 +42664,7 @@ index 2cde55e7cc..5b7529690b 100644 } else { /*enabling per rx queue congestion control */ taildrop.threshold = CONG_THRESHOLD_RX_BYTES_Q; -@@ -690,7 +679,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, +@@ -690,7 +681,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, DPNI_CP_CONGESTION_GROUP, DPNI_QUEUE_RX, dpaa2_q->tc_index, @@ -28283,7 +42673,7 @@ index 2cde55e7cc..5b7529690b 100644 } else { ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, DPNI_CP_QUEUE, DPNI_QUEUE_RX, -@@ -1288,7 +1277,7 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -1288,7 +1279,7 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) if (mtu < RTE_ETHER_MIN_MTU || frame_size > DPAA2_MAX_RX_PKT_LEN) return -EINVAL; @@ -28292,7 +42682,45 @@ index 2cde55e7cc..5b7529690b 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else -@@ -1757,6 +1746,7 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) +@@ -1673,23 +1664,32 @@ dpaa2_dev_stats_reset(struct rte_eth_dev *dev) + /* return 0 means link status changed, -1 means not changed */ + static int + dpaa2_dev_link_update(struct rte_eth_dev *dev, +- int wait_to_complete __rte_unused) ++ int wait_to_complete) + { + int ret; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private; + struct rte_eth_link link; + struct dpni_link_state state = {0}; ++ uint8_t count; + + if (dpni == NULL) { + DPAA2_PMD_ERR("dpni is NULL"); + return 0; + } + +- ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); +- if (ret < 0) { +- DPAA2_PMD_DEBUG("error: dpni_get_link_state %d", ret); +- return -1; ++ for (count = 0; count <= MAX_REPEAT_TIME; count++) { ++ ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, ++ &state); ++ if (ret < 0) { ++ DPAA2_PMD_DEBUG("error: dpni_get_link_state %d", ret); ++ return -1; ++ } ++ if (state.up == ETH_LINK_DOWN && ++ wait_to_complete) ++ rte_delay_ms(CHECK_INTERVAL); ++ else ++ break; + } + + memset(&link, 0, sizeof(struct rte_eth_link)); +@@ -1757,6 +1757,7 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) /* changing tx burst function to start enqueues */ dev->tx_pkt_burst = dpaa2_dev_tx; dev->data->dev_link.link_status = state.up; @@ -28395,6 +42823,21 @@ index 316912fe3e..bd9bcd58b0 100644 RTE_PMD_REGISTER_DPAA2_OBJECT(dprtc, rte_dpaa2_dprtc_obj); +#endif +diff --git a/dpdk/drivers/net/dpaa2/dpaa2_sparser.h b/dpdk/drivers/net/dpaa2/dpaa2_sparser.h +index 365b8062a9..ed0897928b 100644 +--- a/dpdk/drivers/net/dpaa2/dpaa2_sparser.h ++++ b/dpdk/drivers/net/dpaa2/dpaa2_sparser.h +@@ -13,10 +13,6 @@ + #ifndef _DPAA2_SPARSER_H + #define _DPAA2_SPARSER_H + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + #define WRIOP_SS_INITIALIZER(priv) \ + do { \ + /* Base offset of parse profile memory in WRIOP */ \ diff --git a/dpdk/drivers/net/dpaa2/meson.build b/dpdk/drivers/net/dpaa2/meson.build index 571cdb7d4b..fc4707db10 100644 --- a/dpdk/drivers/net/dpaa2/meson.build @@ -28417,6 +42860,29 @@ index 571cdb7d4b..fc4707db10 100644 includes += include_directories('base', 'mc') # depends on fslmc bus which uses experimental API +diff --git a/dpdk/drivers/net/e1000/base/e1000_i210.c b/dpdk/drivers/net/e1000/base/e1000_i210.c +index 9298223c33..025262d1e5 100644 +--- a/dpdk/drivers/net/e1000/base/e1000_i210.c ++++ b/dpdk/drivers/net/e1000/base/e1000_i210.c +@@ -310,6 +310,8 @@ STATIC s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, + } + + for (i = 0; i < words; i++) { ++ ret_val = -E1000_ERR_NVM; ++ + eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | + (data[i] << E1000_NVM_RW_REG_DATA) | + E1000_NVM_RW_REG_START; +diff --git a/dpdk/drivers/net/e1000/base/meson.build b/dpdk/drivers/net/e1000/base/meson.build +index f26f242987..ed00d37aed 100644 +--- a/dpdk/drivers/net/e1000/base/meson.build ++++ b/dpdk/drivers/net/e1000/base/meson.build +@@ -37,4 +37,4 @@ endforeach + base_lib = static_library('e1000_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/e1000/e1000_ethdev.h b/dpdk/drivers/net/e1000/e1000_ethdev.h index 1e41ae9de1..6b1e599441 100644 --- a/dpdk/drivers/net/e1000/e1000_ethdev.h @@ -28431,7 +42897,7 @@ index 1e41ae9de1..6b1e599441 100644 * Maximum number of Ring Descriptors. * diff --git a/dpdk/drivers/net/e1000/em_ethdev.c b/dpdk/drivers/net/e1000/em_ethdev.c -index 080cbe2df5..4a6e6b8d73 100644 +index 080cbe2df5..acb3a40004 100644 --- a/dpdk/drivers/net/e1000/em_ethdev.c +++ b/dpdk/drivers/net/e1000/em_ethdev.c @@ -321,7 +321,7 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev) @@ -28443,7 +42909,27 @@ index 080cbe2df5..4a6e6b8d73 100644 eth_em_close(eth_dev); -@@ -1795,8 +1795,7 @@ eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -767,6 +767,9 @@ eth_em_close(struct rte_eth_dev *dev) + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + eth_em_stop(dev); + adapter->stopped = 1; + em_dev_free_queues(dev); +@@ -971,8 +974,7 @@ eth_em_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) + + /* Rx Errors */ + rte_stats->imissed = stats->mpc; +- rte_stats->ierrors = stats->crcerrs + +- stats->rlec + stats->ruc + stats->roc + ++ rte_stats->ierrors = stats->crcerrs + stats->rlec + + stats->rxerrc + stats->algnerrc + stats->cexterr; + + /* Tx Errors */ +@@ -1795,24 +1797,27 @@ eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) if (ret != 0) return ret; @@ -28453,7 +42939,23 @@ index 080cbe2df5..4a6e6b8d73 100644 /* check that mtu is within the allowed range */ if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) -@@ -1812,7 +1811,7 @@ eth_em_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + return -EINVAL; + +- /* refuse mtu that requires the support of scattered packets when this +- * feature has not been enabled before. */ +- if (!dev->data->scattered_rx && +- frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) ++ /* ++ * If device is started, refuse mtu that requires the support of ++ * scattered packets when this feature has not been enabled before. ++ */ ++ if (dev->data->dev_started && !dev->data->scattered_rx && ++ frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { ++ PMD_INIT_LOG(ERR, "Stop port first."); + return -EINVAL; ++ } + + hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); rctl = E1000_READ_REG(hw, E1000_RCTL); /* switch to jumbo mode if needed */ @@ -28463,7 +42965,7 @@ index 080cbe2df5..4a6e6b8d73 100644 DEV_RX_OFFLOAD_JUMBO_FRAME; rctl |= E1000_RCTL_LPE; diff --git a/dpdk/drivers/net/e1000/igb_ethdev.c b/dpdk/drivers/net/e1000/igb_ethdev.c -index a3e30dbe5a..a7886041f6 100644 +index a3e30dbe5a..521573ae46 100644 --- a/dpdk/drivers/net/e1000/igb_ethdev.c +++ b/dpdk/drivers/net/e1000/igb_ethdev.c @@ -922,7 +922,7 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev) @@ -28484,7 +42986,46 @@ index a3e30dbe5a..a7886041f6 100644 igbvf_dev_close(eth_dev); -@@ -3087,6 +3087,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +@@ -1544,6 +1544,9 @@ eth_igb_close(struct rte_eth_dev *dev) + struct e1000_filter_info *filter_info = + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + eth_igb_stop(dev); + + e1000_phy_hw_reset(hw); +@@ -1849,8 +1852,7 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) + + /* Rx Errors */ + rte_stats->imissed = stats->mpc; +- rte_stats->ierrors = stats->crcerrs + +- stats->rlec + stats->ruc + stats->roc + ++ rte_stats->ierrors = stats->crcerrs + stats->rlec + + stats->rxerrc + stats->algnerrc + stats->cexterr; + + /* Tx Errors */ +@@ -2711,8 +2713,7 @@ igb_vlan_hw_extend_disable(struct rte_eth_dev *dev) + /* Update maximum packet length */ + if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) + E1000_WRITE_REG(hw, E1000_RLPML, +- dev->data->dev_conf.rxmode.max_rx_pkt_len + +- VLAN_TAG_SIZE); ++ dev->data->dev_conf.rxmode.max_rx_pkt_len); + } + + static void +@@ -2731,7 +2732,7 @@ igb_vlan_hw_extend_enable(struct rte_eth_dev *dev) + if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) + E1000_WRITE_REG(hw, E1000_RLPML, + dev->data->dev_conf.rxmode.max_rx_pkt_len + +- 2 * VLAN_TAG_SIZE); ++ VLAN_TAG_SIZE); + } + + static int +@@ -3087,6 +3088,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) uint32_t rx_buf_size; uint32_t max_high_water; uint32_t rctl; @@ -28492,7 +43033,7 @@ index a3e30dbe5a..a7886041f6 100644 hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); if (fc_conf->autoneg != hw->mac.autoneg) -@@ -3124,6 +3125,39 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +@@ -3124,6 +3126,39 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) rctl &= ~E1000_RCTL_PMCF; E1000_WRITE_REG(hw, E1000_RCTL, rctl); @@ -28532,7 +43073,34 @@ index a3e30dbe5a..a7886041f6 100644 E1000_WRITE_FLUSH(hw); return 0; -@@ -4543,7 +4577,7 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -3390,6 +3425,9 @@ igbvf_dev_close(struct rte_eth_dev *dev) + + PMD_INIT_FUNC_TRACE(); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + e1000_reset_hw(hw); + + igbvf_dev_stop(dev); +@@ -4534,16 +4572,20 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + frame_size > dev_info.max_rx_pktlen) + return -EINVAL; + +- /* refuse mtu that requires the support of scattered packets when this +- * feature has not been enabled before. */ +- if (!dev->data->scattered_rx && +- frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) ++ /* ++ * If device is started, refuse mtu that requires the support of ++ * scattered packets when this feature has not been enabled before. ++ */ ++ if (dev->data->dev_started && !dev->data->scattered_rx && ++ frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) { ++ PMD_INIT_LOG(ERR, "Stop port first."); + return -EINVAL; ++ } + rctl = E1000_READ_REG(hw, E1000_RCTL); /* switch to jumbo mode if needed */ @@ -28541,8 +43109,31 @@ index a3e30dbe5a..a7886041f6 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; rctl |= E1000_RCTL_LPE; +@@ -5481,9 +5523,6 @@ eth_igb_get_module_eeprom(struct rte_eth_dev *dev, + u16 first_word, last_word; + int i = 0; + +- if (info->length == 0) +- return -EINVAL; +- + first_word = info->offset >> 1; + last_word = (info->offset + info->length - 1) >> 1; + +diff --git a/dpdk/drivers/net/e1000/igb_flow.c b/dpdk/drivers/net/e1000/igb_flow.c +index 43fef889b5..63cb82660c 100644 +--- a/dpdk/drivers/net/e1000/igb_flow.c ++++ b/dpdk/drivers/net/e1000/igb_flow.c +@@ -350,7 +350,7 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr, + memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, +- item, "Not supported action."); ++ act, "Not supported action."); + return -rte_errno; + } + filter->queue = diff --git a/dpdk/drivers/net/e1000/igb_rxtx.c b/dpdk/drivers/net/e1000/igb_rxtx.c -index 684fa4ad89..5260bbe341 100644 +index 684fa4ad89..cd70624c7f 100644 --- a/dpdk/drivers/net/e1000/igb_rxtx.c +++ b/dpdk/drivers/net/e1000/igb_rxtx.c @@ -1295,113 +1295,107 @@ igb_tx_done_cleanup(struct igb_tx_queue *txq, uint32_t free_cnt) @@ -28568,7 +43159,9 @@ index 684fa4ad89..5260bbe341 100644 - */ + sw_ring = txq->sw_ring; + txr = txq->tx_ring; -+ + +- /* Get last segment in most recently added packet. */ +- tx_first = sw_ring[txq->tx_tail].last_id; + /* tx_tail is the last sent packet on the sw_ring. Goto the end + * of that packet (the last segment in the packet chain) and + * then the next segment will be the start of the oldest segment @@ -28576,20 +43169,15 @@ index 684fa4ad89..5260bbe341 100644 + * attempted to be freed. + */ -- /* Get last segment in most recently added packet. */ -- tx_first = sw_ring[txq->tx_tail].last_id; -+ /* Get last segment in most recently added packet. */ -+ tx_first = sw_ring[txq->tx_tail].last_id; - - /* Get the next segment, which is the oldest segment in ring. */ - tx_first = sw_ring[tx_first].next_id; -+ /* Get the next segment, which is the oldest segment in ring. */ -+ tx_first = sw_ring[tx_first].next_id; ++ /* Get last segment in most recently added packet. */ ++ tx_first = sw_ring[txq->tx_tail].last_id; - /* Set the current index to the first. */ - tx_id = tx_first; -+ /* Set the current index to the first. */ -+ tx_id = tx_first; ++ /* Get the next segment, which is the oldest segment in ring. */ ++ tx_first = sw_ring[tx_first].next_id; - /* - * Loop through each packet. For each packet, verify that an @@ -28617,6 +43205,9 @@ index 684fa4ad89..5260bbe341 100644 - */ - do { - rte_pktmbuf_free_seg(sw_ring[tx_id].mbuf); ++ /* Set the current index to the first. */ ++ tx_id = tx_first; ++ + /* Loop through each packet. For each packet, verify that an + * mbuf exists and that the last segment is free. If so, free + * it and move on. @@ -28765,8 +43356,30 @@ index 684fa4ad89..5260bbe341 100644 return rx_offload_capa; } +@@ -2340,15 +2341,18 @@ eth_igb_rx_init(struct rte_eth_dev *dev) + * Configure support of jumbo frames, if any. + */ + if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { ++ uint32_t max_len = dev->data->dev_conf.rxmode.max_rx_pkt_len; ++ + rctl |= E1000_RCTL_LPE; + + /* + * Set maximum packet length by default, and might be updated + * together with enabling/disabling dual VLAN. + */ +- E1000_WRITE_REG(hw, E1000_RLPML, +- dev->data->dev_conf.rxmode.max_rx_pkt_len + +- VLAN_TAG_SIZE); ++ if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) ++ max_len += VLAN_TAG_SIZE; ++ ++ E1000_WRITE_REG(hw, E1000_RLPML, max_len); + } else + rctl &= ~E1000_RCTL_LPE; + diff --git a/dpdk/drivers/net/ena/base/ena_com.c b/dpdk/drivers/net/ena/base/ena_com.c -index 8b51660a45..f8e8f448e3 100644 +index 8b51660a45..50b39b88ba 100644 --- a/dpdk/drivers/net/ena/base/ena_com.c +++ b/dpdk/drivers/net/ena/base/ena_com.c @@ -401,19 +401,21 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev, @@ -28819,6 +43432,24 @@ index 8b51660a45..f8e8f448e3 100644 break; if (ENA_TIME_EXPIRE(timeout)) { +@@ -1338,7 +1340,7 @@ int ena_com_execute_admin_command(struct ena_com_admin_queue *admin_queue, + ena_trc_err("Failed to submit command [%ld]\n", + PTR_ERR(comp_ctx)); + +- return PTR_ERR(comp_ctx); ++ return (int)PTR_ERR(comp_ctx); + } + + ret = ena_com_wait_and_process_admin_cq(comp_ctx, admin_queue); +@@ -1557,7 +1559,7 @@ int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, u32 groups_flag) + int ena_com_get_dma_width(struct ena_com_dev *ena_dev) + { + u32 caps = ena_com_reg_bar_read32(ena_dev, ENA_REGS_CAPS_OFF); +- int width; ++ u32 width; + + if (unlikely(caps == ENA_MMIO_READ_TIMEOUT)) { + ena_trc_err("Reg read timeout occurred\n"); @@ -1634,9 +1636,11 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev) struct ena_com_aenq *aenq = &ena_dev->aenq; u16 size; @@ -28833,6 +43464,15 @@ index 8b51660a45..f8e8f448e3 100644 admin_queue->comp_ctx = NULL; size = ADMIN_SQ_SIZE(admin_queue->q_depth); if (sq->entries) +@@ -2259,7 +2263,7 @@ int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu) + cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE; + cmd.aq_common_descriptor.flags = 0; + cmd.feat_common.feature_id = ENA_ADMIN_MTU; +- cmd.u.mtu.mtu = mtu; ++ cmd.u.mtu.mtu = (u32)mtu; + + ret = ena_com_execute_admin_command(admin_queue, + (struct ena_admin_aq_entry *)&cmd, @@ -2313,7 +2317,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev) if (unlikely(ret)) return ret; @@ -28897,6 +43537,24 @@ index 8b51660a45..f8e8f448e3 100644 if (func) *func = rss->hash_func; +@@ -2653,7 +2665,7 @@ int ena_com_indirect_table_set(struct ena_com_dev *ena_dev) + return ret; + } + +- cmd.control_buffer.length = (1ULL << rss->tbl_log_size) * ++ cmd.control_buffer.length = (u32)(1ULL << rss->tbl_log_size) * + sizeof(struct ena_admin_rss_ind_table_entry); + + ret = ena_com_execute_admin_command(admin_queue, +@@ -2675,7 +2687,7 @@ int ena_com_indirect_table_get(struct ena_com_dev *ena_dev, u32 *ind_tbl) + u32 tbl_size; + int i, rc; + +- tbl_size = (1ULL << rss->tbl_log_size) * ++ tbl_size = (u32)(1ULL << rss->tbl_log_size) * + sizeof(struct ena_admin_rss_ind_table_entry); + + rc = ena_com_get_feature_ex(ena_dev, &get_resp, diff --git a/dpdk/drivers/net/ena/base/ena_com.h b/dpdk/drivers/net/ena/base/ena_com.h index ef42bd4f56..fed2dec3e4 100644 --- a/dpdk/drivers/net/ena/base/ena_com.h @@ -29035,7 +43693,7 @@ index ef42bd4f56..fed2dec3e4 100644 * Prepare interrupt update register with the supplied parameters. */ diff --git a/dpdk/drivers/net/ena/base/ena_plat_dpdk.h b/dpdk/drivers/net/ena/base/ena_plat_dpdk.h -index 9e1492cac4..9773be09e7 100644 +index 9e1492cac4..58767fdf30 100644 --- a/dpdk/drivers/net/ena/base/ena_plat_dpdk.h +++ b/dpdk/drivers/net/ena/base/ena_plat_dpdk.h @@ -1,5 +1,5 @@ @@ -29045,7 +43703,15 @@ index 9e1492cac4..9773be09e7 100644 * All rights reserved. */ -@@ -55,8 +55,8 @@ typedef uint64_t dma_addr_t; +@@ -24,6 +24,7 @@ + #include + + #include ++#include + + typedef uint64_t u64; + typedef uint32_t u32; +@@ -55,11 +56,15 @@ typedef uint64_t dma_addr_t; #define ENA_ABORT() abort() @@ -29055,8 +43721,16 @@ index 9e1492cac4..9773be09e7 100644 +#define ENA_UDELAY(x) rte_delay_us_block(x) #define ENA_TOUCH(x) ((void)(x)) - #define memcpy_toio memcpy -@@ -71,26 +71,15 @@ typedef uint64_t dma_addr_t; +-#define memcpy_toio memcpy ++/* Avoid nested declaration on arm64, as it may define rte_memcpy as memcpy. */ ++#if defined(RTE_ARCH_X86) ++#undef memcpy ++#define memcpy rte_memcpy ++#endif + #define wmb rte_wmb + #define rmb rte_rmb + #define mb rte_mb +@@ -71,26 +76,15 @@ typedef uint64_t dma_addr_t; (rte_get_timer_cycles() * US_PER_S / rte_get_timer_hz()) extern int ena_logtype_com; @@ -29091,7 +43765,7 @@ index 9e1492cac4..9773be09e7 100644 #define BITS_PER_LONG_LONG (__SIZEOF_LONG_LONG__ * 8) #define U64_C(x) x ## ULL -@@ -178,18 +167,24 @@ do { \ +@@ -178,18 +172,24 @@ do { \ * Each rte_memzone should have unique name. * To satisfy it, count number of allocations and add it to name. */ @@ -29125,7 +43799,7 @@ index 9e1492cac4..9773be09e7 100644 if (mz == NULL) { \ virt = NULL; \ phys = 0; \ -@@ -199,22 +194,33 @@ extern uint32_t ena_alloc_cnt; +@@ -199,22 +199,33 @@ extern uint32_t ena_alloc_cnt; phys = mz->iova; \ } \ } while (0) @@ -29168,7 +43842,7 @@ index 9e1492cac4..9773be09e7 100644 if (mz == NULL) { \ virt = NULL; \ phys = 0; \ -@@ -224,7 +230,17 @@ extern uint32_t ena_alloc_cnt; +@@ -224,7 +235,17 @@ extern uint32_t ena_alloc_cnt; phys = mz->iova; \ } \ } while (0) @@ -29187,7 +43861,7 @@ index 9e1492cac4..9773be09e7 100644 #define ENA_MEM_ALLOC_NODE(dmadev, size, virt, node, dev_node) \ do { \ ENA_TOUCH(dmadev); ENA_TOUCH(dev_node); \ -@@ -290,4 +306,6 @@ extern uint32_t ena_alloc_cnt; +@@ -290,4 +311,6 @@ extern uint32_t ena_alloc_cnt; #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) @@ -29195,10 +43869,22 @@ index 9e1492cac4..9773be09e7 100644 + #endif /* DPDK_ENA_COM_ENA_PLAT_DPDK_H_ */ diff --git a/dpdk/drivers/net/ena/ena_ethdev.c b/dpdk/drivers/net/ena/ena_ethdev.c -index 8bbd80dfb3..d098387a8c 100644 +index 8bbd80dfb3..7601d2fa25 100644 --- a/dpdk/drivers/net/ena/ena_ethdev.c +++ b/dpdk/drivers/net/ena/ena_ethdev.c -@@ -89,7 +89,7 @@ struct ena_stats { +@@ -58,11 +58,6 @@ + + #define ENA_MIN_RING_DESC 128 + +-enum ethtool_stringset { +- ETH_SS_TEST = 0, +- ETH_SS_STATS, +-}; +- + struct ena_stats { + char name[ETH_GSTRING_LEN]; + int stat_offset; +@@ -89,7 +84,7 @@ struct ena_stats { * Each rte_memzone should have unique name. * To satisfy it, count number of allocation and add it to name. */ @@ -29207,7 +43893,42 @@ index 8bbd80dfb3..d098387a8c 100644 static const struct ena_stats ena_stats_global_strings[] = { ENA_STAT_GLOBAL_ENTRY(wd_expired), -@@ -267,21 +267,23 @@ static inline void ena_rx_mbuf_prepare(struct rte_mbuf *mbuf, +@@ -147,6 +142,23 @@ static const struct ena_stats ena_stats_rx_strings[] = { + #define ENA_TX_OFFLOAD_NOTSUP_MASK \ + (PKT_TX_OFFLOAD_MASK ^ ENA_TX_OFFLOAD_MASK) + ++/** HW specific offloads capabilities. */ ++/* IPv4 checksum offload. */ ++#define ENA_L3_IPV4_CSUM 0x0001 ++/* TCP/UDP checksum offload for IPv4 packets. */ ++#define ENA_L4_IPV4_CSUM 0x0002 ++/* TCP/UDP checksum offload for IPv4 packets with pseudo header checksum. */ ++#define ENA_L4_IPV4_CSUM_PARTIAL 0x0004 ++/* TCP/UDP checksum offload for IPv6 packets. */ ++#define ENA_L4_IPV6_CSUM 0x0008 ++/* TCP/UDP checksum offload for IPv6 packets with pseudo header checksum. */ ++#define ENA_L4_IPV6_CSUM_PARTIAL 0x0010 ++/* TSO support for IPv4 packets. */ ++#define ENA_IPV4_TSO 0x0020 ++ ++/* Device supports setting RSS hash. */ ++#define ENA_RX_RSS_HASH 0x0040 ++ + int ena_logtype_init; + int ena_logtype_driver; + +@@ -212,6 +224,10 @@ static int ena_queue_start(struct ena_ring *ring); + static int ena_queue_start_all(struct rte_eth_dev *dev, + enum ena_ring_type ring_type); + static void ena_stats_restart(struct rte_eth_dev *dev); ++static uint64_t ena_get_rx_port_offloads(struct ena_adapter *adapter); ++static uint64_t ena_get_tx_port_offloads(struct ena_adapter *adapter); ++static uint64_t ena_get_rx_queue_offloads(struct ena_adapter *adapter); ++static uint64_t ena_get_tx_queue_offloads(struct ena_adapter *adapter); + static int ena_infos_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); + static int ena_rss_reta_update(struct rte_eth_dev *dev, +@@ -267,21 +283,29 @@ static inline void ena_rx_mbuf_prepare(struct rte_mbuf *mbuf, else if (ena_rx_ctx->l4_proto == ENA_ETH_IO_L4_PROTO_UDP) packet_type |= RTE_PTYPE_L4_UDP; @@ -29228,18 +43949,65 @@ index 8bbd80dfb3..d098387a8c 100644 ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN; else - if (unlikely(ena_rx_ctx->l4_csum_err) && !ena_rx_ctx->frag) +- ol_flags |= PKT_RX_L4_CKSUM_BAD; +- else + if (unlikely(ena_rx_ctx->l4_csum_err)) - ol_flags |= PKT_RX_L4_CKSUM_BAD; - else -- ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN; ++ /* ++ * For the L4 Rx checksum offload the HW may indicate ++ * bad checksum although it's valid. Because of that, ++ * we're setting the UNKNOWN flag to let the app ++ * re-verify the checksum. ++ */ + ol_flags |= PKT_RX_L4_CKSUM_UNKNOWN; - - if (unlikely(ena_rx_ctx->l3_csum_err)) - ol_flags |= PKT_RX_IP_CKSUM_BAD; ++ else + ol_flags |= PKT_RX_L4_CKSUM_GOOD; mbuf->ol_flags = ol_flags; mbuf->packet_type = packet_type; -@@ -1079,16 +1081,15 @@ static int ena_create_io_queue(struct ena_ring *ring) +@@ -310,6 +334,8 @@ static inline void ena_tx_mbuf_prepare(struct rte_mbuf *mbuf, + + if (mbuf->ol_flags & PKT_TX_IPV6) { + ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV6; ++ /* For the IPv6 packets, DF always needs to be true. */ ++ ena_tx_ctx->df = 1; + } else { + ena_tx_ctx->l3_proto = ENA_ETH_IO_L3_PROTO_IPV4; + +@@ -317,7 +343,7 @@ static inline void ena_tx_mbuf_prepare(struct rte_mbuf *mbuf, + if (mbuf->packet_type & + (RTE_PTYPE_L4_NONFRAG + | RTE_PTYPE_INNER_L4_NONFRAG)) +- ena_tx_ctx->df = true; ++ ena_tx_ctx->df = 1; + } + + /* check if L4 checksum is needed */ +@@ -470,6 +496,9 @@ static void ena_close(struct rte_eth_dev *dev) + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + struct ena_adapter *adapter = dev->data->dev_private; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (adapter->state == ENA_ADAPTER_STATE_RUNNING) + ena_stop(dev); + adapter->state = ENA_ADAPTER_STATE_CLOSED; +@@ -731,8 +760,10 @@ static void ena_tx_queue_release_bufs(struct ena_ring *ring) + for (i = 0; i < ring->ring_size; ++i) { + struct ena_tx_buffer *tx_buf = &ring->tx_buffer_info[i]; + +- if (tx_buf->mbuf) ++ if (tx_buf->mbuf) { + rte_pktmbuf_free(tx_buf->mbuf); ++ tx_buf->mbuf = NULL; ++ } + } + } + +@@ -1079,16 +1110,15 @@ static int ena_create_io_queue(struct ena_ring *ring) ena_qid = ENA_IO_TXQ_IDX(ring->id); ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX; ctx.mem_queue_type = ena_dev->tx_mem_queue_type; @@ -29257,7 +44025,7 @@ index 8bbd80dfb3..d098387a8c 100644 ctx.qid = ena_qid; ctx.msix_vector = -1; /* interrupts not used */ ctx.numa_node = ring->numa_socket_id; -@@ -1181,6 +1182,10 @@ static int ena_queue_start(struct ena_ring *ring) +@@ -1181,6 +1211,10 @@ static int ena_queue_start(struct ena_ring *ring) PMD_INIT_LOG(ERR, "Failed to populate rx ring !"); return ENA_COM_FAULT; } @@ -29268,7 +44036,87 @@ index 8bbd80dfb3..d098387a8c 100644 return 0; } -@@ -1675,7 +1680,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) +@@ -1371,7 +1405,7 @@ static int ena_populate_rx_queue(struct ena_ring *rxq, unsigned int count) + ena_assert_msg(((in_use + count) < ring_size), "bad ring state\n"); + + /* get resources for incoming packets */ +- rc = rte_mempool_get_bulk(rxq->mb_pool, (void **)mbufs, count); ++ rc = rte_pktmbuf_alloc_bulk(rxq->mb_pool, mbufs, count); + if (unlikely(rc < 0)) { + rte_atomic64_inc(&rxq->adapter->drv_stats->rx_nombuf); + ++rxq->rx_stats.mbuf_alloc_fail; +@@ -1410,8 +1444,7 @@ static int ena_populate_rx_queue(struct ena_ring *rxq, unsigned int count) + if (unlikely(i < count)) { + PMD_DRV_LOG(WARNING, "refilled rx qid %d with only %d " + "buffers (from %d)\n", rxq->id, i, count); +- rte_mempool_put_bulk(rxq->mb_pool, (void **)(&mbufs[i]), +- count - i); ++ rte_pktmbuf_free_bulk(&mbufs[i], count - i); + ++rxq->rx_stats.refill_partial; + } + +@@ -1563,6 +1596,9 @@ static void ena_timer_wd_callback(__rte_unused struct rte_timer *timer, + struct ena_adapter *adapter = arg; + struct rte_eth_dev *dev = adapter->rte_dev; + ++ if (unlikely(adapter->trigger_reset)) ++ return; ++ + check_for_missing_keep_alive(adapter); + check_for_admin_com_state(adapter); + +@@ -1662,6 +1698,50 @@ static int ena_calc_io_queue_num(struct ena_com_dev *ena_dev, + return io_queue_num; + } + ++static void ++ena_set_offloads(struct ena_offloads *offloads, ++ struct ena_admin_feature_offload_desc *offload_desc) ++{ ++ if (offload_desc->tx & ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK) ++ offloads->tx_offloads |= ENA_IPV4_TSO; ++ ++ /* Tx IPv4 checksum offloads */ ++ if (offload_desc->tx & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK) ++ offloads->tx_offloads |= ENA_L3_IPV4_CSUM; ++ if (offload_desc->tx & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_FULL_MASK) ++ offloads->tx_offloads |= ENA_L4_IPV4_CSUM; ++ if (offload_desc->tx & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK) ++ offloads->tx_offloads |= ENA_L4_IPV4_CSUM_PARTIAL; ++ ++ /* Tx IPv6 checksum offloads */ ++ if (offload_desc->tx & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK) ++ offloads->tx_offloads |= ENA_L4_IPV6_CSUM; ++ if (offload_desc->tx & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK) ++ offloads->tx_offloads |= ENA_L4_IPV6_CSUM_PARTIAL; ++ ++ /* Rx IPv4 checksum offloads */ ++ if (offload_desc->rx_supported & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK) ++ offloads->rx_offloads |= ENA_L3_IPV4_CSUM; ++ if (offload_desc->rx_supported & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK) ++ offloads->rx_offloads |= ENA_L4_IPV4_CSUM; ++ ++ /* Rx IPv6 checksum offloads */ ++ if (offload_desc->rx_supported & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK) ++ offloads->rx_offloads |= ENA_L4_IPV6_CSUM; ++ ++ if (offload_desc->rx_supported & ++ ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK) ++ offloads->rx_offloads |= ENA_RX_RSS_HASH; ++} ++ + static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) + { + struct ena_calc_queue_size_ctx calc_queue_ctx = { 0 }; +@@ -1675,7 +1755,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) int rc; static int adapters_found; @@ -29277,7 +44125,318 @@ index 8bbd80dfb3..d098387a8c 100644 eth_dev->dev_ops = &ena_dev_ops; eth_dev->rx_pkt_burst = ð_ena_recv_pkts; -@@ -2480,7 +2485,7 @@ static int ena_xstats_get(struct rte_eth_dev *dev, +@@ -1766,14 +1846,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev) + /* Set max MTU for this device */ + adapter->max_mtu = get_feat_ctx.dev_attr.max_mtu; + +- /* set device support for offloads */ +- adapter->offloads.tso4_supported = (get_feat_ctx.offload.tx & +- ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK) != 0; +- adapter->offloads.tx_csum_supported = (get_feat_ctx.offload.tx & +- ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV4_CSUM_PART_MASK) != 0; +- adapter->offloads.rx_csum_supported = +- (get_feat_ctx.offload.rx_supported & +- ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK) != 0; ++ ena_set_offloads(&adapter->offloads, &get_feat_ctx.offload); + + /* Copy MAC address and point DPDK to it */ + eth_dev->data->mac_addrs = (struct rte_ether_addr *)adapter->mac_addr; +@@ -1868,8 +1941,13 @@ static int ena_dev_configure(struct rte_eth_dev *dev) + + adapter->state = ENA_ADAPTER_STATE_CONFIG; + +- adapter->tx_selected_offloads = dev->data->dev_conf.txmode.offloads; +- adapter->rx_selected_offloads = dev->data->dev_conf.rxmode.offloads; ++ dev->data->dev_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS; ++ ++ /* Scattered Rx cannot be turned off in the HW, so this capability must ++ * be forced. ++ */ ++ dev->data->scattered_rx = 1; ++ + return 0; + } + +@@ -1900,12 +1978,66 @@ static void ena_init_rings(struct ena_adapter *adapter) + } + } + ++static uint64_t ena_get_rx_port_offloads(struct ena_adapter *adapter) ++{ ++ uint64_t port_offloads = 0; ++ ++ if (adapter->offloads.rx_offloads & ENA_L3_IPV4_CSUM) ++ port_offloads |= DEV_RX_OFFLOAD_IPV4_CKSUM; ++ ++ if (adapter->offloads.rx_offloads & ++ (ENA_L4_IPV4_CSUM | ENA_L4_IPV6_CSUM)) ++ port_offloads |= ++ DEV_RX_OFFLOAD_UDP_CKSUM | DEV_RX_OFFLOAD_TCP_CKSUM; ++ ++ if (adapter->offloads.rx_offloads & ENA_RX_RSS_HASH) ++ port_offloads |= DEV_RX_OFFLOAD_RSS_HASH; ++ ++ port_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; ++ port_offloads |= DEV_RX_OFFLOAD_SCATTER; ++ ++ return port_offloads; ++} ++ ++static uint64_t ena_get_tx_port_offloads(struct ena_adapter *adapter) ++{ ++ uint64_t port_offloads = 0; ++ ++ if (adapter->offloads.tx_offloads & ENA_IPV4_TSO) ++ port_offloads |= DEV_TX_OFFLOAD_TCP_TSO; ++ ++ if (adapter->offloads.tx_offloads & ENA_L3_IPV4_CSUM) ++ port_offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM; ++ if (adapter->offloads.tx_offloads & ++ (ENA_L4_IPV4_CSUM_PARTIAL | ENA_L4_IPV4_CSUM | ++ ENA_L4_IPV6_CSUM | ENA_L4_IPV6_CSUM_PARTIAL)) ++ port_offloads |= ++ DEV_TX_OFFLOAD_UDP_CKSUM | DEV_TX_OFFLOAD_TCP_CKSUM; ++ ++ port_offloads |= DEV_TX_OFFLOAD_MULTI_SEGS; ++ ++ return port_offloads; ++} ++ ++static uint64_t ena_get_rx_queue_offloads(struct ena_adapter *adapter) ++{ ++ RTE_SET_USED(adapter); ++ ++ return 0; ++} ++ ++static uint64_t ena_get_tx_queue_offloads(struct ena_adapter *adapter) ++{ ++ RTE_SET_USED(adapter); ++ ++ return 0; ++} ++ + static int ena_infos_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) + { + struct ena_adapter *adapter; + struct ena_com_dev *ena_dev; +- uint64_t rx_feat = 0, tx_feat = 0; + + ena_assert_msg(dev->data != NULL, "Uninitialized device\n"); + ena_assert_msg(dev->data->dev_private != NULL, "Uninitialized device\n"); +@@ -1924,27 +2056,11 @@ static int ena_infos_get(struct rte_eth_dev *dev, + ETH_LINK_SPEED_50G | + ETH_LINK_SPEED_100G; + +- /* Set Tx & Rx features available for device */ +- if (adapter->offloads.tso4_supported) +- tx_feat |= DEV_TX_OFFLOAD_TCP_TSO; +- +- if (adapter->offloads.tx_csum_supported) +- tx_feat |= DEV_TX_OFFLOAD_IPV4_CKSUM | +- DEV_TX_OFFLOAD_UDP_CKSUM | +- DEV_TX_OFFLOAD_TCP_CKSUM; +- +- if (adapter->offloads.rx_csum_supported) +- rx_feat |= DEV_RX_OFFLOAD_IPV4_CKSUM | +- DEV_RX_OFFLOAD_UDP_CKSUM | +- DEV_RX_OFFLOAD_TCP_CKSUM; +- +- rx_feat |= DEV_RX_OFFLOAD_JUMBO_FRAME; +- + /* Inform framework about available features */ +- dev_info->rx_offload_capa = rx_feat; +- dev_info->rx_queue_offload_capa = rx_feat; +- dev_info->tx_offload_capa = tx_feat; +- dev_info->tx_queue_offload_capa = tx_feat; ++ dev_info->rx_offload_capa = ena_get_rx_port_offloads(adapter); ++ dev_info->tx_offload_capa = ena_get_tx_port_offloads(adapter); ++ dev_info->rx_queue_offload_capa = ena_get_rx_queue_offloads(adapter); ++ dev_info->tx_queue_offload_capa = ena_get_tx_queue_offloads(adapter); + + dev_info->flow_type_rss_offloads = ETH_RSS_IP | ETH_RSS_TCP | + ETH_RSS_UDP; +@@ -1957,8 +2073,6 @@ static int ena_infos_get(struct rte_eth_dev *dev, + dev_info->max_tx_queues = adapter->num_queues; + dev_info->reta_size = ENA_RX_RSS_TABLE_SIZE; + +- adapter->tx_supported_offloads = tx_feat; +- adapter->rx_supported_offloads = rx_feat; + + dev_info->rx_desc_lim.nb_max = adapter->rx_ring_size; + dev_info->rx_desc_lim.nb_min = ENA_MIN_RING_DESC; +@@ -2102,45 +2216,60 @@ eth_ena_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + uint32_t i; + struct rte_mbuf *m; + struct ena_ring *tx_ring = (struct ena_ring *)(tx_queue); ++ struct ena_adapter *adapter = tx_ring->adapter; + struct rte_ipv4_hdr *ip_hdr; + uint64_t ol_flags; ++ uint64_t l4_csum_flag; ++ uint64_t dev_offload_capa; + uint16_t frag_field; ++ bool need_pseudo_csum; + ++ dev_offload_capa = adapter->offloads.tx_offloads; + for (i = 0; i != nb_pkts; i++) { + m = tx_pkts[i]; + ol_flags = m->ol_flags; + +- if (!(ol_flags & PKT_TX_IPV4)) ++ /* Check if any offload flag was set */ ++ if (ol_flags == 0) + continue; + +- /* If there was not L2 header length specified, assume it is +- * length of the ethernet header. +- */ +- if (unlikely(m->l2_len == 0)) +- m->l2_len = sizeof(struct rte_ether_hdr); +- +- ip_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, +- m->l2_len); +- frag_field = rte_be_to_cpu_16(ip_hdr->fragment_offset); +- +- if ((frag_field & RTE_IPV4_HDR_DF_FLAG) != 0) { +- m->packet_type |= RTE_PTYPE_L4_NONFRAG; +- +- /* If IPv4 header has DF flag enabled and TSO support is +- * disabled, partial chcecksum should not be calculated. +- */ +- if (!tx_ring->adapter->offloads.tso4_supported) +- continue; +- } +- +- if ((ol_flags & ENA_TX_OFFLOAD_NOTSUP_MASK) != 0 || +- (ol_flags & PKT_TX_L4_MASK) == +- PKT_TX_SCTP_CKSUM) { ++ l4_csum_flag = ol_flags & PKT_TX_L4_MASK; ++ /* SCTP checksum offload is not supported by the ENA. */ ++ if ((ol_flags & ENA_TX_OFFLOAD_NOTSUP_MASK) || ++ l4_csum_flag == PKT_TX_SCTP_CKSUM) { ++ PMD_TX_LOG(DEBUG, ++ "mbuf[%" PRIu32 "] has unsupported offloads flags set: 0x%" PRIu64 "\n", ++ i, ol_flags); + rte_errno = ENOTSUP; + return i; + } + + #ifdef RTE_LIBRTE_ETHDEV_DEBUG ++ /* Check if requested offload is also enabled for the queue */ ++ if ((ol_flags & PKT_TX_IP_CKSUM && ++ !(tx_ring->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM)) || ++ (l4_csum_flag == PKT_TX_TCP_CKSUM && ++ !(tx_ring->offloads & DEV_TX_OFFLOAD_TCP_CKSUM)) || ++ (l4_csum_flag == PKT_TX_UDP_CKSUM && ++ !(tx_ring->offloads & DEV_TX_OFFLOAD_UDP_CKSUM))) { ++ PMD_TX_LOG(DEBUG, ++ "mbuf[%" PRIu32 "]: requested offloads: %" PRIu16 " are not enabled for the queue[%u]\n", ++ i, m->nb_segs, tx_ring->id); ++ rte_errno = EINVAL; ++ return i; ++ } ++ ++ /* The caller is obligated to set l2 and l3 len if any cksum ++ * offload is enabled. ++ */ ++ if (unlikely(ol_flags & (PKT_TX_IP_CKSUM | PKT_TX_L4_MASK) && ++ (m->l2_len == 0 || m->l3_len == 0))) { ++ PMD_TX_LOG(DEBUG, ++ "mbuf[%" PRIu32 "]: l2_len or l3_len values are 0 while the offload was requested\n", ++ i); ++ rte_errno = EINVAL; ++ return i; ++ } + ret = rte_validate_tx_offload(m); + if (ret != 0) { + rte_errno = -ret; +@@ -2148,16 +2277,76 @@ eth_ena_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + } + #endif + +- /* In case we are supposed to TSO and have DF not set (DF=0) +- * hardware must be provided with partial checksum, otherwise +- * it will take care of necessary calculations. ++ /* Verify HW support for requested offloads and determine if ++ * pseudo header checksum is needed. + */ ++ need_pseudo_csum = false; ++ if (ol_flags & PKT_TX_IPV4) { ++ if (ol_flags & PKT_TX_IP_CKSUM && ++ !(dev_offload_capa & ENA_L3_IPV4_CSUM)) { ++ rte_errno = ENOTSUP; ++ return i; ++ } + +- ret = rte_net_intel_cksum_flags_prepare(m, +- ol_flags & ~PKT_TX_TCP_SEG); +- if (ret != 0) { +- rte_errno = -ret; +- return i; ++ if (ol_flags & PKT_TX_TCP_SEG && ++ !(dev_offload_capa & ENA_IPV4_TSO)) { ++ rte_errno = ENOTSUP; ++ return i; ++ } ++ ++ /* Check HW capabilities and if pseudo csum is needed ++ * for L4 offloads. ++ */ ++ if (l4_csum_flag != PKT_TX_L4_NO_CKSUM && ++ !(dev_offload_capa & ENA_L4_IPV4_CSUM)) { ++ if (dev_offload_capa & ++ ENA_L4_IPV4_CSUM_PARTIAL) { ++ need_pseudo_csum = true; ++ } else { ++ rte_errno = ENOTSUP; ++ return i; ++ } ++ } ++ ++ /* Parse the DF flag */ ++ ip_hdr = rte_pktmbuf_mtod_offset(m, ++ struct rte_ipv4_hdr *, m->l2_len); ++ frag_field = rte_be_to_cpu_16(ip_hdr->fragment_offset); ++ if (frag_field & RTE_IPV4_HDR_DF_FLAG) { ++ m->packet_type |= RTE_PTYPE_L4_NONFRAG; ++ } else if (ol_flags & PKT_TX_TCP_SEG) { ++ /* In case we are supposed to TSO and have DF ++ * not set (DF=0) hardware must be provided with ++ * partial checksum. ++ */ ++ need_pseudo_csum = true; ++ } ++ } else if (ol_flags & PKT_TX_IPV6) { ++ /* There is no support for IPv6 TSO as for now. */ ++ if (ol_flags & PKT_TX_TCP_SEG) { ++ rte_errno = ENOTSUP; ++ return i; ++ } ++ ++ /* Check HW capabilities and if pseudo csum is needed */ ++ if (l4_csum_flag != PKT_TX_L4_NO_CKSUM && ++ !(dev_offload_capa & ENA_L4_IPV6_CSUM)) { ++ if (dev_offload_capa & ++ ENA_L4_IPV6_CSUM_PARTIAL) { ++ need_pseudo_csum = true; ++ } else { ++ rte_errno = ENOTSUP; ++ return i; ++ } ++ } ++ } ++ ++ if (need_pseudo_csum) { ++ ret = rte_net_intel_cksum_flags_prepare(m, ol_flags); ++ if (ret != 0) { ++ rte_errno = -ret; ++ return i; ++ } + } + } + +@@ -2480,7 +2669,7 @@ static int ena_xstats_get(struct rte_eth_dev *dev, return 0; for (stat = 0; stat < ENA_STATS_ARRAY_GLOBAL; stat++, count++) { @@ -29286,6 +44445,57 @@ index 8bbd80dfb3..d098387a8c 100644 stats_begin = &adapter->dev_stats; xstats[count].id = count; +diff --git a/dpdk/drivers/net/ena/ena_ethdev.h b/dpdk/drivers/net/ena/ena_ethdev.h +index af5eeea280..308e59cae7 100644 +--- a/dpdk/drivers/net/ena/ena_ethdev.h ++++ b/dpdk/drivers/net/ena/ena_ethdev.h +@@ -142,9 +142,8 @@ struct ena_stats_dev { + }; + + struct ena_offloads { +- bool tso4_supported; +- bool tx_csum_supported; +- bool rx_csum_supported; ++ uint32_t tx_offloads; ++ uint32_t rx_offloads; + }; + + /* board specific private data structure */ +@@ -180,11 +179,6 @@ struct ena_adapter { + struct ena_driver_stats *drv_stats; + enum ena_adapter_state state; + +- uint64_t tx_supported_offloads; +- uint64_t tx_selected_offloads; +- uint64_t rx_supported_offloads; +- uint64_t rx_selected_offloads; +- + bool link_status; + + enum ena_regs_reset_reason_types reset_reason; +diff --git a/dpdk/drivers/net/ena/ena_platform.h b/dpdk/drivers/net/ena/ena_platform.h +index d3e40e0e9e..748928b2d9 100644 +--- a/dpdk/drivers/net/ena/ena_platform.h ++++ b/dpdk/drivers/net/ena/ena_platform.h +@@ -6,18 +6,6 @@ + #ifndef __ENA_PLATFORM_H__ + #define __ENA_PLATFORM_H__ + +-#define swap16_to_le(x) (x) +- +-#define swap32_to_le(x) (x) +- +-#define swap64_to_le(x) (x) +- +-#define swap16_from_le(x) (x) +- +-#define swap32_from_le(x) (x) +- +-#define swap64_from_le(x) (x) +- + #define ena_assert_msg(cond, msg) \ + do { \ + if (unlikely(!(cond))) { \ diff --git a/dpdk/drivers/net/enetc/base/enetc_hw.h b/dpdk/drivers/net/enetc/base/enetc_hw.h index 2fe7ccb5bb..00813284ee 100644 --- a/dpdk/drivers/net/enetc/base/enetc_hw.h @@ -29321,7 +44531,7 @@ index 8c830a5c06..6a2c4c68e5 100644 * upper_32_bits - return bits 32-63 of a number * @n: the number we're accessing diff --git a/dpdk/drivers/net/enetc/enetc_ethdev.c b/dpdk/drivers/net/enetc/enetc_ethdev.c -index 20b77c006c..4f3e61cfdc 100644 +index 20b77c006c..b1281c9b82 100644 --- a/dpdk/drivers/net/enetc/enetc_ethdev.c +++ b/dpdk/drivers/net/enetc/enetc_ethdev.c @@ -1,5 +1,5 @@ @@ -29341,7 +44551,17 @@ index 20b77c006c..4f3e61cfdc 100644 /* Enabling Station Interface */ enetc_wr(enetc_hw, ENETC_SIMR, ENETC_SIMR_EN); -@@ -658,7 +661,7 @@ enetc_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -544,6 +547,9 @@ enetc_dev_close(struct rte_eth_dev *dev) + uint16_t i; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + enetc_dev_stop(dev); + + for (i = 0; i < dev->data->nb_rx_queues; i++) { +@@ -658,7 +664,7 @@ enetc_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EINVAL; } @@ -29350,8 +44570,48 @@ index 20b77c006c..4f3e61cfdc 100644 dev->data->dev_conf.rxmode.offloads &= DEV_RX_OFFLOAD_JUMBO_FRAME; else +diff --git a/dpdk/drivers/net/enic/base/vnic_dev.c b/dpdk/drivers/net/enic/base/vnic_dev.c +index 899df07df7..4ce44362a9 100644 +--- a/dpdk/drivers/net/enic/base/vnic_dev.c ++++ b/dpdk/drivers/net/enic/base/vnic_dev.c +@@ -520,6 +520,9 @@ static int vnic_dev_flowman_enable(struct vnic_dev *vdev, u32 *mode, + u64 ops; + static u32 instance; + ++ /* Advanced filtering is a prerequisite */ ++ if (!vnic_dev_capable_adv_filters(vdev)) ++ return 0; + /* flowman devcmd available? */ + if (!vnic_dev_capable(vdev, CMD_FLOW_MANAGER_OP)) + return 0; +@@ -570,8 +573,8 @@ static int vnic_dev_flowman_enable(struct vnic_dev *vdev, u32 *mode, + return 1; + } + +-/* Determine the "best" filtering mode VIC is capaible of. Returns one of 4 +- * value or 0 on error: ++/* Determine the "best" filtering mode VIC is capable of. Returns one of 4 ++ * value or 0 if filtering is unavailble: + * FILTER_FLOWMAN- flowman api capable + * FILTER_DPDK_1- advanced filters availabile + * FILTER_USNIC_IP_FLAG - advanced filters but with the restriction that +@@ -606,6 +609,14 @@ int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode, + args[0] = CMD_ADD_FILTER; + args[1] = 0; + err = vnic_dev_cmd_args(vdev, CMD_CAPABILITY, args, 2, 1000); ++ /* ++ * ERR_EPERM may be returned if, for example, vNIC is ++ * on a VF. It simply means no filtering is available ++ */ ++ if (err == -ERR_EPERM) { ++ *mode = 0; ++ return 0; ++ } + if (err) + return err; + max_level = args[1]; diff --git a/dpdk/drivers/net/enic/enic_ethdev.c b/dpdk/drivers/net/enic/enic_ethdev.c -index a7a178e41b..2733ac73a1 100644 +index a7a178e41b..1af36947da 100644 --- a/dpdk/drivers/net/enic/enic_ethdev.c +++ b/dpdk/drivers/net/enic/enic_ethdev.c @@ -374,18 +374,6 @@ static int enicpmd_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) @@ -29373,6 +44633,16 @@ index a7a178e41b..2733ac73a1 100644 return enic_set_vlan_strip(enic); } +@@ -469,6 +457,9 @@ static void enicpmd_dev_close(struct rte_eth_dev *eth_dev) + struct enic *enic = pmd_priv(eth_dev); + + ENICPMD_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + enic_remove(enic); + } + diff --git a/dpdk/drivers/net/enic/enic_flow.c b/dpdk/drivers/net/enic/enic_flow.c index 6cd3640174..a845dd4b41 100644 --- a/dpdk/drivers/net/enic/enic_flow.c @@ -29592,7 +44862,7 @@ index e3e3d737bc..e87988f48b 100644 error); if (ret != 0) diff --git a/dpdk/drivers/net/failsafe/failsafe.c b/dpdk/drivers/net/failsafe/failsafe.c -index 8af31d71b3..72362f35de 100644 +index 8af31d71b3..978c55007a 100644 --- a/dpdk/drivers/net/failsafe/failsafe.c +++ b/dpdk/drivers/net/failsafe/failsafe.c @@ -190,6 +190,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev) @@ -29603,6 +44873,16 @@ index 8af31d71b3..72362f35de 100644 dev->dev_ops = &failsafe_ops; dev->data->mac_addrs = &PRIV(dev)->mac_addrs[0]; dev->data->dev_link = eth_link; +@@ -347,8 +348,7 @@ rte_pmd_failsafe_probe(struct rte_vdev_device *vdev) + INFO("Initializing " FAILSAFE_DRIVER_NAME " for %s", + name); + +- if (rte_eal_process_type() == RTE_PROC_SECONDARY && +- strlen(rte_vdev_device_args(vdev)) == 0) { ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY) { + eth_dev = rte_eth_dev_attach_secondary(name); + if (!eth_dev) { + ERROR("Failed to probe %s", name); diff --git a/dpdk/drivers/net/failsafe/failsafe_ether.c b/dpdk/drivers/net/failsafe/failsafe_ether.c index 93deacd134..98fbdefc50 100644 --- a/dpdk/drivers/net/failsafe/failsafe_ether.c @@ -29665,7 +44945,7 @@ index 0f34c5bbac..bb5b089b31 100644 priv->rxp.efd = -1; } diff --git a/dpdk/drivers/net/failsafe/failsafe_ops.c b/dpdk/drivers/net/failsafe/failsafe_ops.c -index a87e49b97d..96f7e456f9 100644 +index a87e49b97d..f63be9b11d 100644 --- a/dpdk/drivers/net/failsafe/failsafe_ops.c +++ b/dpdk/drivers/net/failsafe/failsafe_ops.c @@ -380,7 +380,7 @@ fs_rx_queue_release(void *queue) @@ -29677,7 +44957,16 @@ index a87e49b97d..96f7e456f9 100644 close(rxq->event_fd); FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) { if (ETH(sdev)->data->rx_queues != NULL && -@@ -1068,6 +1068,15 @@ fs_dev_merge_info(struct rte_eth_dev_info *info, +@@ -1051,6 +1051,8 @@ static void + fs_dev_merge_info(struct rte_eth_dev_info *info, + const struct rte_eth_dev_info *sinfo) + { ++ info->min_mtu = RTE_MAX(info->min_mtu, sinfo->min_mtu); ++ info->max_mtu = RTE_MIN(info->max_mtu, sinfo->max_mtu); + info->max_rx_pktlen = RTE_MIN(info->max_rx_pktlen, sinfo->max_rx_pktlen); + info->max_rx_queues = RTE_MIN(info->max_rx_queues, sinfo->max_rx_queues); + info->max_tx_queues = RTE_MIN(info->max_tx_queues, sinfo->max_tx_queues); +@@ -1068,6 +1070,15 @@ fs_dev_merge_info(struct rte_eth_dev_info *info, info->rx_queue_offload_capa &= sinfo->rx_queue_offload_capa; info->tx_queue_offload_capa &= sinfo->tx_queue_offload_capa; info->flow_type_rss_offloads &= sinfo->flow_type_rss_offloads; @@ -29693,7 +44982,16 @@ index a87e49b97d..96f7e456f9 100644 } /** -@@ -1117,6 +1126,8 @@ fs_dev_infos_get(struct rte_eth_dev *dev, +@@ -1110,6 +1121,8 @@ fs_dev_infos_get(struct rte_eth_dev *dev, + int ret; + + /* Use maximum upper bounds by default */ ++ infos->min_mtu = RTE_ETHER_MIN_MTU; ++ infos->max_mtu = UINT16_MAX; + infos->max_rx_pktlen = UINT32_MAX; + infos->max_rx_queues = RTE_MAX_QUEUES_PER_PORT; + infos->max_tx_queues = RTE_MAX_QUEUES_PER_PORT; +@@ -1117,6 +1130,8 @@ fs_dev_infos_get(struct rte_eth_dev *dev, infos->max_hash_mac_addrs = UINT32_MAX; infos->max_vfs = UINT16_MAX; infos->max_vmdq_pools = UINT16_MAX; @@ -29702,6 +45000,26 @@ index a87e49b97d..96f7e456f9 100644 /* * Set of capabilities that can be verified upon +@@ -1137,7 +1152,8 @@ fs_dev_infos_get(struct rte_eth_dev *dev, + DEV_RX_OFFLOAD_JUMBO_FRAME | + DEV_RX_OFFLOAD_SCATTER | + DEV_RX_OFFLOAD_TIMESTAMP | +- DEV_RX_OFFLOAD_SECURITY; ++ DEV_RX_OFFLOAD_SECURITY | ++ DEV_RX_OFFLOAD_RSS_HASH; + + infos->rx_queue_offload_capa = + DEV_RX_OFFLOAD_VLAN_STRIP | +@@ -1154,7 +1170,8 @@ fs_dev_infos_get(struct rte_eth_dev *dev, + DEV_RX_OFFLOAD_JUMBO_FRAME | + DEV_RX_OFFLOAD_SCATTER | + DEV_RX_OFFLOAD_TIMESTAMP | +- DEV_RX_OFFLOAD_SECURITY; ++ DEV_RX_OFFLOAD_SECURITY | ++ DEV_RX_OFFLOAD_RSS_HASH; + + infos->tx_offload_capa = + DEV_TX_OFFLOAD_MULTI_SEGS | diff --git a/dpdk/drivers/net/failsafe/failsafe_private.h b/dpdk/drivers/net/failsafe/failsafe_private.h index 8e9706aef0..651578a128 100644 --- a/dpdk/drivers/net/failsafe/failsafe_private.h @@ -29734,10 +45052,29 @@ index 722bf1ee04..338de40f23 100644 +endif include $(RTE_SDK)/mk/rte.lib.mk +diff --git a/dpdk/drivers/net/fm10k/base/meson.build b/dpdk/drivers/net/fm10k/base/meson.build +index 40d9b730a3..d77ab9252d 100644 +--- a/dpdk/drivers/net/fm10k/base/meson.build ++++ b/dpdk/drivers/net/fm10k/base/meson.build +@@ -28,4 +28,4 @@ endforeach + base_lib = static_library('fm10k_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/fm10k/fm10k_ethdev.c b/dpdk/drivers/net/fm10k/fm10k_ethdev.c -index 407baa16c3..7a83b6f68e 100644 +index 407baa16c3..d2d8fd268a 100644 --- a/dpdk/drivers/net/fm10k/fm10k_ethdev.c +++ b/dpdk/drivers/net/fm10k/fm10k_ethdev.c +@@ -266,7 +266,7 @@ rx_queue_clean(struct fm10k_rx_queue *q) + for (i = 0; i < q->nb_fake_desc; ++i) + q->hw_ring[q->nb_desc + i] = zero; + +- /* vPMD driver has a different way of releasing mbufs. */ ++ /* vPMD has a different way of releasing mbufs. */ + if (q->rx_using_sse) { + fm10k_rx_queue_release_mbufs_vec(q); + return; @@ -1575,28 +1575,9 @@ fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) } @@ -29794,6 +45131,30 @@ index 407baa16c3..7a83b6f68e 100644 /* allocate memory for the software ring */ q->sw_ring = rte_zmalloc_socket("fm10k sw ring", +@@ -2819,6 +2803,8 @@ fm10k_dev_close(struct rte_eth_dev *dev) + struct rte_intr_handle *intr_handle = &pdev->intr_handle; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + fm10k_mbx_lock(hw); + hw->mac.ops.update_lport_state(hw, hw->mac.dglort_map, +@@ -3274,14 +3260,7 @@ static int + eth_fm10k_dev_uninit(struct rte_eth_dev *dev) + { + PMD_INIT_FUNC_TRACE(); +- +- /* only uninitialize in the primary process */ +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) +- return 0; +- +- /* safe to close dev here */ + fm10k_dev_close(dev); +- + return 0; + } + diff --git a/dpdk/drivers/net/fm10k/fm10k_rxtx.c b/dpdk/drivers/net/fm10k/fm10k_rxtx.c index 5c31121839..4accaa2cd6 100644 --- a/dpdk/drivers/net/fm10k/fm10k_rxtx.c @@ -29808,9 +45169,38 @@ index 5c31121839..4accaa2cd6 100644 q->sw_ring[q->next_free] = mb; q->hw_ring[q->next_free].buffer_addr = diff --git a/dpdk/drivers/net/fm10k/fm10k_rxtx_vec.c b/dpdk/drivers/net/fm10k/fm10k_rxtx_vec.c -index d76dfd16fd..1194251396 100644 +index d76dfd16fd..a441d33980 100644 --- a/dpdk/drivers/net/fm10k/fm10k_rxtx_vec.c +++ b/dpdk/drivers/net/fm10k/fm10k_rxtx_vec.c +@@ -472,7 +472,7 @@ fm10k_recv_raw_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + mbp1 = _mm_loadu_si128((__m128i *)&mbufp[pos]); + + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs0[3] = _mm_loadu_si128((__m128i *)(rxdp + 3)); + rte_compiler_barrier(); + +@@ -484,9 +484,9 @@ fm10k_recv_raw_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + mbp2 = _mm_loadu_si128((__m128i *)&mbufp[pos+2]); + #endif + ++ /* A.1 load desc[2-0] */ + descs0[2] = _mm_loadu_si128((__m128i *)(rxdp + 2)); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs0[1] = _mm_loadu_si128((__m128i *)(rxdp + 1)); + rte_compiler_barrier(); + descs0[0] = _mm_loadu_si128((__m128i *)(rxdp)); +@@ -544,7 +544,7 @@ fm10k_recv_raw_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + /* and with mask to extract bits, flipping 1-0 */ + __m128i eop_bits = _mm_andnot_si128(staterr, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ @@ -645,18 +645,15 @@ fm10k_reassemble_packets(struct fm10k_rx_queue *rxq, return pkt_idx; } @@ -29869,7 +45259,7 @@ index d76dfd16fd..1194251396 100644 .reset = fm10k_reset_tx_queue, }; diff --git a/dpdk/drivers/net/hinic/base/hinic_compat.h b/dpdk/drivers/net/hinic/base/hinic_compat.h -index e4a7f12d15..473a273b6b 100644 +index e4a7f12d15..ac42ca5f8e 100644 --- a/dpdk/drivers/net/hinic/base/hinic_compat.h +++ b/dpdk/drivers/net/hinic/base/hinic_compat.h @@ -150,22 +150,25 @@ static inline int hinic_test_and_set_bit(int nr, volatile unsigned long *addr) @@ -29905,7 +45295,7 @@ index e4a7f12d15..473a273b6b 100644 void dma_pool_free(struct pci_pool *pool, void *vaddr, dma_addr_t dma); #define kzalloc(size, flag) rte_zmalloc(NULL, size, HINIC_MEM_ALLOC_ALIGN_MIN) -@@ -195,16 +198,23 @@ static inline u32 readl(const volatile void *addr) +@@ -195,16 +198,24 @@ static inline u32 readl(const volatile void *addr) #define spin_lock(spinlock_prt) rte_spinlock_lock(spinlock_prt) #define spin_unlock(spinlock_prt) rte_spinlock_unlock(spinlock_prt) @@ -29915,6 +45305,7 @@ index e4a7f12d15..473a273b6b 100644 +#else +#define CLOCK_TYPE CLOCK_MONOTONIC +#endif ++#define HINIC_MUTEX_TIMEOUT 10 + +static inline unsigned long clock_gettime_ms(void) { @@ -29934,6 +45325,38 @@ index e4a7f12d15..473a273b6b 100644 #define msecs_to_jiffies(ms) (ms) #define time_before(now, end) ((now) < (end)) +@@ -247,24 +258,14 @@ static inline int hinic_mutex_destroy(pthread_mutex_t *pthreadmutex) + static inline int hinic_mutex_lock(pthread_mutex_t *pthreadmutex) + { + int err; ++ struct timespec tout; + +- err = pthread_mutex_lock(pthreadmutex); +- if (!err) { +- return err; +- } else if (err == EOWNERDEAD) { +- PMD_DRV_LOG(ERR, "Mutex lock failed. (ErrorNo=%d)", errno); +-#if defined(__GLIBC__) +-#if __GLIBC_PREREQ(2, 12) +- (void)pthread_mutex_consistent(pthreadmutex); +-#else +- (void)pthread_mutex_consistent_np(pthreadmutex); +-#endif +-#else +- (void)pthread_mutex_consistent(pthreadmutex); +-#endif +- } else { +- PMD_DRV_LOG(ERR, "Mutex lock failed. (ErrorNo=%d)", errno); +- } ++ (void)clock_gettime(CLOCK_TYPE, &tout); ++ ++ tout.tv_sec += HINIC_MUTEX_TIMEOUT; ++ err = pthread_mutex_timedlock(pthreadmutex, &tout); ++ if (err) ++ PMD_DRV_LOG(ERR, "Mutex lock failed. (ErrorNo=%d)", err); + + return err; + } diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_api_cmd.c b/dpdk/drivers/net/hinic/base/hinic_pmd_api_cmd.c index dbffc2e3b0..b72edc0652 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_api_cmd.c @@ -30099,9 +45522,18 @@ index eb8de24d6e..1816636c34 100644 int hinic_comm_cmdqs_init(struct hinic_hwdev *hwdev) diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_cmdq.h b/dpdk/drivers/net/hinic/base/hinic_pmd_cmdq.h -index da939e16fa..4ce0a4c5b8 100644 +index da939e16fa..c20a2f2aca 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_cmdq.h +++ b/dpdk/drivers/net/hinic/base/hinic_pmd_cmdq.h +@@ -9,7 +9,7 @@ + + #define HINIC_SCMD_DATA_LEN 16 + +-/* hiovs pmd use 64, kernel l2nic use 4096 */ ++/* hiovs PMD use 64, kernel l2nic use 4096 */ + #define HINIC_CMDQ_DEPTH 64 + + #define HINIC_CMDQ_BUF_SIZE 2048U @@ -170,6 +170,7 @@ struct hinic_cmdq_ctxt { enum hinic_cmdq_status { @@ -30154,7 +45586,7 @@ index 16046ecde3..5e6dc3914b 100644 #define HINIC_EQ_MAX_PAGES 8 diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_hwdev.c b/dpdk/drivers/net/hinic/base/hinic_pmd_hwdev.c -index 8b16897ade..8a0faa6975 100644 +index 8b16897ade..09e1891b21 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_hwdev.c +++ b/dpdk/drivers/net/hinic/base/hinic_pmd_hwdev.c @@ -112,9 +112,9 @@ void hinic_be32_to_cpu(void *data, u32 len) @@ -30421,7 +45853,7 @@ index 8b16897ade..8a0faa6975 100644 memset(&attr, 0, sizeof(attr)); attr.func_idx = hinic_global_func_id(hwdev); -@@ -781,9 +815,16 @@ static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, +@@ -781,13 +815,20 @@ static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, attr.no_snooping = no_snooping; attr.tph_en = tph_en; @@ -30441,6 +45873,11 @@ index 8b16897ade..8a0faa6975 100644 } /** +- * dma_attr_table_init - initialize the the default dma attributes ++ * dma_attr_table_init - initialize the default dma attributes + * @hwdev: the pointer to the private hardware device object + */ + static int dma_attr_table_init(struct hinic_hwdev *hwdev) @@ -925,17 +966,26 @@ static void fault_report_show(struct hinic_hwdev *hwdev, static int resources_state_set(struct hinic_hwdev *hwdev, enum hinic_res_state state) @@ -30760,10 +46197,27 @@ index bf7b4906dc..b17f0df1db 100644 u8 send_msg_id; diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.c b/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.c -index eee50a80d1..d5fd16f235 100644 +index eee50a80d1..6357fbe8ae 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.c +++ b/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.c -@@ -248,6 +248,19 @@ static void free_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt) +@@ -133,16 +133,12 @@ static void prepare_header(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, + static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, void *msg, + int msg_len) + { +- u32 cmd_buf_max = MAX_PF_MGMT_BUF_SIZE; +- + memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV); + + mgmt_cmd += MGMT_MSG_RSVD_FOR_DEV; +- cmd_buf_max -= MGMT_MSG_RSVD_FOR_DEV; + memcpy(mgmt_cmd, header, sizeof(*header)); + + mgmt_cmd += sizeof(*header); +- cmd_buf_max -= sizeof(*header); + memcpy(mgmt_cmd, msg, msg_len); + } + +@@ -248,6 +244,19 @@ static void free_msg_buf(struct hinic_msg_pf_to_mgmt *pf_to_mgmt) free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt); } @@ -30783,7 +46237,7 @@ index eee50a80d1..d5fd16f235 100644 /** * send_msg_to_mgmt_async - send async message * @pf_to_mgmt: PF to MGMT channel -@@ -309,6 +322,14 @@ static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, +@@ -309,6 +318,14 @@ static int send_msg_to_mgmt_sync(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, u64 header; u16 cmd_size = mgmt_msg_len(msg_len); @@ -30798,7 +46252,7 @@ index eee50a80d1..d5fd16f235 100644 if (direction == HINIC_MSG_RESPONSE) prepare_header(pf_to_mgmt, &header, msg_len, mod, ack_type, direction, cmd, resp_msg_id); -@@ -462,19 +483,6 @@ hinic_pf_to_mgmt_sync(struct hinic_hwdev *hwdev, +@@ -462,19 +479,6 @@ hinic_pf_to_mgmt_sync(struct hinic_hwdev *hwdev, return err; } @@ -30818,7 +46272,7 @@ index eee50a80d1..d5fd16f235 100644 int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size, u32 timeout) -@@ -484,10 +492,6 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, +@@ -484,10 +488,6 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, if (!hwdev || in_size > HINIC_MSG_TO_MGMT_MAX_LEN) return -EINVAL; @@ -30829,7 +46283,7 @@ index eee50a80d1..d5fd16f235 100644 if (hinic_func_type(hwdev) == TYPE_VF) { rc = hinic_mbox_to_pf(hwdev, mod, cmd, buf_in, in_size, buf_out, out_size, timeout); -@@ -500,8 +504,7 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, +@@ -500,8 +500,7 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd, } int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd, @@ -30839,7 +46293,7 @@ index eee50a80d1..d5fd16f235 100644 { struct hinic_msg_pf_to_mgmt *pf_to_mgmt = ((struct hinic_hwdev *)hwdev)->pf_to_mgmt; -@@ -526,19 +529,21 @@ int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd, +@@ -526,19 +525,21 @@ int hinic_msg_to_mgmt_no_ack(void *hwdev, enum hinic_mod_type mod, u8 cmd, } static bool check_mgmt_seq_id_and_seg_len(struct hinic_recv_msg *recv_msg, @@ -30866,10 +46320,11 @@ index eee50a80d1..d5fd16f235 100644 } return true; -@@ -611,16 +616,21 @@ static int recv_mgmt_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, +@@ -610,22 +611,25 @@ static int recv_mgmt_msg_handler(struct hinic_msg_pf_to_mgmt *pf_to_mgmt, + void *msg_body = header + sizeof(msg_header); u8 *dest_msg; u8 seq_id, seq_len; - u32 msg_buf_max = MAX_PF_MGMT_BUF_SIZE; +- u32 msg_buf_max = MAX_PF_MGMT_BUF_SIZE; + u8 front_id; + u16 msg_id; @@ -30891,6 +46346,11 @@ index eee50a80d1..d5fd16f235 100644 return HINIC_ERROR; } + dest_msg = (u8 *)recv_msg->msg + seq_id * HINIC_MSG_SEG_LEN; +- msg_buf_max -= seq_id * HINIC_MSG_SEG_LEN; + memcpy(dest_msg, msg_body, seq_len); + + if (!HINIC_MSG_HEADER_GET(msg_header, LAST)) diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.h b/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.h index cc18843bf8..5099a3a8d6 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_mgmt.h @@ -31073,9 +46533,20 @@ index b9e037ec2d..bf39b0272b 100644 int hinic_init_function_table(void *hwdev, u16 rx_buf_sz); diff --git a/dpdk/drivers/net/hinic/base/hinic_pmd_nicio.c b/dpdk/drivers/net/hinic/base/hinic_pmd_nicio.c -index f6cc03341b..9d9f2a7a56 100644 +index f6cc03341b..928a35da78 100644 --- a/dpdk/drivers/net/hinic/base/hinic_pmd_nicio.c +++ b/dpdk/drivers/net/hinic/base/hinic_pmd_nicio.c +@@ -230,8 +230,8 @@ static void hinic_rq_prepare_ctxt(struct hinic_rq *rq, + wq_block_pfn_hi = upper_32_bits(wq_block_pfn); + wq_block_pfn_lo = lower_32_bits(wq_block_pfn); + +- /* must config as ceq enable but do not generate ceq */ +- rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(1, EN) | ++ /* config as ceq disable, but must set msix state disable */ ++ rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(0, EN) | + RQ_CTXT_CEQ_ATTR_SET(1, OWNER); + + rq_ctxt->pi_intr_attr = RQ_CTXT_PI_SET(pi_start, IDX) | @@ -471,6 +471,8 @@ static int hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz) { @@ -31251,8 +46722,18 @@ index 53ecc225c8..354d0338de 100644 void hinic_wq_free(struct hinic_hwdev *hwdev, struct hinic_wq *wq); +diff --git a/dpdk/drivers/net/hinic/base/meson.build b/dpdk/drivers/net/hinic/base/meson.build +index 6cf947f841..227c589fcc 100644 +--- a/dpdk/drivers/net/hinic/base/meson.build ++++ b/dpdk/drivers/net/hinic/base/meson.build +@@ -34,4 +34,4 @@ c_args = cflags + base_lib = static_library('hinic_base', sources, + dependencies: [static_rte_eal, static_rte_ethdev, static_rte_bus_pci, static_rte_hash], + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/hinic/hinic_pmd_ethdev.c b/dpdk/drivers/net/hinic/hinic_pmd_ethdev.c -index 803a39e2da..a0499da7d4 100644 +index 803a39e2da..a7c3d7bf75 100644 --- a/dpdk/drivers/net/hinic/hinic_pmd_ethdev.c +++ b/dpdk/drivers/net/hinic/hinic_pmd_ethdev.c @@ -57,6 +57,7 @@ @@ -31403,7 +46884,17 @@ index 803a39e2da..a0499da7d4 100644 /* rx queue stats */ q_num = (nic_dev->num_rq < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? nic_dev->num_rq : RTE_ETHDEV_QUEUE_STAT_CNTRS; -@@ -1700,12 +1689,6 @@ static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -1608,6 +1597,9 @@ static int hinic_vlan_filter_set(struct rte_eth_dev *dev, + if (vlan_id > RTE_ETHER_MAX_VLAN_ID) + return -EINVAL; + ++ if (vlan_id == 0) ++ return 0; ++ + func_id = hinic_global_func_id(nic_dev->hwdev); + + if (enable) { +@@ -1700,12 +1692,6 @@ static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask) nic_dev->proc_dev_name, dev->data->port_id); } @@ -31416,7 +46907,7 @@ index 803a39e2da..a0499da7d4 100644 return 0; } -@@ -1730,14 +1713,25 @@ static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev) +@@ -1730,14 +1716,25 @@ static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev) static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev, bool enable) { @@ -31444,7 +46935,7 @@ index 803a39e2da..a0499da7d4 100644 } /** -@@ -2490,26 +2484,53 @@ static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev) +@@ -2490,26 +2487,53 @@ static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev) up_pgid, up_bw, up_strict); } @@ -31504,7 +46995,36 @@ index 803a39e2da..a0499da7d4 100644 return 0; } -@@ -3044,6 +3065,8 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) +@@ -2845,6 +2869,9 @@ static void hinic_dev_close(struct rte_eth_dev *dev) + { + struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (hinic_test_and_set_bit(HINIC_DEV_CLOSE, &nic_dev->dev_status)) { + PMD_DRV_LOG(WARNING, "Device %s already closed", + dev->data->name); +@@ -2951,6 +2978,10 @@ static const struct eth_dev_ops hinic_pmd_vf_ops = { + .filter_ctrl = hinic_dev_filter_ctrl, + }; + ++static const struct eth_dev_ops hinic_dev_sec_ops = { ++ .dev_infos_get = hinic_dev_infos_get, ++}; ++ + static int hinic_func_init(struct rte_eth_dev *eth_dev) + { + struct rte_pci_device *pci_dev; +@@ -2964,6 +2995,7 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) + + /* EAL is SECONDARY and eth_dev is already created */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ eth_dev->dev_ops = &hinic_dev_sec_ops; + PMD_DRV_LOG(INFO, "Initialize %s in secondary process", + eth_dev->data->name); + +@@ -3044,6 +3076,8 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) } hinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status); @@ -31513,7 +47033,7 @@ index 803a39e2da..a0499da7d4 100644 /* initialize filter info */ filter_info = &nic_dev->filter; memset(filter_info, 0, sizeof(struct hinic_filter_info)); -@@ -3115,6 +3138,8 @@ static int hinic_dev_uninit(struct rte_eth_dev *dev) +@@ -3115,6 +3149,8 @@ static int hinic_dev_uninit(struct rte_eth_dev *dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; @@ -31922,19 +47442,61 @@ index a1ca580b1b..dabbc6c1d8 100644 void hinic_destroy_sq(struct hinic_hwdev *hwdev, u16 q_id); diff --git a/dpdk/drivers/net/hns3/hns3_cmd.c b/dpdk/drivers/net/hns3/hns3_cmd.c -index 65a5af8e4f..dc2473a0f7 100644 +index 65a5af8e4f..07a3185f6b 100644 --- a/dpdk/drivers/net/hns3/hns3_cmd.c +++ b/dpdk/drivers/net/hns3/hns3_cmd.c -@@ -215,12 +215,12 @@ hns3_cmd_csq_clean(struct hns3_hw *hw) - head = hns3_read_dev(hw, HNS3_CMDQ_TX_HEAD_REG); +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include +@@ -25,10 +25,6 @@ + #include "hns3_intr.h" + #include "hns3_logs.h" - if (!is_valid_csq_clean_head(csq, head)) { +-#define hns3_is_csq(ring) ((ring)->flag & HNS3_TYPE_CSQ) +- +-#define cmq_ring_to_dev(ring) (&(ring)->dev->pdev->dev) +- + static int + hns3_ring_space(struct hns3_cmq_ring *ring) + { +@@ -63,10 +59,12 @@ static int + hns3_allocate_dma_mem(struct hns3_hw *hw, struct hns3_cmq_ring *ring, + uint64_t size, uint32_t alignment) + { ++ static uint64_t hns3_dma_memzone_id; + const struct rte_memzone *mz = NULL; + char z_name[RTE_MEMZONE_NAMESIZE]; + +- snprintf(z_name, sizeof(z_name), "hns3_dma_%" PRIu64, rte_rand()); ++ snprintf(z_name, sizeof(z_name), "hns3_dma_%" PRIu64, ++ __atomic_fetch_add(&hns3_dma_memzone_id, 1, __ATOMIC_RELAXED)); + mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, + RTE_MEMZONE_IOVA_CONTIG, alignment, + RTE_PGSIZE_2M); +@@ -210,17 +208,18 @@ hns3_cmd_csq_clean(struct hns3_hw *hw) + { + struct hns3_cmq_ring *csq = &hw->cmq.csq; + uint32_t head; ++ uint32_t addr; + int clean; + + head = hns3_read_dev(hw, HNS3_CMDQ_TX_HEAD_REG); +- +- if (!is_valid_csq_clean_head(csq, head)) { - struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); - hns3_err(hw, "wrong cmd head (%u, %u-%u)", head, - csq->next_to_use, csq->next_to_clean); +- hns3_err(hw, "wrong cmd head (%u, %u-%u)", head, +- csq->next_to_use, csq->next_to_clean); - rte_atomic16_set(&hw->reset.disable_cmd, 1); - - hns3_schedule_delayed_reset(hns); ++ addr = hns3_read_dev(hw, HNS3_CMDQ_TX_ADDR_L_REG); ++ if (!is_valid_csq_clean_head(csq, head) || addr == 0) { ++ hns3_err(hw, "wrong cmd addr(%0x) head (%u, %u-%u)", addr, head, ++ csq->next_to_use, csq->next_to_clean); + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + rte_atomic16_set(&hw->reset.disable_cmd, 1); + hns3_schedule_delayed_reset(HNS3_DEV_HW_TO_ADAPTER(hw)); @@ -31942,7 +47504,7 @@ index 65a5af8e4f..dc2473a0f7 100644 return -EIO; } -@@ -289,7 +289,7 @@ hns3_cmd_convert_err_code(uint16_t desc_ret) +@@ -289,7 +288,7 @@ hns3_cmd_convert_err_code(uint16_t desc_ret) case HNS3_CMD_INVALID: return -EBADR; default: @@ -31951,7 +47513,7 @@ index 65a5af8e4f..dc2473a0f7 100644 } } -@@ -349,11 +349,23 @@ static int hns3_cmd_poll_reply(struct hns3_hw *hw) +@@ -349,11 +348,23 @@ static int hns3_cmd_poll_reply(struct hns3_hw *hw) /* * hns3_cmd_send - send command to command queue @@ -31979,7 +47541,7 @@ index 65a5af8e4f..dc2473a0f7 100644 * sends the queue, cleans the queue, etc */ int -@@ -517,7 +529,7 @@ hns3_cmd_init(struct hns3_hw *hw) +@@ -517,7 +528,7 @@ hns3_cmd_init(struct hns3_hw *hw) return 0; err_cmd_init: @@ -31988,7 +47550,7 @@ index 65a5af8e4f..dc2473a0f7 100644 return ret; } -@@ -541,9 +553,21 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw) +@@ -541,9 +552,21 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw) void hns3_cmd_uninit(struct hns3_hw *hw) { @@ -32012,10 +47574,16 @@ index 65a5af8e4f..dc2473a0f7 100644 rte_spinlock_unlock(&hw->cmq.crq.lock); rte_spinlock_unlock(&hw->cmq.csq.lock); diff --git a/dpdk/drivers/net/hns3/hns3_cmd.h b/dpdk/drivers/net/hns3/hns3_cmd.h -index be0ecbe86b..5a7b7a44e0 100644 +index be0ecbe86b..58b44cdc7c 100644 --- a/dpdk/drivers/net/hns3/hns3_cmd.h +++ b/dpdk/drivers/net/hns3/hns3_cmd.h -@@ -6,6 +6,7 @@ +@@ -1,11 +1,12 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_CMD_H_ #define _HNS3_CMD_H_ #define HNS3_CMDQ_TX_TIMEOUT 30000 @@ -32076,7 +47644,24 @@ index be0ecbe86b..5a7b7a44e0 100644 #define HNS3_UMV_SPC_ALC_B 0 struct hns3_umv_spc_alc_cmd { uint8_t allocate; -@@ -673,6 +692,36 @@ struct hns3_tqp_map_cmd { +@@ -362,8 +381,6 @@ struct hns3_umv_spc_alc_cmd { + #define HNS3_CFG_RD_LEN_BYTES 16 + #define HNS3_CFG_RD_LEN_UNIT 4 + +-#define HNS3_CFG_VMDQ_S 0 +-#define HNS3_CFG_VMDQ_M GENMASK(7, 0) + #define HNS3_CFG_TC_NUM_S 8 + #define HNS3_CFG_TC_NUM_M GENMASK(15, 8) + #define HNS3_CFG_TQP_DESC_N_S 16 +@@ -491,7 +508,6 @@ struct hns3_cfg_gro_status_cmd { + + #define HNS3_RSS_HASH_KEY_OFFSET_B 4 + +-#define HNS3_RSS_CFG_TBL_SIZE 16 + #define HNS3_RSS_HASH_KEY_NUM 16 + /* Configure the algorithm mode and Hash Key, opcode:0x0D01 */ + struct hns3_rss_generic_config_cmd { +@@ -673,6 +689,36 @@ struct hns3_tqp_map_cmd { uint8_t rsv[18]; }; @@ -32113,10 +47698,27 @@ index be0ecbe86b..5a7b7a44e0 100644 struct hns3_config_max_frm_size_cmd { uint16_t max_frm_size; uint8_t min_frm_size; +@@ -691,7 +737,8 @@ enum hns3_mac_vlan_add_resp_code { + HNS3_ADD_MC_OVERFLOW, /* ADD failed for MC overflow */ + }; + +-#define HNS3_MC_MAC_VLAN_ADD_DESC_NUM 3 ++#define HNS3_MC_MAC_VLAN_OPS_DESC_NUM 3 ++#define HNS3_UC_MAC_VLAN_OPS_DESC_NUM 1 + + #define HNS3_MAC_VLAN_BIT0_EN_B 0 + #define HNS3_MAC_VLAN_BIT1_EN_B 1 diff --git a/dpdk/drivers/net/hns3/hns3_dcb.c b/dpdk/drivers/net/hns3/hns3_dcb.c -index 19235dfb92..62d8930c15 100644 +index 19235dfb92..81fe86aa39 100644 --- a/dpdk/drivers/net/hns3/hns3_dcb.c +++ b/dpdk/drivers/net/hns3/hns3_dcb.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -337,7 +337,7 @@ hns3_dcb_get_shapping_para(uint8_t ir_b, uint8_t ir_u, uint8_t ir_s, return shapping_para; } @@ -32217,6 +47819,15 @@ index 19235dfb92..62d8930c15 100644 } int +@@ -1080,7 +1103,7 @@ hns3_qs_bp_cfg(struct hns3_hw *hw, uint8_t tc, uint8_t grp_id, uint32_t bit_map) + static void + hns3_get_rx_tx_en_status(struct hns3_hw *hw, bool *tx_en, bool *rx_en) + { +- switch (hw->current_mode) { ++ switch (hw->requested_fc_mode) { + case HNS3_FC_NONE: + *tx_en = false; + *rx_en = false; @@ -1235,6 +1258,8 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed) { struct rte_eth_dcb_rx_conf *dcb_rx_conf; @@ -32226,7 +47837,13 @@ index 19235dfb92..62d8930c15 100644 uint8_t max_tc = 0; uint8_t pfc_en; int i; -@@ -1260,6 +1285,10 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed) +@@ -1255,11 +1280,15 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed) + * We ensure that dcb information can be reconfigured + * after the hns3_priority_flow_ctrl_set function called. + */ +- if (hw->current_mode != HNS3_FC_FULL) ++ if (hw->requested_fc_mode != HNS3_FC_FULL) + *changed = true; pfc_en = RTE_LEN2MASK((uint8_t)dcb_rx_conf->nb_tcs, uint8_t); if (hw->dcb_info.pfc_en != pfc_en) *changed = true; @@ -32289,7 +47906,50 @@ index 19235dfb92..62d8930c15 100644 } static int -@@ -1422,10 +1466,15 @@ hns3_dcb_configure(struct hns3_adapter *hns) +@@ -1346,9 +1390,10 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + struct hns3_pf *pf = &hns->pf; + struct hns3_hw *hw = &hns->hw; + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; ++ enum hns3_fc_mode requested_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; +- int ret, status; ++ uint8_t pfc_en = hw->dcb_info.pfc_en; ++ int ret; + + if (pf->tx_sch_mode != HNS3_FLAG_TC_BASE_SCH_MODE && + pf->tx_sch_mode != HNS3_FLAG_VNET_BASE_SCH_MODE) +@@ -1373,10 +1418,10 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + + ret = hns3_buffer_alloc(hw); + if (ret) +- return ret; ++ goto buffer_alloc_fail; + + hw->current_fc_status = HNS3_FC_STATUS_PFC; +- hw->current_mode = HNS3_FC_FULL; ++ hw->requested_fc_mode = HNS3_FC_FULL; + ret = hns3_dcb_pause_setup_hw(hw); + if (ret) { + hns3_err(hw, "setup pfc failed! ret = %d", ret); +@@ -1397,12 +1442,12 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns) + return 0; + + pfc_setup_fail: +- hw->current_mode = current_mode; ++ hw->requested_fc_mode = requested_fc_mode; + hw->current_fc_status = fc_status; ++ ++buffer_alloc_fail: ++ hw->dcb_info.pfc_en = pfc_en; + hw->dcb_info.hw_pfc_map = hw_pfc_map; +- status = hns3_buffer_alloc(hw); +- if (status) +- hns3_err(hw, "recover packet buffer fail! status = %d", status); + + return ret; + } +@@ -1422,10 +1467,15 @@ hns3_dcb_configure(struct hns3_adapter *hns) hns3_dcb_cfg_validate(hns, &num_tc, &map_changed); if (map_changed || rte_atomic16_read(&hw->reset.resetting)) { @@ -32307,6 +47967,16 @@ index 19235dfb92..62d8930c15 100644 return ret; } } +@@ -1469,8 +1519,7 @@ hns3_dcb_init(struct hns3_hw *hw) + * will be changed. + */ + if (hw->adapter_state == HNS3_NIC_UNINITIALIZED) { +- hw->requested_mode = HNS3_FC_NONE; +- hw->current_mode = hw->requested_mode; ++ hw->requested_fc_mode = HNS3_FC_NONE; + pf->pause_time = HNS3_DEFAULT_PAUSE_TRANS_TIME; + hw->current_fc_status = HNS3_FC_STATUS_NONE; + @@ -1479,7 +1528,8 @@ hns3_dcb_init(struct hns3_hw *hw) hns3_err(hw, "dcb info init failed: %d", ret); return ret; @@ -32331,10 +48001,124 @@ index 19235dfb92..62d8930c15 100644 ret = hns3_q_to_qs_map(hw); if (ret) { hns3_err(hw, "failed to map nq to qs! ret = %d", ret); +@@ -1543,6 +1594,30 @@ hns3_dcb_cfg_update(struct hns3_adapter *hns) + return ret; + } + ++static void ++hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) ++{ ++ switch (mode) { ++ case RTE_FC_NONE: ++ hw->requested_fc_mode = HNS3_FC_NONE; ++ break; ++ case RTE_FC_RX_PAUSE: ++ hw->requested_fc_mode = HNS3_FC_RX_PAUSE; ++ break; ++ case RTE_FC_TX_PAUSE: ++ hw->requested_fc_mode = HNS3_FC_TX_PAUSE; ++ break; ++ case RTE_FC_FULL: ++ hw->requested_fc_mode = HNS3_FC_FULL; ++ break; ++ default: ++ hw->requested_fc_mode = HNS3_FC_NONE; ++ hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " ++ "configured to RTE_FC_NONE", mode); ++ break; ++ } ++} ++ + /* + * hns3_dcb_pfc_enable - Enable priority flow control + * @dev: pointer to ethernet device +@@ -1555,15 +1630,15 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; ++ enum hns3_fc_mode old_fc_mode = hw->requested_fc_mode; + uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map; + uint8_t pfc_en = hw->dcb_info.pfc_en; + uint8_t priority = pfc_conf->priority; + uint16_t pause_time = pf->pause_time; +- int ret, status; ++ int ret; + + pf->pause_time = pfc_conf->fc.pause_time; +- hw->current_mode = hw->requested_mode; ++ hns3_get_fc_mode(hw, pfc_conf->fc.mode); + hw->current_fc_status = HNS3_FC_STATUS_PFC; + hw->dcb_info.pfc_en |= BIT(priority); + hw->dcb_info.hw_pfc_map = +@@ -1574,7 +1649,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + + /* + * The flow control mode of all UPs will be changed based on +- * current_mode coming from user. ++ * requested_fc_mode coming from user. + */ + ret = hns3_dcb_pause_setup_hw(hw); + if (ret) { +@@ -1585,14 +1660,11 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf) + return 0; + + pfc_setup_fail: +- hw->current_mode = current_mode; ++ hw->requested_fc_mode = old_fc_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + hw->dcb_info.pfc_en = pfc_en; + hw->dcb_info.hw_pfc_map = hw_pfc_map; +- status = hns3_buffer_alloc(hw); +- if (status) +- hns3_err(hw, "recover packet buffer fail: %d", status); + + return ret; + } +@@ -1608,19 +1680,19 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ enum hns3_fc_mode old_fc_mode = hw->requested_fc_mode; + enum hns3_fc_status fc_status = hw->current_fc_status; +- enum hns3_fc_mode current_mode = hw->current_mode; + uint16_t pause_time = pf->pause_time; + int ret; + + pf->pause_time = fc_conf->pause_time; +- hw->current_mode = hw->requested_mode; ++ hns3_get_fc_mode(hw, fc_conf->mode); + + /* + * In fact, current_fc_status is HNS3_FC_STATUS_NONE when mode + * of flow control is configured to be HNS3_FC_NONE. + */ +- if (hw->current_mode == HNS3_FC_NONE) ++ if (hw->requested_fc_mode == HNS3_FC_NONE) + hw->current_fc_status = HNS3_FC_STATUS_NONE; + else + hw->current_fc_status = HNS3_FC_STATUS_MAC_PAUSE; +@@ -1634,7 +1706,7 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return 0; + + setup_fc_fail: +- hw->current_mode = current_mode; ++ hw->requested_fc_mode = old_fc_mode; + hw->current_fc_status = fc_status; + pf->pause_time = pause_time; + diff --git a/dpdk/drivers/net/hns3/hns3_dcb.h b/dpdk/drivers/net/hns3/hns3_dcb.h -index 9ec4e704b3..fe67d3a466 100644 +index 9ec4e704b3..ff406bc693 100644 --- a/dpdk/drivers/net/hns3/hns3_dcb.h +++ b/dpdk/drivers/net/hns3/hns3_dcb.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_DCB_H_ @@ -24,16 +24,19 @@ enum hns3_shap_bucket { struct hns3_priority_weight_cmd { uint8_t pri_id; @@ -32428,9 +48212,16 @@ index 9ec4e704b3..fe67d3a466 100644 #endif /* _HNS3_DCB_H_ */ diff --git a/dpdk/drivers/net/hns3/hns3_ethdev.c b/dpdk/drivers/net/hns3/hns3_ethdev.c -index 72315718a8..66be58dc26 100644 +index 72315718a8..1a8d729bc4 100644 --- a/dpdk/drivers/net/hns3/hns3_ethdev.c +++ b/dpdk/drivers/net/hns3/hns3_ethdev.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -35,9 +35,7 @@ #define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1 @@ -32502,8 +48293,12 @@ index 72315718a8..66be58dc26 100644 */ if (on == 0 && vlan_id == 0) return 0; -@@ -346,12 +352,12 @@ hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) - * vlan list. The vlan id in vlan list will be writen in vlan filter +@@ -343,15 +349,15 @@ hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on) + * When port base vlan enabled, we use port base vlan as the vlan + * filter condition. In this case, we don't update vlan filter table + * when user add new vlan or remove exist vlan, just update the +- * vlan list. The vlan id in vlan list will be writen in vlan filter ++ * vlan list. The vlan id in vlan list will be written in vlan filter * table until port base vlan disabled */ - if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) { @@ -32530,7 +48325,17 @@ index 72315718a8..66be58dc26 100644 rxvlan_cfg.strip_tag1_en = false; rxvlan_cfg.strip_tag2_en = enable; } else { -@@ -550,7 +555,7 @@ hns3_set_vlan_filter_ctrl(struct hns3_hw *hw, uint8_t vlan_type, +@@ -518,7 +523,8 @@ hns3_en_hw_strip_rxvtag(struct hns3_adapter *hns, bool enable) + + ret = hns3_set_vlan_rx_offload_cfg(hns, &rxvlan_cfg); + if (ret) { +- hns3_err(hw, "enable strip rx vtag failed, ret =%d", ret); ++ hns3_err(hw, "%s strip rx vtag failed, ret = %d.", ++ enable ? "enable" : "disable", ret); + return ret; + } + +@@ -550,7 +556,7 @@ hns3_set_vlan_filter_ctrl(struct hns3_hw *hw, uint8_t vlan_type, } static int @@ -32539,7 +48344,7 @@ index 72315718a8..66be58dc26 100644 { struct hns3_hw *hw = &hns->hw; int ret; -@@ -558,14 +563,29 @@ hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable) +@@ -558,14 +564,29 @@ hns3_enable_vlan_filter(struct hns3_adapter *hns, bool enable) ret = hns3_set_vlan_filter_ctrl(hw, HNS3_FILTER_TYPE_VF, HNS3_FILTER_FE_EGRESS, false, 0); if (ret) { @@ -32571,7 +48376,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -583,6 +603,23 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -583,6 +604,23 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) rte_spinlock_lock(&hw->lock); rxmode = &dev->data->dev_conf.rxmode; tmp_mask = (unsigned int)mask; @@ -32595,7 +48400,7 @@ index 72315718a8..66be58dc26 100644 if (tmp_mask & ETH_VLAN_STRIP_MASK) { /* Enable or disable VLAN stripping */ enable = rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP ? -@@ -591,7 +628,8 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -591,7 +629,8 @@ hns3_vlan_offload_set(struct rte_eth_dev *dev, int mask) ret = hns3_en_hw_strip_rxvtag(hns, enable); if (ret) { rte_spinlock_unlock(&hw->lock); @@ -32605,7 +48410,7 @@ index 72315718a8..66be58dc26 100644 return ret; } } -@@ -683,16 +721,6 @@ hns3_vlan_txvlan_cfg(struct hns3_adapter *hns, uint16_t port_base_vlan_state, +@@ -683,16 +722,6 @@ hns3_vlan_txvlan_cfg(struct hns3_adapter *hns, uint16_t port_base_vlan_state, return ret; } @@ -32622,7 +48427,7 @@ index 72315718a8..66be58dc26 100644 static void hns3_rm_all_vlan_table(struct hns3_adapter *hns, bool is_del_list) -@@ -701,10 +729,10 @@ hns3_rm_all_vlan_table(struct hns3_adapter *hns, bool is_del_list) +@@ -701,10 +730,10 @@ hns3_rm_all_vlan_table(struct hns3_adapter *hns, bool is_del_list) struct hns3_pf *pf = &hns->pf; LIST_FOREACH(vlan_entry, &pf->vlan_list, next) { @@ -32636,7 +48441,7 @@ index 72315718a8..66be58dc26 100644 } if (is_del_list) { -@@ -724,10 +752,10 @@ hns3_add_all_vlan_table(struct hns3_adapter *hns) +@@ -724,10 +753,10 @@ hns3_add_all_vlan_table(struct hns3_adapter *hns) struct hns3_pf *pf = &hns->pf; LIST_FOREACH(vlan_entry, &pf->vlan_list, next) { @@ -32650,7 +48455,7 @@ index 72315718a8..66be58dc26 100644 } } -@@ -735,13 +763,12 @@ static void +@@ -735,13 +764,12 @@ static void hns3_remove_all_vlan_table(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; @@ -32666,7 +48471,7 @@ index 72315718a8..66be58dc26 100644 if (ret) { hns3_err(hw, "Failed to remove all vlan table, ret =%d", ret); -@@ -752,63 +779,66 @@ hns3_remove_all_vlan_table(struct hns3_adapter *hns) +@@ -752,63 +780,66 @@ hns3_remove_all_vlan_table(struct hns3_adapter *hns) static int hns3_update_vlan_filter_entries(struct hns3_adapter *hns, @@ -32760,7 +48565,7 @@ index 72315718a8..66be58dc26 100644 hns3_update_rx_offload_cfg(hns, &rx_vlan_cfg); return ret; -@@ -817,17 +847,15 @@ hns3_en_rx_strip_all(struct hns3_adapter *hns, int on) +@@ -817,17 +848,15 @@ hns3_en_rx_strip_all(struct hns3_adapter *hns, int on) static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) { @@ -32768,7 +48573,8 @@ index 72315718a8..66be58dc26 100644 struct hns3_hw *hw = &hns->hw; uint16_t port_base_vlan_state; - uint16_t old_pvid; - int ret; +- int ret; ++ int ret, err; - if (on == 0 && pvid != pf->port_base_vlan_cfg.pvid) { - if (pf->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) @@ -32781,7 +48587,7 @@ index 72315718a8..66be58dc26 100644 return 0; } -@@ -835,29 +863,30 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) +@@ -835,29 +864,44 @@ hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on) HNS3_PORT_BASE_VLAN_DISABLE; ret = hns3_vlan_txvlan_cfg(hns, port_base_vlan_state, pvid); if (ret) { @@ -32795,9 +48601,10 @@ index 72315718a8..66be58dc26 100644 + ret = hns3_en_pvid_strip(hns, on); if (ret) { - hns3_err(hw, "Failed to config rx vlan strip, ret =%d", ret); +- return ret; + hns3_err(hw, "failed to config rx vlan strip for pvid, " + "ret = %d", ret); - return ret; ++ goto pvid_vlan_strip_fail; } - if (pvid == HNS3_INVLID_PVID) @@ -32811,17 +48618,32 @@ index 72315718a8..66be58dc26 100644 - hns3_err(hw, "Failed to update vlan filter entries, ret =%d", + hns3_err(hw, "failed to update vlan filter entries, ret = %d", ret); - return ret; +- return ret; ++ goto vlan_filter_set_fail; } out: - hns3_store_port_base_vlan_info(hns, pvid, on); + hw->port_base_vlan_cfg.state = port_base_vlan_state; + hw->port_base_vlan_cfg.pvid = on ? pvid : HNS3_INVALID_PVID; ++ return ret; ++ ++vlan_filter_set_fail: ++ err = hns3_en_pvid_strip(hns, hw->port_base_vlan_cfg.state == ++ HNS3_PORT_BASE_VLAN_ENABLE); ++ if (err) ++ hns3_err(hw, "fail to rollback pvid strip, ret = %d", err); ++ ++pvid_vlan_strip_fail: ++ err = hns3_vlan_txvlan_cfg(hns, hw->port_base_vlan_cfg.state, ++ hw->port_base_vlan_cfg.pvid); ++ if (err) ++ hns3_err(hw, "fail to rollback txvlan status, ret = %d", err); ++ return ret; } -@@ -866,22 +895,37 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) +@@ -866,22 +910,37 @@ hns3_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; @@ -32868,7 +48690,7 @@ index 72315718a8..66be58dc26 100644 } static int -@@ -890,7 +934,13 @@ hns3_default_vlan_config(struct hns3_adapter *hns) +@@ -890,7 +949,13 @@ hns3_default_vlan_config(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; int ret; @@ -32883,7 +48705,7 @@ index 72315718a8..66be58dc26 100644 if (ret) hns3_err(hw, "default vlan 0 config failed, ret =%d", ret); return ret; -@@ -909,10 +959,12 @@ hns3_init_vlan_config(struct hns3_adapter *hns) +@@ -909,10 +974,12 @@ hns3_init_vlan_config(struct hns3_adapter *hns) * ensure that the hardware configuration remains unchanged before and * after reset. */ @@ -32899,7 +48721,7 @@ index 72315718a8..66be58dc26 100644 if (ret) { hns3_err(hw, "vlan init fail in pf, ret =%d", ret); return ret; -@@ -932,7 +984,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) +@@ -932,7 +999,7 @@ hns3_init_vlan_config(struct hns3_adapter *hns) * and hns3_restore_vlan_conf later. */ if (rte_atomic16_read(&hw->reset.resetting) == 0) { @@ -32908,7 +48730,7 @@ index 72315718a8..66be58dc26 100644 if (ret) { hns3_err(hw, "pvid set fail in pf, ret =%d", ret); return ret; -@@ -954,17 +1006,31 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns) +@@ -954,17 +1021,31 @@ hns3_restore_vlan_conf(struct hns3_adapter *hns) { struct hns3_pf *pf = &hns->pf; struct hns3_hw *hw = &hns->hw; @@ -32942,7 +48764,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -976,6 +1042,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) +@@ -976,6 +1057,7 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) struct rte_eth_dev_data *data = dev->data; struct rte_eth_txmode *txmode; struct hns3_hw *hw = &hns->hw; @@ -32950,7 +48772,7 @@ index 72315718a8..66be58dc26 100644 int ret; txmode = &data->dev_conf.txmode; -@@ -989,17 +1056,26 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) +@@ -989,17 +1071,26 @@ hns3_dev_configure_vlan(struct rte_eth_dev *dev) txmode->hw_vlan_reject_untagged); /* Apply vlan offload setting */ @@ -32980,25 +48802,127 @@ index 72315718a8..66be58dc26 100644 txmode->pvid, ret); return ret; -@@ -1335,7 +1411,7 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) - struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); - struct hns3_mac_vlan_tbl_entry_cmd req; - struct hns3_pf *pf = &hns->pf; -- struct hns3_cmd_desc desc; -+ struct hns3_cmd_desc desc[3]; - char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; - uint16_t egress_port = 0; - uint8_t vf_id; -@@ -1370,7 +1446,7 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +@@ -1222,28 +1313,31 @@ hns3_get_mac_vlan_cmd_status(struct hns3_hw *hw, uint16_t cmdq_resp, + static int + hns3_lookup_mac_vlan_tbl(struct hns3_hw *hw, + struct hns3_mac_vlan_tbl_entry_cmd *req, +- struct hns3_cmd_desc *desc, bool is_mc) ++ struct hns3_cmd_desc *desc, uint8_t desc_num) + { + uint8_t resp_code; + uint16_t retval; + int ret; ++ int i; + +- hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_MAC_VLAN_ADD, true); +- if (is_mc) { +- desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- memcpy(desc[0].data, req, +- sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); +- hns3_cmd_setup_basic_desc(&desc[1], HNS3_OPC_MAC_VLAN_ADD, +- true); +- desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- hns3_cmd_setup_basic_desc(&desc[2], HNS3_OPC_MAC_VLAN_ADD, ++ if (desc_num == HNS3_MC_MAC_VLAN_OPS_DESC_NUM) { ++ for (i = 0; i < desc_num - 1; i++) { ++ hns3_cmd_setup_basic_desc(&desc[i], ++ HNS3_OPC_MAC_VLAN_ADD, true); ++ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ if (i == 0) ++ memcpy(desc[i].data, req, ++ sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); ++ } ++ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_MAC_VLAN_ADD, + true); +- ret = hns3_cmd_send(hw, desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM); + } else { ++ hns3_cmd_setup_basic_desc(&desc[0], HNS3_OPC_MAC_VLAN_ADD, ++ true); + memcpy(desc[0].data, req, + sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); +- ret = hns3_cmd_send(hw, desc, 1); + } ++ ret = hns3_cmd_send(hw, desc, desc_num); + if (ret) { + hns3_err(hw, "lookup mac addr failed for cmd_send, ret =%d.", + ret); +@@ -1259,38 +1353,40 @@ hns3_lookup_mac_vlan_tbl(struct hns3_hw *hw, + static int + hns3_add_mac_vlan_tbl(struct hns3_hw *hw, + struct hns3_mac_vlan_tbl_entry_cmd *req, +- struct hns3_cmd_desc *mc_desc) ++ struct hns3_cmd_desc *desc, uint8_t desc_num) + { + uint8_t resp_code; + uint16_t retval; + int cfg_status; + int ret; ++ int i; + +- if (mc_desc == NULL) { +- struct hns3_cmd_desc desc; +- +- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_MAC_VLAN_ADD, false); +- memcpy(desc.data, req, ++ if (desc_num == HNS3_UC_MAC_VLAN_OPS_DESC_NUM) { ++ hns3_cmd_setup_basic_desc(desc, HNS3_OPC_MAC_VLAN_ADD, false); ++ memcpy(desc->data, req, + sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); +- ret = hns3_cmd_send(hw, &desc, 1); +- resp_code = (rte_le_to_cpu_32(desc.data[0]) >> 8) & 0xff; +- retval = rte_le_to_cpu_16(desc.retval); ++ ret = hns3_cmd_send(hw, desc, desc_num); ++ resp_code = (rte_le_to_cpu_32(desc->data[0]) >> 8) & 0xff; ++ retval = rte_le_to_cpu_16(desc->retval); + + cfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code, + HNS3_MAC_VLAN_ADD); + } else { +- hns3_cmd_reuse_desc(&mc_desc[0], false); +- mc_desc[0].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- hns3_cmd_reuse_desc(&mc_desc[1], false); +- mc_desc[1].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); +- hns3_cmd_reuse_desc(&mc_desc[2], false); +- mc_desc[2].flag &= rte_cpu_to_le_16(~HNS3_CMD_FLAG_NEXT); +- memcpy(mc_desc[0].data, req, ++ for (i = 0; i < desc_num; i++) { ++ hns3_cmd_reuse_desc(&desc[i], false); ++ if (i == desc_num - 1) ++ desc[i].flag &= ++ rte_cpu_to_le_16(~HNS3_CMD_FLAG_NEXT); ++ else ++ desc[i].flag |= ++ rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT); ++ } ++ memcpy(desc[0].data, req, + sizeof(struct hns3_mac_vlan_tbl_entry_cmd)); +- mc_desc[0].retval = 0; +- ret = hns3_cmd_send(hw, mc_desc, HNS3_MC_MAC_VLAN_ADD_DESC_NUM); +- resp_code = (rte_le_to_cpu_32(mc_desc[0].data[0]) >> 8) & 0xff; +- retval = rte_le_to_cpu_16(mc_desc[0].retval); ++ desc[0].retval = 0; ++ ret = hns3_cmd_send(hw, desc, desc_num); ++ resp_code = (rte_le_to_cpu_32(desc[0].data[0]) >> 8) & 0xff; ++ retval = rte_le_to_cpu_16(desc[0].retval); + + cfg_status = hns3_get_mac_vlan_cmd_status(hw, retval, resp_code, + HNS3_MAC_VLAN_ADD); +@@ -1370,10 +1466,12 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) * it if the entry is inexistent. Repeated unicast entry * is not allowed in the mac vlan table. */ - ret = hns3_lookup_mac_vlan_tbl(hw, &req, &desc, false); -+ ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, false); ++ ret = hns3_lookup_mac_vlan_tbl(hw, &req, &desc, ++ HNS3_UC_MAC_VLAN_OPS_DESC_NUM); if (ret == -ENOENT) { if (!hns3_is_umv_space_full(hw)) { - ret = hns3_add_mac_vlan_tbl(hw, &req, NULL); -@@ -1398,6 +1474,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +- ret = hns3_add_mac_vlan_tbl(hw, &req, NULL); ++ ret = hns3_add_mac_vlan_tbl(hw, &req, &desc, ++ HNS3_UC_MAC_VLAN_OPS_DESC_NUM); + if (!ret) + hns3_update_umv_space(hw, false); + return ret; +@@ -1398,26 +1496,86 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) return ret; } @@ -33051,8 +48975,11 @@ index 72315718a8..66be58dc26 100644 + static int hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, - uint32_t idx, __attribute__ ((unused)) uint32_t pool) -@@ -1407,12 +1530,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, +- uint32_t idx, __attribute__ ((unused)) uint32_t pool) ++ __rte_unused uint32_t idx, __rte_unused uint32_t pool) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; int ret; rte_spinlock_lock(&hw->lock); @@ -33082,7 +49009,12 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -1434,7 +1572,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +- if (idx == 0) +- hw->mac.default_addr_setted = true; + rte_spinlock_unlock(&hw->lock); + + return ret; +@@ -1434,7 +1592,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) if (!rte_is_valid_assigned_ether_addr(mac_addr)) { rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); @@ -33091,7 +49023,7 @@ index 72315718a8..66be58dc26 100644 mac_str); return -EINVAL; } -@@ -1461,18 +1599,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) +@@ -1461,18 +1619,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) int ret; rte_spinlock_lock(&hw->lock); @@ -33118,7 +49050,83 @@ index 72315718a8..66be58dc26 100644 } static int -@@ -1573,19 +1711,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del) +@@ -1482,35 +1640,18 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_ether_addr *oaddr; + char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; +- bool default_addr_setted; +- bool rm_succes = false; + int ret, ret_val; + +- /* check if mac addr is valid */ +- if (!rte_is_valid_assigned_ether_addr(mac_addr)) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, +- mac_addr); +- hns3_err(hw, "Failed to set mac addr, addr(%s) invalid", +- mac_str); +- return -EINVAL; +- } +- +- oaddr = (struct rte_ether_addr *)hw->mac.mac_addr; +- default_addr_setted = hw->mac.default_addr_setted; +- if (default_addr_setted && !!rte_is_same_ether_addr(mac_addr, oaddr)) +- return 0; +- + rte_spinlock_lock(&hw->lock); +- if (default_addr_setted) { +- ret = hns3_remove_uc_addr_common(hw, oaddr); +- if (ret) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, +- oaddr); +- hns3_warn(hw, "Remove old uc mac address(%s) fail: %d", +- mac_str, ret); +- rm_succes = false; +- } else +- rm_succes = true; ++ oaddr = (struct rte_ether_addr *)hw->mac.mac_addr; ++ ret = hns3_remove_uc_addr_common(hw, oaddr); ++ if (ret) { ++ rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ oaddr); ++ hns3_warn(hw, "Remove old uc mac address(%s) fail: %d", ++ mac_str, ret); ++ rte_spinlock_unlock(&hw->lock); ++ return ret; + } + + ret = hns3_add_uc_addr_common(hw, mac_addr); +@@ -1529,7 +1670,6 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + + rte_ether_addr_copy(mac_addr, + (struct rte_ether_addr *)hw->mac.mac_addr); +- hw->mac.default_addr_setted = true; + rte_spinlock_unlock(&hw->lock); + + return 0; +@@ -1545,16 +1685,12 @@ hns3_set_default_mac_addr(struct rte_eth_dev *dev, + } + + err_add_uc_addr: +- if (rm_succes) { +- ret_val = hns3_add_uc_addr_common(hw, oaddr); +- if (ret_val) { +- rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, +- oaddr); +- hns3_warn(hw, +- "Failed to restore old uc mac addr(%s): %d", +- mac_str, ret_val); +- hw->mac.default_addr_setted = false; +- } ++ ret_val = hns3_add_uc_addr_common(hw, oaddr); ++ if (ret_val) { ++ rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, ++ oaddr); ++ hns3_warn(hw, "Failed to restore old uc mac addr(%s): %d", ++ mac_str, ret_val); + } + rte_spinlock_unlock(&hw->lock); + +@@ -1573,19 +1709,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del) for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) { addr = &hw->data->mac_addrs[i]; @@ -33148,7 +49156,17 @@ index 72315718a8..66be58dc26 100644 } } return err; -@@ -1632,7 +1773,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +@@ -1622,8 +1761,8 @@ hns3_update_desc_vfid(struct hns3_cmd_desc *desc, uint8_t vfid, bool clr) + static int + hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + { ++ struct hns3_cmd_desc desc[HNS3_MC_MAC_VLAN_OPS_DESC_NUM]; + struct hns3_mac_vlan_tbl_entry_cmd req; +- struct hns3_cmd_desc desc[3]; + char mac_str[RTE_ETHER_ADDR_FMT_SIZE]; + uint8_t vf_id; + int ret; +@@ -1632,7 +1771,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) if (!rte_is_multicast_ether_addr(mac_addr)) { rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); @@ -33157,7 +49175,25 @@ index 72315718a8..66be58dc26 100644 mac_str); return -EINVAL; } -@@ -1661,7 +1802,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) +@@ -1640,7 +1779,8 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + memset(&req, 0, sizeof(req)); + hns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0); + hns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true); +- ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true); ++ ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, ++ HNS3_MC_MAC_VLAN_OPS_DESC_NUM); + if (ret) { + /* This mac addr do not exist, add new entry for it */ + memset(desc[0].data, 0, sizeof(desc[0].data)); +@@ -1655,13 +1795,14 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + */ + vf_id = 0; + hns3_update_desc_vfid(desc, vf_id, false); +- ret = hns3_add_mac_vlan_tbl(hw, &req, desc); ++ ret = hns3_add_mac_vlan_tbl(hw, &req, desc, ++ HNS3_MC_MAC_VLAN_OPS_DESC_NUM); + if (ret) { + if (ret == -ENOSPC) hns3_err(hw, "mc mac vlan table is full"); rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, mac_addr); @@ -33166,7 +49202,17 @@ index 72315718a8..66be58dc26 100644 } return ret; -@@ -1726,7 +1867,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, +@@ -1688,7 +1829,8 @@ hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr) + memset(&req, 0, sizeof(req)); + hns3_set_bit(req.entry_type, HNS3_MAC_VLAN_BIT0_EN_B, 0); + hns3_prepare_mac_addr(&req, mac_addr->addr_bytes, true); +- ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, true); ++ ret = hns3_lookup_mac_vlan_tbl(hw, &req, desc, ++ HNS3_MC_MAC_VLAN_OPS_DESC_NUM); + if (ret == 0) { + /* + * This mac addr exist, remove this handle's VFID for it. +@@ -1726,7 +1868,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, uint32_t j; if (nb_mc_addr > HNS3_MC_MACADDR_NUM) { @@ -33175,7 +49221,7 @@ index 72315718a8..66be58dc26 100644 "invalid. valid range: 0~%d", nb_mc_addr, HNS3_MC_MACADDR_NUM); return -EINVAL; -@@ -1739,7 +1880,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, +@@ -1739,7 +1881,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); hns3_err(hw, @@ -33184,7 +49230,7 @@ index 72315718a8..66be58dc26 100644 mac_str); return -EINVAL; } -@@ -1750,12 +1891,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, +@@ -1750,12 +1892,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw, rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr); @@ -33216,10 +49262,48 @@ index 72315718a8..66be58dc26 100644 } return 0; -@@ -2021,37 +2180,143 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev) - return hns3_check_mq_mode(dev); - } +@@ -1942,24 +2102,17 @@ hns3_check_mq_mode(struct rte_eth_dev *dev) + int max_tc = 0; + int i; + +- dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; +- dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; +- +- if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB_RSS) { +- hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB_RSS is not supported. " +- "rx_mq_mode = %d", rx_mq_mode); +- return -EINVAL; +- } +- +- if (rx_mq_mode == ETH_MQ_RX_VMDQ_DCB || +- tx_mq_mode == ETH_MQ_TX_VMDQ_DCB) { +- hns3_err(hw, "ETH_MQ_RX_VMDQ_DCB and ETH_MQ_TX_VMDQ_DCB " +- "is not supported. rx_mq_mode = %d, tx_mq_mode = %d", ++ if ((rx_mq_mode & ETH_MQ_RX_VMDQ_FLAG) || ++ (tx_mq_mode == ETH_MQ_TX_VMDQ_DCB || ++ tx_mq_mode == ETH_MQ_TX_VMDQ_ONLY)) { ++ hns3_err(hw, "VMDQ is not supported, rx_mq_mode = %d, tx_mq_mode = %d.", + rx_mq_mode, tx_mq_mode); +- return -EINVAL; ++ return -EOPNOTSUPP; + } +- if (rx_mq_mode == ETH_MQ_RX_DCB_RSS) { ++ dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; ++ dcb_tx_conf = &dev->data->dev_conf.tx_adv_conf.dcb_tx_conf; ++ if (rx_mq_mode & ETH_MQ_RX_DCB_FLAG) { + if (dcb_rx_conf->nb_tcs > pf->tc_max) { + hns3_err(hw, "nb_tcs(%u) > max_tc(%u) driver supported.", + dcb_rx_conf->nb_tcs, pf->tc_max); +@@ -2017,41 +2170,183 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev) + return -EOPNOTSUPP; + } + +- /* Check multiple queue mode */ +- return hns3_check_mq_mode(dev); ++ return 0; ++} ++ +static int +hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap, + enum hns3_ring_type queue_type, uint16_t queue_id) @@ -33319,6 +49403,41 @@ index 72315718a8..66be58dc26 100644 + return 0; +} + ++static int ++hns3_refresh_mtu(struct rte_eth_dev *dev, struct rte_eth_conf *conf) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ uint32_t max_rx_pkt_len; ++ uint16_t mtu; ++ int ret; ++ ++ if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)) ++ return 0; ++ ++ /* ++ * If jumbo frames are enabled, MTU needs to be refreshed ++ * according to the maximum RX packet length. ++ */ ++ max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; ++ if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || ++ max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { ++ hns3_err(hw, "maximum Rx packet length must be greater than %u " ++ "and no more than %u when jumbo frame enabled.", ++ (uint16_t)HNS3_DEFAULT_FRAME_LEN, ++ (uint16_t)HNS3_MAX_FRAME_LEN); ++ return -EINVAL; ++ } ++ ++ mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); ++ ret = hns3_dev_mtu_set(dev, mtu); ++ if (ret) ++ return ret; ++ dev->data->mtu = mtu; ++ ++ return 0; + } + static int hns3_dev_configure(struct rte_eth_dev *dev) { @@ -33332,8 +49451,7 @@ index 72315718a8..66be58dc26 100644 uint16_t nb_rx_q = dev->data->nb_rx_queues; uint16_t nb_tx_q = dev->data->nb_tx_queues; struct rte_eth_rss_conf rss_conf; -+ uint32_t max_rx_pkt_len; - uint16_t mtu; +- uint16_t mtu; int ret; /* @@ -33369,10 +49487,14 @@ index 72315718a8..66be58dc26 100644 } - hw->adapter_state = HNS3_NIC_CONFIGURING; ++ ret = hns3_check_mq_mode(dev); ++ if (ret) ++ goto cfg_err; ++ if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) { ret = hns3_check_dcb_cfg(dev); if (ret) -@@ -2060,7 +2325,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) +@@ -2060,7 +2355,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) /* When RSS is not configured, redirect the packet queue 0 */ if ((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) { @@ -33382,32 +49504,33 @@ index 72315718a8..66be58dc26 100644 if (rss_conf.rss_key == NULL) { rss_conf.rss_key = rss_cfg->key; rss_conf.rss_key_len = HNS3_RSS_KEY_SIZE; -@@ -2076,12 +2343,18 @@ hns3_dev_configure(struct rte_eth_dev *dev) - * according to the maximum RX packet length. - */ - if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { +@@ -2071,22 +2368,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) + goto cfg_err; + } + +- /* +- * If jumbo frames are enabled, MTU needs to be refreshed +- * according to the maximum RX packet length. +- */ +- if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { - /* - * Security of max_rx_pkt_len is guaranteed in dpdk frame. - * Maximum value of max_rx_pkt_len is HNS3_MAX_FRAME_LEN, so it - * can safely assign to "uint16_t" type variable. - */ - mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(conf->rxmode.max_rx_pkt_len); -+ max_rx_pkt_len = conf->rxmode.max_rx_pkt_len; -+ if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN || -+ max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) { -+ hns3_err(hw, "maximum Rx packet length must be greater " -+ "than %u and less than %u when jumbo frame enabled.", -+ (uint16_t)HNS3_DEFAULT_FRAME_LEN, -+ (uint16_t)HNS3_MAX_FRAME_LEN); -+ ret = -EINVAL; -+ goto cfg_err; -+ } -+ -+ mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len); - ret = hns3_dev_mtu_set(dev, mtu); - if (ret) - goto cfg_err; -@@ -2097,7 +2370,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) +- ret = hns3_dev_mtu_set(dev, mtu); +- if (ret) +- goto cfg_err; +- dev->data->mtu = mtu; +- } ++ ret = hns3_refresh_mtu(dev, conf); ++ if (ret) ++ goto cfg_err; + + ret = hns3_dev_configure_vlan(dev); + if (ret) +@@ -2097,7 +2381,9 @@ hns3_dev_configure(struct rte_eth_dev *dev) return 0; cfg_err: @@ -33417,7 +49540,43 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -2152,7 +2427,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -2119,21 +2405,32 @@ hns3_set_mac_mtu(struct hns3_hw *hw, uint16_t new_mps) + static int + hns3_config_mtu(struct hns3_hw *hw, uint16_t mps) + { ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ int err; + int ret; + + ret = hns3_set_mac_mtu(hw, mps); + if (ret) { +- hns3_err(hw, "Failed to set mtu, ret = %d", ret); ++ hns3_err(hw, "failed to set mtu, ret = %d", ret); + return ret; + } + + ret = hns3_buffer_alloc(hw); + if (ret) { +- hns3_err(hw, "Failed to allocate buffer, ret = %d", ret); +- return ret; ++ hns3_err(hw, "failed to allocate buffer, ret = %d", ret); ++ goto rollback; + } + ++ hns->pf.mps = mps; ++ + return 0; ++ ++rollback: ++ err = hns3_set_mac_mtu(hw, hns->pf.mps); ++ if (err) ++ hns3_err(hw, "fail to rollback MTU, err = %d", err); ++ ++ return ret; + } + + static int +@@ -2152,7 +2449,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) } rte_spinlock_lock(&hw->lock); @@ -33426,20 +49585,29 @@ index 72315718a8..66be58dc26 100644 frame_size = RTE_MAX(frame_size, HNS3_DEFAULT_FRAME_LEN); /* -@@ -2184,11 +2459,19 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -2166,7 +2463,7 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) + dev->data->port_id, mtu, ret); + return ret; + } +- hns->pf.mps = (uint16_t)frame_size; ++ + if (is_jumbo_frame) + dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_JUMBO_FRAME; +@@ -2184,11 +2481,19 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) { struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; + uint16_t queue_num = hw->tqps_num; -+ + +- info->max_rx_queues = hw->tqps_num; + /* + * In interrupt mode, 'max_rx_queues' is set based on the number of + * MSI-X interrupt resources of the hardware. + */ + if (hw->data->dev_conf.intr_conf.rxq == 1) + queue_num = hw->intr_tqps_num; - -- info->max_rx_queues = hw->tqps_num; ++ + info->max_rx_queues = queue_num; info->max_tx_queues = hw->tqps_num; info->max_rx_pktlen = HNS3_MAX_FRAME_LEN; /* CRC included */ @@ -33448,7 +49616,7 @@ index 72315718a8..66be58dc26 100644 info->max_mac_addrs = HNS3_UC_MACADDR_NUM; info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD; info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM | -@@ -2200,11 +2483,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -2200,11 +2505,9 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_RX_OFFLOAD_KEEP_CRC | DEV_RX_OFFLOAD_SCATTER | DEV_RX_OFFLOAD_VLAN_STRIP | @@ -33462,7 +49630,7 @@ index 72315718a8..66be58dc26 100644 info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_TCP_CKSUM | -@@ -2213,7 +2494,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -2213,7 +2516,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT | DEV_TX_OFFLOAD_MULTI_SEGS | @@ -33471,10 +49639,12 @@ index 72315718a8..66be58dc26 100644 info->rx_desc_lim = (struct rte_eth_desc_lim) { .nb_max = HNS3_MAX_RING_DESC, -@@ -2227,6 +2508,17 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -2227,8 +2530,17 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) .nb_align = HNS3_ALIGN_RING_DESC, }; +- info->vmdq_queue_num = 0; +- + info->default_rxconf = (struct rte_eth_rxconf) { + .rx_free_thresh = HNS3_DEFAULT_RX_FREE_THRESH, + /* @@ -33486,10 +49656,10 @@ index 72315718a8..66be58dc26 100644 + .offloads = 0, + }; + - info->vmdq_queue_num = 0; - info->reta_size = HNS3_RSS_IND_TBL_SIZE; -@@ -2268,6 +2560,11 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, + info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; +@@ -2268,6 +2580,11 @@ hns3_dev_link_update(struct rte_eth_dev *eth_dev, struct hns3_mac *mac = &hw->mac; struct rte_eth_link new_link; @@ -33501,7 +49671,7 @@ index 72315718a8..66be58dc26 100644 memset(&new_link, 0, sizeof(new_link)); switch (mac->link_speed) { case ETH_SPEED_NUM_10M: -@@ -2358,6 +2655,7 @@ hns3_query_pf_resource(struct hns3_hw *hw) +@@ -2358,6 +2675,7 @@ hns3_query_pf_resource(struct hns3_hw *hw) hw->total_tqps_num = rte_le_to_cpu_16(req->tqp_num); pf->pkt_buf_size = rte_le_to_cpu_16(req->buf_size) << HNS3_BUF_UNIT_S; hw->tqps_num = RTE_MIN(hw->total_tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); @@ -33509,7 +49679,7 @@ index 72315718a8..66be58dc26 100644 if (req->tx_buf_size) pf->tx_buf_size = -@@ -2377,7 +2675,7 @@ hns3_query_pf_resource(struct hns3_hw *hw) +@@ -2377,7 +2695,7 @@ hns3_query_pf_resource(struct hns3_hw *hw) hw->num_msi = hns3_get_field(rte_le_to_cpu_16(req->pf_intr_vector_number), @@ -33518,7 +49688,16 @@ index 72315718a8..66be58dc26 100644 return 0; } -@@ -2534,7 +2832,7 @@ hns3_get_board_configuration(struct hns3_hw *hw) +@@ -2393,8 +2711,6 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) + req = (struct hns3_cfg_param_cmd *)desc[0].data; + + /* get the configuration */ +- cfg->vmdq_vport_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), +- HNS3_CFG_VMDQ_M, HNS3_CFG_VMDQ_S); + cfg->tc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), + HNS3_CFG_TC_NUM_M, HNS3_CFG_TC_NUM_S); + cfg->tqp_desc_num = hns3_get_field(rte_le_to_cpu_32(req->param[0]), +@@ -2534,10 +2850,9 @@ hns3_get_board_configuration(struct hns3_hw *hw) hw->mac.media_type = cfg.media_type; hw->rss_size_max = cfg.rss_size_max; @@ -33526,8 +49705,22 @@ index 72315718a8..66be58dc26 100644 + hw->rss_dis_flag = false; memcpy(hw->mac.mac_addr, cfg.mac_addr, RTE_ETHER_ADDR_LEN); hw->mac.phy_addr = cfg.phy_addr; - hw->mac.default_addr_setted = false; -@@ -2634,6 +2932,7 @@ hns3_map_tqp(struct hns3_hw *hw) +- hw->mac.default_addr_setted = false; + hw->num_tx_desc = cfg.tqp_desc_num; + hw->num_rx_desc = cfg.tqp_desc_num; + hw->dcb_info.num_pg = 1; +@@ -2587,6 +2902,10 @@ hns3_get_configuration(struct hns3_hw *hw) + return ret; + } + ++ ret = hns3_query_mac_stats_reg_num(hw); ++ if (ret) ++ return ret; ++ + /* Get pf resource */ + ret = hns3_query_pf_resource(hw); + if (ret) { +@@ -2634,6 +2953,7 @@ hns3_map_tqp(struct hns3_hw *hw) uint16_t tqps_num = hw->total_tqps_num; uint16_t func_id; uint16_t tqp_id; @@ -33535,7 +49728,7 @@ index 72315718a8..66be58dc26 100644 int num; int ret; int i; -@@ -2645,10 +2944,11 @@ hns3_map_tqp(struct hns3_hw *hw) +@@ -2645,10 +2965,11 @@ hns3_map_tqp(struct hns3_hw *hw) tqp_id = 0; num = DIV_ROUND_UP(hw->total_tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); for (func_id = 0; func_id < num; func_id++) { @@ -33548,7 +49741,18 @@ index 72315718a8..66be58dc26 100644 if (ret) return ret; } -@@ -3415,6 +3715,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code) +@@ -3135,8 +3456,8 @@ hns3_rx_buffer_calc(struct hns3_hw *hw, struct hns3_pkt_buf_alloc *buf_alloc) + * For different application scenes, the enabled port number, TC number + * and no_drop TC number are different. In order to obtain the better + * performance, software could allocate the buffer size and configure +- * the waterline by tring to decrease the private buffer size according +- * to the order, namely, waterline of valided tc, pfc disabled tc, pfc ++ * the waterline by trying to decrease the private buffer size according ++ * to the order, namely, waterline of valid tc, pfc disabled tc, pfc + * enabled tc. + */ + if (hns3_rx_buf_calc_all(hw, false, buf_alloc)) +@@ -3415,6 +3736,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code) "add mac ethertype failed for undefined, code=%d.", resp_code); return_status = -EIO; @@ -33556,7 +49760,7 @@ index 72315718a8..66be58dc26 100644 } return return_status; -@@ -3521,7 +3822,7 @@ hns3_cmd_set_promisc_mode(struct hns3_hw *hw, struct hns3_promisc_param *param) +@@ -3521,7 +3843,7 @@ hns3_cmd_set_promisc_mode(struct hns3_hw *hw, struct hns3_promisc_param *param) ret = hns3_cmd_send(hw, &desc, 1); if (ret) @@ -33565,7 +49769,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -3549,19 +3850,104 @@ hns3_set_promisc_mode(struct hns3_hw *hw, bool en_uc_pmc, bool en_mc_pmc) +@@ -3549,19 +3871,104 @@ hns3_set_promisc_mode(struct hns3_hw *hw, bool en_uc_pmc, bool en_mc_pmc) return 0; } @@ -33674,7 +49878,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -3569,17 +3955,39 @@ hns3_dev_promiscuous_enable(struct rte_eth_dev *dev) +@@ -3569,17 +3976,39 @@ hns3_dev_promiscuous_enable(struct rte_eth_dev *dev) static int hns3_dev_promiscuous_disable(struct rte_eth_dev *dev) { @@ -33718,7 +49922,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -3589,14 +3997,17 @@ hns3_dev_allmulticast_enable(struct rte_eth_dev *dev) +@@ -3589,14 +4018,17 @@ hns3_dev_allmulticast_enable(struct rte_eth_dev *dev) { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; @@ -33739,7 +49943,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -3606,18 +4017,18 @@ hns3_dev_allmulticast_disable(struct rte_eth_dev *dev) +@@ -3606,18 +4038,18 @@ hns3_dev_allmulticast_disable(struct rte_eth_dev *dev) { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; @@ -33762,7 +49966,7 @@ index 72315718a8..66be58dc26 100644 return ret; } -@@ -3626,13 +4037,22 @@ static int +@@ -3626,13 +4058,22 @@ static int hns3_dev_promisc_restore(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; @@ -33790,7 +49994,7 @@ index 72315718a8..66be58dc26 100644 } static int -@@ -3671,6 +4091,7 @@ static int +@@ -3671,6 +4112,7 @@ static int hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) { struct hns3_mac *mac = &hw->mac; @@ -33798,7 +50002,7 @@ index 72315718a8..66be58dc26 100644 int ret; duplex = hns3_check_speed_dup(duplex, speed); -@@ -3682,6 +4103,13 @@ hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) +@@ -3682,6 +4124,13 @@ hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex) return ret; mac->link_speed = speed; @@ -33812,7 +50016,7 @@ index 72315718a8..66be58dc26 100644 mac->link_duplex = duplex; return 0; -@@ -3763,7 +4191,7 @@ hns3_get_mac_link_status(struct hns3_hw *hw) +@@ -3763,7 +4212,7 @@ hns3_get_mac_link_status(struct hns3_hw *hw) ret = hns3_cmd_send(hw, &desc, 1); if (ret) { hns3_err(hw, "get link status cmd failed %d", ret); @@ -33821,7 +50025,7 @@ index 72315718a8..66be58dc26 100644 } req = (struct hns3_link_status_cmd *)desc.data; -@@ -3772,14 +4200,16 @@ hns3_get_mac_link_status(struct hns3_hw *hw) +@@ -3772,14 +4221,16 @@ hns3_get_mac_link_status(struct hns3_hw *hw) return !!link_status; } @@ -33840,7 +50044,7 @@ index 72315718a8..66be58dc26 100644 } static void -@@ -3828,9 +4258,10 @@ hns3_init_hardware(struct hns3_adapter *hns) +@@ -3828,9 +4279,10 @@ hns3_init_hardware(struct hns3_adapter *hns) goto err_mac_init; } @@ -33853,7 +50057,7 @@ index 72315718a8..66be58dc26 100644 goto err_mac_init; } -@@ -3863,6 +4294,19 @@ hns3_init_hardware(struct hns3_adapter *hns) +@@ -3863,6 +4315,19 @@ hns3_init_hardware(struct hns3_adapter *hns) PMD_INIT_LOG(ERR, "Failed to config gro: %d", ret); goto err_mac_init; } @@ -33873,7 +50077,7 @@ index 72315718a8..66be58dc26 100644 return 0; err_mac_init: -@@ -3870,6 +4314,21 @@ hns3_init_hardware(struct hns3_adapter *hns) +@@ -3870,6 +4335,21 @@ hns3_init_hardware(struct hns3_adapter *hns) return ret; } @@ -33895,7 +50099,7 @@ index 72315718a8..66be58dc26 100644 static int hns3_init_pf(struct rte_eth_dev *eth_dev) { -@@ -3900,6 +4359,18 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) +@@ -3900,6 +4380,18 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_cmd_init; } @@ -33914,7 +50118,7 @@ index 72315718a8..66be58dc26 100644 ret = rte_intr_callback_register(&pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); -@@ -3953,13 +4424,10 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) +@@ -3953,13 +4445,10 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) rte_intr_disable(&pci_dev->intr_handle); hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, eth_dev); @@ -33929,7 +50133,7 @@ index 72315718a8..66be58dc26 100644 err_cmd_init_queue: hw->io_base = NULL; -@@ -3978,6 +4446,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) +@@ -3978,6 +4467,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) hns3_enable_hw_error_intr(hns, false); hns3_rss_uninit(hns); @@ -33937,7 +50141,7 @@ index 72315718a8..66be58dc26 100644 hns3_fdir_filter_uninit(hns); hns3_uninit_umv_space(hw); hns3_pf_disable_irq0(hw); -@@ -4020,15 +4489,116 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) +@@ -4020,15 +4510,116 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) } static int @@ -33953,8 +50157,8 @@ index 72315718a8..66be58dc26 100644 + uint8_t base = 0; + uint8_t vec = 0; + uint16_t q_id; - int ret; - ++ int ret; ++ + if (dev->data->dev_conf.intr_conf.rxq == 0) + return 0; + @@ -34019,8 +50223,8 @@ index 72315718a8..66be58dc26 100644 + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + uint16_t q_id; -+ int ret; -+ + int ret; + + if (dev->data->dev_conf.intr_conf.rxq == 0) + return 0; + @@ -34057,7 +50261,7 @@ index 72315718a8..66be58dc26 100644 rte_spinlock_lock(&hw->lock); hw->adapter_state = HNS3_NIC_STARTING; -@@ -4039,10 +4609,29 @@ hns3_dev_start(struct rte_eth_dev *eth_dev) +@@ -4039,10 +4630,29 @@ hns3_dev_start(struct rte_eth_dev *eth_dev) return ret; } @@ -34089,7 +50293,12 @@ index 72315718a8..66be58dc26 100644 hns3_info(hw, "hns3 dev start successful!"); return 0; -@@ -4070,27 +4659,65 @@ hns3_do_stop(struct hns3_adapter *hns) +@@ -4065,32 +4675,69 @@ hns3_do_stop(struct hns3_adapter *hns) + reset_queue = true; + } else + reset_queue = false; +- hw->mac.default_addr_setted = false; + return hns3_stop_queues(hns, reset_queue); } static void @@ -34146,7 +50355,8 @@ index 72315718a8..66be58dc26 100644 - hns3_mp_req_stop_rxtx(eth_dev); + hns3_mp_req_stop_rxtx(dev); /* Prevent crashes when queues are still in use. */ - rte_delay_ms(hw->tqps_num); +- rte_delay_ms(hw->tqps_num); ++ rte_delay_ms(hw->cfg_max_queues); rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { @@ -34159,7 +50369,16 @@ index 72315718a8..66be58dc26 100644 rte_spinlock_unlock(&hw->lock); } -@@ -4112,7 +4739,6 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) +@@ -4103,6 +4750,8 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; ++ __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ hns3_mp_uninit(); + return; + } + +@@ -4112,7 +4761,6 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) hw->adapter_state = HNS3_NIC_CLOSING; hns3_reset_abort(hns); hw->adapter_state = HNS3_NIC_CLOSED; @@ -34167,7 +50386,104 @@ index 72315718a8..66be58dc26 100644 hns3_configure_all_mc_mac_addr(hns, true); hns3_remove_all_vlan_table(hns); -@@ -4297,15 +4923,13 @@ hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info) +@@ -4122,7 +4770,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev) + rte_free(hw->reset.wait_data); + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; +- hns3_mp_uninit_primary(); ++ hns3_mp_uninit(); + hns3_warn(hw, "Close port %d finished", hw->data->port_id); + } + +@@ -4134,8 +4782,11 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + + fc_conf->pause_time = pf->pause_time; + +- /* return fc current mode */ +- switch (hw->current_mode) { ++ /* ++ * If fc auto-negotiation is not supported, the configured fc mode ++ * from user is the current fc mode. ++ */ ++ switch (hw->requested_fc_mode) { + case HNS3_FC_FULL: + fc_conf->mode = RTE_FC_FULL; + break; +@@ -4154,35 +4805,10 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return 0; + } + +-static void +-hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode) +-{ +- switch (mode) { +- case RTE_FC_NONE: +- hw->requested_mode = HNS3_FC_NONE; +- break; +- case RTE_FC_RX_PAUSE: +- hw->requested_mode = HNS3_FC_RX_PAUSE; +- break; +- case RTE_FC_TX_PAUSE: +- hw->requested_mode = HNS3_FC_TX_PAUSE; +- break; +- case RTE_FC_FULL: +- hw->requested_mode = HNS3_FC_FULL; +- break; +- default: +- hw->requested_mode = HNS3_FC_NONE; +- hns3_warn(hw, "fc_mode(%u) exceeds member scope and is " +- "configured to RTE_FC_NONE", mode); +- break; +- } +-} +- + static int + hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + int ret; + + if (fc_conf->high_water || fc_conf->low_water || +@@ -4211,10 +4837,10 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) + return -EOPNOTSUPP; + } + +- hns3_get_fc_mode(hw, fc_conf->mode); +- if (hw->requested_mode == hw->current_mode && +- pf->pause_time == fc_conf->pause_time) +- return 0; ++ if (hw->num_tc > 1) { ++ hns3_err(hw, "in multi-TC scenarios, MAC pause is not supported."); ++ return -EOPNOTSUPP; ++ } + + rte_spinlock_lock(&hw->lock); + ret = hns3_fc_enable(dev, fc_conf); +@@ -4228,8 +4854,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_pfc_conf *pfc_conf) + { + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); +- uint8_t priority; + int ret; + + if (!hns3_dev_dcb_supported(hw)) { +@@ -4264,13 +4888,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev, + return -EOPNOTSUPP; + } + +- priority = pfc_conf->priority; +- hns3_get_fc_mode(hw, pfc_conf->fc.mode); +- if (hw->dcb_info.pfc_en & BIT(priority) && +- hw->requested_mode == hw->current_mode && +- pfc_conf->fc.pause_time == pf->pause_time) +- return 0; +- + rte_spinlock_lock(&hw->lock); + ret = hns3_dcb_pfc_enable(dev, pfc_conf); + rte_spinlock_unlock(&hw->lock); +@@ -4297,15 +4914,13 @@ hns3_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info) for (i = 0; i < dcb_info->nb_tcs; i++) dcb_info->tc_bws[i] = hw->dcb_info.pg_info[0].tc_dwrr[i]; @@ -34188,7 +50504,7 @@ index 72315718a8..66be58dc26 100644 } rte_spinlock_unlock(&hw->lock); -@@ -4327,31 +4951,24 @@ hns3_reinit_dev(struct hns3_adapter *hns) +@@ -4327,31 +4942,24 @@ hns3_reinit_dev(struct hns3_adapter *hns) ret = hns3_reset_all_queues(hns); if (ret) { hns3_err(hw, "Failed to reset all queues: %d", ret); @@ -34223,7 +50539,7 @@ index 72315718a8..66be58dc26 100644 } static bool -@@ -4573,7 +5190,8 @@ hns3_stop_service(struct hns3_adapter *hns) +@@ -4573,14 +5181,15 @@ hns3_stop_service(struct hns3_adapter *hns) struct rte_eth_dev *eth_dev; eth_dev = &rte_eth_devices[hw->data->port_id]; @@ -34233,7 +50549,15 @@ index 72315718a8..66be58dc26 100644 hw->mac.link_status = ETH_LINK_DOWN; hns3_set_rxtx_function(eth_dev); -@@ -4614,7 +5232,18 @@ hns3_start_service(struct hns3_adapter *hns) + rte_wmb(); + /* Disable datapath on secondary process. */ + hns3_mp_req_stop_rxtx(eth_dev); +- rte_delay_ms(hw->tqps_num); ++ rte_delay_ms(hw->cfg_max_queues); + + rte_spinlock_lock(&hw->lock); + if (hns->hw.adapter_state == HNS3_NIC_STARTED || +@@ -4614,7 +5223,18 @@ hns3_start_service(struct hns3_adapter *hns) eth_dev = &rte_eth_devices[hw->data->port_id]; hns3_set_rxtx_function(eth_dev); hns3_mp_req_start_rxtx(eth_dev); @@ -34253,7 +50577,7 @@ index 72315718a8..66be58dc26 100644 return 0; } -@@ -4648,6 +5277,10 @@ hns3_restore_conf(struct hns3_adapter *hns) +@@ -4648,6 +5268,10 @@ hns3_restore_conf(struct hns3_adapter *hns) if (ret) goto err_promisc; @@ -34264,7 +50588,16 @@ index 72315718a8..66be58dc26 100644 if (hns->hw.adapter_state == HNS3_NIC_STARTED) { ret = hns3_do_start(hns, false); if (ret) -@@ -4748,6 +5381,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { +@@ -4712,7 +5336,7 @@ hns3_reset_service(void *param) + msec = tv_delta.tv_sec * MSEC_PER_SEC + + tv_delta.tv_usec / USEC_PER_MSEC; + if (msec > HNS3_RESET_PROCESS_MS) +- hns3_err(hw, "%d handle long time delta %" PRIx64 ++ hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", + hw->reset.level, msec, + tv.tv_sec, tv.tv_usec); +@@ -4748,6 +5372,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { .tx_queue_setup = hns3_tx_queue_setup, .rx_queue_release = hns3_dev_rx_queue_release, .tx_queue_release = hns3_dev_tx_queue_release, @@ -34273,7 +50606,7 @@ index 72315718a8..66be58dc26 100644 .dev_configure = hns3_dev_configure, .flow_ctrl_get = hns3_flow_ctrl_get, .flow_ctrl_set = hns3_flow_ctrl_set, -@@ -4787,6 +5422,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) +@@ -4787,6 +5413,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) struct rte_device *dev = eth_dev->device; struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev); struct hns3_adapter *hns = eth_dev->data->dev_private; @@ -34282,19 +50615,20 @@ index 72315718a8..66be58dc26 100644 struct hns3_hw *hw = &hns->hw; uint16_t device_id = pci_dev->id.device_id; int ret; -@@ -4806,12 +5443,25 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) +@@ -4806,12 +5434,26 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) hns3_set_rxtx_function(eth_dev); eth_dev->dev_ops = &hns3_eth_dev_ops; if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - hns3_mp_init_secondary(); +- hw->secondary_cnt++; + ret = hns3_mp_init_secondary(); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to init for secondary " + "process, ret = %d", ret); + goto err_mp_init_secondary; + } -+ - hw->secondary_cnt++; ++ __atomic_fetch_add(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ process_data.eth_dev_cnt++; return 0; } @@ -34306,11 +50640,12 @@ index 72315718a8..66be58dc26 100644 + ret); + goto err_mp_init_primary; + } ++ process_data.eth_dev_cnt++; + hw->adapter_state = HNS3_NIC_UNINITIALIZED; if (device_id == HNS3_DEV_ID_25GE_RDMA || -@@ -4852,6 +5502,15 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) +@@ -4852,6 +5494,15 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) goto err_rte_zmalloc; } @@ -34326,7 +50661,7 @@ index 72315718a8..66be58dc26 100644 rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.mac_addr, ð_dev->data->mac_addrs[0]); -@@ -4870,7 +5529,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) +@@ -4870,7 +5521,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) hns3_notify_reset_ready(hw, false); } @@ -34334,20 +50669,20 @@ index 72315718a8..66be58dc26 100644 hns3_info(hw, "hns3 dev initialization successful!"); return 0; -@@ -4879,7 +5537,12 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) +@@ -4879,7 +5529,12 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) err_init_pf: rte_free(hw->reset.wait_data); + err_init_reset: -+ hns3_mp_uninit_primary(); ++ hns3_mp_uninit(); + +err_mp_init_primary: +err_mp_init_secondary: eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; -@@ -4897,8 +5560,11 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev) +@@ -4897,8 +5552,13 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev) PMD_INIT_FUNC_TRACE(); @@ -34356,25 +50691,41 @@ index 72315718a8..66be58dc26 100644 + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; ++ __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ hns3_mp_uninit(); + return 0; + } eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; diff --git a/dpdk/drivers/net/hns3/hns3_ethdev.h b/dpdk/drivers/net/hns3/hns3_ethdev.h -index e9a3fe4107..8ba22dc424 100644 +index e9a3fe4107..b674838226 100644 --- a/dpdk/drivers/net/hns3/hns3_ethdev.h +++ b/dpdk/drivers/net/hns3/hns3_ethdev.h -@@ -145,7 +145,7 @@ enum hns3_media_type { +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_ETHDEV_H_ +@@ -120,7 +120,6 @@ struct hns3_tc_queue_info { + }; + + struct hns3_cfg { +- uint8_t vmdq_vport_num; + uint8_t tc_num; + uint16_t tqp_desc_num; + uint16_t rx_buf_len; +@@ -145,7 +144,6 @@ enum hns3_media_type { struct hns3_mac { uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; - bool default_addr_setted; /* whether default addr(mac_addr) is setted */ -+ bool default_addr_setted; /* whether default addr(mac_addr) is set */ uint8_t media_type; uint8_t phy_addr; uint8_t link_duplex : 1; /* ETH_LINK_[HALF/FULL]_DUPLEX */ -@@ -154,6 +154,19 @@ struct hns3_mac { +@@ -154,6 +152,19 @@ struct hns3_mac { uint32_t link_speed; /* ETH_SPEED_NUM_ */ }; @@ -34394,7 +50745,7 @@ index e9a3fe4107..8ba22dc424 100644 /* Primary process maintains driver state in main thread. * -@@ -243,6 +256,13 @@ enum hns3_reset_level { +@@ -243,6 +254,13 @@ enum hns3_reset_level { * Kernel PF driver use mailbox to inform DPDK VF to do reset, the value * of the reset level and the one defined in kernel driver should be * same. @@ -34408,7 +50759,13 @@ index e9a3fe4107..8ba22dc424 100644 */ HNS3_VF_FULL_RESET = 3, HNS3_FLR_RESET, /* A VF perform FLR reset */ -@@ -348,8 +368,8 @@ struct hns3_hw { +@@ -343,13 +361,14 @@ struct hns3_hw { + struct hns3_tqp_stats tqp_stats; + /* Include Mac stats | Rx stats | Tx stats */ + struct hns3_mac_stats mac_stats; ++ uint32_t mac_stats_reg_num; + uint32_t fw_version; + uint16_t num_msi; uint16_t total_tqps_num; /* total task queue pairs of this PF */ uint16_t tqps_num; /* num task queue pairs of this function */ @@ -34418,7 +50775,7 @@ index e9a3fe4107..8ba22dc424 100644 uint16_t num_tx_desc; /* desc num of per tx queue */ uint16_t num_rx_desc; /* desc num of per rx queue */ -@@ -358,6 +378,7 @@ struct hns3_hw { +@@ -358,18 +377,26 @@ struct hns3_hw { /* The configuration info of RSS */ struct hns3_rss_conf rss_info; @@ -34426,7 +50783,9 @@ index e9a3fe4107..8ba22dc424 100644 uint8_t num_tc; /* Total number of enabled TCs */ uint8_t hw_tc_map; -@@ -366,10 +387,18 @@ struct hns3_hw { +- enum hns3_fc_mode current_mode; +- enum hns3_fc_mode requested_mode; ++ enum hns3_fc_mode requested_fc_mode; /* FC mode requested by user */ struct hns3_dcb_info dcb_info; enum hns3_fc_status current_fc_status; /* current flow control status */ struct hns3_tc_queue_info tc_queue[HNS3_MAX_TC_NUM]; @@ -34447,7 +50806,7 @@ index e9a3fe4107..8ba22dc424 100644 /* * PMD setup and configuration is not thread safe. Since it is not * performance sensitive, it is better to guarantee thread-safety -@@ -399,11 +428,6 @@ struct hns3_user_vlan_table { +@@ -399,11 +426,6 @@ struct hns3_user_vlan_table { uint16_t vlan_id; }; @@ -34459,7 +50818,7 @@ index e9a3fe4107..8ba22dc424 100644 /* Vlan tag configuration for RX direction */ struct hns3_rx_vtag_cfg { uint8_t rx_vlan_offload_en; /* Whether enable rx vlan offload */ -@@ -453,6 +477,7 @@ struct hns3_mp_param { +@@ -453,6 +475,7 @@ struct hns3_mp_param { struct hns3_pf { struct hns3_adapter *adapter; bool is_main_pf; @@ -34467,7 +50826,7 @@ index e9a3fe4107..8ba22dc424 100644 uint32_t pkt_buf_size; /* Total pf buf size for tx/rx */ uint32_t tx_buf_size; /* Tx buffer size for each TC */ -@@ -478,7 +503,6 @@ struct hns3_pf { +@@ -478,7 +501,6 @@ struct hns3_pf { bool support_sfp_query; struct hns3_vtag_cfg vtag_config; @@ -34475,7 +50834,7 @@ index e9a3fe4107..8ba22dc424 100644 LIST_HEAD(vlan_tbl, hns3_user_vlan_table) vlan_list; struct hns3_fdir_info fdir; /* flow director info */ -@@ -528,6 +552,8 @@ struct hns3_adapter { +@@ -528,6 +550,8 @@ struct hns3_adapter { #define hns3_get_bit(origin, shift) \ hns3_get_field((origin), (0x1UL << (shift)), (shift)) @@ -34484,7 +50843,7 @@ index e9a3fe4107..8ba22dc424 100644 /* * upper_32_bits - return bits 32-63 of a number * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress -@@ -555,14 +581,39 @@ struct hns3_adapter { +@@ -555,14 +579,39 @@ struct hns3_adapter { type __max2 = (y); \ __max1 > __max2 ? __max1 : __max2; }) @@ -34526,7 +50885,7 @@ index e9a3fe4107..8ba22dc424 100644 } #define hns3_write_dev(a, reg, value) \ -@@ -631,6 +682,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev, +@@ -631,6 +680,7 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_op filter_op, void *arg); bool hns3_is_reset_pending(struct hns3_adapter *hns); bool hns3vf_is_reset_pending(struct hns3_adapter *hns); @@ -34535,9 +50894,16 @@ index e9a3fe4107..8ba22dc424 100644 static inline bool is_reset_pending(struct hns3_adapter *hns) diff --git a/dpdk/drivers/net/hns3/hns3_ethdev_vf.c b/dpdk/drivers/net/hns3/hns3_ethdev_vf.c -index b1736e73ab..c936114075 100644 +index b1736e73ab..29a483b2f4 100644 --- a/dpdk/drivers/net/hns3/hns3_ethdev_vf.c +++ b/dpdk/drivers/net/hns3/hns3_ethdev_vf.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -59,13 +59,23 @@ static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw, static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev); @@ -34628,7 +50994,7 @@ index b1736e73ab..c936114075 100644 } return 0; } -@@ -118,22 +151,103 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op) +@@ -118,22 +151,106 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op) { uint16_t control; int pos; @@ -34656,9 +51022,12 @@ index b1736e73ab..c936114075 100644 + if (ret < 0) { + PMD_INIT_LOG(ERR, "failed to write PCI offset 0x%x", + (pos + PCI_MSIX_FLAGS)); ++ return -ENXIO; + } ++ return 0; } ++ return -1; } @@ -34735,7 +51104,7 @@ index b1736e73ab..c936114075 100644 static int hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, __attribute__ ((unused)) uint32_t idx, -@@ -144,14 +258,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, +@@ -144,14 +261,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, int ret; rte_spinlock_lock(&hw->lock); @@ -34766,7 +51135,7 @@ index b1736e73ab..c936114075 100644 ret); } -@@ -168,15 +294,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) +@@ -168,15 +297,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx) int ret; rte_spinlock_lock(&hw->lock); @@ -34789,7 +51158,7 @@ index b1736e73ab..c936114075 100644 mac_str, ret); } } -@@ -228,39 +356,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del) +@@ -228,39 +359,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del) { struct hns3_hw *hw = &hns->hw; struct rte_ether_addr *addr; @@ -34847,7 +51216,7 @@ index b1736e73ab..c936114075 100644 int ret; ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST, -@@ -279,11 +407,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns, +@@ -279,11 +410,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns, } static int @@ -34860,7 +51229,7 @@ index b1736e73ab..c936114075 100644 int ret; ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST, -@@ -302,45 +429,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns, +@@ -302,45 +432,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns, } static int @@ -34969,7 +51338,7 @@ index b1736e73ab..c936114075 100644 if (ret) { rte_spinlock_unlock(&hw->lock); return ret; -@@ -349,9 +523,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev, +@@ -349,9 +526,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev, hw->mc_addrs_num--; } @@ -34981,7 +51350,7 @@ index b1736e73ab..c936114075 100644 if (ret) { rte_spinlock_unlock(&hw->lock); return ret; -@@ -380,9 +555,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) +@@ -380,9 +558,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del) if (!rte_is_multicast_ether_addr(addr)) continue; if (del) @@ -34993,7 +51362,7 @@ index b1736e73ab..c936114075 100644 if (ret) { err = ret; rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, -@@ -414,6 +589,97 @@ hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc) +@@ -414,6 +592,97 @@ hns3vf_set_promisc_mode(struct hns3_hw *hw, bool en_bc_pmc) return ret; } @@ -35091,7 +51460,7 @@ index b1736e73ab..c936114075 100644 static int hns3vf_dev_configure(struct rte_eth_dev *dev) { -@@ -424,30 +690,37 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) +@@ -424,30 +693,37 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) uint16_t nb_rx_q = dev->data->nb_rx_queues; uint16_t nb_tx_q = dev->data->nb_tx_queues; struct rte_eth_rss_conf rss_conf; @@ -35140,7 +51509,7 @@ index b1736e73ab..c936114075 100644 rss_conf = conf->rx_adv_conf.rss_conf; if (rss_conf.rss_key == NULL) { rss_conf.rss_key = rss_cfg->key; -@@ -464,12 +737,18 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) +@@ -464,12 +740,18 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) * according to the maximum RX packet length. */ if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { @@ -35165,7 +51534,7 @@ index b1736e73ab..c936114075 100644 ret = hns3vf_dev_mtu_set(dev, mtu); if (ret) goto cfg_err; -@@ -484,7 +763,9 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) +@@ -484,7 +766,9 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) return 0; cfg_err: @@ -35175,7 +51544,7 @@ index b1736e73ab..c936114075 100644 return ret; } -@@ -508,12 +789,14 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -508,12 +792,14 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) uint32_t frame_size = mtu + HNS3_ETH_OVERHEAD; int ret; @@ -35188,15 +51557,15 @@ index b1736e73ab..c936114075 100644 + /* + * The hns3 PF/VF devices on the same port share the hardware MTU + * configuration. Currently, we send mailbox to inform hns3 PF kernel -+ * ethdev driver to finish hardware MTU configuration in hns3 VF PMD -+ * driver, there is no need to stop the port for hns3 VF device, and the -+ * MTU value issued by hns3 VF PMD driver must be less than or equal to ++ * ethdev driver to finish hardware MTU configuration in hns3 VF PMD, ++ * there is no need to stop the port for hns3 VF device, and the ++ * MTU value issued by hns3 VF PMD must be less than or equal to + * PF's MTU. + */ if (rte_atomic16_read(&hw->reset.resetting)) { hns3_err(hw, "Failed to set mtu during resetting"); return -EIO; -@@ -525,7 +808,7 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -525,7 +811,7 @@ hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) rte_spinlock_unlock(&hw->lock); return ret; } @@ -35205,7 +51574,7 @@ index b1736e73ab..c936114075 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else -@@ -542,11 +825,19 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -542,11 +828,19 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) { struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; @@ -35227,7 +51596,7 @@ index b1736e73ab..c936114075 100644 info->max_mac_addrs = HNS3_VF_UC_MACADDR_NUM; info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD; -@@ -559,10 +850,9 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -559,10 +853,9 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_RX_OFFLOAD_KEEP_CRC | DEV_RX_OFFLOAD_SCATTER | DEV_RX_OFFLOAD_VLAN_STRIP | @@ -35240,7 +51609,7 @@ index b1736e73ab..c936114075 100644 info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_TCP_CKSUM | -@@ -571,7 +861,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -571,7 +864,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT | DEV_TX_OFFLOAD_MULTI_SEGS | @@ -35249,10 +51618,11 @@ index b1736e73ab..c936114075 100644 info->rx_desc_lim = (struct rte_eth_desc_lim) { .nb_max = HNS3_MAX_RING_DESC, -@@ -585,6 +875,17 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) +@@ -585,7 +878,16 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) .nb_align = HNS3_ALIGN_RING_DESC, }; +- info->vmdq_queue_num = 0; + info->default_rxconf = (struct rte_eth_rxconf) { + .rx_free_thresh = HNS3_DEFAULT_RX_FREE_THRESH, + /* @@ -35263,10 +51633,17 @@ index b1736e73ab..c936114075 100644 + .rx_drop_en = 1, + .offloads = 0, + }; -+ - info->vmdq_queue_num = 0; info->reta_size = HNS3_RSS_IND_TBL_SIZE; + info->hash_key_size = HNS3_RSS_KEY_SIZE; +@@ -625,7 +927,6 @@ hns3vf_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) + + /* Fetch the events from their corresponding regs */ + cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG); +- + if (BIT(HNS3_VECTOR0_RST_INT_B) & cmdq_stat_reg) { + rst_ing_reg = hns3_read_dev(hw, HNS3_FUN_RST_ING); + hns3_warn(hw, "resetting reg: 0x%x", rst_ing_reg); @@ -710,8 +1011,6 @@ hns3vf_check_tqp_info(struct hns3_hw *hw) return -EINVAL; } @@ -35334,7 +51711,17 @@ index b1736e73ab..c936114075 100644 } static void -@@ -895,6 +1205,13 @@ hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -884,7 +1194,8 @@ hns3vf_en_hw_strip_rxvtag(struct hns3_hw *hw, bool enable) + ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_VLAN, HNS3_MBX_VLAN_RX_OFF_CFG, + &msg_data, sizeof(msg_data), false, NULL, 0); + if (ret) +- hns3_err(hw, "vf enable strip failed, ret =%d", ret); ++ hns3_err(hw, "vf %s strip failed, ret = %d.", ++ enable ? "enable" : "disable", ret); + + return ret; + } +@@ -895,6 +1206,13 @@ hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask) struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct rte_eth_conf *dev_conf = &dev->data->dev_conf; unsigned int tmp_mask; @@ -35348,7 +51735,7 @@ index b1736e73ab..c936114075 100644 tmp_mask = (unsigned int)mask; /* Vlan stripping setting */ -@@ -902,13 +1219,13 @@ hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -902,13 +1220,13 @@ hns3vf_vlan_offload_set(struct rte_eth_dev *dev, int mask) rte_spinlock_lock(&hw->lock); /* Enable or disable VLAN stripping */ if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) @@ -35365,7 +51752,7 @@ index b1736e73ab..c936114075 100644 } static int -@@ -1055,6 +1372,35 @@ hns3vf_service_handler(void *param) +@@ -1055,6 +1373,35 @@ hns3vf_service_handler(void *param) eth_dev); } @@ -35401,7 +51788,7 @@ index b1736e73ab..c936114075 100644 static int hns3vf_init_hardware(struct hns3_adapter *hns) { -@@ -1082,13 +1428,24 @@ hns3vf_init_hardware(struct hns3_adapter *hns) +@@ -1082,13 +1429,24 @@ hns3vf_init_hardware(struct hns3_adapter *hns) goto err_init_hardware; } @@ -35427,7 +51814,7 @@ index b1736e73ab..c936114075 100644 return 0; err_init_hardware: -@@ -1131,6 +1488,11 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) +@@ -1131,6 +1489,11 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) goto err_cmd_init; } @@ -35439,7 +51826,7 @@ index b1736e73ab..c936114075 100644 rte_spinlock_init(&hw->mbx_resp.lock); hns3vf_clear_event_cause(hw, 0); -@@ -1153,8 +1515,6 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) +@@ -1153,8 +1516,6 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) goto err_get_config; } @@ -35448,7 +51835,7 @@ index b1736e73ab..c936114075 100644 ret = hns3vf_clear_vport_list(hw); if (ret) { PMD_INIT_LOG(ERR, "Failed to clear tbl list: %d", ret); -@@ -1176,11 +1536,9 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) +@@ -1176,11 +1537,9 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) hns3_intr_unregister(&pci_dev->intr_handle, hns3vf_interrupt_handler, eth_dev); err_intr_callback_register: @@ -35461,7 +51848,7 @@ index b1736e73ab..c936114075 100644 err_cmd_init_queue: hw->io_base = NULL; -@@ -1225,28 +1583,64 @@ hns3vf_do_stop(struct hns3_adapter *hns) +@@ -1225,28 +1584,64 @@ hns3vf_do_stop(struct hns3_adapter *hns) } static void @@ -35517,7 +51904,8 @@ index b1736e73ab..c936114075 100644 - hns3_mp_req_stop_rxtx(eth_dev); + hns3_mp_req_stop_rxtx(dev); /* Prevent crashes when queues are still in use. */ - rte_delay_ms(hw->tqps_num); +- rte_delay_ms(hw->tqps_num); ++ rte_delay_ms(hw->cfg_max_queues); rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { @@ -35531,19 +51919,31 @@ index b1736e73ab..c936114075 100644 rte_spinlock_unlock(&hw->lock); } -@@ -1256,8 +1650,10 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev) +@@ -1256,8 +1651,13 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev) struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - if (rte_eal_process_type() != RTE_PROC_PRIMARY) + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + rte_free(eth_dev->process_private); ++ eth_dev->process_private = NULL; ++ __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ hns3_mp_uninit(); return; + } if (hw->adapter_state == HNS3_NIC_STARTED) hns3vf_dev_stop(eth_dev); -@@ -1317,7 +1713,9 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) +@@ -1273,7 +1673,7 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev) + rte_free(hw->reset.wait_data); + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; +- hns3_mp_uninit_primary(); ++ hns3_mp_uninit(); + hns3_warn(hw, "Close port %d finished", hw->data->port_id); + } + +@@ -1317,7 +1717,9 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) struct hns3_hw *hw = &hns->hw; int ret; @@ -35554,7 +51954,7 @@ index b1736e73ab..c936114075 100644 ret = hns3_start_queues(hns, reset_queue); if (ret) { -@@ -1329,15 +1727,116 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) +@@ -1329,15 +1731,116 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) } static int @@ -35674,7 +52074,7 @@ index b1736e73ab..c936114075 100644 rte_spinlock_lock(&hw->lock); hw->adapter_state = HNS3_NIC_STARTING; ret = hns3vf_do_start(hns, true); -@@ -1346,13 +1845,30 @@ hns3vf_dev_start(struct rte_eth_dev *eth_dev) +@@ -1346,13 +1849,30 @@ hns3vf_dev_start(struct rte_eth_dev *eth_dev) rte_spinlock_unlock(&hw->lock); return ret; } @@ -35710,7 +52110,7 @@ index b1736e73ab..c936114075 100644 } static bool -@@ -1384,6 +1900,21 @@ hns3vf_is_reset_pending(struct hns3_adapter *hns) +@@ -1384,6 +1904,21 @@ hns3vf_is_reset_pending(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; enum hns3_reset_level reset; @@ -35732,7 +52132,32 @@ index b1736e73ab..c936114075 100644 hns3vf_check_event_cause(hns, NULL); reset = hns3vf_get_reset_level(hw, &hw->reset.pending); if (hw->reset.level != HNS3_NONE_RESET && hw->reset.level < reset) { -@@ -1446,15 +1977,17 @@ static int +@@ -1396,6 +1931,7 @@ hns3vf_is_reset_pending(struct hns3_adapter *hns) + static int + hns3vf_wait_hardware_ready(struct hns3_adapter *hns) + { ++#define HNS3_WAIT_PF_RESET_READY_TIME 5 + struct hns3_hw *hw = &hns->hw; + struct hns3_wait_data *wait_data = hw->reset.wait_data; + struct timeval tv; +@@ -1416,12 +1952,14 @@ hns3vf_wait_hardware_ready(struct hns3_adapter *hns) + return 0; + + wait_data->check_completion = NULL; +- wait_data->interval = 1 * MSEC_PER_SEC * USEC_PER_MSEC; ++ wait_data->interval = HNS3_WAIT_PF_RESET_READY_TIME * ++ MSEC_PER_SEC * USEC_PER_MSEC; + wait_data->count = 1; + wait_data->result = HNS3_WAIT_REQUEST; + rte_eal_alarm_set(wait_data->interval, hns3_wait_callback, + wait_data); +- hns3_warn(hw, "hardware is ready, delay 1 sec for PF reset complete"); ++ hns3_warn(hw, "hardware is ready, delay %d sec for PF reset complete", ++ HNS3_WAIT_PF_RESET_READY_TIME); + return -EAGAIN; + } else if (wait_data->result == HNS3_WAIT_TIMEOUT) { + gettimeofday(&tv, NULL); +@@ -1446,15 +1984,17 @@ static int hns3vf_prepare_reset(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; @@ -35752,7 +52177,7 @@ index b1736e73ab..c936114075 100644 } static int -@@ -1464,7 +1997,8 @@ hns3vf_stop_service(struct hns3_adapter *hns) +@@ -1464,14 +2004,15 @@ hns3vf_stop_service(struct hns3_adapter *hns) struct rte_eth_dev *eth_dev; eth_dev = &rte_eth_devices[hw->data->port_id]; @@ -35762,7 +52187,15 @@ index b1736e73ab..c936114075 100644 hw->mac.link_status = ETH_LINK_DOWN; hns3_set_rxtx_function(eth_dev); -@@ -1502,8 +2036,18 @@ hns3vf_start_service(struct hns3_adapter *hns) + rte_wmb(); + /* Disable datapath on secondary process. */ + hns3_mp_req_stop_rxtx(eth_dev); +- rte_delay_ms(hw->tqps_num); ++ rte_delay_ms(hw->cfg_max_queues); + + rte_spinlock_lock(&hw->lock); + if (hw->adapter_state == HNS3_NIC_STARTED || +@@ -1502,8 +2043,18 @@ hns3vf_start_service(struct hns3_adapter *hns) eth_dev = &rte_eth_devices[hw->data->port_id]; hns3_set_rxtx_function(eth_dev); hns3_mp_req_start_rxtx(eth_dev); @@ -35782,7 +52215,7 @@ index b1736e73ab..c936114075 100644 return 0; } -@@ -1525,6 +2069,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns) +@@ -1525,6 +2076,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns) if (ret) goto err_vlan_table; @@ -35793,7 +52226,16 @@ index b1736e73ab..c936114075 100644 if (hw->adapter_state == HNS3_NIC_STARTED) { ret = hns3vf_do_start(hns, false); if (ret) -@@ -1623,14 +2171,18 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) +@@ -1607,7 +2162,7 @@ hns3vf_reset_service(void *param) + msec = tv_delta.tv_sec * MSEC_PER_SEC + + tv_delta.tv_usec / USEC_PER_MSEC; + if (msec > HNS3_RESET_PROCESS_MS) +- hns3_err(hw, "%d handle long time delta %" PRIx64 ++ hns3_err(hw, "%d handle long time delta %" PRIu64 + " ms time=%ld.%.6ld", + hw->reset.level, msec, tv.tv_sec, tv.tv_usec); + } +@@ -1623,14 +2178,18 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) if (hw->reset.level == HNS3_VF_FULL_RESET) { rte_intr_disable(&pci_dev->intr_handle); @@ -35814,7 +52256,7 @@ index b1736e73ab..c936114075 100644 } if (hw->reset.level == HNS3_VF_FULL_RESET) { -@@ -1650,22 +2202,16 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) +@@ -1650,22 +2209,16 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) ret = hns3_reset_all_queues(hns); if (ret) { hns3_err(hw, "Failed to reset all queues: %d", ret); @@ -35839,7 +52281,7 @@ index b1736e73ab..c936114075 100644 } static const struct eth_dev_ops hns3vf_eth_dev_ops = { -@@ -1685,6 +2231,8 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = { +@@ -1685,6 +2238,8 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = { .tx_queue_setup = hns3_tx_queue_setup, .rx_queue_release = hns3_dev_rx_queue_release, .tx_queue_release = hns3_dev_tx_queue_release, @@ -35848,19 +52290,20 @@ index b1736e73ab..c936114075 100644 .dev_configure = hns3vf_dev_configure, .mac_addr_add = hns3vf_add_mac_addr, .mac_addr_remove = hns3vf_remove_mac_addr, -@@ -1736,12 +2284,24 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1736,12 +2291,25 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) hns3_set_rxtx_function(eth_dev); eth_dev->dev_ops = &hns3vf_eth_dev_ops; if (rte_eal_process_type() != RTE_PROC_PRIMARY) { - hns3_mp_init_secondary(); +- hw->secondary_cnt++; + ret = hns3_mp_init_secondary(); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to init for secondary " + "process, ret = %d", ret); + goto err_mp_init_secondary; + } -+ - hw->secondary_cnt++; ++ __atomic_fetch_add(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ process_data.eth_dev_cnt++; return 0; } @@ -35872,10 +52315,11 @@ index b1736e73ab..c936114075 100644 + ret); + goto err_mp_init_primary; + } ++ process_data.eth_dev_cnt++; hw->adapter_state = HNS3_NIC_UNINITIALIZED; hns->is_vf = true; -@@ -1771,8 +2331,10 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1771,8 +2339,10 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) goto err_rte_zmalloc; } @@ -35886,18 +52330,18 @@ index b1736e73ab..c936114075 100644 hw->adapter_state = HNS3_NIC_INITIALIZED; /* * Pass the information to the rte_eth_dev_close() that it should also -@@ -1798,6 +2360,10 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1798,6 +2368,10 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) rte_free(hw->reset.wait_data); err_init_reset: -+ hns3_mp_uninit_primary(); ++ hns3_mp_uninit(); + +err_mp_init_primary: +err_mp_init_secondary: eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; -@@ -1816,8 +2382,11 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev) +@@ -1816,8 +2390,13 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev) PMD_INIT_FUNC_TRACE(); @@ -35906,15 +52350,24 @@ index b1736e73ab..c936114075 100644 + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + rte_free(eth_dev->process_private); + eth_dev->process_private = NULL; ++ __atomic_fetch_sub(&hw->secondary_cnt, 1, __ATOMIC_RELAXED); ++ hns3_mp_uninit(); + return 0; + } eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; diff --git a/dpdk/drivers/net/hns3/hns3_fdir.c b/dpdk/drivers/net/hns3/hns3_fdir.c -index ca3c78e1ce..98a044f567 100644 +index ca3c78e1ce..49df88662b 100644 --- a/dpdk/drivers/net/hns3/hns3_fdir.c +++ b/dpdk/drivers/net/hns3/hns3_fdir.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -619,7 +619,7 @@ static void hns3_fd_convert_meta_data(struct hns3_fd_key_cfg *cfg, uint8_t *key_x, uint8_t *key_y) { @@ -35977,11 +52430,56 @@ index ca3c78e1ce..98a044f567 100644 return ret; } +@@ -991,6 +1012,10 @@ int hns3_clear_all_fdir_filter(struct hns3_adapter *hns) + rte_hash_reset(fdir_info->hash_handle); + rte_spinlock_unlock(&fdir_info->flows_lock); + ++ memset(fdir_info->hash_map, 0, ++ sizeof(struct hns3_fdir_rule_ele *) * ++ fdir_info->fd_cfg.rule_num[HNS3_FD_STAGE_1]); ++ + fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list); + while (fdir_filter) { + TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); +diff --git a/dpdk/drivers/net/hns3/hns3_fdir.h b/dpdk/drivers/net/hns3/hns3_fdir.h +index f7b4216136..0c78121ded 100644 +--- a/dpdk/drivers/net/hns3/hns3_fdir.h ++++ b/dpdk/drivers/net/hns3/hns3_fdir.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_FDIR_H_ diff --git a/dpdk/drivers/net/hns3/hns3_flow.c b/dpdk/drivers/net/hns3/hns3_flow.c -index bcd121f48b..b1d3d81aee 100644 +index bcd121f48b..7ac6e06e7b 100644 --- a/dpdk/drivers/net/hns3/hns3_flow.c +++ b/dpdk/drivers/net/hns3/hns3_flow.c -@@ -46,8 +46,7 @@ static enum rte_flow_item_type first_items[] = { +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include +@@ -11,15 +11,6 @@ + #include "hns3_ethdev.h" + #include "hns3_logs.h" + +-/* Default default keys */ +-static uint8_t hns3_hash_key[] = { +- 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, +- 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, +- 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, +- 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, +- 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA +-}; +- + static const uint8_t full_mask[VNI_OR_TNI_LEN] = { 0xFF, 0xFF, 0xFF }; + static const uint8_t zero_mask[VNI_OR_TNI_LEN] = { 0x00, 0x00, 0x00 }; + +@@ -46,8 +37,7 @@ static enum rte_flow_item_type first_items[] = { RTE_FLOW_ITEM_TYPE_NVGRE, RTE_FLOW_ITEM_TYPE_VXLAN, RTE_FLOW_ITEM_TYPE_GENEVE, @@ -35991,7 +52489,7 @@ index bcd121f48b..b1d3d81aee 100644 }; static enum rte_flow_item_type L2_next_items[] = { -@@ -67,8 +66,7 @@ static enum rte_flow_item_type L3_next_items[] = { +@@ -67,8 +57,7 @@ static enum rte_flow_item_type L3_next_items[] = { static enum rte_flow_item_type L4_next_items[] = { RTE_FLOW_ITEM_TYPE_VXLAN, RTE_FLOW_ITEM_TYPE_GENEVE, @@ -36001,7 +52499,16 @@ index bcd121f48b..b1d3d81aee 100644 }; static enum rte_flow_item_type tunnel_next_items[] = { -@@ -128,9 +126,9 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, +@@ -122,23 +111,33 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_pf *pf = &hns->pf; ++ struct hns3_hw *hw = &hns->hw; + struct hns3_flow_counter *cnt; ++ uint64_t value; ++ int ret; + + cnt = hns3_counter_lookup(dev, id); if (cnt) { if (!cnt->shared || cnt->shared != shared) return rte_flow_error_set(error, ENOTSUP, @@ -36014,7 +52521,14 @@ index bcd121f48b..b1d3d81aee 100644 cnt->ref_cnt++; return 0; } -@@ -138,7 +136,7 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, + ++ /* Clear the counter by read ops because the counter is read-clear */ ++ ret = hns3_get_count(hw, id, &value); ++ if (ret) ++ return rte_flow_error_set(error, EIO, ++ RTE_FLOW_ERROR_TYPE_HANDLE, NULL, ++ "Clear counter failed!"); ++ cnt = rte_zmalloc("hns3 counter", sizeof(*cnt), 0); if (cnt == NULL) return rte_flow_error_set(error, ENOMEM, @@ -36023,7 +52537,7 @@ index bcd121f48b..b1d3d81aee 100644 "Alloc mem for counter failed"); cnt->id = id; cnt->shared = shared; -@@ -166,13 +164,13 @@ hns3_counter_query(struct rte_eth_dev *dev, struct rte_flow *flow, +@@ -166,18 +165,20 @@ hns3_counter_query(struct rte_eth_dev *dev, struct rte_flow *flow, cnt = hns3_counter_lookup(dev, flow->counter_id); if (cnt == NULL) return rte_flow_error_set(error, EINVAL, @@ -36039,7 +52553,14 @@ index bcd121f48b..b1d3d81aee 100644 NULL, "Read counter fail."); return ret; } -@@ -224,14 +222,19 @@ hns3_handle_action_queue(struct rte_eth_dev *dev, + qc->hits_set = 1; + qc->hits = value; ++ qc->bytes_set = 0; ++ qc->bytes = 0; + + return 0; + } +@@ -224,14 +225,19 @@ hns3_handle_action_queue(struct rte_eth_dev *dev, struct rte_flow_error *error) { struct hns3_adapter *hns = dev->data->dev_private; @@ -36061,7 +52582,7 @@ index bcd121f48b..b1d3d81aee 100644 rule->queue_id = queue->index; rule->action = HNS3_FD_ACTION_ACCEPT_PACKET; return 0; -@@ -274,9 +277,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, +@@ -274,9 +280,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, (const struct rte_flow_action_mark *)actions->conf; if (mark->id >= HNS3_MAX_FILTER_ID) return rte_flow_error_set(error, EINVAL, @@ -36074,7 +52595,7 @@ index bcd121f48b..b1d3d81aee 100644 rule->fd_id = mark->id; rule->flags |= HNS3_RULE_FLAG_FDID; break; -@@ -290,9 +293,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, +@@ -290,9 +296,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, counter_num = pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1]; if (act_count->id >= counter_num) return rte_flow_error_set(error, EINVAL, @@ -36087,7 +52608,7 @@ index bcd121f48b..b1d3d81aee 100644 rule->act_cnt = *act_count; rule->flags |= HNS3_RULE_FLAG_COUNTER; break; -@@ -456,7 +459,7 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -456,7 +462,7 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, ipv4_mask->hdr.time_to_live || ipv4_mask->hdr.hdr_checksum) { return rte_flow_error_set(error, EINVAL, @@ -36096,7 +52617,7 @@ index bcd121f48b..b1d3d81aee 100644 item, "Only support src & dst ip,tos,proto in IPV4"); } -@@ -521,7 +524,7 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -521,7 +527,7 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (ipv6_mask->hdr.vtc_flow || ipv6_mask->hdr.payload_len || ipv6_mask->hdr.hop_limits) { return rte_flow_error_set(error, EINVAL, @@ -36105,7 +52626,7 @@ index bcd121f48b..b1d3d81aee 100644 item, "Only support src & dst ip,proto in IPV6"); } -@@ -581,7 +584,7 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -581,7 +587,7 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum || tcp_mask->hdr.tcp_urp) { return rte_flow_error_set(error, EINVAL, @@ -36114,7 +52635,7 @@ index bcd121f48b..b1d3d81aee 100644 item, "Only support src & dst port in TCP"); } -@@ -628,7 +631,7 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -628,7 +634,7 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, udp_mask = item->mask; if (udp_mask->hdr.dgram_len || udp_mask->hdr.dgram_cksum) { return rte_flow_error_set(error, EINVAL, @@ -36123,7 +52644,7 @@ index bcd121f48b..b1d3d81aee 100644 item, "Only support src & dst port in UDP"); } -@@ -675,7 +678,7 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -675,7 +681,7 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, sctp_mask = item->mask; if (sctp_mask->hdr.cksum) return rte_flow_error_set(error, EINVAL, @@ -36132,7 +52653,7 @@ index bcd121f48b..b1d3d81aee 100644 item, "Only support src & dst port in SCTP"); -@@ -820,14 +823,14 @@ hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -820,14 +826,14 @@ hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (vxlan_mask->flags) return rte_flow_error_set(error, EINVAL, @@ -36149,7 +52670,7 @@ index bcd121f48b..b1d3d81aee 100644 "VNI must be totally masked or not in VxLAN"); if (vxlan_mask->vni[0]) { hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1); -@@ -871,14 +874,14 @@ hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -871,14 +877,14 @@ hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (nvgre_mask->protocol || nvgre_mask->c_k_s_rsvd0_ver) return rte_flow_error_set(error, EINVAL, @@ -36166,7 +52687,7 @@ index bcd121f48b..b1d3d81aee 100644 "TNI must be totally masked or not in NVGRE"); if (nvgre_mask->tni[0]) { -@@ -925,13 +928,13 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -925,13 +931,13 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (geneve_mask->ver_opt_len_o_c_rsvd0 || geneve_mask->protocol) return rte_flow_error_set(error, EINVAL, @@ -36182,7 +52703,7 @@ index bcd121f48b..b1d3d81aee 100644 "VNI must be totally masked or not in GENEVE"); if (geneve_mask->vni[0]) { hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1); -@@ -962,7 +965,7 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, +@@ -962,7 +968,7 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, break; default: return rte_flow_error_set(error, ENOTSUP, @@ -36191,7 +52712,7 @@ index bcd121f48b..b1d3d81aee 100644 NULL, "Unsupported tunnel type!"); } if (ret) -@@ -1016,7 +1019,7 @@ hns3_parse_normal(const struct rte_flow_item *item, +@@ -1016,7 +1022,7 @@ hns3_parse_normal(const struct rte_flow_item *item, break; default: return rte_flow_error_set(error, ENOTSUP, @@ -36200,7 +52721,7 @@ index bcd121f48b..b1d3d81aee 100644 NULL, "Unsupported normal type!"); } -@@ -1032,7 +1035,7 @@ hns3_validate_item(const struct rte_flow_item *item, +@@ -1032,7 +1038,7 @@ hns3_validate_item(const struct rte_flow_item *item, if (item->last) return rte_flow_error_set(error, ENOTSUP, @@ -36209,7 +52730,7 @@ index bcd121f48b..b1d3d81aee 100644 "Not supported last point for range"); for (i = 0; i < step_mngr.count; i++) { -@@ -1054,8 +1057,7 @@ is_tunnel_packet(enum rte_flow_item_type type) +@@ -1054,49 +1060,35 @@ is_tunnel_packet(enum rte_flow_item_type type) if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || type == RTE_FLOW_ITEM_TYPE_VXLAN || type == RTE_FLOW_ITEM_TYPE_NVGRE || @@ -36219,7 +52740,71 @@ index bcd121f48b..b1d3d81aee 100644 return true; return false; } -@@ -1116,11 +1118,6 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, + + /* +- * Parse the rule to see if it is a IP or MAC VLAN flow director rule. +- * And get the flow director filter info BTW. +- * UDP/TCP/SCTP PATTERN: +- * The first not void item can be ETH or IPV4 or IPV6 +- * The second not void item must be IPV4 or IPV6 if the first one is ETH. +- * The next not void item could be UDP or TCP or SCTP (optional) +- * The next not void item could be RAW (for flexbyte, optional) +- * The next not void item must be END. +- * A Fuzzy Match pattern can appear at any place before END. +- * Fuzzy Match is optional for IPV4 but is required for IPV6 +- * MAC VLAN PATTERN: +- * The first not void item must be ETH. +- * The second not void item must be MAC VLAN. +- * The next not void item must be END. +- * ACTION: +- * The first not void action should be QUEUE or DROP. +- * The second not void optional action should be MARK, +- * mark_id is a uint32_t number. +- * The next not void action should be END. +- * UDP/TCP/SCTP pattern example: +- * ITEM Spec Mask +- * ETH NULL NULL +- * IPV4 src_addr 192.168.1.20 0xFFFFFFFF +- * dst_addr 192.167.3.50 0xFFFFFFFF +- * UDP/TCP/SCTP src_port 80 0xFFFF +- * dst_port 80 0xFFFF +- * END +- * MAC VLAN pattern example: +- * ITEM Spec Mask +- * ETH dst_addr +- {0xAC, 0x7B, 0xA1, {0xFF, 0xFF, 0xFF, +- 0x2C, 0x6D, 0x36} 0xFF, 0xFF, 0xFF} +- * MAC VLAN tci 0x2016 0xEFFF +- * END +- * Other members in mask and spec should set to 0x00. +- * Item->last should be NULL. ++ * Parse the flow director rule. ++ * The supported PATTERN: ++ * case: non-tunnel packet: ++ * ETH : src-mac, dst-mac, ethertype ++ * VLAN: tag1, tag2 ++ * IPv4: src-ip, dst-ip, tos, proto ++ * IPv6: src-ip(last 32 bit addr), dst-ip(last 32 bit addr), proto ++ * UDP : src-port, dst-port ++ * TCP : src-port, dst-port ++ * SCTP: src-port, dst-port, tag ++ * case: tunnel packet: ++ * OUTER-ETH: ethertype ++ * OUTER-L3 : proto ++ * OUTER-L4 : src-port, dst-port ++ * TUNNEL : vni, flow-id(only valid when NVGRE) ++ * INNER-ETH/VLAN/IPv4/IPv6/UDP/TCP/SCTP: same as non-tunnel packet ++ * The supported ACTION: ++ * QUEUE ++ * DROP ++ * COUNT ++ * MARK: the id range [0, 4094] ++ * FLAG ++ * RSS: only valid if firmware support FD_QUEUE_REGION. + */ + static int + hns3_parse_fdir_filter(struct rte_eth_dev *dev, +@@ -1116,11 +1108,6 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Fdir not supported in VF"); @@ -36231,14 +52816,12 @@ index bcd121f48b..b1d3d81aee 100644 step_mngr.items = first_items; step_mngr.count = ARRAY_SIZE(first_items); for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { -@@ -1193,10 +1190,24 @@ static bool +@@ -1193,12 +1180,33 @@ static bool hns3_action_rss_same(const struct rte_flow_action_rss *comp, const struct rte_flow_action_rss *with) { - return (comp->func == with->func && -- comp->level == with->level && -- comp->types == with->types && -- comp->key_len == with->key_len && ++ bool rss_key_is_same; + bool func_is_same; + + /* @@ -36252,15 +52835,26 @@ index bcd121f48b..b1d3d81aee 100644 + if (comp->func == RTE_ETH_HASH_FUNCTION_MAX) + func_is_same = false; + else -+ func_is_same = (with->func ? (comp->func == with->func) : true); ++ func_is_same = (with->func != RTE_ETH_HASH_FUNCTION_DEFAULT) ? ++ (comp->func == with->func) : true; + -+ return (func_is_same && ++ if (with->key_len == 0 || with->key == NULL) ++ rss_key_is_same = 1; ++ else ++ rss_key_is_same = comp->key_len == with->key_len && ++ !memcmp(comp->key, with->key, with->key_len); ++ ++ return (func_is_same && rss_key_is_same && + comp->types == (with->types & HNS3_ETH_RSS_SUPPORT) && -+ comp->level == with->level && comp->key_len == with->key_len && + comp->level == with->level && +- comp->types == with->types && +- comp->key_len == with->key_len && comp->queue_num == with->queue_num && - !memcmp(comp->key, with->key, with->key_len) && +- !memcmp(comp->key, with->key, with->key_len) && !memcmp(comp->queue, with->queue, -@@ -1242,65 +1253,49 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, + sizeof(*with->queue) * with->queue_num)); + } +@@ -1242,65 +1250,49 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, const struct rte_flow_action_rss *rss; const struct rte_flow_action *act; uint32_t act_index = 0; @@ -36343,7 +52937,7 @@ index bcd121f48b..b1d3d81aee 100644 act_index++; -@@ -1328,6 +1323,7 @@ hns3_disable_rss(struct hns3_hw *hw) +@@ -1328,6 +1320,7 @@ hns3_disable_rss(struct hns3_hw *hw) /* Disable RSS */ hw->rss_info.conf.types = 0; @@ -36351,7 +52945,7 @@ index bcd121f48b..b1d3d81aee 100644 return 0; } -@@ -1335,9 +1331,8 @@ hns3_disable_rss(struct hns3_hw *hw) +@@ -1335,9 +1328,8 @@ hns3_disable_rss(struct hns3_hw *hw) static void hns3_parse_rss_key(struct hns3_hw *hw, struct rte_flow_action_rss *rss_conf) { @@ -36363,7 +52957,7 @@ index bcd121f48b..b1d3d81aee 100644 rss_conf->key = hns3_hash_key; rss_conf->key_len = HNS3_RSS_KEY_SIZE; } -@@ -1360,7 +1355,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, +@@ -1360,7 +1352,7 @@ hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, *hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; break; default: @@ -36372,7 +52966,7 @@ index bcd121f48b..b1d3d81aee 100644 algo_func); return -EINVAL; } -@@ -1378,10 +1373,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) +@@ -1378,10 +1370,8 @@ hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) struct hns3_rss_tuple_cfg *tuple; int ret; @@ -36383,7 +52977,7 @@ index bcd121f48b..b1d3d81aee 100644 ret = hns3_parse_rss_algorithm(hw, &rss_config->func, &hash_algo); if (ret) return ret; -@@ -1409,26 +1402,19 @@ hns3_update_indir_table(struct rte_eth_dev *dev, +@@ -1409,26 +1399,19 @@ hns3_update_indir_table(struct rte_eth_dev *dev, struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; uint8_t indir_tbl[HNS3_RSS_IND_TBL_SIZE]; @@ -36415,7 +53009,7 @@ index bcd121f48b..b1d3d81aee 100644 return -EINVAL; } queue_id = conf->queue[j]; -@@ -1442,7 +1428,9 @@ static int +@@ -1442,7 +1425,9 @@ static int hns3_config_rss_filter(struct rte_eth_dev *dev, const struct hns3_rss_conf *conf, bool add) { @@ -36425,7 +53019,7 @@ index bcd121f48b..b1d3d81aee 100644 struct hns3_hw *hw = &hns->hw; struct hns3_rss_conf *rss_info; uint64_t flow_types; -@@ -1469,8 +1457,18 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, +@@ -1469,8 +1454,18 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, return -EINVAL; } @@ -36445,7 +53039,7 @@ index bcd121f48b..b1d3d81aee 100644 if (flow_types != rss_flow_conf.types) hns3_warn(hw, "modified RSS types based on hardware support, " "requested:%" PRIx64 " configured:%" PRIx64, -@@ -1478,38 +1476,44 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, +@@ -1478,38 +1473,44 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, /* Update the useful flow types */ rss_flow_conf.types = flow_types; @@ -36468,8 +53062,12 @@ index bcd121f48b..b1d3d81aee 100644 + if (ret) { + hns3_err(hw, "RSS disable failed(%d)", ret); + return ret; -+ } -+ + } +- return -EINVAL; +- } + +- /* Get rx queues num */ +- num = dev->data->nb_rx_queues; + if (rss_flow_conf.queue_num) { + /* + * Due the content of queue pointer have been reset to @@ -36477,12 +53075,8 @@ index bcd121f48b..b1d3d81aee 100644 + */ + rss_info->conf.queue = NULL; + rss_info->conf.queue_num = 0; - } -- return -EINVAL; -- } - -- /* Get rx queues num */ -- num = dev->data->nb_rx_queues; ++ } ++ + /* set RSS func invalid after flushed */ + rss_info->conf.func = RTE_ETH_HASH_FUNCTION_MAX; + return 0; @@ -36509,7 +53103,7 @@ index bcd121f48b..b1d3d81aee 100644 /* Set hash algorithm and flow types by the user's config */ ret = hns3_hw_rss_hash_set(hw, &rss_flow_conf); -@@ -1522,23 +1526,65 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, +@@ -1522,23 +1523,65 @@ hns3_config_rss_filter(struct rte_eth_dev *dev, goto rss_config_err; } @@ -36529,15 +53123,16 @@ index bcd121f48b..b1d3d81aee 100644 -/* Remove the rss filter */ static int hns3_clear_rss_filter(struct rte_eth_dev *dev) -+{ + { + struct hns3_process_private *process_list = dev->process_private; -+ struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_rss_conf_ele *rss_filter_ptr; -+ struct hns3_hw *hw = &hns->hw; + struct hns3_hw *hw = &hns->hw; + int rss_rule_succ_cnt = 0; /* count for success of clearing RSS rules */ + int rss_rule_fail_cnt = 0; /* count for failure of clearing RSS rules */ + int ret = 0; -+ + +- if (hw->rss_info.conf.queue_num == 0) + rss_filter_ptr = TAILQ_FIRST(&process_list->filter_rss_list); + while (rss_filter_ptr) { + TAILQ_REMOVE(&process_list->filter_rss_list, rss_filter_ptr, @@ -36564,11 +53159,10 @@ index bcd121f48b..b1d3d81aee 100644 + +int +hns3_restore_rss_filter(struct rte_eth_dev *dev) - { - struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - -- if (hw->rss_info.conf.queue_num == 0) ++{ ++ struct hns3_adapter *hns = dev->data->dev_private; ++ struct hns3_hw *hw = &hns->hw; ++ + /* When user flush all rules, it doesn't need to restore RSS rule */ + if (hw->rss_info.conf.func == RTE_ETH_HASH_FUNCTION_MAX) return 0; @@ -36578,7 +53172,7 @@ index bcd121f48b..b1d3d81aee 100644 } static int -@@ -1549,7 +1595,6 @@ hns3_flow_parse_rss(struct rte_eth_dev *dev, +@@ -1549,7 +1592,6 @@ hns3_flow_parse_rss(struct rte_eth_dev *dev, struct hns3_hw *hw = &hns->hw; bool ret; @@ -36586,7 +53180,7 @@ index bcd121f48b..b1d3d81aee 100644 ret = hns3_action_rss_same(&hw->rss_info.conf, &conf->conf); if (ret) { hns3_err(hw, "Enter duplicate RSS configuration : %d", ret); -@@ -1673,8 +1718,9 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -1673,8 +1715,9 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, ret = -ENOMEM; goto err; } @@ -36598,7 +53192,7 @@ index bcd121f48b..b1d3d81aee 100644 TAILQ_INSERT_TAIL(&process_list->filter_rss_list, rss_filter_ptr, entries); -@@ -1696,16 +1742,18 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -1696,16 +1739,18 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, flow->counter_id = fdir_rule.act_cnt.id; } @@ -36625,7 +53219,7 @@ index bcd121f48b..b1d3d81aee 100644 memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule, sizeof(struct hns3_fdir_rule)); TAILQ_INSERT_TAIL(&process_list->fdir_list, -@@ -1716,10 +1764,10 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -1716,10 +1761,10 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return flow; } @@ -36637,7 +53231,7 @@ index bcd121f48b..b1d3d81aee 100644 err: rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to create flow"); -@@ -1740,7 +1788,6 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, +@@ -1740,7 +1785,6 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct hns3_fdir_rule_ele *fdir_rule_ptr; struct hns3_rss_conf_ele *rss_filter_ptr; struct hns3_flow_mem *flow_node; @@ -36645,7 +53239,7 @@ index bcd121f48b..b1d3d81aee 100644 enum rte_filter_type filter_type; struct hns3_fdir_rule fdir_rule; int ret; -@@ -1770,7 +1817,8 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, +@@ -1770,7 +1814,8 @@ hns3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, break; case RTE_ETH_FILTER_HASH: rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule; @@ -36655,7 +53249,7 @@ index bcd121f48b..b1d3d81aee 100644 if (ret) return rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_HANDLE, -@@ -1822,8 +1870,11 @@ hns3_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) +@@ -1822,8 +1867,11 @@ hns3_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) } ret = hns3_clear_rss_filter(dev); @@ -36669,9 +53263,25 @@ index bcd121f48b..b1d3d81aee 100644 hns3_filterlist_flush(dev); diff --git a/dpdk/drivers/net/hns3/hns3_intr.c b/dpdk/drivers/net/hns3/hns3_intr.c -index 6c3ebd3ee1..46d617c68e 100644 +index 6c3ebd3ee1..44038788fc 100644 --- a/dpdk/drivers/net/hns3/hns3_intr.c +++ b/dpdk/drivers/net/hns3/hns3_intr.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include +@@ -855,7 +855,7 @@ hns3_clear_reset_level(struct hns3_hw *hw, uint64_t *levels) + static bool + hns3_reset_err_handle(struct hns3_adapter *hns) + { +-#define MAX_RESET_FAIL_CNT 5 ++#define MAX_RESET_FAIL_CNT 30 + + struct hns3_hw *hw = &hns->hw; + @@ -882,8 +882,14 @@ hns3_reset_err_handle(struct hns3_adapter *hns) return true; } @@ -36688,6 +53298,15 @@ index 6c3ebd3ee1..46d617c68e 100644 reset_fail: hw->reset.attempts = 0; hw->reset.stats.fail_cnt++; +@@ -943,7 +949,7 @@ hns3_reset_pre(struct hns3_adapter *hns) + static int + hns3_reset_post(struct hns3_adapter *hns) + { +-#define TIMEOUT_RETRIES_CNT 5 ++#define TIMEOUT_RETRIES_CNT 30 + struct hns3_hw *hw = &hns->hw; + struct timeval tv_delta; + struct timeval tv; @@ -1001,7 +1007,9 @@ hns3_reset_post(struct hns3_adapter *hns) hw->reset.attempts = 0; hw->reset.stats.success_cnt++; @@ -36698,10 +53317,39 @@ index 6c3ebd3ee1..46d617c68e 100644 gettimeofday(&tv, NULL); timersub(&tv, &hw->reset.start_time, &tv_delta); hns3_warn(hw, "%s reset done fail_cnt:%" PRIx64 +diff --git a/dpdk/drivers/net/hns3/hns3_intr.h b/dpdk/drivers/net/hns3/hns3_intr.h +index d0af16c502..cf390de5dd 100644 +--- a/dpdk/drivers/net/hns3/hns3_intr.h ++++ b/dpdk/drivers/net/hns3/hns3_intr.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_INTR_H_ +diff --git a/dpdk/drivers/net/hns3/hns3_logs.h b/dpdk/drivers/net/hns3/hns3_logs.h +index f3fc7b51d6..aa135db982 100644 +--- a/dpdk/drivers/net/hns3/hns3_logs.h ++++ b/dpdk/drivers/net/hns3/hns3_logs.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_LOGS_H_ diff --git a/dpdk/drivers/net/hns3/hns3_mbx.c b/dpdk/drivers/net/hns3/hns3_mbx.c -index c1647af4bf..64996c9ae1 100644 +index c1647af4bf..fe5eb0b74d 100644 --- a/dpdk/drivers/net/hns3/hns3_mbx.c +++ b/dpdk/drivers/net/hns3/hns3_mbx.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -150,6 +150,8 @@ hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode, { struct hns3_mbx_vf_to_pf_cmd *req; @@ -36730,7 +53378,15 @@ index c1647af4bf..64996c9ae1 100644 /* synchronous send */ if (need_resp) { -@@ -211,6 +219,7 @@ hns3_mbx_handler(struct hns3_hw *hw) +@@ -176,6 +184,7 @@ hns3_send_mbx_msg(struct hns3_hw *hw, uint16_t code, uint16_t subcode, + hw->mbx_resp.head++; + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { ++ hw->mbx_resp.head--; + rte_spinlock_unlock(&hw->mbx_resp.lock); + hns3_err(hw, "VF failed(=%d) to send mbx message to PF", + ret); +@@ -211,6 +220,7 @@ hns3_mbx_handler(struct hns3_hw *hw) struct hns3_mac *mac = &hw->mac; enum hns3_reset_level reset_level; uint16_t *msg_q; @@ -36738,7 +53394,7 @@ index c1647af4bf..64996c9ae1 100644 uint32_t tail; tail = hw->arq.tail; -@@ -219,7 +228,8 @@ hns3_mbx_handler(struct hns3_hw *hw) +@@ -219,7 +229,8 @@ hns3_mbx_handler(struct hns3_hw *hw) while (tail != hw->arq.head) { msg_q = hw->arq.msg_q[hw->arq.head]; @@ -36748,7 +53404,7 @@ index c1647af4bf..64996c9ae1 100644 case HNS3_MBX_LINK_STAT_CHANGE: memcpy(&mac->link_speed, &msg_q[2], sizeof(mac->link_speed)); -@@ -241,7 +251,7 @@ hns3_mbx_handler(struct hns3_hw *hw) +@@ -241,7 +252,7 @@ hns3_mbx_handler(struct hns3_hw *hw) break; default: hns3_err(hw, "Fetched unsupported(%d) message from arq", @@ -36757,7 +53413,7 @@ index c1647af4bf..64996c9ae1 100644 break; } -@@ -282,6 +292,40 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg) +@@ -282,6 +293,40 @@ hns3_update_resp_position(struct hns3_hw *hw, uint32_t resp_msg) resp->tail = tail; } @@ -36783,8 +53439,8 @@ index c1647af4bf..64996c9ae1 100644 +} + +static void -+hns3_handle_link_change_event(struct hns3_hw *hw, -+ struct hns3_mbx_pf_to_vf_cmd *req) ++hns3pf_handle_link_change_event(struct hns3_hw *hw, ++ struct hns3_mbx_vf_to_pf_cmd *req) +{ +#define LINK_STATUS_OFFSET 1 +#define LINK_FAIL_CODE_OFFSET 2 @@ -36798,7 +53454,7 @@ index c1647af4bf..64996c9ae1 100644 void hns3_dev_handle_mbx_msg(struct hns3_hw *hw) { -@@ -291,6 +335,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) +@@ -291,6 +336,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) struct hns3_cmd_desc *desc; uint32_t msg_data; uint16_t *msg_q; @@ -36806,7 +53462,7 @@ index c1647af4bf..64996c9ae1 100644 uint16_t flag; uint8_t *temp; int i; -@@ -301,12 +346,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) +@@ -301,12 +347,13 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) desc = &crq->desc[crq->next_to_use]; req = (struct hns3_mbx_pf_to_vf_cmd *)desc->data; @@ -36821,7 +53477,7 @@ index c1647af4bf..64996c9ae1 100644 /* dropping/not processing this invalid message */ crq->desc[crq->next_to_use].flag = 0; -@@ -314,7 +360,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) +@@ -314,7 +361,7 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) continue; } @@ -36830,21 +53486,46 @@ index c1647af4bf..64996c9ae1 100644 case HNS3_MBX_PF_VF_RESP: resp->resp_status = hns3_resp_to_errno(req->msg[3]); -@@ -335,6 +381,9 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) +@@ -335,9 +382,18 @@ hns3_dev_handle_mbx_msg(struct hns3_hw *hw) hns3_mbx_handler(hw); break; + case HNS3_MBX_PUSH_LINK_STATUS: -+ hns3_handle_link_change_event(hw, req); ++ /* ++ * This message is reported by the firmware and is ++ * reported in 'struct hns3_mbx_vf_to_pf_cmd' format. ++ * Therefore, we should cast the req variable to ++ * 'struct hns3_mbx_vf_to_pf_cmd' and then process it. ++ */ ++ hns3pf_handle_link_change_event(hw, ++ (struct hns3_mbx_vf_to_pf_cmd *)req); + break; default: - hns3_err(hw, - "VF received unsupported(%d) mbx msg from PF", +- hns3_err(hw, +- "VF received unsupported(%d) mbx msg from PF", ++ hns3_err(hw, "received unsupported(%d) mbx msg", + req->msg[0]); + break; + } diff --git a/dpdk/drivers/net/hns3/hns3_mbx.h b/dpdk/drivers/net/hns3/hns3_mbx.h -index 01eddb845d..b01eaacc3c 100644 +index 01eddb845d..a1077fa6aa 100644 --- a/dpdk/drivers/net/hns3/hns3_mbx.h +++ b/dpdk/drivers/net/hns3/hns3_mbx.h -@@ -41,6 +41,8 @@ enum HNS3_MBX_OPCODE { +@@ -1,12 +1,10 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_MBX_H_ + #define _HNS3_MBX_H_ + +-#define HNS3_MBX_VF_MSG_DATA_NUM 16 +- + enum HNS3_MBX_OPCODE { + HNS3_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ + HNS3_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset */ +@@ -41,6 +39,8 @@ enum HNS3_MBX_OPCODE { HNS3_MBX_GET_QID_IN_PF, /* (VF -> PF) get queue id in pf */ HNS3_MBX_HANDLE_VF_TBL = 38, /* (VF -> PF) store/clear hw cfg tbl */ @@ -36853,7 +53534,7 @@ index 01eddb845d..b01eaacc3c 100644 }; /* below are per-VF mac-vlan subcodes */ -@@ -64,6 +66,13 @@ enum hns3_mbx_tbl_cfg_subcode { +@@ -64,10 +64,15 @@ enum hns3_mbx_tbl_cfg_subcode { HNS3_MBX_VPORT_LIST_CLEAR = 0, }; @@ -36866,11 +53547,19 @@ index 01eddb845d..b01eaacc3c 100644 + #define HNS3_MBX_MAX_MSG_SIZE 16 #define HNS3_MBX_MAX_RESP_DATA_SIZE 8 - #define HNS3_MBX_RING_MAP_BASIC_MSG_NUM 3 -@@ -104,6 +113,19 @@ struct hns3_mbx_pf_to_vf_cmd { +-#define HNS3_MBX_RING_MAP_BASIC_MSG_NUM 3 +-#define HNS3_MBX_RING_NODE_VARIABLE_NUM 3 + + struct hns3_mbx_resp_status { + rte_spinlock_t lock; /* protects against contending sync cmd resp */ +@@ -104,10 +109,17 @@ struct hns3_mbx_pf_to_vf_cmd { uint16_t msg[8]; }; +-struct hns3_vf_rst_cmd { +- uint8_t dest_vfid; +- uint8_t vf_rst; +- uint8_t rsv[22]; +struct hns3_ring_chain_param { + uint8_t ring_type; + uint8_t tqp_index; @@ -36882,25 +53571,51 @@ index 01eddb845d..b01eaacc3c 100644 + uint8_t vector_id; + uint8_t ring_num; + struct hns3_ring_chain_param param[HNS3_MBX_MAX_RING_CHAIN_PARAM_NUM]; -+}; -+ - struct hns3_vf_rst_cmd { - uint8_t dest_vfid; - uint8_t vf_rst; + }; + + struct hns3_pf_rst_done_cmd { diff --git a/dpdk/drivers/net/hns3/hns3_mp.c b/dpdk/drivers/net/hns3/hns3_mp.c -index 596c31064a..639f46ced8 100644 +index 596c31064a..b017387efd 100644 --- a/dpdk/drivers/net/hns3/hns3_mp.c +++ b/dpdk/drivers/net/hns3/hns3_mp.c -@@ -14,6 +14,8 @@ +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include +@@ -14,6 +14,9 @@ #include "hns3_rxtx.h" #include "hns3_mp.h" -+static bool hns3_inited; ++/* local data for primary or secondary process. */ ++struct hns3_process_local_data process_data; + /* * Initialize IPC message. * -@@ -192,9 +194,20 @@ void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev) +@@ -86,8 +89,8 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + case HNS3_MP_REQ_START_RXTX: + PMD_INIT_LOG(INFO, "port %u starting datapath", + dev->data->port_id); +- rte_mb(); + hns3_set_rxtx_function(dev); ++ rte_mb(); + mp_init_msg(dev, &mp_res, param->type); + res->result = 0; + ret = rte_mp_reply(&mp_res, peer); +@@ -130,7 +133,8 @@ mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type) + int ret; + int i; + +- if (!hw->secondary_cnt) ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY || ++ __atomic_load_n(&hw->secondary_cnt, __ATOMIC_RELAXED) == 0) + return; + if (type != HNS3_MP_REQ_START_RXTX && type != HNS3_MP_REQ_STOP_RXTX) { + hns3_err(hw, "port %u unknown request (req_type %d)", +@@ -192,23 +196,48 @@ void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev) /* * Initialize by primary process. */ @@ -36910,26 +53625,32 @@ index 596c31064a..639f46ced8 100644 - rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle); + int ret; + -+ if (!hns3_inited) { -+ /* primary is allowed to not support IPC */ -+ ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle); -+ if (ret && rte_errno != ENOTSUP) -+ return ret; ++ if (process_data.init_done) ++ return 0; + -+ hns3_inited = true; -+ } ++ /* primary is allowed to not support IPC */ ++ ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle); ++ if (ret && rte_errno != ENOTSUP) ++ return ret; ++ ++ process_data.init_done = true; + + return 0; } - /* -@@ -202,13 +215,24 @@ void hns3_mp_init_primary(void) - */ - void hns3_mp_uninit_primary(void) +-/* +- * Un-initialize by primary process. +- */ +-void hns3_mp_uninit_primary(void) ++void hns3_mp_uninit(void) { - rte_mp_action_unregister(HNS3_MP_NAME); -+ if (hns3_inited) ++ process_data.eth_dev_cnt--; ++ ++ if (process_data.eth_dev_cnt == 0) { + rte_mp_action_unregister(HNS3_MP_NAME); ++ process_data.init_done = false; ++ } } /* @@ -36941,35 +53662,58 @@ index 596c31064a..639f46ced8 100644 - rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle); + int ret; + -+ if (!hns3_inited) { -+ ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle); -+ if (ret) -+ return ret; ++ if (process_data.init_done) ++ return 0; + -+ hns3_inited = true; -+ } ++ ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle); ++ if (ret) ++ return ret; ++ ++ process_data.init_done = true; + + return 0; } diff --git a/dpdk/drivers/net/hns3/hns3_mp.h b/dpdk/drivers/net/hns3/hns3_mp.h -index aefbeb140e..036546ae11 100644 +index aefbeb140e..ef334648ff 100644 --- a/dpdk/drivers/net/hns3/hns3_mp.h +++ b/dpdk/drivers/net/hns3/hns3_mp.h -@@ -7,8 +7,8 @@ +@@ -1,14 +1,21 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + #ifndef _HNS3_MP_H_ + #define _HNS3_MP_H_ + ++/* Local data for primary or secondary process. */ ++struct hns3_process_local_data { ++ bool init_done; /* Process action register completed flag. */ ++ int eth_dev_cnt; /* Ethdev count under the current process. */ ++}; ++extern struct hns3_process_local_data process_data; ++ void hns3_mp_req_start_rxtx(struct rte_eth_dev *dev); void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev); -void hns3_mp_init_primary(void); -+int hns3_mp_init_primary(void); - void hns3_mp_uninit_primary(void); +-void hns3_mp_uninit_primary(void); -void hns3_mp_init_secondary(void); ++int hns3_mp_init_primary(void); ++void hns3_mp_uninit(void); +int hns3_mp_init_secondary(void); #endif /* _HNS3_MP_H_ */ diff --git a/dpdk/drivers/net/hns3/hns3_regs.c b/dpdk/drivers/net/hns3/hns3_regs.c -index 23405030e7..2f34357d48 100644 +index 23405030e7..a38e945670 100644 --- a/dpdk/drivers/net/hns3/hns3_regs.c +++ b/dpdk/drivers/net/hns3/hns3_regs.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -116,17 +116,12 @@ static int hns3_get_regs_length(struct hns3_hw *hw, uint32_t *length) { @@ -37001,7 +53745,7 @@ index 23405030e7..2f34357d48 100644 - regs_num_64_bit * sizeof(uint64_t); + len = (cmdq_lines + common_lines + ring_lines * hw->tqps_num + + tqp_intr_lines * hw->num_msi) * REG_NUM_PER_LINE; -+ + + if (!hns->is_vf) { + ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); + if (ret) { @@ -37015,7 +53759,7 @@ index 23405030e7..2f34357d48 100644 + REG_LEN_PER_LINE + 1; + len += dfx_reg_lines * REG_NUM_PER_LINE; + } - ++ + *length = len; return 0; } @@ -37116,9 +53860,24 @@ index 23405030e7..2f34357d48 100644 struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; uint32_t regs_num_32_bit; -@@ -344,7 +357,10 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) +@@ -323,11 +336,6 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + uint32_t *data; + int ret; + +- if (regs == NULL) { +- hns3_err(hw, "the input parameter regs is NULL!"); +- return -EINVAL; +- } +- + ret = hns3_get_regs_length(hw, &length); + if (ret) + return ret; +@@ -343,8 +351,13 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) + if (regs->length && regs->length != length) return -ENOTSUP; ++ regs->version = hw->fw_version; ++ /* fetching per-PF registers values from PF PCIe register space */ - hns3_direct_access_regs(hw, data); + data += hns3_direct_access_regs(hw, data); @@ -37128,7 +53887,7 @@ index 23405030e7..2f34357d48 100644 ret = hns3_get_regs_num(hw, ®s_num_32_bit, ®s_num_64_bit); if (ret) { -@@ -358,11 +374,16 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) +@@ -358,11 +371,16 @@ hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs) hns3_err(hw, "Get 32 bit register failed, ret = %d", ret); return ret; } @@ -37149,9 +53908,16 @@ index 23405030e7..2f34357d48 100644 return ret; } diff --git a/dpdk/drivers/net/hns3/hns3_regs.h b/dpdk/drivers/net/hns3/hns3_regs.h -index 2f5faafe18..64bd6931b3 100644 +index 2f5faafe18..2535bc977a 100644 --- a/dpdk/drivers/net/hns3/hns3_regs.h +++ b/dpdk/drivers/net/hns3/hns3_regs.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_REGS_H_ @@ -94,6 +94,16 @@ #define HNS3_TQP_INTR_RL_REG 0x20900 @@ -37170,10 +53936,30 @@ index 2f5faafe18..64bd6931b3 100644 int hns3_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs); #endif /* _HNS3_REGS_H_ */ diff --git a/dpdk/drivers/net/hns3/hns3_rss.c b/dpdk/drivers/net/hns3/hns3_rss.c -index b8c20e6d9d..a63d6ef725 100644 +index b8c20e6d9d..5b747a01ec 100644 --- a/dpdk/drivers/net/hns3/hns3_rss.c +++ b/dpdk/drivers/net/hns3/hns3_rss.c -@@ -127,7 +127,7 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include +@@ -12,10 +12,8 @@ + #include "hns3_ethdev.h" + #include "hns3_logs.h" + +-/* +- * The hash key used for rss initialization. +- */ +-static const uint8_t hns3_hash_key[] = { ++/* Default hash keys */ ++const uint8_t hns3_hash_key[] = { + 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, + 0x41, 0x67, 0x25, 0x3D, 0x43, 0xA3, 0x8F, 0xB0, + 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, +@@ -127,7 +125,7 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { num = i * HNS3_RSS_CFG_TBL_SIZE + j; @@ -37182,7 +53968,7 @@ index b8c20e6d9d..a63d6ef725 100644 } ret = hns3_cmd_send(hw, &desc, 1); if (ret) { -@@ -211,7 +211,11 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, +@@ -211,7 +209,11 @@ hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, req->ipv6_fragment_en |= HNS3_IP_OTHER_BIT_MASK; break; default: @@ -37195,7 +53981,7 @@ index b8c20e6d9d..a63d6ef725 100644 break; } } -@@ -251,12 +255,15 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -251,12 +253,15 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, struct hns3_hw *hw = &hns->hw; struct hns3_rss_tuple_cfg *tuple = &hw->rss_info.rss_tuple_sets; struct hns3_rss_conf *rss_cfg = &hw->rss_info; @@ -37212,7 +53998,7 @@ index b8c20e6d9d..a63d6ef725 100644 rte_spinlock_lock(&hw->lock); ret = hns3_set_rss_tuple_by_rss_hf(hw, tuple, rss_hf); if (ret) -@@ -285,6 +292,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -285,6 +290,8 @@ hns3_dev_rss_hash_update(struct rte_eth_dev *dev, ret = -EINVAL; goto conf_err; } @@ -37221,7 +54007,7 @@ index b8c20e6d9d..a63d6ef725 100644 ret = hns3_set_rss_algo_key(hw, algo, key); if (ret) goto conf_err; -@@ -319,8 +328,10 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, +@@ -319,8 +326,10 @@ hns3_dev_rss_hash_conf_get(struct rte_eth_dev *dev, rss_conf->rss_hf = rss_cfg->conf.types; /* Get the RSS Key required by the user */ @@ -37233,7 +54019,7 @@ index b8c20e6d9d..a63d6ef725 100644 rte_spinlock_unlock(&hw->lock); return 0; -@@ -347,7 +358,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, +@@ -347,7 +356,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, struct hns3_rss_conf *rss_cfg = &hw->rss_info; uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ uint8_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; @@ -37242,7 +54028,7 @@ index b8c20e6d9d..a63d6ef725 100644 int ret; if (reta_size != indir_size || reta_size > ETH_RSS_RETA_SIZE_512) { -@@ -359,16 +370,15 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, +@@ -359,16 +368,15 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, rte_spinlock_lock(&hw->lock); memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, HNS3_RSS_IND_TBL_SIZE); @@ -37264,7 +54050,7 @@ index b8c20e6d9d..a63d6ef725 100644 return -EINVAL; } -@@ -417,7 +427,7 @@ hns3_dev_rss_reta_query(struct rte_eth_dev *dev, +@@ -417,39 +425,65 @@ hns3_dev_rss_reta_query(struct rte_eth_dev *dev, shift = i % RTE_RETA_GROUP_SIZE; if (reta_conf[idx].mask & (1ULL << shift)) reta_conf[idx].reta[shift] = @@ -37273,7 +54059,80 @@ index b8c20e6d9d..a63d6ef725 100644 } rte_spinlock_unlock(&hw->lock); return 0; -@@ -500,7 +510,9 @@ hns3_set_default_rss_args(struct hns3_hw *hw) + } + +-/* +- * Used to configure the tc_size and tc_offset. +- */ ++static void ++hns3_set_rss_tc_mode_entry(struct hns3_hw *hw, uint8_t *tc_valid, ++ uint16_t *tc_size, uint16_t *tc_offset, ++ uint8_t tc_num) ++{ ++ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); ++ uint16_t rss_size = hw->alloc_rss_size; ++ uint16_t roundup_size; ++ uint16_t i; ++ ++ roundup_size = roundup_pow_of_two(rss_size); ++ roundup_size = ilog2(roundup_size); ++ ++ for (i = 0; i < tc_num; i++) { ++ if (hns->is_vf) { ++ /* ++ * For packets with VLAN priorities destined for the VF, ++ * hardware still assign Rx queue based on the Up-to-TC ++ * mapping PF configured. But VF has only one TC. If ++ * other TC don't enable, it causes that the priority ++ * packets that aren't destined for TC0 aren't received ++ * by RSS hash but is destined for queue 0. So driver ++ * has to enable the unused TC by using TC0 queue ++ * mapping configuration. ++ */ ++ tc_valid[i] = (hw->hw_tc_map & BIT(i)) ? ++ !!(hw->hw_tc_map & BIT(i)) : 1; ++ tc_size[i] = roundup_size; ++ tc_offset[i] = (hw->hw_tc_map & BIT(i)) ? ++ rss_size * i : 0; ++ } else { ++ tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); ++ tc_size[i] = tc_valid[i] ? roundup_size : 0; ++ tc_offset[i] = tc_valid[i] ? rss_size * i : 0; ++ } ++ } ++} ++ + static int + hns3_set_rss_tc_mode(struct hns3_hw *hw) + { +- uint16_t rss_size = hw->alloc_rss_size; + struct hns3_rss_tc_mode_cmd *req; + uint16_t tc_offset[HNS3_MAX_TC_NUM]; + uint8_t tc_valid[HNS3_MAX_TC_NUM]; + uint16_t tc_size[HNS3_MAX_TC_NUM]; + struct hns3_cmd_desc desc; +- uint16_t roundup_size; + uint16_t i; + int ret; + +- req = (struct hns3_rss_tc_mode_cmd *)desc.data; +- +- roundup_size = roundup_pow_of_two(rss_size); +- roundup_size = ilog2(roundup_size); +- +- for (i = 0; i < HNS3_MAX_TC_NUM; i++) { +- tc_valid[i] = !!(hw->hw_tc_map & BIT(i)); +- tc_size[i] = roundup_size; +- tc_offset[i] = rss_size * i; +- } ++ hns3_set_rss_tc_mode_entry(hw, tc_valid, tc_size, ++ tc_offset, HNS3_MAX_TC_NUM); + ++ req = (struct hns3_rss_tc_mode_cmd *)desc.data; + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_TC_MODE, false); + for (i = 0; i < HNS3_MAX_TC_NUM; i++) { + uint16_t mode = 0; +@@ -500,7 +534,9 @@ hns3_set_default_rss_args(struct hns3_hw *hw) int i; /* Default hash algorithm */ @@ -37284,7 +54143,16 @@ index b8c20e6d9d..a63d6ef725 100644 memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); /* Initialize RSS indirection table */ -@@ -524,7 +536,7 @@ hns3_config_rss(struct hns3_adapter *hns) +@@ -509,7 +545,7 @@ hns3_set_default_rss_args(struct hns3_hw *hw) + } + + /* +- * RSS initialization for hns3 pmd driver. ++ * RSS initialization for hns3 PMD. + */ + int + hns3_config_rss(struct hns3_adapter *hns) +@@ -524,7 +560,7 @@ hns3_config_rss(struct hns3_adapter *hns) enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; @@ -37293,7 +54161,7 @@ index b8c20e6d9d..a63d6ef725 100644 if (((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) hns3_rss_uninit(hns); -@@ -538,10 +550,16 @@ hns3_config_rss(struct hns3_adapter *hns) +@@ -538,10 +574,16 @@ hns3_config_rss(struct hns3_adapter *hns) if (ret) return ret; @@ -37314,7 +54182,7 @@ index b8c20e6d9d..a63d6ef725 100644 ret = hns3_set_rss_tc_mode(hw); if (ret) -@@ -550,9 +568,11 @@ hns3_config_rss(struct hns3_adapter *hns) +@@ -550,9 +592,11 @@ hns3_config_rss(struct hns3_adapter *hns) return ret; rss_indir_table_uninit: @@ -37329,10 +54197,26 @@ index b8c20e6d9d..a63d6ef725 100644 rss_tuple_uninit: hns3_rss_tuple_uninit(hw); +@@ -564,7 +608,7 @@ hns3_config_rss(struct hns3_adapter *hns) + } + + /* +- * RSS uninitialization for hns3 pmd driver. ++ * RSS uninitialization for hns3 PMD. + */ + void + hns3_rss_uninit(struct hns3_adapter *hns) diff --git a/dpdk/drivers/net/hns3/hns3_rss.h b/dpdk/drivers/net/hns3/hns3_rss.h -index 7ffc151314..b49e399901 100644 +index 7ffc151314..920abb3f31 100644 --- a/dpdk/drivers/net/hns3/hns3_rss.h +++ b/dpdk/drivers/net/hns3/hns3_rss.h +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_RSS_H_ @@ -54,6 +54,7 @@ struct hns3_rss_conf { struct hns3_rss_tuple_cfg rss_tuple_sets; uint8_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; /* Shadow table */ @@ -37341,7 +54225,16 @@ index 7ffc151314..b49e399901 100644 }; /* Bit 8 ~Bit 15 */ -@@ -121,4 +122,6 @@ int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, +@@ -99,6 +100,8 @@ static inline uint32_t roundup_pow_of_two(uint32_t x) + return 1UL << fls(x - 1); + } + ++extern const uint8_t hns3_hash_key[]; ++ + struct hns3_adapter; + + int hns3_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -121,4 +124,6 @@ int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); int hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, const uint8_t *key); @@ -37349,9 +54242,16 @@ index 7ffc151314..b49e399901 100644 + #endif /* _HNS3_RSS_H_ */ diff --git a/dpdk/drivers/net/hns3/hns3_rxtx.c b/dpdk/drivers/net/hns3/hns3_rxtx.c -index 8166447131..5971cf6cd5 100644 +index 8166447131..c538c98725 100644 --- a/dpdk/drivers/net/hns3/hns3_rxtx.c +++ b/dpdk/drivers/net/hns3/hns3_rxtx.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -30,13 +30,14 @@ #include "hns3_logs.h" @@ -37498,7 +54398,23 @@ index 8166447131..5971cf6cd5 100644 } static int -@@ -220,20 +315,54 @@ hns3_init_tx_queue_hw(struct hns3_tx_queue *txq) +@@ -199,7 +294,7 @@ hns3_init_rx_queue_hw(struct hns3_rx_queue *rxq) + + hns3_write_dev(rxq, HNS3_RING_RX_BASEADDR_L_REG, (uint32_t)dma_addr); + hns3_write_dev(rxq, HNS3_RING_RX_BASEADDR_H_REG, +- (uint32_t)((dma_addr >> 31) >> 1)); ++ (uint32_t)(dma_addr >> 32)); + + hns3_write_dev(rxq, HNS3_RING_RX_BD_LEN_REG, + hns3_buf_size2type(rx_buf_len)); +@@ -214,26 +309,60 @@ hns3_init_tx_queue_hw(struct hns3_tx_queue *txq) + + hns3_write_dev(txq, HNS3_RING_TX_BASEADDR_L_REG, (uint32_t)dma_addr); + hns3_write_dev(txq, HNS3_RING_TX_BASEADDR_H_REG, +- (uint32_t)((dma_addr >> 31) >> 1)); ++ (uint32_t)(dma_addr >> 32)); + + hns3_write_dev(txq, HNS3_RING_TX_BD_NUM_REG, HNS3_CFG_DESC_NUM(txq->nb_tx_desc)); } @@ -38833,7 +55749,7 @@ index 8166447131..5971cf6cd5 100644 /* free original mbufs */ rte_pktmbuf_free(tx_pkt); -@@ -1320,180 +2051,211 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt, +@@ -1320,180 +2051,212 @@ hns3_reassemble_tx_pkts(void *tx_queue, struct rte_mbuf *tx_pkt, } static void @@ -39079,6 +55995,7 @@ index 8166447131..5971cf6cd5 100644 - /* Enable L4 checksum offloads */ switch (ol_flags & PKT_TX_L4_MASK) { ++ case PKT_TX_TCP_CKSUM | PKT_TX_TCP_SEG: case PKT_TX_TCP_CKSUM: tmp = *type_cs_vlan_tso_len; - hns3_set_field(tmp, HNS3_TXD_L4T_M, HNS3_TXD_L4T_S, @@ -39143,7 +56060,7 @@ index 8166447131..5971cf6cd5 100644 desc->tx.type_cs_vlan_tso_len |= rte_cpu_to_le_32(value); } -@@ -1509,12 +2271,6 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts, +@@ -1509,12 +2272,6 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts, for (i = 0; i < nb_pkts; i++) { m = tx_pkts[i]; @@ -39156,7 +56073,7 @@ index 8166447131..5971cf6cd5 100644 #ifdef RTE_LIBRTE_ETHDEV_DEBUG ret = rte_validate_tx_offload(m); if (ret != 0) { -@@ -1534,18 +2290,23 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts, +@@ -1534,18 +2291,23 @@ hns3_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts, static int hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id, @@ -39189,7 +56106,7 @@ index 8166447131..5971cf6cd5 100644 return 0; } -@@ -1553,17 +2314,13 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id, +@@ -1553,17 +2315,13 @@ hns3_parse_cksum(struct hns3_tx_queue *txq, uint16_t tx_desc_id, uint16_t hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { @@ -39207,7 +56124,7 @@ index 8166447131..5971cf6cd5 100644 uint16_t tx_pkt_num; uint16_t tx_bd_max; uint16_t nb_buf; -@@ -1572,16 +2329,10 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1572,16 +2330,10 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* free useless buffer */ hns3_tx_free_useless_buffer(txq); @@ -39225,7 +56142,7 @@ index 8166447131..5971cf6cd5 100644 /* send packets */ tx_bak_pkt = &txq->sw_ring[tx_next_use]; -@@ -1590,7 +2341,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1590,7 +2342,7 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) nb_buf = tx_pkt->nb_segs; @@ -39234,7 +56151,7 @@ index 8166447131..5971cf6cd5 100644 if (nb_tx == 0) return 0; -@@ -1629,15 +2380,14 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1629,15 +2381,14 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) nb_buf = m_seg->nb_segs; } @@ -39252,7 +56169,7 @@ index 8166447131..5971cf6cd5 100644 tx_next_use++; tx_bak_pkt++; if (tx_next_use >= tx_bd_max) { -@@ -1650,15 +2400,13 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1650,15 +2401,13 @@ hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) nb_hold += i; txq->next_to_use = tx_next_use; @@ -39270,11 +56187,24 @@ index 8166447131..5971cf6cd5 100644 return nb_tx; } +@@ -1683,6 +2432,6 @@ void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev) + } else { + eth_dev->rx_pkt_burst = hns3_dummy_rxtx_burst; + eth_dev->tx_pkt_burst = hns3_dummy_rxtx_burst; +- eth_dev->tx_pkt_prepare = hns3_dummy_rxtx_burst; ++ eth_dev->tx_pkt_prepare = NULL; + } + } diff --git a/dpdk/drivers/net/hns3/hns3_rxtx.h b/dpdk/drivers/net/hns3/hns3_rxtx.h -index daf51f4095..88a75843b3 100644 +index daf51f4095..3ed1d90dcd 100644 --- a/dpdk/drivers/net/hns3/hns3_rxtx.h +++ b/dpdk/drivers/net/hns3/hns3_rxtx.h -@@ -5,11 +5,20 @@ +@@ -1,15 +1,24 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + #ifndef _HNS3_RXTX_H_ #define _HNS3_RXTX_H_ @@ -39296,7 +56226,17 @@ index daf51f4095..88a75843b3 100644 #define HNS3_BD_SIZE_512_TYPE 0 #define HNS3_BD_SIZE_1024_TYPE 1 -@@ -222,6 +231,7 @@ struct hns3_entry { +@@ -69,9 +78,6 @@ + #define HNS3_RXD_LUM_B 9 + #define HNS3_RXD_CRCP_B 10 + #define HNS3_RXD_L3L4P_B 11 +-#define HNS3_RXD_TSIND_S 12 +-#define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S) +-#define HNS3_RXD_LKBK_B 15 + #define HNS3_RXD_GRO_SIZE_S 16 + #define HNS3_RXD_GRO_SIZE_M (0x3ff << HNS3_RXD_GRO_SIZE_S) + +@@ -222,6 +228,7 @@ struct hns3_entry { struct hns3_rx_queue { void *io_base; @@ -39304,7 +56244,7 @@ index daf51f4095..88a75843b3 100644 struct hns3_adapter *hns; struct rte_mempool *mb_pool; struct hns3_desc *rx_ring; -@@ -235,17 +245,24 @@ struct hns3_rx_queue { +@@ -235,17 +242,24 @@ struct hns3_rx_queue { uint16_t queue_id; uint16_t port_id; uint16_t nb_rx_desc; @@ -39333,7 +56273,7 @@ index daf51f4095..88a75843b3 100644 uint64_t l2_errors; uint64_t pkt_len_errors; uint64_t l3_csum_erros; -@@ -269,19 +286,28 @@ struct hns3_tx_queue { +@@ -269,19 +283,28 @@ struct hns3_tx_queue { uint16_t next_to_use; uint16_t tx_bd_ready; @@ -39368,7 +56308,7 @@ index daf51f4095..88a75843b3 100644 enum hns3_cksum_status { HNS3_CKSUM_NONE = 0, -@@ -295,6 +321,10 @@ void hns3_dev_rx_queue_release(void *queue); +@@ -295,6 +318,10 @@ void hns3_dev_rx_queue_release(void *queue); void hns3_dev_tx_queue_release(void *queue); void hns3_free_all_queues(struct rte_eth_dev *dev); int hns3_reset_all_queues(struct hns3_adapter *hns); @@ -39379,7 +56319,7 @@ index daf51f4095..88a75843b3 100644 int hns3_start_queues(struct hns3_adapter *hns, bool reset_queue); int hns3_stop_queues(struct hns3_adapter *hns, bool reset_queue); void hns3_dev_release_mbufs(struct hns3_adapter *hns); -@@ -311,4 +341,12 @@ uint16_t hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, +@@ -311,4 +338,12 @@ uint16_t hns3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev); void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev); @@ -39393,9 +56333,16 @@ index daf51f4095..88a75843b3 100644 + #endif /* _HNS3_RXTX_H_ */ diff --git a/dpdk/drivers/net/hns3/hns3_stats.c b/dpdk/drivers/net/hns3/hns3_stats.c -index 9948beb179..d2ef722cfb 100644 +index 9948beb179..b4bc4f28f3 100644 --- a/dpdk/drivers/net/hns3/hns3_stats.c +++ b/dpdk/drivers/net/hns3/hns3_stats.c +@@ -1,5 +1,5 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #include @@ -219,8 +219,6 @@ static const struct hns3_xstats_name_offset hns3_reset_stats_strings[] = { /* The statistic of errors in Rx BD */ @@ -39405,7 +56352,170 @@ index 9948beb179..d2ef722cfb 100644 {"RX_PKT_LEN_ERRORS", HNS3_RX_BD_ERROR_STATS_FIELD_OFFSET(pkt_len_errors)}, {"L2_RX_ERRORS", -@@ -492,6 +490,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) +@@ -250,24 +248,21 @@ static const struct hns3_xstats_name_offset hns3_rx_bd_error_strings[] = { + #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \ + HNS3_NUM_RESET_XSTATS) + +-/* +- * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034. +- * This command is used before send 'query_mac_stat command', the descriptor +- * number of 'query_mac_stat command' must match with reg_num in this command. +- * @praram hw +- * Pointer to structure hns3_hw. +- * @return +- * 0 on success. +- */ + static int +-hns3_update_mac_stats(struct hns3_hw *hw, const uint32_t desc_num) ++hns3_update_mac_stats(struct hns3_hw *hw) + { ++#define HNS3_MAC_STATS_REG_NUM_PER_DESC 4 ++ + uint64_t *data = (uint64_t *)(&hw->mac_stats); + struct hns3_cmd_desc *desc; ++ uint32_t stats_iterms; + uint64_t *desc_data; +- uint16_t i, k, n; ++ uint32_t desc_num; ++ uint16_t i; + int ret; + ++ /* The first desc has a 64-bit header, so need to consider it. */ ++ desc_num = hw->mac_stats_reg_num / HNS3_MAC_STATS_REG_NUM_PER_DESC + 1; + desc = rte_malloc("hns3_mac_desc", + desc_num * sizeof(struct hns3_cmd_desc), 0); + if (desc == NULL) { +@@ -283,65 +278,71 @@ hns3_update_mac_stats(struct hns3_hw *hw, const uint32_t desc_num) + return ret; + } + +- for (i = 0; i < desc_num; i++) { +- /* For special opcode 0034, only the first desc has the head */ +- if (i == 0) { +- desc_data = (uint64_t *)(&desc[i].data[0]); +- n = HNS3_RD_FIRST_STATS_NUM; +- } else { +- desc_data = (uint64_t *)(&desc[i]); +- n = HNS3_RD_OTHER_STATS_NUM; +- } +- +- for (k = 0; k < n; k++) { +- *data += rte_le_to_cpu_64(*desc_data); +- data++; +- desc_data++; +- } ++ stats_iterms = RTE_MIN(sizeof(hw->mac_stats) / sizeof(uint64_t), ++ hw->mac_stats_reg_num); ++ desc_data = (uint64_t *)(&desc[0].data[0]); ++ for (i = 0; i < stats_iterms; i++) { ++ /* ++ * Data memory is continuous and only the first descriptor has a ++ * header in this command. ++ */ ++ *data += rte_le_to_cpu_64(*desc_data); ++ data++; ++ desc_data++; + } + rte_free(desc); + + return 0; + } + +-/* +- * Query Mac stat reg num command ,opcode id: 0x0033. +- * This command is used before send 'query_mac_stat command', the descriptor +- * number of 'query_mac_stat command' must match with reg_num in this command. +- * @praram rte_stats +- * Pointer to structure rte_eth_stats. +- * @return +- * 0 on success. +- */ + static int +-hns3_mac_query_reg_num(struct rte_eth_dev *dev, uint32_t *desc_num) ++hns3_mac_query_reg_num(struct hns3_hw *hw, uint32_t *reg_num) + { +- struct hns3_adapter *hns = dev->data->dev_private; +- struct hns3_hw *hw = &hns->hw; ++#define HNS3_MAC_STATS_RSV_REG_NUM_ON_HIP08_B 3 + struct hns3_cmd_desc desc; +- uint32_t *desc_data; +- uint32_t reg_num; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_REG_NUM, true); + ret = hns3_cmd_send(hw, &desc, 1); +- if (ret) ++ if (ret) { ++ hns3_err(hw, "failed to query MAC statistic reg number, ret = %d", ++ ret); + return ret; ++ } + +- /* +- * The num of MAC statistics registers that are provided by IMP in this +- * version. +- */ +- desc_data = (uint32_t *)(&desc.data[0]); +- reg_num = rte_le_to_cpu_32(*desc_data); ++ /* The number of MAC statistics registers are provided by firmware. */ ++ *reg_num = rte_le_to_cpu_32(desc.data[0]); ++ if (*reg_num == 0) { ++ hns3_err(hw, "MAC statistic reg number is invalid!"); ++ return -ENODATA; ++ } + + /* +- * The descriptor number of 'query_additional_mac_stat command' is +- * '1 + (reg_num-3)/4 + ((reg_num-3)%4 !=0)'; +- * This value is 83 in this version ++ * If driver doesn't request the firmware to report more MAC statistics ++ * iterms and the total number of MAC statistics registers by using new ++ * method, firmware will only reports the number of valid statistics ++ * registers. However, structure hns3_mac_stats in driver contains valid ++ * and reserved statistics iterms. In this case, the total register ++ * number must be added to three reserved statistics registers. + */ +- *desc_num = 1 + ((reg_num - 3) >> 2) + +- (uint32_t)(((reg_num - 3) & 0x3) ? 1 : 0); ++ *reg_num += HNS3_MAC_STATS_RSV_REG_NUM_ON_HIP08_B; ++ ++ return 0; ++} ++ ++int ++hns3_query_mac_stats_reg_num(struct hns3_hw *hw) ++{ ++ uint32_t mac_stats_reg_num = 0; ++ int ret; ++ ++ ret = hns3_mac_query_reg_num(hw, &mac_stats_reg_num); ++ if (ret) ++ return ret; ++ ++ hw->mac_stats_reg_num = mac_stats_reg_num; ++ if (hw->mac_stats_reg_num > sizeof(hw->mac_stats) / sizeof(uint64_t)) ++ hns3_warn(hw, "MAC stats reg number from firmware is greater than stats iterms in driver."); + + return 0; + } +@@ -351,15 +352,8 @@ hns3_query_update_mac_stats(struct rte_eth_dev *dev) + { + struct hns3_adapter *hns = dev->data->dev_private; + struct hns3_hw *hw = &hns->hw; +- uint32_t desc_num; +- int ret; + +- ret = hns3_mac_query_reg_num(dev, &desc_num); +- if (ret == 0) +- ret = hns3_update_mac_stats(hw, desc_num); +- else +- hns3_err(hw, "Query mac reg num fail : %d", ret); +- return ret; ++ return hns3_update_mac_stats(hw); + } + + /* Get tqp stats from register */ +@@ -492,6 +486,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) if (ret) { hns3_err(hw, "Failed to reset RX No.%d queue stat: %d", i, ret); @@ -39413,7 +56523,7 @@ index 9948beb179..d2ef722cfb 100644 } hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_TX_STATUS, -@@ -502,20 +501,19 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) +@@ -502,20 +497,19 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) if (ret) { hns3_err(hw, "Failed to reset TX No.%d queue stat: %d", i, ret); @@ -39439,7 +56549,7 @@ index 9948beb179..d2ef722cfb 100644 } } -@@ -524,7 +522,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) +@@ -524,7 +518,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) return 0; } @@ -39448,7 +56558,7 @@ index 9948beb179..d2ef722cfb 100644 hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev) { struct hns3_adapter *hns = dev->data->dev_private; -@@ -533,10 +531,14 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev) +@@ -533,10 +527,14 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev) int ret; ret = hns3_query_update_mac_stats(dev); @@ -39464,7 +56574,32 @@ index 9948beb179..d2ef722cfb 100644 } /* This function calculates the number of xstats based on the current config */ -@@ -593,9 +595,9 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, +@@ -560,9 +558,13 @@ hns3_xstats_calc_num(struct rte_eth_dev *dev) + * @praram xstats + * A pointer to a table of structure of type *rte_eth_xstat* + * to be filled with device statistics ids and values. +- * This parameter can be set to NULL if n is 0. ++ * This parameter can be set to NULL if and only if n is 0. + * @param n + * The size of the xstats array (number of elements). ++ * If lower than the required number of elements, the function returns the ++ * required number of elements. ++ * If equal to zero, the xstats parameter must be NULL, the function returns ++ * the required number of elements. + * @return + * 0 on fail, count(The size of the statistics elements) on success. + */ +@@ -581,9 +583,6 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + int count; + int ret; + +- if (xstats == NULL) +- return 0; +- + count = hns3_xstats_calc_num(dev); + if ((int)n < count) + return count; +@@ -593,9 +592,9 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, if (!hns->is_vf) { /* Update Mac stats */ ret = hns3_query_update_mac_stats(dev); @@ -39476,7 +56611,7 @@ index 9948beb179..d2ef722cfb 100644 } /* Get MAC stats from hw->hw_xstats.mac_stats struct */ -@@ -752,9 +754,13 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, +@@ -752,9 +751,13 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, char *addr; int ret; @@ -39491,7 +56626,7 @@ index 9948beb179..d2ef722cfb 100644 /* Update tqp stats by read register */ ret = hns3_update_tqp_stats(hw); if (ret) { -@@ -802,6 +808,15 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, +@@ -802,6 +805,15 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, } } @@ -39507,7 +56642,7 @@ index 9948beb179..d2ef722cfb 100644 for (i = 0; i < size; i++) { if (ids[i] >= cnt_stats) { hns3_err(hw, "ids[%d] (%" PRIx64 ") is invalid, " -@@ -850,9 +865,16 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, +@@ -850,9 +862,16 @@ hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, uint16_t i, j; uint64_t len; @@ -39525,7 +56660,7 @@ index 9948beb179..d2ef722cfb 100644 len = cnt_stats * sizeof(struct rte_eth_xstat_name); xstats_names_copy = rte_zmalloc("hns3_xstats_names", len, 0); if (xstats_names_copy == NULL) { -@@ -911,17 +933,37 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) +@@ -911,17 +930,37 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_pf *pf = &hns->pf; @@ -39566,10 +56701,52 @@ index 9948beb179..d2ef722cfb 100644 memset(&pf->abn_int_stats, 0, sizeof(struct hns3_err_msix_intr_stats)); diff --git a/dpdk/drivers/net/hns3/hns3_stats.h b/dpdk/drivers/net/hns3/hns3_stats.h -index 365bae083d..34c76be21e 100644 +index 365bae083d..be51bbca8b 100644 --- a/dpdk/drivers/net/hns3/hns3_stats.h +++ b/dpdk/drivers/net/hns3/hns3_stats.h -@@ -141,8 +141,8 @@ int hns3_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, +@@ -1,14 +1,10 @@ + /* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2018-2019 Hisilicon Limited. ++ * Copyright(c) 2018-2019 HiSilicon Limited. + */ + + #ifndef _HNS3_STATS_H_ + #define _HNS3_STATS_H_ + +-/* stats macro */ +-#define HNS3_MAC_CMD_NUM 21 +-#define HNS3_RD_FIRST_STATS_NUM 2 +-#define HNS3_RD_OTHER_STATS_NUM 4 + #define HNS3_VALUES_BYTES 8 + + /* TQP stats */ +@@ -23,6 +19,7 @@ struct hns3_tqp_stats { + struct hns3_mac_stats { + uint64_t mac_tx_mac_pause_num; + uint64_t mac_rx_mac_pause_num; ++ uint64_t rsv0; + uint64_t mac_tx_pfc_pri0_pkt_num; + uint64_t mac_tx_pfc_pri1_pkt_num; + uint64_t mac_tx_pfc_pri2_pkt_num; +@@ -59,7 +56,7 @@ struct hns3_mac_stats { + uint64_t mac_tx_1519_2047_oct_pkt_num; + uint64_t mac_tx_2048_4095_oct_pkt_num; + uint64_t mac_tx_4096_8191_oct_pkt_num; +- uint64_t rsv0; ++ uint64_t rsv1; + uint64_t mac_tx_8192_9216_oct_pkt_num; + uint64_t mac_tx_9217_12287_oct_pkt_num; + uint64_t mac_tx_12288_16383_oct_pkt_num; +@@ -86,7 +83,7 @@ struct hns3_mac_stats { + uint64_t mac_rx_1519_2047_oct_pkt_num; + uint64_t mac_rx_2048_4095_oct_pkt_num; + uint64_t mac_rx_4096_8191_oct_pkt_num; +- uint64_t rsv1; ++ uint64_t rsv2; + uint64_t mac_rx_8192_9216_oct_pkt_num; + uint64_t mac_rx_9217_12287_oct_pkt_num; + uint64_t mac_rx_12288_16383_oct_pkt_num; +@@ -141,12 +138,13 @@ int hns3_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned int size); int hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, @@ -39580,11 +56757,26 @@ index 365bae083d..34c76be21e 100644 uint32_t size); int hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, + const uint64_t *ids, + uint32_t size); + int hns3_stats_reset(struct rte_eth_dev *dev); ++int hns3_query_mac_stats_reg_num(struct hns3_hw *hw); + #endif /* _HNS3_STATS_H_ */ diff --git a/dpdk/drivers/net/i40e/Makefile b/dpdk/drivers/net/i40e/Makefile -index 435eb511ad..4ea58bd9e7 100644 +index 435eb511ad..3f7565fbd6 100644 --- a/dpdk/drivers/net/i40e/Makefile +++ b/dpdk/drivers/net/i40e/Makefile -@@ -72,7 +72,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_dcb.c +@@ -35,6 +35,9 @@ CFLAGS_BASE_DRIVER += -Wno-missing-field-initializers + CFLAGS_BASE_DRIVER += -Wno-pointer-to-int-cast + CFLAGS_BASE_DRIVER += -Wno-format-nonliteral + CFLAGS_BASE_DRIVER += -Wno-unused-variable ++ifeq ($(shell test $(CLANG_MAJOR_VERSION) -ge 13 && echo 1), 1) ++CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable ++endif + else + CFLAGS_BASE_DRIVER = -Wno-sign-compare + CFLAGS_BASE_DRIVER += -Wno-unused-value +@@ -72,7 +75,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_dcb.c SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c @@ -39605,7 +56797,7 @@ index 8a5339cfff..b46593566b 100644 Intel® I40E driver diff --git a/dpdk/drivers/net/i40e/base/i40e_adminq.c b/dpdk/drivers/net/i40e/base/i40e_adminq.c -index 38214a3731..584da0383c 100644 +index 38214a3731..48f9d8071a 100644 --- a/dpdk/drivers/net/i40e/base/i40e_adminq.c +++ b/dpdk/drivers/net/i40e/base/i40e_adminq.c @@ -1,5 +1,5 @@ @@ -39615,7 +56807,40 @@ index 38214a3731..584da0383c 100644 */ #include "i40e_status.h" -@@ -835,7 +835,7 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, +@@ -468,7 +468,7 @@ enum i40e_status_code i40e_init_arq(struct i40e_hw *hw) + /* initialize base registers */ + ret_code = i40e_config_arq_regs(hw); + if (ret_code != I40E_SUCCESS) +- goto init_adminq_free_rings; ++ goto init_config_regs; + + /* success! */ + hw->aq.arq.count = hw->aq.num_arq_entries; +@@ -476,6 +476,10 @@ enum i40e_status_code i40e_init_arq(struct i40e_hw *hw) + + init_adminq_free_rings: + i40e_free_adminq_arq(hw); ++ return ret_code; ++ ++init_config_regs: ++ i40e_free_arq_bufs(hw); + + init_adminq_exit: + return ret_code; +@@ -583,8 +587,10 @@ STATIC void i40e_resume_aq(struct i40e_hw *hw) + enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) + { + #ifdef PF_DRIVER +- u16 cfg_ptr, oem_hi, oem_lo; +- u16 eetrack_lo, eetrack_hi; ++ u16 oem_hi = 0, oem_lo = 0; ++ u16 eetrack_hi = 0; ++ u16 eetrack_lo = 0; ++ u16 cfg_ptr = 0; + #endif + enum i40e_status_code ret_code; + #ifdef PF_DRIVER +@@ -835,7 +841,7 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, if (val >= hw->aq.num_asq_entries) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: head overrun at %d\n", val); @@ -39636,7 +56861,7 @@ index 769d84809e..6ce262ad4b 100644 #ifndef _I40E_ADMINQ_H_ diff --git a/dpdk/drivers/net/i40e/base/i40e_adminq_cmd.h b/dpdk/drivers/net/i40e/base/i40e_adminq_cmd.h -index b459be9212..48f93313bd 100644 +index b459be9212..3d56d12fe8 100644 --- a/dpdk/drivers/net/i40e/base/i40e_adminq_cmd.h +++ b/dpdk/drivers/net/i40e/base/i40e_adminq_cmd.h @@ -1,5 +1,5 @@ @@ -39655,6 +56880,19 @@ index b459be9212..48f93313bd 100644 __le16 seid; #define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF __le16 vlan_tag; +@@ -1935,8 +1935,10 @@ enum i40e_aq_phy_type { + I40E_PHY_TYPE_25GBASE_LR = 0x22, + I40E_PHY_TYPE_25GBASE_AOC = 0x23, + I40E_PHY_TYPE_25GBASE_ACC = 0x24, +- I40E_PHY_TYPE_2_5GBASE_T = 0x30, +- I40E_PHY_TYPE_5GBASE_T = 0x31, ++ I40E_PHY_TYPE_2_5GBASE_T = 0x26, ++ I40E_PHY_TYPE_5GBASE_T = 0x27, ++ I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS = 0x30, ++ I40E_PHY_TYPE_5GBASE_T_LINK_STATUS = 0x31, + I40E_PHY_TYPE_MAX, + I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD, + I40E_PHY_TYPE_EMPTY = 0xFE, diff --git a/dpdk/drivers/net/i40e/base/i40e_alloc.h b/dpdk/drivers/net/i40e/base/i40e_alloc.h index 4fc1860155..ae14e4d932 100644 --- a/dpdk/drivers/net/i40e/base/i40e_alloc.h @@ -39667,7 +56905,7 @@ index 4fc1860155..ae14e4d932 100644 #ifndef _I40E_ALLOC_H_ diff --git a/dpdk/drivers/net/i40e/base/i40e_common.c b/dpdk/drivers/net/i40e/base/i40e_common.c -index 37911a99e5..50812eb80e 100644 +index 37911a99e5..6099ebe571 100644 --- a/dpdk/drivers/net/i40e/base/i40e_common.c +++ b/dpdk/drivers/net/i40e/base/i40e_common.c @@ -1,7 +1,9 @@ @@ -39681,6 +56919,44 @@ index 37911a99e5..50812eb80e 100644 #include "i40e_type.h" #include "i40e_adminq.h" #include "i40e_prototype.h" +@@ -1259,12 +1261,15 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) + case I40E_PHY_TYPE_40GBASE_LR4: + case I40E_PHY_TYPE_25GBASE_LR: + case I40E_PHY_TYPE_25GBASE_SR: ++ case I40E_PHY_TYPE_10GBASE_AOC: ++ case I40E_PHY_TYPE_25GBASE_AOC: ++ case I40E_PHY_TYPE_40GBASE_AOC: + media = I40E_MEDIA_TYPE_FIBER; + break; + case I40E_PHY_TYPE_100BASE_TX: + case I40E_PHY_TYPE_1000BASE_T: +- case I40E_PHY_TYPE_2_5GBASE_T: +- case I40E_PHY_TYPE_5GBASE_T: ++ case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS: ++ case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS: + case I40E_PHY_TYPE_10GBASE_T: + media = I40E_MEDIA_TYPE_BASET; + break; +@@ -1273,10 +1278,7 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) + case I40E_PHY_TYPE_10GBASE_CR1: + case I40E_PHY_TYPE_40GBASE_CR4: + case I40E_PHY_TYPE_10GBASE_SFPP_CU: +- case I40E_PHY_TYPE_40GBASE_AOC: +- case I40E_PHY_TYPE_10GBASE_AOC: + case I40E_PHY_TYPE_25GBASE_CR: +- case I40E_PHY_TYPE_25GBASE_AOC: + case I40E_PHY_TYPE_25GBASE_ACC: + media = I40E_MEDIA_TYPE_DA; + break; +@@ -1324,7 +1326,7 @@ STATIC enum i40e_status_code i40e_poll_globr(struct i40e_hw *hw, + return I40E_ERR_RESET_FAILED; + } + +-#define I40E_PF_RESET_WAIT_COUNT 200 ++#define I40E_PF_RESET_WAIT_COUNT 1000 + /** + * i40e_pf_reset - Reset the PF + * @hw: pointer to the hardware structure @@ -1700,19 +1702,22 @@ enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw, status = i40e_asq_send_command(hw, &desc, abilities, abilities_size, cmd_details); @@ -39711,18 +56987,21 @@ index 37911a99e5..50812eb80e 100644 if (status != I40E_SUCCESS) return status; -@@ -2025,8 +2030,8 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw, +@@ -2025,8 +2030,11 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw, hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE) hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU; - if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && - hw->aq.api_min_ver >= 7) { ++ /* 'Get Link Status' response data structure from X722 FW has ++ * different format and does not contain this information ++ */ + if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE && + hw->mac.type != I40E_MAC_X722) { __le32 tmp; i40e_memcpy(&tmp, resp->link_type, sizeof(tmp), -@@ -2219,6 +2224,22 @@ enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags, +@@ -2219,6 +2227,22 @@ enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags, return status; } @@ -39745,7 +57024,7 @@ index 37911a99e5..50812eb80e 100644 /** * i40e_aq_add_vsi * @hw: pointer to the hw struct -@@ -2344,18 +2365,16 @@ enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw, +@@ -2344,18 +2368,16 @@ enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw, if (set) { flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST; @@ -39769,7 +57048,7 @@ index 37911a99e5..50812eb80e 100644 cmd->seid = CPU_TO_LE16(seid); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); -@@ -2487,11 +2506,17 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw, +@@ -2487,11 +2509,17 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw, i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_vsi_promiscuous_modes); @@ -39788,7 +57067,40 @@ index 37911a99e5..50812eb80e 100644 cmd->seid = CPU_TO_LE16(seid); cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID); -@@ -2883,9 +2908,16 @@ enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw) +@@ -2601,7 +2629,7 @@ enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw, + } + + /** +- * i40e_get_vsi_params - get VSI configuration info ++ * i40e_aq_get_vsi_params - get VSI configuration info + * @hw: pointer to the hw struct + * @vsi_ctx: pointer to a vsi context struct + * @cmd_details: pointer to command details structure or NULL +@@ -2862,7 +2890,7 @@ enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up) + } + + /** +- * i40e_updatelink_status - update status of the HW network link ++ * i40e_update_link_info - update status of the HW network link + * @hw: pointer to the hw struct + **/ + enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw) +@@ -2875,17 +2903,27 @@ enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw) + return status; + + /* extra checking needed to ensure link info to user is timely */ +- if ((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) && +- ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) || +- !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) { +- status = i40e_aq_get_phy_capabilities(hw, false, false, ++ if (((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) && ++ ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) || ++ !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) || ++ hw->mac.type == I40E_MAC_X722) { ++ status = i40e_aq_get_phy_capabilities(hw, false, ++ hw->mac.type == ++ I40E_MAC_X722, + &abilities, NULL); if (status) return status; @@ -39808,7 +57120,7 @@ index 37911a99e5..50812eb80e 100644 i40e_memcpy(hw->phy.link_info.module_type, &abilities.module_type, sizeof(hw->phy.link_info.module_type), I40E_NONDMA_TO_NONDMA); -@@ -3960,7 +3992,7 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, +@@ -3960,7 +3998,7 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, p->wr_csr_prot = (u64)number; p->wr_csr_prot |= (u64)logical_id << 32; i40e_debug(hw, I40E_DEBUG_INIT, @@ -39817,7 +57129,7 @@ index 37911a99e5..50812eb80e 100644 (p->wr_csr_prot & 0xffff)); break; case I40E_AQ_CAP_ID_NVM_MGMT: -@@ -4300,7 +4332,7 @@ enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw, +@@ -4300,7 +4338,7 @@ enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw, cmd->type = mib_type; cmd->length = CPU_TO_LE16(buff_size); @@ -39826,8 +57138,44 @@ index 37911a99e5..50812eb80e 100644 cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)buff)); status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); +@@ -4684,7 +4722,7 @@ enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index, + } + + /** +- * i40e_aq_get_switch_resource_alloc (0x0204) ++ * i40e_aq_get_switch_resource_alloc - command (0x0204) to get allocations + * @hw: pointer to the hw struct + * @num_entries: pointer to u8 to store the number of resource entries returned + * @buf: pointer to a user supplied buffer. This buffer must be large enough +@@ -5825,7 +5863,7 @@ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw, + * @filter_count: number of filters contained in the buffer + * + * Set the cloud filters for a given VSI. The contents of the +- * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the ++ * i40e_aqc_cloud_filters_element_bb are filled in by the caller of + * the function. + * + **/ +@@ -6766,7 +6804,7 @@ u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num) + } + + /** +- * i40e_blink_phy_led ++ * i40e_blink_phy_link_led + * @hw: pointer to the HW structure + * @time: time how long led will blinks in secs + * @interval: gap between LED on and off in msecs +@@ -7333,7 +7371,7 @@ enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw, + } + + /** +- * i40e_aq_opc_set_ns_proxy_table_entry ++ * i40e_aq_set_ns_proxy_table_entry + * @hw: pointer to the HW structure + * @ns_proxy_table_entry: pointer to NS table entry command struct + * @cmd_details: pointer to command details diff --git a/dpdk/drivers/net/i40e/base/i40e_dcb.c b/dpdk/drivers/net/i40e/base/i40e_dcb.c -index a26f82b3a6..5a1f9903a5 100644 +index a26f82b3a6..a1c9470057 100644 --- a/dpdk/drivers/net/i40e/base/i40e_dcb.c +++ b/dpdk/drivers/net/i40e/base/i40e_dcb.c @@ -1,5 +1,5 @@ @@ -39837,6 +57185,15 @@ index a26f82b3a6..5a1f9903a5 100644 */ #include "i40e_adminq.h" +@@ -235,7 +235,7 @@ static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv, + } + + /** +- * i40e_parse_ieee_etsrec_tlv ++ * i40e_parse_ieee_tlv + * @tlv: IEEE 802.1Qaz TLV + * @dcbcfg: Local store to update ETS REC data + * @@ -1212,7 +1212,8 @@ enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw) /** @@ -39914,7 +57271,7 @@ index 289264ed99..f9aad7dc31 100644 #ifndef _I40E_HMC_H_ diff --git a/dpdk/drivers/net/i40e/base/i40e_lan_hmc.c b/dpdk/drivers/net/i40e/base/i40e_lan_hmc.c -index 0afee49b13..d3969396f0 100644 +index 0afee49b13..d3bd683ff3 100644 --- a/dpdk/drivers/net/i40e/base/i40e_lan_hmc.c +++ b/dpdk/drivers/net/i40e/base/i40e_lan_hmc.c @@ -1,5 +1,5 @@ @@ -39924,6 +57281,15 @@ index 0afee49b13..d3969396f0 100644 */ #include "i40e_osdep.h" +@@ -516,7 +516,7 @@ enum i40e_status_code i40e_configure_lan_hmc(struct i40e_hw *hw, + } + + /** +- * i40e_delete_hmc_object - remove hmc objects ++ * i40e_delete_lan_hmc_object - remove hmc objects + * @hw: pointer to the HW structure + * @info: pointer to i40e_hmc_delete_obj_info struct + * diff --git a/dpdk/drivers/net/i40e/base/i40e_lan_hmc.h b/dpdk/drivers/net/i40e/base/i40e_lan_hmc.h index e531ec490a..aa5dceb792 100644 --- a/dpdk/drivers/net/i40e/base/i40e_lan_hmc.h @@ -39936,10 +57302,10 @@ index e531ec490a..aa5dceb792 100644 #ifndef _I40E_LAN_HMC_H_ diff --git a/dpdk/drivers/net/i40e/base/i40e_nvm.c b/dpdk/drivers/net/i40e/base/i40e_nvm.c -index 6c8ca87718..16aebd077f 100644 +index 6c8ca87718..338972a2f9 100644 --- a/dpdk/drivers/net/i40e/base/i40e_nvm.c +++ b/dpdk/drivers/net/i40e/base/i40e_nvm.c -@@ -1,7 +1,9 @@ +@@ -1,11 +1,13 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2001-2018 + * Copyright(c) 2001-2020 Intel Corporation @@ -39950,6 +57316,11 @@ index 6c8ca87718..16aebd077f 100644 #include "i40e_prototype.h" /** +- * i40e_init_nvm_ops - Initialize NVM function pointers ++ * i40e_init_nvm - Initialize NVM function pointers + * @hw: pointer to the HW structure + * + * Setup the function pointers and the NVM info structure. Should be called @@ -77,7 +79,7 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw, if (ret_code) @@ -39968,7 +57339,21 @@ index 6c8ca87718..16aebd077f 100644 time_left, ret_code, hw->aq.asq_last_status); } } -@@ -1203,7 +1205,7 @@ STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw, +@@ -682,10 +684,11 @@ enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw) + DEBUGFUNC("i40e_update_nvm_checksum"); + + ret_code = i40e_calc_nvm_checksum(hw, &checksum); +- le_sum = CPU_TO_LE16(checksum); +- if (ret_code == I40E_SUCCESS) ++ if (ret_code == I40E_SUCCESS) { ++ le_sum = CPU_TO_LE16(checksum); + ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, + 1, &le_sum, true); ++ } + + return ret_code; + } +@@ -1203,7 +1206,7 @@ STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw, gtime = rd32(hw, I40E_GLVFGEN_TIMER); if (gtime >= hw->nvm.hw_semaphore_timeout) { i40e_debug(hw, I40E_DEBUG_ALL, @@ -40057,7 +57442,7 @@ index 1dad4f4b83..cd72169f14 100644 #ifndef _I40E_STATUS_H_ diff --git a/dpdk/drivers/net/i40e/base/i40e_type.h b/dpdk/drivers/net/i40e/base/i40e_type.h -index 06863d772d..cc72cc0d58 100644 +index 06863d772d..98952d9cfc 100644 --- a/dpdk/drivers/net/i40e/base/i40e_type.h +++ b/dpdk/drivers/net/i40e/base/i40e_type.h @@ -1,5 +1,5 @@ @@ -40078,8 +57463,23 @@ index 06863d772d..cc72cc0d58 100644 /* Number of Receive Descriptors must be a multiple of 32 if * the number of descriptors is greater than 32. */ +@@ -329,12 +329,8 @@ struct i40e_phy_info { + I40E_PHY_TYPE_OFFSET) + #define I40E_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC + \ + I40E_PHY_TYPE_OFFSET) +-/* Offset for 2.5G/5G PHY Types value to bit number conversion */ +-#define I40E_PHY_TYPE_OFFSET2 (-10) +-#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T + \ +- I40E_PHY_TYPE_OFFSET2) +-#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T + \ +- I40E_PHY_TYPE_OFFSET2) ++#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T) ++#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T) + #define I40E_HW_CAP_MAX_GPIO 30 + #define I40E_HW_CAP_MDIO_PORT_MODE_MDIO 0 + #define I40E_HW_CAP_MDIO_PORT_MODE_I2C 1 diff --git a/dpdk/drivers/net/i40e/base/meson.build b/dpdk/drivers/net/i40e/base/meson.build -index 3dee8c9754..bfc38ae1a0 100644 +index 3dee8c9754..03069e7e9b 100644 --- a/dpdk/drivers/net/i40e/base/meson.build +++ b/dpdk/drivers/net/i40e/base/meson.build @@ -1,5 +1,5 @@ @@ -40089,8 +57489,14 @@ index 3dee8c9754..bfc38ae1a0 100644 sources = [ 'i40e_adminq.c', +@@ -30,4 +30,4 @@ endforeach + base_lib = static_library('i40e_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/i40e/base/virtchnl.h b/dpdk/drivers/net/i40e/base/virtchnl.h -index 88096cb45c..acd7b7eb88 100644 +index 88096cb45c..1b4e76f60b 100644 --- a/dpdk/drivers/net/i40e/base/virtchnl.h +++ b/dpdk/drivers/net/i40e/base/virtchnl.h @@ -1,5 +1,5 @@ @@ -40134,7 +57540,45 @@ index 88096cb45c..acd7b7eb88 100644 #define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \ VIRTCHNL_VF_OFFLOAD_VLAN | \ VIRTCHNL_VF_OFFLOAD_RSS_PF) -@@ -518,10 +523,23 @@ enum virtchnl_event_codes { +@@ -383,9 +388,36 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select); + * PF removes the filters and returns status. + */ + ++/* VIRTCHNL_ETHER_ADDR_LEGACY ++ * Prior to adding the @type member to virtchnl_ether_addr, there were 2 pad ++ * bytes. Moving forward all VF drivers should not set type to ++ * VIRTCHNL_ETHER_ADDR_LEGACY. This is only here to not break previous/legacy ++ * behavior. The control plane function (i.e. PF) can use a best effort method ++ * of tracking the primary/device unicast in this case, but there is no ++ * guarantee and functionality depends on the implementation of the PF. ++ */ ++ ++/* VIRTCHNL_ETHER_ADDR_PRIMARY ++ * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_PRIMARY for the ++ * primary/device unicast MAC address filter for VIRTCHNL_OP_ADD_ETH_ADDR and ++ * VIRTCHNL_OP_DEL_ETH_ADDR. This allows for the underlying control plane ++ * function (i.e. PF) to accurately track and use this MAC address for ++ * displaying on the host and for VM/function reset. ++ */ ++ ++/* VIRTCHNL_ETHER_ADDR_EXTRA ++ * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_EXTRA for any extra ++ * unicast and/or multicast filters that are being added/deleted via ++ * VIRTCHNL_OP_DEL_ETH_ADDR/VIRTCHNL_OP_ADD_ETH_ADDR respectively. ++ */ + struct virtchnl_ether_addr { + u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; +- u8 pad[2]; ++ u8 type; ++#define VIRTCHNL_ETHER_ADDR_LEGACY 0 ++#define VIRTCHNL_ETHER_ADDR_PRIMARY 1 ++#define VIRTCHNL_ETHER_ADDR_EXTRA 2 ++#define VIRTCHNL_ETHER_ADDR_TYPE_MASK 3 /* first two bits of type are valid */ ++ u8 pad; + }; + + VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr); +@@ -518,10 +550,23 @@ enum virtchnl_event_codes { struct virtchnl_pf_event { enum virtchnl_event_codes event; union { @@ -40159,7 +57603,7 @@ index 88096cb45c..acd7b7eb88 100644 int severity; diff --git a/dpdk/drivers/net/i40e/i40e_ethdev.c b/dpdk/drivers/net/i40e/i40e_ethdev.c -index 5999c964bd..2e23631211 100644 +index 5999c964bd..62ef536464 100644 --- a/dpdk/drivers/net/i40e/i40e_ethdev.c +++ b/dpdk/drivers/net/i40e/i40e_ethdev.c @@ -47,6 +47,8 @@ @@ -40171,7 +57615,84 @@ index 5999c964bd..2e23631211 100644 /* Maximun number of capability elements */ #define I40E_MAX_CAP_ELE_NUM 128 -@@ -775,6 +777,21 @@ static inline void i40e_config_automask(struct i40e_pf *pf) +@@ -199,12 +201,12 @@ + #define I40E_TRANSLATE_INSET 0 + #define I40E_TRANSLATE_REG 1 + +-#define I40E_INSET_IPV4_TOS_MASK 0x0009FF00UL +-#define I40E_INSET_IPv4_TTL_MASK 0x000D00FFUL +-#define I40E_INSET_IPV4_PROTO_MASK 0x000DFF00UL +-#define I40E_INSET_IPV6_TC_MASK 0x0009F00FUL +-#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x000CFF00UL +-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL ++#define I40E_INSET_IPV4_TOS_MASK 0x0000FF00UL ++#define I40E_INSET_IPV4_TTL_MASK 0x000000FFUL ++#define I40E_INSET_IPV4_PROTO_MASK 0x0000FF00UL ++#define I40E_INSET_IPV6_TC_MASK 0x0000F00FUL ++#define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x0000FF00UL ++#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000000FFUL + + /* PCI offset for querying capability */ + #define PCI_DEV_CAP_REG 0xA4 +@@ -217,6 +219,25 @@ + /* Bit mask of Extended Tag enable/disable */ + #define PCI_DEV_CTRL_EXT_TAG_MASK (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT) + ++#define I40E_GLQF_PIT_IPV4_START 2 ++#define I40E_GLQF_PIT_IPV4_COUNT 2 ++#define I40E_GLQF_PIT_IPV6_START 4 ++#define I40E_GLQF_PIT_IPV6_COUNT 2 ++ ++#define I40E_GLQF_PIT_SOURCE_OFF_GET(a) \ ++ (((a) & I40E_GLQF_PIT_SOURCE_OFF_MASK) >> \ ++ I40E_GLQF_PIT_SOURCE_OFF_SHIFT) ++ ++#define I40E_GLQF_PIT_DEST_OFF_GET(a) \ ++ (((a) & I40E_GLQF_PIT_DEST_OFF_MASK) >> \ ++ I40E_GLQF_PIT_DEST_OFF_SHIFT) ++ ++#define I40E_GLQF_PIT_FSIZE_GET(a) (((a) & I40E_GLQF_PIT_FSIZE_MASK) >> \ ++ I40E_GLQF_PIT_FSIZE_SHIFT) ++ ++#define I40E_GLQF_PIT_BUILD(off, mask) (((off) << 16) | (mask)) ++#define I40E_FDIR_FIELD_OFFSET(a) ((a) >> 1) ++ + static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_params); + static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev); + static int i40e_dev_configure(struct rte_eth_dev *dev); +@@ -527,7 +548,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { + /* store statistics names and its offset in stats structure */ + struct rte_i40e_xstats_name_off { + char name[RTE_ETH_XSTATS_NAME_SIZE]; +- unsigned offset; ++ int offset; + }; + + static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = { +@@ -537,6 +558,8 @@ static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = { + {"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)}, + {"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats, + rx_unknown_protocol)}, ++ {"rx_size_error_packets", offsetof(struct i40e_pf, rx_err1) - ++ offsetof(struct i40e_pf, stats)}, + {"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)}, + {"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)}, + {"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)}, +@@ -720,10 +743,11 @@ i40e_write_global_rx_ctl(struct i40e_hw *hw, uint32_t reg_addr, + uint32_t reg_val) + { + uint32_t ori_reg_val; +- struct rte_eth_dev *dev; ++ struct rte_eth_dev_data *dev_data = ++ ((struct i40e_adapter *)hw->back)->pf.dev_data; ++ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id]; + + ori_reg_val = i40e_read_rx_ctl(hw, reg_addr); +- dev = ((struct i40e_adapter *)hw->back)->eth_dev; + i40e_write_rx_ctl(hw, reg_addr, reg_val); + if (ori_reg_val != reg_val) + PMD_DRV_LOG(WARNING, +@@ -775,6 +799,21 @@ static inline void i40e_config_automask(struct i40e_pf *pf) I40E_WRITE_REG(hw, I40E_GLINT_CTL, val); } @@ -40193,7 +57714,43 @@ index 5999c964bd..2e23631211 100644 #define I40E_FLOW_CONTROL_ETHERTYPE 0x8808 /* -@@ -1442,8 +1459,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) +@@ -827,6 +866,8 @@ floating_veb_list_handler(__rte_unused const char *key, + idx = strtoul(floating_veb_value, &end, 10); + if (errno || end == NULL) + return -1; ++ if (idx < 0) ++ return -1; + while (isblank(*end)) + end++; + if (*end == '-') { +@@ -1193,7 +1234,9 @@ i40e_aq_debug_write_global_register(struct i40e_hw *hw, + struct i40e_asq_cmd_details *cmd_details) + { + uint64_t ori_reg_val; +- struct rte_eth_dev *dev; ++ struct rte_eth_dev_data *dev_data = ++ ((struct i40e_adapter *)hw->back)->pf.dev_data; ++ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id]; + int ret; + + ret = i40e_aq_debug_read_register(hw, reg_addr, &ori_reg_val, NULL); +@@ -1203,7 +1246,6 @@ i40e_aq_debug_write_global_register(struct i40e_hw *hw, + reg_addr); + return -EIO; + } +- dev = ((struct i40e_adapter *)hw->back)->eth_dev; + + if (ori_reg_val != reg_val) + PMD_DRV_LOG(WARNING, +@@ -1373,7 +1415,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) + rte_eth_copy_pci_info(dev, pci_dev); + + pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); +- pf->adapter->eth_dev = dev; + pf->dev_data = dev->data; + + hw->back = I40E_PF_TO_ADAPTER(pf); +@@ -1442,8 +1483,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret); return -EIO; } @@ -40205,7 +57762,42 @@ index 5999c964bd..2e23631211 100644 hw->flags &= ~I40E_HW_FLAG_802_1AD_CAPABLE; PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x", -@@ -2005,7 +2023,7 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect, +@@ -1681,12 +1723,14 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) + return 0; + + err_init_fdir_filter_list: +- rte_free(pf->tunnel.hash_table); ++ rte_hash_free(pf->tunnel.hash_table); + rte_free(pf->tunnel.hash_map); + err_init_tunnel_filter_list: +- rte_free(pf->ethertype.hash_table); ++ rte_hash_free(pf->ethertype.hash_table); + rte_free(pf->ethertype.hash_map); + err_init_ethtype_filter_list: ++ rte_intr_callback_unregister(intr_handle, ++ i40e_dev_interrupt_handler, dev); + rte_free(dev->data->mac_addrs); + dev->data->mac_addrs = NULL; + err_mac_alloc: +@@ -1844,7 +1888,7 @@ i40e_dev_configure(struct rte_eth_dev *dev) + /* VMDQ setup. + * Needs to move VMDQ setting out of i40e_pf_config_mq_rx() as VMDQ and + * RSS setting have different requirements. +- * General PMD driver call sequence are NIC init, configure, ++ * General PMD call sequence are NIC init, configure, + * rx/tx_queue_setup and dev_start. In rx/tx_queue_setup() function, it + * will try to lookup the VSI that specific queue belongs to if VMDQ + * applicable. So, VMDQ setting has to be done before +@@ -1892,7 +1936,7 @@ i40e_dev_configure(struct rte_eth_dev *dev) + void + i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi) + { +- struct rte_eth_dev *dev = vsi->adapter->eth_dev; ++ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(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); +@@ -2005,10 +2049,10 @@ __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect, I40E_WRITE_FLUSH(hw); } @@ -40213,8 +57805,12 @@ index 5999c964bd..2e23631211 100644 +int i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) { - struct rte_eth_dev *dev = vsi->adapter->eth_dev; -@@ -2025,10 +2043,14 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) +- struct rte_eth_dev *dev = vsi->adapter->eth_dev; ++ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(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); +@@ -2025,10 +2069,14 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) /* VF bind interrupt */ if (vsi->type == I40E_VSI_SRIOV) { @@ -40230,7 +57826,7 @@ index 5999c964bd..2e23631211 100644 } /* PF & VMDq bind interrupt */ -@@ -2045,7 +2067,10 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) +@@ -2045,7 +2093,10 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) } for (i = 0; i < vsi->nb_used_qps; i++) { @@ -40242,7 +57838,7 @@ index 5999c964bd..2e23631211 100644 if (!rte_intr_allow_others(intr_handle)) /* allow to share MISC_VEC_ID */ msix_vect = I40E_MISC_VEC_ID; -@@ -2070,9 +2095,11 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) +@@ -2070,12 +2121,14 @@ i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) msix_vect++; nb_msix--; } @@ -40254,8 +57850,12 @@ index 5999c964bd..2e23631211 100644 +void i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi) { - struct rte_eth_dev *dev = vsi->adapter->eth_dev; -@@ -2099,7 +2126,7 @@ i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi) +- struct rte_eth_dev *dev = vsi->adapter->eth_dev; ++ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(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); +@@ -2099,10 +2152,10 @@ i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi) I40E_WRITE_FLUSH(hw); } @@ -40263,8 +57863,22 @@ index 5999c964bd..2e23631211 100644 +void i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi) { - struct rte_eth_dev *dev = vsi->adapter->eth_dev; -@@ -2241,6 +2268,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) +- struct rte_eth_dev *dev = vsi->adapter->eth_dev; ++ struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(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); +@@ -2215,7 +2268,8 @@ i40e_phy_conf_link(struct i40e_hw *hw, + phy_conf.phy_type = is_up ? cpu_to_le32(phy_type_mask) : 0; + phy_conf.phy_type_ext = is_up ? (I40E_AQ_PHY_TYPE_EXT_25G_KR | + I40E_AQ_PHY_TYPE_EXT_25G_CR | I40E_AQ_PHY_TYPE_EXT_25G_SR | +- I40E_AQ_PHY_TYPE_EXT_25G_LR) : 0; ++ I40E_AQ_PHY_TYPE_EXT_25G_LR | I40E_AQ_PHY_TYPE_EXT_25G_AOC | ++ I40E_AQ_PHY_TYPE_EXT_25G_ACC) : 0; + phy_conf.fec_config = phy_ab.fec_cfg_curr_mod_ext_info; + phy_conf.eee_capability = phy_ab.eee_capability; + phy_conf.eeer = phy_ab.eeer_val; +@@ -2241,6 +2295,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct rte_eth_conf *conf = &dev->data->dev_conf; @@ -40274,7 +57888,7 @@ index 5999c964bd..2e23631211 100644 if (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) { conf->link_speeds = ETH_LINK_SPEED_40G | ETH_LINK_SPEED_25G | -@@ -2248,11 +2278,12 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) +@@ -2248,11 +2305,12 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) ETH_LINK_SPEED_10G | ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M; @@ -40290,7 +57904,7 @@ index 5999c964bd..2e23631211 100644 return i40e_phy_conf_link(hw, abilities, speed, true); } -@@ -2268,16 +2299,10 @@ i40e_dev_start(struct rte_eth_dev *dev) +@@ -2268,16 +2326,10 @@ i40e_dev_start(struct rte_eth_dev *dev) struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; uint32_t intr_vector = 0; struct i40e_vsi *vsi; @@ -40308,7 +57922,7 @@ index 5999c964bd..2e23631211 100644 rte_intr_disable(intr_handle); if ((rte_intr_cap_multiple(intr_handle) || -@@ -2306,35 +2331,38 @@ i40e_dev_start(struct rte_eth_dev *dev) +@@ -2306,35 +2358,38 @@ i40e_dev_start(struct rte_eth_dev *dev) ret = i40e_dev_rxtx_init(pf); if (ret != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "Failed to init rx/tx queues"); @@ -40361,7 +57975,7 @@ index 5999c964bd..2e23631211 100644 } /* Enable receiving broadcast packets */ -@@ -2364,7 +2392,7 @@ i40e_dev_start(struct rte_eth_dev *dev) +@@ -2364,7 +2419,7 @@ i40e_dev_start(struct rte_eth_dev *dev) ret = i40e_aq_set_lb_modes(hw, dev->data->dev_conf.lpbk_mode, NULL); if (ret != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "fail to set loopback link"); @@ -40370,7 +57984,7 @@ index 5999c964bd..2e23631211 100644 } } -@@ -2372,7 +2400,7 @@ i40e_dev_start(struct rte_eth_dev *dev) +@@ -2372,7 +2427,7 @@ i40e_dev_start(struct rte_eth_dev *dev) ret = i40e_apply_link_speed(dev); if (I40E_SUCCESS != ret) { PMD_DRV_LOG(ERR, "Fail to apply link setting"); @@ -40379,7 +57993,7 @@ index 5999c964bd..2e23631211 100644 } if (!rte_intr_allow_others(intr_handle)) { -@@ -2415,9 +2443,12 @@ i40e_dev_start(struct rte_eth_dev *dev) +@@ -2415,9 +2470,12 @@ i40e_dev_start(struct rte_eth_dev *dev) return I40E_SUCCESS; @@ -40395,7 +58009,7 @@ index 5999c964bd..2e23631211 100644 return ret; } -@@ -2441,7 +2472,11 @@ i40e_dev_stop(struct rte_eth_dev *dev) +@@ -2441,7 +2499,11 @@ i40e_dev_stop(struct rte_eth_dev *dev) } /* Disable all queues */ @@ -40408,7 +58022,7 @@ index 5999c964bd..2e23631211 100644 /* un-map queues with interrupt registers */ i40e_vsi_disable_queues_intr(main_vsi); -@@ -2452,10 +2487,6 @@ i40e_dev_stop(struct rte_eth_dev *dev) +@@ -2452,10 +2514,6 @@ i40e_dev_stop(struct rte_eth_dev *dev) i40e_vsi_queues_unbind_intr(pf->vmdq[i].vsi); } @@ -40419,7 +58033,16 @@ index 5999c964bd..2e23631211 100644 /* Clear all queues and release memory */ i40e_dev_clear_queues(dev); -@@ -2594,7 +2625,7 @@ i40e_dev_close(struct rte_eth_dev *dev) +@@ -2500,6 +2558,8 @@ i40e_dev_close(struct rte_eth_dev *dev) + int retries = 0; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + ret = rte_eth_switch_domain_free(pf->switch_domain_id); + if (ret) +@@ -2594,7 +2654,7 @@ i40e_dev_close(struct rte_eth_dev *dev) do { ret = rte_intr_callback_unregister(intr_handle, i40e_dev_interrupt_handler, dev); @@ -40428,7 +58051,7 @@ index 5999c964bd..2e23631211 100644 break; } else if (ret != -EAGAIN) { PMD_INIT_LOG(ERR, -@@ -2617,6 +2648,8 @@ i40e_dev_close(struct rte_eth_dev *dev) +@@ -2617,6 +2677,8 @@ i40e_dev_close(struct rte_eth_dev *dev) /* Remove all Traffic Manager configuration */ i40e_tm_conf_uninit(dev); @@ -40437,7 +58060,7 @@ index 5999c964bd..2e23631211 100644 hw->adapter_closed = 1; } -@@ -2919,6 +2952,21 @@ i40e_dev_link_update(struct rte_eth_dev *dev, +@@ -2919,6 +2981,21 @@ i40e_dev_link_update(struct rte_eth_dev *dev, return ret; } @@ -40459,7 +58082,7 @@ index 5999c964bd..2e23631211 100644 /* Get all the statistics of a VSI */ void i40e_update_vsi_stats(struct i40e_vsi *vsi) -@@ -2928,9 +2976,9 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi) +@@ -2928,9 +3005,9 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi) struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); int idx = rte_le_to_cpu_16(vsi->info.stat_counter_idx); @@ -40472,7 +58095,7 @@ index 5999c964bd..2e23631211 100644 i40e_stat_update_48(hw, I40E_GLV_UPRCH(idx), I40E_GLV_UPRCL(idx), vsi->offset_loaded, &oes->rx_unicast, &nes->rx_unicast); -@@ -2951,9 +2999,9 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi) +@@ -2951,9 +3028,9 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi) i40e_stat_update_32(hw, I40E_GLV_RUPP(idx), vsi->offset_loaded, &oes->rx_unknown_protocol, &nes->rx_unknown_protocol); @@ -40485,7 +58108,7 @@ index 5999c964bd..2e23631211 100644 i40e_stat_update_48(hw, I40E_GLV_UPTCH(idx), I40E_GLV_UPTCL(idx), vsi->offset_loaded, &oes->tx_unicast, &nes->tx_unicast); -@@ -2995,17 +3043,18 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) +@@ -2995,17 +3072,18 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */ /* Get rx/tx bytes of internal transfer packets */ @@ -40515,7 +58138,7 @@ index 5999c964bd..2e23631211 100644 /* Get total internal rx packet count */ i40e_stat_update_48(hw, I40E_GLV_UPRCH(hw->port), I40E_GLV_UPRCL(hw->port), -@@ -3045,10 +3094,10 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) +@@ -3045,10 +3123,10 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) pf->internal_stats.rx_broadcast) * RTE_ETHER_CRC_LEN; /* Get statistics of struct i40e_eth_stats */ @@ -40530,7 +58153,7 @@ index 5999c964bd..2e23631211 100644 i40e_stat_update_48(hw, I40E_GLPRT_UPRCH(hw->port), I40E_GLPRT_UPRCL(hw->port), pf->offset_loaded, &os->eth.rx_unicast, -@@ -3103,10 +3152,10 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) +@@ -3103,10 +3181,14 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) pf->offset_loaded, &os->eth.rx_unknown_protocol, &ns->eth.rx_unknown_protocol); @@ -40538,6 +58161,10 @@ index 5999c964bd..2e23631211 100644 - I40E_GLPRT_GOTCL(hw->port), - pf->offset_loaded, &os->eth.tx_bytes, - &ns->eth.tx_bytes); ++ i40e_stat_update_48(hw, I40E_GL_RXERR1_H(hw->pf_id + I40E_MAX_VF), ++ I40E_GL_RXERR1_L(hw->pf_id + I40E_MAX_VF), ++ pf->offset_loaded, &pf->rx_err1_offset, ++ &pf->rx_err1); + i40e_stat_update_48_in_64(hw, I40E_GLPRT_GOTCH(hw->port), + I40E_GLPRT_GOTCL(hw->port), + pf->offset_loaded, &os->eth.tx_bytes, @@ -40545,7 +58172,35 @@ index 5999c964bd..2e23631211 100644 i40e_stat_update_48(hw, I40E_GLPRT_UPTCH(hw->port), I40E_GLPRT_UPTCL(hw->port), pf->offset_loaded, &os->eth.tx_unicast, -@@ -3851,6 +3900,39 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, +@@ -3302,7 +3384,8 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) + stats->ipackets = pf->main_vsi->eth_stats.rx_unicast + + pf->main_vsi->eth_stats.rx_multicast + + pf->main_vsi->eth_stats.rx_broadcast - +- pf->main_vsi->eth_stats.rx_discards; ++ pf->main_vsi->eth_stats.rx_discards - ++ pf->rx_err1; + stats->opackets = ns->eth.tx_unicast + + ns->eth.tx_multicast + + ns->eth.tx_broadcast; +@@ -3316,7 +3399,8 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) + pf->main_vsi->eth_stats.rx_discards; + stats->ierrors = ns->crc_errors + + ns->rx_length_errors + ns->rx_undersize + +- ns->rx_oversize + ns->rx_fragments + ns->rx_jabber; ++ ns->rx_oversize + ns->rx_fragments + ns->rx_jabber + ++ pf->rx_err1; + + if (pf->vfs) { + for (i = 0; i < pf->vf_num; i++) { +@@ -3641,6 +3725,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + DEV_TX_OFFLOAD_IPIP_TNL_TSO | + DEV_TX_OFFLOAD_GENEVE_TNL_TSO | + DEV_TX_OFFLOAD_MULTI_SEGS | ++ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM | + dev_info->tx_queue_offload_capa; + dev_info->dev_capa = + RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | +@@ -3851,6 +3936,39 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, return ret; } @@ -40585,7 +58240,7 @@ index 5999c964bd..2e23631211 100644 static int i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) { -@@ -3858,11 +3940,6 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -3858,11 +3976,6 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) struct i40e_vsi *vsi = pf->main_vsi; struct rte_eth_rxmode *rxmode; @@ -40597,7 +58252,7 @@ index 5999c964bd..2e23631211 100644 rxmode = &dev->data->dev_conf.rxmode; if (mask & ETH_VLAN_FILTER_MASK) { if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) -@@ -3892,6 +3969,14 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) +@@ -3892,6 +4005,14 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) i40e_vsi_config_double_vlan(vsi, FALSE); } @@ -40612,7 +58267,7 @@ index 5999c964bd..2e23631211 100644 return 0; } -@@ -4359,7 +4444,6 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) +@@ -4359,7 +4480,6 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) { struct i40e_pf *pf; struct i40e_hw *hw; @@ -40620,7 +58275,7 @@ index 5999c964bd..2e23631211 100644 if (!vsi || !lut) return -EINVAL; -@@ -4368,12 +4452,16 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) +@@ -4368,12 +4488,16 @@ i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) hw = I40E_VSI_TO_HW(vsi); if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { @@ -40643,7 +58298,24 @@ index 5999c964bd..2e23631211 100644 } } else { uint32_t *lut_dw = (uint32_t *)lut; -@@ -4930,6 +5018,7 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, +@@ -4493,13 +4617,15 @@ i40e_allocate_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw, + u64 size, + u32 alignment) + { ++ static uint64_t i40e_dma_memzone_id; + const struct rte_memzone *mz = NULL; + char z_name[RTE_MEMZONE_NAMESIZE]; + + if (!mem) + return I40E_ERR_PARAM; + +- snprintf(z_name, sizeof(z_name), "i40e_dma_%"PRIu64, rte_rand()); ++ snprintf(z_name, sizeof(z_name), "i40e_dma_%" PRIu64, ++ __atomic_fetch_add(&i40e_dma_memzone_id, 1, __ATOMIC_RELAXED)); + mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, + RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M); + if (!mz) +@@ -4930,6 +5056,7 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, { struct pool_entry *entry, *next, *prev, *valid_entry = NULL; uint32_t pool_offset; @@ -40651,7 +58323,7 @@ index 5999c964bd..2e23631211 100644 int insert; if (pool == NULL) { -@@ -4968,12 +5057,13 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, +@@ -4968,12 +5095,13 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, } insert = 0; @@ -40667,7 +58339,7 @@ index 5999c964bd..2e23631211 100644 rte_free(valid_entry); valid_entry = next; insert = 1; -@@ -4983,13 +5073,15 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, +@@ -4983,13 +5111,15 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, if (prev != NULL) { /* Merge with previous one */ if (prev->base + prev->len == valid_entry->base) { @@ -40684,7 +58356,7 @@ index 5999c964bd..2e23631211 100644 insert = 1; } } -@@ -5005,8 +5097,8 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, +@@ -5005,8 +5135,8 @@ i40e_res_pool_free(struct i40e_res_pool_info *pool, LIST_INSERT_HEAD(&pool->free_list, valid_entry, next); } @@ -40695,7 +58367,7 @@ index 5999c964bd..2e23631211 100644 return 0; } -@@ -5710,10 +5802,14 @@ i40e_vsi_setup(struct i40e_pf *pf, +@@ -5710,10 +5840,14 @@ i40e_vsi_setup(struct i40e_pf *pf, ret = i40e_res_pool_alloc(&pf->msix_pool, 1); if (ret < 0) { PMD_DRV_LOG(ERR, "VSI %d get heap failed %d", vsi->seid, ret); @@ -40713,7 +58385,7 @@ index 5999c964bd..2e23631211 100644 } else { vsi->msix_intr = 0; vsi->nb_msix = 0; -@@ -6062,6 +6158,7 @@ i40e_dev_init_vlan(struct rte_eth_dev *dev) +@@ -6062,6 +6196,7 @@ i40e_dev_init_vlan(struct rte_eth_dev *dev) /* Apply vlan offload setting */ mask = ETH_VLAN_STRIP_MASK | @@ -40721,7 +58393,16 @@ index 5999c964bd..2e23631211 100644 ETH_VLAN_FILTER_MASK | ETH_VLAN_EXTEND_MASK; ret = i40e_vlan_offload_set(dev, mask); -@@ -6277,33 +6374,6 @@ i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) +@@ -6158,6 +6293,8 @@ i40e_pf_setup(struct i40e_pf *pf) + memset(&pf->stats_offset, 0, sizeof(struct i40e_hw_port_stats)); + memset(&pf->internal_stats, 0, sizeof(struct i40e_eth_stats)); + memset(&pf->internal_stats_offset, 0, sizeof(struct i40e_eth_stats)); ++ pf->rx_err1 = 0; ++ pf->rx_err1_offset = 0; + + ret = i40e_pf_get_switch_config(pf); + if (ret != I40E_SUCCESS) { +@@ -6277,33 +6414,6 @@ i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) return I40E_SUCCESS; } @@ -40755,7 +58436,7 @@ index 5999c964bd..2e23631211 100644 int i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) { -@@ -6355,59 +6425,6 @@ i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) +@@ -6355,59 +6465,6 @@ i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) return I40E_SUCCESS; } @@ -40815,7 +58496,27 @@ index 5999c964bd..2e23631211 100644 /* Initialize VSI for TX */ static int -@@ -6607,9 +6624,13 @@ i40e_stat_update_48(struct i40e_hw *hw, +@@ -6427,8 +6484,7 @@ i40e_dev_tx_init(struct i40e_pf *pf) + break; + } + if (ret == I40E_SUCCESS) +- i40e_set_tx_function(container_of(pf, struct i40e_adapter, pf) +- ->eth_dev); ++ i40e_set_tx_function(&rte_eth_devices[pf->dev_data->port_id]); + + return ret; + } +@@ -6456,8 +6512,7 @@ i40e_dev_rx_init(struct i40e_pf *pf) + } + } + if (ret == I40E_SUCCESS) +- i40e_set_rx_function(container_of(pf, struct i40e_adapter, pf) +- ->eth_dev); ++ i40e_set_rx_function(&rte_eth_devices[pf->dev_data->port_id]); + + return ret; + } +@@ -6607,9 +6662,13 @@ i40e_stat_update_48(struct i40e_hw *hw, { uint64_t new_data; @@ -40832,7 +58533,7 @@ index 5999c964bd..2e23631211 100644 if (!offset_loaded) *offset = new_data; -@@ -7505,7 +7526,6 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) +@@ -7505,7 +7564,6 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) uint16_t key_idx = (vsi->type == I40E_VSI_SRIOV) ? I40E_VFQF_HKEY_MAX_INDEX : I40E_PFQF_HKEY_MAX_INDEX; @@ -40840,7 +58541,7 @@ index 5999c964bd..2e23631211 100644 if (!key || key_len == 0) { PMD_DRV_LOG(DEBUG, "No key to be configured"); -@@ -7518,11 +7538,16 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) +@@ -7518,11 +7576,16 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { struct i40e_aqc_get_set_rss_key_data *key_dw = @@ -40861,7 +58562,7 @@ index 5999c964bd..2e23631211 100644 } else { uint32_t *hash_key = (uint32_t *)key; uint16_t i; -@@ -7542,7 +7567,7 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) +@@ -7542,7 +7605,7 @@ i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) I40E_WRITE_FLUSH(hw); } @@ -40870,7 +58571,228 @@ index 5999c964bd..2e23631211 100644 } static int -@@ -10411,6 +10436,7 @@ i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value) +@@ -7930,7 +7993,7 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf) + struct i40e_aqc_replace_cloud_filters_cmd filter_replace; + struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); +- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + enum i40e_status_code status = I40E_SUCCESS; + + if (pf->support_multi_driver) { +@@ -7991,7 +8054,7 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf) + struct i40e_aqc_replace_cloud_filters_cmd filter_replace; + struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); +- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + enum i40e_status_code status = I40E_SUCCESS; + + if (pf->support_multi_driver) { +@@ -8066,7 +8129,7 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf) + struct i40e_aqc_replace_cloud_filters_cmd filter_replace; + struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); +- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + enum i40e_status_code status = I40E_SUCCESS; + + if (pf->support_multi_driver) { +@@ -8154,7 +8217,7 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf) + struct i40e_aqc_replace_cloud_filters_cmd filter_replace; + struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); +- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + enum i40e_status_code status = I40E_SUCCESS; + + if (pf->support_multi_driver) { +@@ -9603,49 +9666,116 @@ i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input) + return val; + } + ++static int ++i40e_get_inset_field_offset(struct i40e_hw *hw, uint32_t pit_reg_start, ++ uint32_t pit_reg_count, uint32_t hdr_off) ++{ ++ const uint32_t pit_reg_end = pit_reg_start + pit_reg_count; ++ uint32_t field_off = I40E_FDIR_FIELD_OFFSET(hdr_off); ++ uint32_t i, reg_val, src_off, count; ++ ++ for (i = pit_reg_start; i < pit_reg_end; i++) { ++ reg_val = i40e_read_rx_ctl(hw, I40E_GLQF_PIT(i)); ++ ++ src_off = I40E_GLQF_PIT_SOURCE_OFF_GET(reg_val); ++ count = I40E_GLQF_PIT_FSIZE_GET(reg_val); ++ ++ if (src_off <= field_off && (src_off + count) > field_off) ++ break; ++ } ++ ++ if (i >= pit_reg_end) { ++ PMD_DRV_LOG(ERR, ++ "Hardware GLQF_PIT configuration does not support this field mask"); ++ return -1; ++ } ++ ++ return I40E_GLQF_PIT_DEST_OFF_GET(reg_val) + field_off - src_off; ++} ++ + int +-i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem) ++i40e_generate_inset_mask_reg(struct i40e_hw *hw, uint64_t inset, ++ uint32_t *mask, uint8_t nb_elem) + { +- uint8_t i, idx = 0; +- uint64_t inset_need_mask = inset; ++ static const uint64_t mask_inset[] = { ++ I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, ++ I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT }; + + static const struct { + uint64_t inset; + uint32_t mask; +- } inset_mask_map[] = { +- {I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK}, +- {I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0}, +- {I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK}, +- {I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK}, +- {I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK}, +- {I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0}, +- {I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK}, +- {I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}, ++ uint32_t offset; ++ } inset_mask_offset_map[] = { ++ { I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK, ++ offsetof(struct rte_ipv4_hdr, type_of_service) }, ++ ++ { I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK, ++ offsetof(struct rte_ipv4_hdr, next_proto_id) }, ++ ++ { I40E_INSET_IPV4_TTL, I40E_INSET_IPV4_TTL_MASK, ++ offsetof(struct rte_ipv4_hdr, time_to_live) }, ++ ++ { I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK, ++ offsetof(struct rte_ipv6_hdr, vtc_flow) }, ++ ++ { I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK, ++ offsetof(struct rte_ipv6_hdr, proto) }, ++ ++ { I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK, ++ offsetof(struct rte_ipv6_hdr, hop_limits) }, + }; + +- if (!inset || !mask || !nb_elem) ++ uint32_t i; ++ int idx = 0; ++ ++ assert(mask); ++ if (!inset) + return 0; + +- for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { ++ for (i = 0; i < RTE_DIM(mask_inset); i++) { + /* Clear the inset bit, if no MASK is required, + * for example proto + ttl + */ +- if ((inset & inset_mask_map[i].inset) == +- inset_mask_map[i].inset && inset_mask_map[i].mask == 0) +- inset_need_mask &= ~inset_mask_map[i].inset; +- if (!inset_need_mask) +- return 0; ++ if ((mask_inset[i] & inset) == mask_inset[i]) { ++ inset &= ~mask_inset[i]; ++ if (!inset) ++ return 0; ++ } + } +- for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { +- if ((inset_need_mask & inset_mask_map[i].inset) == +- inset_mask_map[i].inset) { +- if (idx >= nb_elem) { +- PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks"); +- return -EINVAL; +- } +- mask[idx] = inset_mask_map[i].mask; +- idx++; ++ ++ for (i = 0; i < RTE_DIM(inset_mask_offset_map); i++) { ++ uint32_t pit_start, pit_count; ++ int offset; ++ ++ if (!(inset_mask_offset_map[i].inset & inset)) ++ continue; ++ ++ if (inset_mask_offset_map[i].inset & ++ (I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | ++ I40E_INSET_IPV4_TTL)) { ++ pit_start = I40E_GLQF_PIT_IPV4_START; ++ pit_count = I40E_GLQF_PIT_IPV4_COUNT; ++ } else { ++ pit_start = I40E_GLQF_PIT_IPV6_START; ++ pit_count = I40E_GLQF_PIT_IPV6_COUNT; ++ } ++ ++ offset = i40e_get_inset_field_offset(hw, pit_start, pit_count, ++ inset_mask_offset_map[i].offset); ++ ++ if (offset < 0) ++ return -EINVAL; ++ ++ if (idx >= nb_elem) { ++ PMD_DRV_LOG(ERR, ++ "Configuration of inset mask out of range %u", ++ nb_elem); ++ return -ERANGE; + } ++ ++ mask[idx] = I40E_GLQF_PIT_BUILD((uint32_t)offset, ++ inset_mask_offset_map[i].mask); ++ idx++; + } + + return idx; +@@ -9667,9 +9797,10 @@ 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); +- struct rte_eth_dev *dev; ++ struct rte_eth_dev_data *dev_data = ++ ((struct i40e_adapter *)hw->back)->pf.dev_data; ++ struct rte_eth_dev *dev = &rte_eth_devices[dev_data->port_id]; + +- dev = ((struct i40e_adapter *)hw->back)->eth_dev; + if (reg != val) { + i40e_write_rx_ctl(hw, addr, val); + PMD_DRV_LOG(WARNING, +@@ -9699,7 +9830,7 @@ i40e_filter_input_set_init(struct i40e_pf *pf) + + input_set = i40e_get_default_input_set(pctype); + +- num = i40e_generate_inset_mask_reg(input_set, mask_reg, ++ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) + return; +@@ -9804,7 +9935,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw, + inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype)); + input_set |= pf->hash_input_set[pctype]; + } +- num = i40e_generate_inset_mask_reg(input_set, mask_reg, ++ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) + return -EINVAL; +@@ -9877,7 +10008,7 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf, + inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS; + else + input_set |= pf->fdir.input_set[pctype]; +- num = i40e_generate_inset_mask_reg(input_set, mask_reg, ++ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) + return -EINVAL; +@@ -10411,6 +10542,7 @@ i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value) { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) }, { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) }, { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) }, @@ -40878,7 +58800,7 @@ index 5999c964bd..2e23631211 100644 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) }, { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) }, -@@ -10542,7 +10568,6 @@ i40e_configure_registers(struct i40e_hw *hw) +@@ -10542,7 +10674,6 @@ i40e_configure_registers(struct i40e_hw *hw) } } @@ -40886,7 +58808,17 @@ index 5999c964bd..2e23631211 100644 #define I40E_VSI_TSR_QINQ_CONFIG 0xc030 #define I40E_VSI_L2TAGSTXVALID(_i) (0x00042800 + ((_i) * 4)) #define I40E_VSI_L2TAGSTXVALID_QINQ 0xab -@@ -12044,7 +12069,7 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev, +@@ -12018,9 +12149,6 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev, + uint32_t value = 0; + uint32_t i; + +- if (!info || !info->length || !info->data) +- return -EINVAL; +- + if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP) + is_sfp = true; + +@@ -12044,7 +12172,7 @@ static int i40e_get_module_eeprom(struct rte_eth_dev *dev, } status = i40e_aq_get_phy_register(hw, I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, @@ -40895,7 +58827,7 @@ index 5999c964bd..2e23631211 100644 if (status) return -EIO; data[i] = (uint8_t)value; -@@ -12121,7 +12146,7 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -12121,7 +12249,7 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EBUSY; } @@ -40904,11 +58836,46 @@ index 5999c964bd..2e23631211 100644 dev_data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else +@@ -12688,7 +12816,7 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf) + struct i40e_aqc_replace_cloud_filters_cmd filter_replace; + struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; + struct i40e_hw *hw = I40E_PF_TO_HW(pf); +- struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + + if (pf->support_multi_driver) { + PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); diff --git a/dpdk/drivers/net/i40e/i40e_ethdev.h b/dpdk/drivers/net/i40e/i40e_ethdev.h -index 295ad593b9..91d6830a3c 100644 +index 295ad593b9..4de21cd64a 100644 --- a/dpdk/drivers/net/i40e/i40e_ethdev.h +++ b/dpdk/drivers/net/i40e/i40e_ethdev.h -@@ -269,6 +269,10 @@ enum i40e_flxpld_layer_idx { +@@ -17,6 +17,13 @@ + + #include "base/i40e_register.h" + ++/** ++ * _i=0...143, ++ * counters 0-127 are for the 128 VFs, ++ * counters 128-143 are for the 16 PFs ++ */ ++#define I40E_GL_RXERR1_H(_i) (0x00318004 + ((_i) * 8)) ++ + #define I40E_VLAN_TAG_SIZE 4 + + #define I40E_AQ_LEN 32 +@@ -88,8 +95,10 @@ + do { \ + uint32_t ori_val; \ + struct rte_eth_dev *dev; \ ++ struct rte_eth_dev_data *dev_data; \ + ori_val = I40E_READ_REG((hw), (reg)); \ +- dev = ((struct i40e_adapter *)hw->back)->eth_dev; \ ++ dev_data = ((struct i40e_adapter *)hw->back)->pf.dev_data; \ ++ dev = &rte_eth_devices[dev_data->port_id]; \ + I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((hw), \ + (reg)), (value)); \ + if (ori_val != value) \ +@@ -269,6 +278,10 @@ enum i40e_flxpld_layer_idx { */ #define I40E_ETH_OVERHEAD \ (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + I40E_VLAN_TAG_SIZE * 2) @@ -40919,7 +58886,7 @@ index 295ad593b9..91d6830a3c 100644 struct i40e_adapter; struct rte_pci_driver; -@@ -387,6 +391,8 @@ struct i40e_vsi { +@@ -387,6 +400,8 @@ struct i40e_vsi { uint8_t vlan_anti_spoof_on; /* The VLAN anti-spoofing enabled */ uint8_t vlan_filter_on; /* The VLAN filter enabled */ struct i40e_bw_info bw_info; /* VSI bandwidth information */ @@ -40928,7 +58895,7 @@ index 295ad593b9..91d6830a3c 100644 }; struct pool_entry { -@@ -533,17 +539,30 @@ enum i40e_fdir_ip_type { +@@ -533,17 +548,30 @@ enum i40e_fdir_ip_type { I40E_FDIR_IPTYPE_IPV6, }; @@ -40959,7 +58926,7 @@ index 295ad593b9..91d6830a3c 100644 }; /* A structure used to define the input for a flow director filter entry */ -@@ -595,15 +614,6 @@ struct i40e_fdir_filter_conf { +@@ -595,15 +623,6 @@ struct i40e_fdir_filter_conf { struct i40e_fdir_action action; /* Action taken when match */ }; @@ -40975,7 +58942,17 @@ index 295ad593b9..91d6830a3c 100644 struct i40e_fdir_flex_mask { uint8_t word_mask; /**< Bit i enables word i of flexible payload */ uint8_t nb_bitmask; -@@ -1007,6 +1017,10 @@ struct i40e_pf { +@@ -944,6 +963,9 @@ struct i40e_pf { + + struct i40e_hw_port_stats stats_offset; + struct i40e_hw_port_stats stats; ++ u64 rx_err1; /* rxerr1 */ ++ u64 rx_err1_offset; ++ + /* internal packet statistics, it should be excluded from the total */ + struct i40e_eth_stats internal_stats_offset; + struct i40e_eth_stats internal_stats; +@@ -1007,6 +1029,10 @@ struct i40e_pf { uint16_t switch_domain_id; struct i40e_vf_msg_cfg vf_msg_cfg; @@ -40986,7 +58963,7 @@ index 295ad593b9..91d6830a3c 100644 }; enum pending_msg { -@@ -1051,6 +1065,7 @@ struct i40e_vf { +@@ -1051,6 +1077,7 @@ struct i40e_vf { bool promisc_unicast_enabled; bool promisc_multicast_enabled; @@ -40994,7 +58971,15 @@ index 295ad593b9..91d6830a3c 100644 uint32_t version_major; /* Major version number */ uint32_t version_minor; /* Minor version number */ uint16_t promisc_flags; /* Promiscuous setting */ -@@ -1170,8 +1185,9 @@ void i40e_update_vsi_stats(struct i40e_vsi *vsi); +@@ -1086,7 +1113,6 @@ struct i40e_vf { + struct i40e_adapter { + /* Common for both PF and VF */ + struct i40e_hw hw; +- struct rte_eth_dev *eth_dev; + + /* Specific for PF or VF */ + union { +@@ -1170,8 +1196,9 @@ void i40e_update_vsi_stats(struct i40e_vsi *vsi); void i40e_pf_disable_irq0(struct i40e_hw *hw); void i40e_pf_enable_irq0(struct i40e_hw *hw); int i40e_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete); @@ -41005,7 +58990,7 @@ index 295ad593b9..91d6830a3c 100644 int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi, struct i40e_vsi_vlan_pvid_info *info); int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on); -@@ -1181,6 +1197,7 @@ uint64_t i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags); +@@ -1181,6 +1208,7 @@ uint64_t i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags); enum i40e_status_code i40e_fdir_setup_tx_resources(struct i40e_pf *pf); enum i40e_status_code i40e_fdir_setup_rx_resources(struct i40e_pf *pf); int i40e_fdir_setup(struct i40e_pf *pf); @@ -41013,8 +58998,28 @@ index 295ad593b9..91d6830a3c 100644 const struct rte_memzone *i40e_memzone_reserve(const char *name, uint32_t len, int socket_id); +@@ -1259,8 +1287,8 @@ bool is_i40evf_supported(struct rte_eth_dev *dev); + + int i40e_validate_input_set(enum i40e_filter_pctype pctype, + enum rte_filter_type filter, uint64_t inset); +-int i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, +- uint8_t nb_elem); ++int i40e_generate_inset_mask_reg(struct i40e_hw *hw, 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, +@@ -1335,7 +1363,7 @@ i40e_get_vsi_from_adapter(struct i40e_adapter *adapter) + #define I40E_VSI_TO_DEV_DATA(vsi) \ + (((struct i40e_vsi *)vsi)->adapter->pf.dev_data) + #define I40E_VSI_TO_ETH_DEV(vsi) \ +- (((struct i40e_vsi *)vsi)->adapter->eth_dev) ++ (&rte_eth_devices[((struct i40e_vsi *)vsi)->adapter->pf.dev_data->port_id]) + + /* I40E_PF_TO */ + #define I40E_PF_TO_HW(pf) \ diff --git a/dpdk/drivers/net/i40e/i40e_ethdev_vf.c b/dpdk/drivers/net/i40e/i40e_ethdev_vf.c -index 5dba0928b9..9a8d2ed9b6 100644 +index 5dba0928b9..9f1c0f4ac4 100644 --- a/dpdk/drivers/net/i40e/i40e_ethdev_vf.c +++ b/dpdk/drivers/net/i40e/i40e_ethdev_vf.c @@ -91,7 +91,8 @@ static int i40evf_vlan_filter_set(struct rte_eth_dev *dev, @@ -41027,7 +59032,17 @@ index 5dba0928b9..9a8d2ed9b6 100644 static int i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev); static int i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev); static int i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev); -@@ -262,7 +263,7 @@ i40evf_read_pfmsg(struct rte_eth_dev *dev, struct i40evf_arq_msg_info *data) +@@ -105,6 +106,9 @@ static int i40evf_dev_tx_queue_start(struct rte_eth_dev *dev, + uint16_t tx_queue_id); + static int i40evf_dev_tx_queue_stop(struct rte_eth_dev *dev, + uint16_t tx_queue_id); ++static int i40evf_add_del_eth_addr(struct rte_eth_dev *dev, ++ struct rte_ether_addr *addr, ++ bool add, uint8_t type); + static int i40evf_add_mac_addr(struct rte_eth_dev *dev, + struct rte_ether_addr *addr, + uint32_t index, +@@ -262,7 +266,7 @@ i40evf_read_pfmsg(struct rte_eth_dev *dev, struct i40evf_arq_msg_info *data) case VIRTCHNL_EVENT_RESET_IMPENDING: vf->vf_reset = true; vf->pend_msg |= PFMSG_RESET_IMPENDING; @@ -41036,7 +59051,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 break; case VIRTCHNL_EVENT_PF_DRIVER_CLOSE: vf->dev_closed = true; -@@ -316,7 +317,7 @@ _atomic_set_cmd(struct i40e_vf *vf, enum virtchnl_ops ops) +@@ -316,7 +320,7 @@ _atomic_set_cmd(struct i40e_vf *vf, enum virtchnl_ops ops) #define ASQ_DELAY_MS 10 static int @@ -41045,7 +59060,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 { 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); -@@ -407,6 +408,19 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args) +@@ -407,6 +411,19 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args) return err | vf->cmd_retval; } @@ -41065,7 +59080,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 /* * Check API version with sync wait until version read or fail from admin queue */ -@@ -467,7 +481,8 @@ i40evf_get_vf_resource(struct rte_eth_dev *dev) +@@ -467,7 +484,8 @@ i40evf_get_vf_resource(struct rte_eth_dev *dev) VIRTCHNL_VF_OFFLOAD_RSS_AQ | VIRTCHNL_VF_OFFLOAD_RSS_REG | VIRTCHNL_VF_OFFLOAD_VLAN | @@ -41075,7 +59090,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 args.in_args = (uint8_t *)∩︀ args.in_args_size = sizeof(caps); } else { -@@ -518,10 +533,19 @@ i40evf_config_promisc(struct rte_eth_dev *dev, +@@ -518,10 +536,19 @@ i40evf_config_promisc(struct rte_eth_dev *dev, err = i40evf_execute_vf_cmd(dev, &args); @@ -41097,7 +59112,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 } static int -@@ -763,7 +787,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev) +@@ -763,7 +790,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev) for (i = 0; i < dev->data->nb_tx_queues; i++) { if (i40evf_dev_tx_queue_stop(dev, i) != 0) { PMD_DRV_LOG(ERR, "Fail to stop queue %u", i); @@ -41105,7 +59120,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 } } -@@ -771,7 +794,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev) +@@ -771,7 +797,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev) for (i = 0; i < dev->data->nb_rx_queues; i++) { if (i40evf_dev_rx_queue_stop(dev, i) != 0) { PMD_DRV_LOG(ERR, "Fail to stop queue %u", i); @@ -41113,7 +59128,132 @@ index 5dba0928b9..9a8d2ed9b6 100644 } } -@@ -1034,8 +1056,18 @@ i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid) +@@ -779,10 +804,9 @@ i40evf_stop_queues(struct rte_eth_dev *dev) + } + + static int +-i40evf_add_mac_addr(struct rte_eth_dev *dev, +- struct rte_ether_addr *addr, +- __rte_unused uint32_t index, +- __rte_unused uint32_t pool) ++i40evf_add_del_eth_addr(struct rte_eth_dev *dev, ++ struct rte_ether_addr *addr, ++ bool add, uint8_t type) + { + struct virtchnl_ether_addr_list *list; + struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); +@@ -791,83 +815,70 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev, + int err; + struct vf_cmd_info args; + +- if (rte_is_zero_ether_addr(addr)) { +- PMD_DRV_LOG(ERR, "Invalid mac:%x:%x:%x:%x:%x:%x", +- addr->addr_bytes[0], addr->addr_bytes[1], +- addr->addr_bytes[2], addr->addr_bytes[3], +- addr->addr_bytes[4], addr->addr_bytes[5]); +- return I40E_ERR_INVALID_MAC_ADDR; +- } +- + list = (struct virtchnl_ether_addr_list *)cmd_buffer; + list->vsi_id = vf->vsi_res->vsi_id; + list->num_elements = 1; ++ list->list[0].type = type; + rte_memcpy(list->list[0].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); + +- args.ops = VIRTCHNL_OP_ADD_ETH_ADDR; ++ args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR; + args.in_args = cmd_buffer; + args.in_args_size = sizeof(cmd_buffer); + args.out_buffer = vf->aq_resp; + args.out_size = I40E_AQ_BUF_SZ; + err = i40evf_execute_vf_cmd(dev, &args); + if (err) +- PMD_DRV_LOG(ERR, "fail to execute command " +- "OP_ADD_ETHER_ADDRESS"); +- else +- vf->vsi.mac_num++; +- ++ PMD_DRV_LOG(ERR, "fail to execute command %s", ++ add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR"); + return err; + } + +-static void +-i40evf_del_mac_addr_by_addr(struct rte_eth_dev *dev, +- struct rte_ether_addr *addr) ++static int ++i40evf_add_mac_addr(struct rte_eth_dev *dev, ++ struct rte_ether_addr *addr, ++ __rte_unused uint32_t index, ++ __rte_unused uint32_t pool) + { +- struct virtchnl_ether_addr_list *list; + struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); +- uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) + \ +- sizeof(struct virtchnl_ether_addr)]; + int err; +- struct vf_cmd_info args; + +- if (i40e_validate_mac_addr(addr->addr_bytes) != I40E_SUCCESS) { +- PMD_DRV_LOG(ERR, "Invalid mac:%x-%x-%x-%x-%x-%x", ++ if (rte_is_zero_ether_addr(addr)) { ++ PMD_DRV_LOG(ERR, "Invalid mac:%x:%x:%x:%x:%x:%x", + addr->addr_bytes[0], addr->addr_bytes[1], + addr->addr_bytes[2], addr->addr_bytes[3], + addr->addr_bytes[4], addr->addr_bytes[5]); +- return; ++ return I40E_ERR_INVALID_MAC_ADDR; + } + +- list = (struct virtchnl_ether_addr_list *)cmd_buffer; +- list->vsi_id = vf->vsi_res->vsi_id; +- list->num_elements = 1; +- rte_memcpy(list->list[0].addr, addr->addr_bytes, +- sizeof(addr->addr_bytes)); ++ err = i40evf_add_del_eth_addr(dev, addr, TRUE, VIRTCHNL_ETHER_ADDR_EXTRA); + +- args.ops = VIRTCHNL_OP_DEL_ETH_ADDR; +- args.in_args = cmd_buffer; +- args.in_args_size = sizeof(cmd_buffer); +- args.out_buffer = vf->aq_resp; +- args.out_size = I40E_AQ_BUF_SZ; +- err = i40evf_execute_vf_cmd(dev, &args); + if (err) +- PMD_DRV_LOG(ERR, "fail to execute command " +- "OP_DEL_ETHER_ADDRESS"); ++ PMD_DRV_LOG(ERR, "fail to add MAC address"); + else +- vf->vsi.mac_num--; +- return; ++ vf->vsi.mac_num++; ++ ++ return err; + } + + static void + i40evf_del_mac_addr(struct rte_eth_dev *dev, uint32_t index) + { ++ struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + struct rte_eth_dev_data *data = dev->data; + struct rte_ether_addr *addr; ++ int err; + + addr = &data->mac_addrs[index]; + +- i40evf_del_mac_addr_by_addr(dev, addr); ++ err = i40evf_add_del_eth_addr(dev, addr, FALSE, VIRTCHNL_ETHER_ADDR_EXTRA); ++ ++ if (err) ++ PMD_DRV_LOG(ERR, "fail to delete MAC address"); ++ else ++ vf->vsi.mac_num--; ++ ++ return; + } + + static int +@@ -1034,8 +1045,18 @@ i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid) args.out_buffer = vf->aq_resp; args.out_size = I40E_AQ_BUF_SZ; err = i40evf_execute_vf_cmd(dev, &args); @@ -41133,7 +59273,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 return err; } -@@ -1057,12 +1089,28 @@ i40evf_request_queues(struct rte_eth_dev *dev, uint16_t num) +@@ -1057,12 +1078,28 @@ i40evf_request_queues(struct rte_eth_dev *dev, uint16_t num) args.out_size = I40E_AQ_BUF_SZ; rte_eal_alarm_cancel(i40evf_dev_alarm_handler, dev); @@ -41165,7 +59305,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 return err; } -@@ -1199,6 +1247,7 @@ i40evf_init_vf(struct rte_eth_dev *dev) +@@ -1199,6 +1236,7 @@ i40evf_init_vf(struct rte_eth_dev *dev) vf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); vf->dev_data = dev->data; @@ -41173,7 +59313,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 err = i40e_set_mac_type(hw); if (err) { PMD_INIT_LOG(ERR, "set_mac_type failed: %d", err); -@@ -1338,8 +1387,47 @@ i40evf_handle_pf_event(struct rte_eth_dev *dev, uint8_t *msg, +@@ -1338,8 +1376,47 @@ i40evf_handle_pf_event(struct rte_eth_dev *dev, uint8_t *msg, break; case VIRTCHNL_EVENT_LINK_CHANGE: PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event"); @@ -41223,7 +59363,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 break; case VIRTCHNL_EVENT_PF_DRIVER_CLOSE: PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event"); -@@ -1492,7 +1580,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1492,7 +1569,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev) hw->bus.device = pci_dev->addr.devid; hw->bus.func = pci_dev->addr.function; hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; @@ -41232,7 +59372,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 hw->adapter_closed = 0; /* Pass the information to the rte_eth_dev_close() that it should also -@@ -1588,7 +1676,20 @@ i40evf_dev_configure(struct rte_eth_dev *dev) +@@ -1588,7 +1665,20 @@ i40evf_dev_configure(struct rte_eth_dev *dev) ad->tx_vec_allowed = true; if (num_queue_pairs > vf->vsi_res->num_queue_pairs) { @@ -41254,7 +59394,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 PMD_DRV_LOG(INFO, "change queue pairs from %u to %u", vf->vsi_res->num_queue_pairs, num_queue_pairs); -@@ -1772,22 +1873,22 @@ i40evf_rxq_init(struct rte_eth_dev *dev, struct i40e_rx_queue *rxq) +@@ -1772,22 +1862,22 @@ i40evf_rxq_init(struct rte_eth_dev *dev, struct i40e_rx_queue *rxq) * Check if the jumbo frame and maximum packet length are set correctly */ if (dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { @@ -41281,7 +59421,17 @@ index 5dba0928b9..9a8d2ed9b6 100644 return I40E_ERR_CONFIG; } } -@@ -2160,76 +2261,32 @@ static int +@@ -1965,6 +2055,9 @@ i40evf_add_del_all_mac_addr(struct rte_eth_dev *dev, bool add) + continue; + rte_memcpy(list->list[j].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); ++ list->list[j].type = (j == 0 ? ++ VIRTCHNL_ETHER_ADDR_PRIMARY : ++ VIRTCHNL_ETHER_ADDR_EXTRA); + PMD_DRV_LOG(DEBUG, "add/rm mac:%x:%x:%x:%x:%x:%x", + addr->addr_bytes[0], addr->addr_bytes[1], + addr->addr_bytes[2], addr->addr_bytes[3], +@@ -2160,76 +2253,32 @@ static int i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev) { struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); @@ -41290,13 +59440,13 @@ index 5dba0928b9..9a8d2ed9b6 100644 - /* If enabled, just return */ - if (vf->promisc_unicast_enabled) - return 0; -- + - ret = i40evf_config_promisc(dev, 1, vf->promisc_multicast_enabled); - if (ret == 0) - vf->promisc_unicast_enabled = TRUE; - else - ret = -EAGAIN; - +- - return ret; + return i40evf_config_promisc(dev, true, vf->promisc_multicast_enabled); } @@ -41306,7 +59456,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 { struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); - int ret; -- + - /* If disabled, just return */ - if (!vf->promisc_unicast_enabled) - return 0; @@ -41316,7 +59466,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 - vf->promisc_unicast_enabled = FALSE; - else - ret = -EAGAIN; - +- - return ret; + return i40evf_config_promisc(dev, false, vf->promisc_multicast_enabled); } @@ -41362,7 +59512,7 @@ index 5dba0928b9..9a8d2ed9b6 100644 } static int -@@ -2331,6 +2388,7 @@ i40evf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +@@ -2331,6 +2380,7 @@ i40evf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) stats->imissed = pstats->rx_discards; stats->oerrors = pstats->tx_errors + pstats->tx_discards; stats->ibytes = pstats->rx_bytes; @@ -41370,7 +59520,17 @@ index 5dba0928b9..9a8d2ed9b6 100644 stats->obytes = pstats->tx_bytes; } else { PMD_DRV_LOG(ERR, "Get statistics failed"); -@@ -2351,8 +2409,9 @@ i40evf_dev_close(struct rte_eth_dev *dev) +@@ -2344,6 +2394,9 @@ i40evf_dev_close(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); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + i40evf_dev_stop(dev); + i40e_dev_free_queues(dev); + /* +@@ -2351,8 +2404,9 @@ i40evf_dev_close(struct rte_eth_dev *dev) * it is a workaround solution when work with kernel driver * and it is not the normal way */ @@ -41382,7 +59542,16 @@ index 5dba0928b9..9a8d2ed9b6 100644 rte_eal_alarm_cancel(i40evf_dev_alarm_handler, dev); i40evf_reset_vf(dev); -@@ -2747,7 +2806,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -2656,7 +2710,7 @@ i40evf_config_rss(struct i40e_vf *vf) + } + + for (i = 0; i < rss_lut_size; i++) +- lut_info[i] = i % vf->num_queue_pairs; ++ lut_info[i] = i % num; + + ret = i40evf_set_rss_lut(&vf->vsi, lut_info, + rss_lut_size); +@@ -2747,7 +2801,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EBUSY; } @@ -41391,8 +59560,43 @@ index 5dba0928b9..9a8d2ed9b6 100644 dev_data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else +@@ -2764,6 +2818,10 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev, + { + 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); ++ struct rte_ether_addr *old_addr; ++ int ret; ++ ++ old_addr = (struct rte_ether_addr *)hw->mac.addr; + + if (!rte_is_valid_assigned_ether_addr(mac_addr)) { + PMD_DRV_LOG(ERR, "Tried to set invalid MAC address."); +@@ -2773,9 +2831,13 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev, + if (vf->flags & I40E_FLAG_VF_MAC_BY_PF) + return -EPERM; + +- i40evf_del_mac_addr_by_addr(dev, (struct rte_ether_addr *)hw->mac.addr); ++ if (rte_is_same_ether_addr(old_addr, mac_addr)) ++ return 0; ++ ++ i40evf_add_del_eth_addr(dev, old_addr, FALSE, VIRTCHNL_ETHER_ADDR_PRIMARY); + +- if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0) ++ ret = i40evf_add_del_eth_addr(dev, mac_addr, TRUE, VIRTCHNL_ETHER_ADDR_PRIMARY); ++ if (ret) + return -EIO; + + rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)hw->mac.addr); +@@ -2819,6 +2881,7 @@ i40evf_add_del_mc_addr_list(struct rte_eth_dev *dev, + + memcpy(list->list[i].addr, mc_addrs[i].addr_bytes, + sizeof(list->list[i].addr)); ++ list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA; + } + + args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR; diff --git a/dpdk/drivers/net/i40e/i40e_fdir.c b/dpdk/drivers/net/i40e/i40e_fdir.c -index dee007daae..fb9f2c0fce 100644 +index dee007daae..cf206e8274 100644 --- a/dpdk/drivers/net/i40e/i40e_fdir.c +++ b/dpdk/drivers/net/i40e/i40e_fdir.c @@ -113,7 +113,7 @@ i40e_fdir_rx_queue_init(struct i40e_rx_queue *rxq) @@ -41404,6 +59608,15 @@ index dee007daae..fb9f2c0fce 100644 rx_ctx.tphrdesc_ena = 1; rx_ctx.tphwdesc_ena = 1; rx_ctx.tphdata_ena = 1; +@@ -156,7 +156,7 @@ i40e_fdir_setup(struct i40e_pf *pf) + int err = I40E_SUCCESS; + char z_name[RTE_MEMZONE_NAMESIZE]; + const struct rte_memzone *mz = NULL; +- struct rte_eth_dev *eth_dev = pf->adapter->eth_dev; ++ struct rte_eth_dev *eth_dev = &rte_eth_devices[pf->dev_data->port_id]; + + if ((pf->flags & I40E_FLAG_FDIR) == 0) { + PMD_INIT_LOG(ERR, "HW doesn't support FDIR"); @@ -222,6 +222,11 @@ i40e_fdir_setup(struct i40e_pf *pf) goto fail_mem; } @@ -41672,7 +59885,7 @@ index dee007daae..fb9f2c0fce 100644 return ret; diff --git a/dpdk/drivers/net/i40e/i40e_flow.c b/dpdk/drivers/net/i40e/i40e_flow.c -index 61021037c8..4f5f31c802 100644 +index 61021037c8..3862fb80d4 100644 --- a/dpdk/drivers/net/i40e/i40e_flow.c +++ b/dpdk/drivers/net/i40e/i40e_flow.c @@ -26,7 +26,10 @@ @@ -41840,7 +60053,33 @@ index 61021037c8..4f5f31c802 100644 static int i40e_flow_set_fdir_inset(struct i40e_pf *pf, enum i40e_filter_pctype pctype, -@@ -2479,19 +2336,16 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -2344,7 +2201,7 @@ i40e_flow_set_fdir_inset(struct i40e_pf *pf, + !memcmp(&pf->fdir.input_set[pctype], &input_set, sizeof(uint64_t))) + return 0; + +- num = i40e_generate_inset_mask_reg(input_set, mask_reg, ++ num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg, + I40E_INSET_MASK_NUM_REG); + if (num < 0) + return -EINVAL; +@@ -2453,7 +2310,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, + const struct rte_flow_item *item = pattern; + const struct rte_flow_item_eth *eth_spec, *eth_mask; + const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; +- const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask; ++ const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask; + const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; + const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; + const struct rte_flow_item_udp *udp_spec, *udp_mask; +@@ -2464,7 +2321,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, + + uint8_t pctype = 0; + uint64_t input_set = I40E_INSET_NONE; +- uint16_t frag_off; + enum rte_flow_item_type item_type; + enum rte_flow_item_type next_type; + enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END; +@@ -2479,23 +2335,20 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, uint16_t len_arr[I40E_MAX_FLXPLD_FIED]; struct i40e_fdir_flex_pit flex_pit; uint8_t next_dst_off = 0; @@ -41861,7 +60100,12 @@ index 61021037c8..4f5f31c802 100644 outer_tpid = i40e_get_outer_vlan(dev); filter->input.flow_ext.customized_pctype = false; for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { -@@ -2542,7 +2396,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +- if (item->last) { ++ if (item->last && item->type != RTE_FLOW_ITEM_TYPE_IPV4) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, +@@ -2542,7 +2395,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, if (next_type == RTE_FLOW_ITEM_TYPE_VLAN || ether_type == RTE_ETHER_TYPE_IPV4 || ether_type == RTE_ETHER_TYPE_IPV6 || @@ -41869,7 +60113,7 @@ index 61021037c8..4f5f31c802 100644 ether_type == outer_tpid) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, -@@ -2565,12 +2418,22 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -2565,12 +2417,22 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, RTE_ASSERT(!(input_set & I40E_INSET_LAST_ETHER_TYPE)); if (vlan_spec && vlan_mask) { @@ -41897,7 +60141,7 @@ index 61021037c8..4f5f31c802 100644 } if (vlan_spec && vlan_mask && vlan_mask->inner_type) { if (vlan_mask->inner_type != RTE_BE16(0xffff)) { -@@ -2587,7 +2450,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -2587,7 +2449,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, if (ether_type == RTE_ETHER_TYPE_IPV4 || ether_type == RTE_ETHER_TYPE_IPV6 || @@ -41905,7 +60149,111 @@ index 61021037c8..4f5f31c802 100644 ether_type == outer_tpid) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, -@@ -2941,6 +2803,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -2608,15 +2469,40 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, + l3 = RTE_FLOW_ITEM_TYPE_IPV4; + ipv4_spec = item->spec; + ipv4_mask = item->mask; ++ ipv4_last = item->last; + pctype = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER; + layer_idx = I40E_FLXPLD_L3_IDX; + ++ if (ipv4_last) { ++ if (!ipv4_spec || !ipv4_mask || !outer_ip) { ++ rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, ++ "Not support range"); ++ return -rte_errno; ++ } ++ /* Only fragment_offset supports range */ ++ if (ipv4_last->hdr.version_ihl || ++ ipv4_last->hdr.type_of_service || ++ ipv4_last->hdr.total_length || ++ ipv4_last->hdr.packet_id || ++ ipv4_last->hdr.time_to_live || ++ ipv4_last->hdr.next_proto_id || ++ ipv4_last->hdr.hdr_checksum || ++ ipv4_last->hdr.src_addr || ++ ipv4_last->hdr.dst_addr) { ++ rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, ++ "Not support range"); ++ return -rte_errno; ++ } ++ } + if (ipv4_spec && ipv4_mask && outer_ip) { + /* Check IPv4 mask and update input set */ + if (ipv4_mask->hdr.version_ihl || + ipv4_mask->hdr.total_length || + ipv4_mask->hdr.packet_id || +- ipv4_mask->hdr.fragment_offset || + ipv4_mask->hdr.hdr_checksum) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, +@@ -2637,11 +2523,56 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, + input_set |= I40E_INSET_IPV4_PROTO; + + /* Check if it is fragment. */ +- frag_off = ipv4_spec->hdr.fragment_offset; +- frag_off = rte_be_to_cpu_16(frag_off); +- if (frag_off & RTE_IPV4_HDR_OFFSET_MASK || +- frag_off & RTE_IPV4_HDR_MF_FLAG) +- pctype = I40E_FILTER_PCTYPE_FRAG_IPV4; ++ uint16_t frag_mask = ++ ipv4_mask->hdr.fragment_offset; ++ uint16_t frag_spec = ++ ipv4_spec->hdr.fragment_offset; ++ uint16_t frag_last = 0; ++ if (ipv4_last) ++ frag_last = ++ ipv4_last->hdr.fragment_offset; ++ if (frag_mask) { ++ frag_mask = rte_be_to_cpu_16(frag_mask); ++ frag_spec = rte_be_to_cpu_16(frag_spec); ++ frag_last = rte_be_to_cpu_16(frag_last); ++ /* frag_off mask has to be 0x3fff */ ++ if (frag_mask != ++ (RTE_IPV4_HDR_OFFSET_MASK | ++ RTE_IPV4_HDR_MF_FLAG)) { ++ rte_flow_error_set(error, ++ EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, ++ "Invalid IPv4 fragment_offset mask"); ++ return -rte_errno; ++ } ++ /* ++ * non-frag rule: ++ * mask=0x3fff,spec=0 ++ * frag rule: ++ * mask=0x3fff,spec=0x8,last=0x2000 ++ */ ++ if (frag_spec == ++ (1 << RTE_IPV4_HDR_FO_SHIFT) && ++ frag_last == RTE_IPV4_HDR_MF_FLAG) { ++ pctype = ++ I40E_FILTER_PCTYPE_FRAG_IPV4; ++ } else if (frag_spec || frag_last) { ++ rte_flow_error_set(error, ++ EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, ++ "Invalid IPv4 fragment_offset rule"); ++ return -rte_errno; ++ } ++ } else if (frag_spec || frag_last) { ++ rte_flow_error_set(error, ++ EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ item, ++ "Invalid fragment_offset"); ++ return -rte_errno; ++ } + + /* Get the filter info */ + filter->input.flow.ip4_flow.proto = +@@ -2941,6 +2872,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, flex_size = 0; memset(&flex_pit, 0, sizeof(struct i40e_fdir_flex_pit)); @@ -41913,7 +60261,7 @@ index 61021037c8..4f5f31c802 100644 flex_pit.size = raw_spec->length / sizeof(uint16_t); flex_pit.dst_offset = -@@ -2967,27 +2830,21 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -2967,27 +2899,24 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, return -rte_errno; } @@ -41931,6 +60279,9 @@ index 61021037c8..4f5f31c802 100644 - for (i = 0; i < raw_spec->length; i++) { j = i + next_dst_off; ++ if (j >= RTE_ETH_FDIR_MAX_FLEXLEN || ++ j >= I40E_FDIR_MAX_FLEX_LEN) ++ break; filter->input.flow_ext.flexbytes[j] = raw_spec->pattern[i]; - flex_mask[j] = raw_mask->pattern[i]; @@ -41948,7 +60299,7 @@ index 61021037c8..4f5f31c802 100644 break; case RTE_FLOW_ITEM_TYPE_VF: vf_spec = item->spec; -@@ -3043,29 +2900,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, +@@ -3043,29 +2972,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, "Invalid pattern mask."); return -rte_errno; } @@ -41978,7 +60329,7 @@ index 61021037c8..4f5f31c802 100644 } filter->input.pctype = pctype; -@@ -3208,8 +3042,7 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, +@@ -3208,8 +3114,7 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, cons_filter_type = RTE_ETH_FILTER_FDIR; @@ -41988,7 +60339,7 @@ index 61021037c8..4f5f31c802 100644 /* Enable fdir when fdir flow is added at first time. */ ret = i40e_fdir_setup(pf); if (ret != I40E_SUCCESS) { -@@ -3225,10 +3058,12 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, +@@ -3225,10 +3130,12 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev, NULL, "Failed to configure fdir."); goto err; } @@ -42003,7 +60354,7 @@ index 61021037c8..4f5f31c802 100644 return 0; err: i40e_fdir_teardown(pf); -@@ -3424,10 +3259,10 @@ i40e_flow_parse_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, +@@ -3424,10 +3331,10 @@ i40e_flow_parse_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, if (vlan_spec && vlan_mask) { if (vlan_mask->tci == @@ -42016,7 +60367,7 @@ index 61021037c8..4f5f31c802 100644 filter_type |= ETH_TUNNEL_FILTER_IVLAN; } break; -@@ -3655,10 +3490,10 @@ i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev, +@@ -3655,10 +3562,10 @@ i40e_flow_parse_nvgre_pattern(__rte_unused struct rte_eth_dev *dev, if (vlan_spec && vlan_mask) { if (vlan_mask->tci == @@ -42029,7 +60380,7 @@ index 61021037c8..4f5f31c802 100644 filter_type |= ETH_TUNNEL_FILTER_IVLAN; } break; -@@ -4179,14 +4014,9 @@ i40e_flow_parse_qinq_pattern(__rte_unused struct rte_eth_dev *dev, +@@ -4179,14 +4086,9 @@ i40e_flow_parse_qinq_pattern(__rte_unused struct rte_eth_dev *dev, } /* Get filter specification */ @@ -42047,7 +60398,7 @@ index 61021037c8..4f5f31c802 100644 } else { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, -@@ -4280,7 +4110,7 @@ i40e_flow_parse_rss_pattern(__rte_unused struct rte_eth_dev *dev, +@@ -4280,7 +4182,7 @@ i40e_flow_parse_rss_pattern(__rte_unused struct rte_eth_dev *dev, vlan_mask = item->mask; if (vlan_spec && vlan_mask) { if (vlan_mask->tci == @@ -42056,7 +60407,7 @@ index 61021037c8..4f5f31c802 100644 info->region[0].user_priority[0] = (rte_be_to_cpu_16( vlan_spec->tci) >> 13) & 0x7; -@@ -4326,13 +4156,59 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, +@@ -4326,13 +4228,59 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, const struct rte_flow_action *act; const struct rte_flow_action_rss *rss; struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); @@ -42118,7 +60469,7 @@ index 61021037c8..4f5f31c802 100644 NEXT_ITEM_OF_ACTION(act, actions, index); rss = act->conf; -@@ -4350,14 +4226,27 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, +@@ -4350,14 +4298,27 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, } if (action_flag) { @@ -42149,7 +60500,7 @@ index 61021037c8..4f5f31c802 100644 } /** -@@ -4455,9 +4344,9 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, +@@ -4455,9 +4416,9 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, info->region[i].user_priority_num++; } @@ -42162,7 +60513,7 @@ index 61021037c8..4f5f31c802 100644 info->region[i].hw_flowtype[j] = tmp; info->region[i].flowtype_num++; } -@@ -4470,9 +4359,9 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, +@@ -4470,9 +4431,9 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, info->region[i].user_priority_num++; } @@ -42175,7 +60526,7 @@ index 61021037c8..4f5f31c802 100644 info->region[i].hw_flowtype[j] = tmp; info->region[i].flowtype_num++; } -@@ -4796,9 +4685,6 @@ i40e_flow_destroy(struct rte_eth_dev *dev, +@@ -4796,9 +4757,6 @@ i40e_flow_destroy(struct rte_eth_dev *dev, /* If the last flow is destroyed, disable fdir. */ if (!ret && TAILQ_EMPTY(&pf->fdir.fdir_list)) { @@ -42185,7 +60536,7 @@ index 61021037c8..4f5f31c802 100644 i40e_fdir_rx_proc_enable(dev, 0); } break; -@@ -4956,9 +4842,6 @@ i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) +@@ -4956,16 +4914,13 @@ i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) return -rte_errno; } @@ -42195,7 +60546,15 @@ index 61021037c8..4f5f31c802 100644 return ret; } -@@ -4992,11 +4875,14 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf) + static int + i40e_flow_flush_fdir_filter(struct i40e_pf *pf) + { +- struct rte_eth_dev *dev = pf->adapter->eth_dev; ++ struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; + struct i40e_fdir_info *fdir_info = &pf->fdir; + struct i40e_fdir_filter *fdir_filter; + enum i40e_filter_pctype pctype; +@@ -4992,11 +4947,14 @@ i40e_flow_flush_fdir_filter(struct i40e_pf *pf) } for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; @@ -42213,11 +60572,172 @@ index 61021037c8..4f5f31c802 100644 return ret; } +diff --git a/dpdk/drivers/net/i40e/i40e_pf.c b/dpdk/drivers/net/i40e/i40e_pf.c +index 7bf1e79410..842f5c281f 100644 +--- a/dpdk/drivers/net/i40e/i40e_pf.c ++++ b/dpdk/drivers/net/i40e/i40e_pf.c +@@ -29,6 +29,28 @@ + + #define I40E_CFG_CRCSTRIP_DEFAULT 1 + ++/* Supported RSS offloads */ ++#define I40E_DEFAULT_RSS_HENA ( \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_L2_PAYLOAD)) ++ ++#define I40E_DEFAULT_RSS_HENA_EXPANDED (I40E_DEFAULT_RSS_HENA | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | \ ++ BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP)) ++ + static int + i40e_pf_host_switch_queues(struct i40e_pf_vf *vf, + struct virtchnl_queue_select *qsel, +@@ -333,6 +355,10 @@ i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, uint8_t *msg, + + vf_res->vf_cap_flags = vf->request_caps & + I40E_VIRTCHNL_OFFLOAD_CAPS; ++ ++ if (vf->request_caps & VIRTCHNL_VF_OFFLOAD_REQ_QUEUES) ++ vf_res->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_REQ_QUEUES; ++ + /* For X722, it supports write back on ITR + * without binding queue to interrupt vector. + */ +@@ -1284,6 +1310,37 @@ i40e_pf_host_process_cmd_request_queues(struct i40e_pf_vf *vf, uint8_t *msg) + (u8 *)vfres, sizeof(*vfres)); + } + ++static void ++i40e_pf_host_process_cmd_get_rss_hena(struct i40e_pf_vf *vf) ++{ ++ struct virtchnl_rss_hena vrh = {0}; ++ struct i40e_pf *pf = vf->pf; ++ ++ if (pf->adapter->hw.mac.type == I40E_MAC_X722) ++ vrh.hena = I40E_DEFAULT_RSS_HENA_EXPANDED; ++ else ++ vrh.hena = I40E_DEFAULT_RSS_HENA; ++ ++ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_RSS_HENA_CAPS, ++ I40E_SUCCESS, (uint8_t *)&vrh, sizeof(vrh)); ++} ++ ++static void ++i40e_pf_host_process_cmd_set_rss_hena(struct i40e_pf_vf *vf, uint8_t *msg) ++{ ++ struct virtchnl_rss_hena *vrh = ++ (struct virtchnl_rss_hena *)msg; ++ struct i40e_hw *hw = &vf->pf->adapter->hw; ++ ++ i40e_write_rx_ctl(hw, I40E_VFQF_HENA1(0, vf->vf_idx), ++ (uint32_t)vrh->hena); ++ i40e_write_rx_ctl(hw, I40E_VFQF_HENA1(1, vf->vf_idx), ++ (uint32_t)(vrh->hena >> 32)); ++ ++ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_SET_RSS_HENA, ++ I40E_SUCCESS, NULL, 0); ++} ++ + void + i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, + uint16_t abs_vf_id, uint32_t opcode, +@@ -1454,6 +1511,14 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, + PMD_DRV_LOG(INFO, "OP_REQUEST_QUEUES received"); + i40e_pf_host_process_cmd_request_queues(vf, msg); + break; ++ case VIRTCHNL_OP_GET_RSS_HENA_CAPS: ++ PMD_DRV_LOG(INFO, "OP_GET_RSS_HENA_CAPS received"); ++ i40e_pf_host_process_cmd_get_rss_hena(vf); ++ break; ++ case VIRTCHNL_OP_SET_RSS_HENA: ++ PMD_DRV_LOG(INFO, "OP_SET_RSS_HENA received"); ++ i40e_pf_host_process_cmd_set_rss_hena(vf, msg); ++ break; + + /* Don't add command supported below, which will + * return an error code. diff --git a/dpdk/drivers/net/i40e/i40e_rxtx.c b/dpdk/drivers/net/i40e/i40e_rxtx.c -index 17dc8c78f7..352fb426df 100644 +index 17dc8c78f7..67d3973d4a 100644 --- a/dpdk/drivers/net/i40e/i40e_rxtx.c +++ b/dpdk/drivers/net/i40e/i40e_rxtx.c -@@ -989,6 +989,24 @@ i40e_set_tso_ctx(struct rte_mbuf *mbuf, union i40e_tx_offload tx_offload) +@@ -66,6 +66,7 @@ + PKT_TX_QINQ_PKT | \ + PKT_TX_VLAN_PKT | \ + PKT_TX_TUNNEL_MASK | \ ++ PKT_TX_OUTER_UDP_CKSUM | \ + I40E_TX_IEEE1588_TMST) + + #define I40E_TX_OFFLOAD_NOTSUP_MASK \ +@@ -417,7 +418,7 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq) + uint16_t pkt_len; + uint64_t qword1; + uint32_t rx_status; +- int32_t s[I40E_LOOK_AHEAD], nb_dd; ++ int32_t s[I40E_LOOK_AHEAD], var, nb_dd; + int32_t i, j, nb_rx = 0; + uint64_t pkt_flags; + uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl; +@@ -450,8 +451,18 @@ i40e_rx_scan_hw_ring(struct i40e_rx_queue *rxq) + rte_smp_rmb(); + + /* Compute how many status bits were set */ +- for (j = 0, nb_dd = 0; j < I40E_LOOK_AHEAD; j++) +- nb_dd += s[j] & (1 << I40E_RX_DESC_STATUS_DD_SHIFT); ++ for (j = 0, nb_dd = 0; j < I40E_LOOK_AHEAD; j++) { ++ var = s[j] & (1 << I40E_RX_DESC_STATUS_DD_SHIFT); ++#ifdef RTE_ARCH_ARM ++ /* For Arm platforms, only compute continuous status bits */ ++ if (var) ++ nb_dd += 1; ++ else ++ break; ++#else ++ nb_dd += var; ++#endif ++ } + + nb_rx += nb_dd; + +@@ -692,6 +703,12 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) + break; + } + ++ /** ++ * Use acquire fence to ensure that qword1 which includes DD ++ * bit is loaded before loading of other descriptor words. ++ */ ++ __atomic_thread_fence(__ATOMIC_ACQUIRE); ++ + rxd = *rxdp; + nb_hold++; + rxe = &sw_ring[rx_id]; +@@ -808,6 +825,12 @@ i40e_recv_scattered_pkts(void *rx_queue, + break; + } + ++ /** ++ * Use acquire fence to ensure that qword1 which includes DD ++ * bit is loaded before loading of other descriptor words. ++ */ ++ __atomic_thread_fence(__ATOMIC_ACQUIRE); ++ + rxd = *rxdp; + nb_hold++; + rxe = &sw_ring[rx_id]; +@@ -989,6 +1012,24 @@ i40e_set_tso_ctx(struct rte_mbuf *mbuf, union i40e_tx_offload tx_offload) return ctx_desc; } @@ -42242,7 +60762,7 @@ index 17dc8c78f7..352fb426df 100644 uint16_t i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { -@@ -1021,7 +1039,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1021,7 +1062,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* Check if the descriptor ring needs to be cleaned. */ if (txq->nb_tx_free < txq->tx_free_thresh) @@ -42251,7 +60771,7 @@ index 17dc8c78f7..352fb426df 100644 for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) { td_cmd = 0; -@@ -1046,8 +1064,15 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1046,8 +1087,15 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) * The number of descriptors that must be allocated for * a packet equals to the number of the segments of that * packet plus 1 context descriptor if needed. @@ -42268,7 +60788,7 @@ index 17dc8c78f7..352fb426df 100644 tx_last = (uint16_t)(tx_id + nb_used - 1); /* Circular ring */ -@@ -1160,6 +1185,24 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1160,6 +1208,24 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) slen = m_seg->data_len; buf_dma_addr = rte_mbuf_data_iova(m_seg); @@ -42293,7 +60813,7 @@ index 17dc8c78f7..352fb426df 100644 PMD_TX_LOG(DEBUG, "mbuf: %p, TDD[%u]:\n" "buf_dma_addr: %#"PRIx64";\n" "td_cmd: %#x;\n" -@@ -1205,7 +1248,8 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1205,7 +1271,8 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) (unsigned) txq->port_id, (unsigned) txq->queue_id, (unsigned) tx_id, (unsigned) nb_tx); @@ -42303,7 +60823,7 @@ index 17dc8c78f7..352fb426df 100644 txq->tx_tail = tx_id; return nb_tx; -@@ -1527,6 +1571,15 @@ i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) +@@ -1527,6 +1594,15 @@ i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) PMD_INIT_FUNC_TRACE(); rxq = dev->data->rx_queues[rx_queue_id]; @@ -42319,7 +60839,7 @@ index 17dc8c78f7..352fb426df 100644 err = i40e_alloc_rx_queue_mbufs(rxq); if (err) { -@@ -1559,6 +1612,11 @@ i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +@@ -1559,6 +1635,11 @@ i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); rxq = dev->data->rx_queues[rx_queue_id]; @@ -42331,7 +60851,7 @@ index 17dc8c78f7..352fb426df 100644 /* * rx_queue_id is queue id application refers to, while -@@ -1587,6 +1645,15 @@ i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) +@@ -1587,6 +1668,15 @@ i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) PMD_INIT_FUNC_TRACE(); txq = dev->data->tx_queues[tx_queue_id]; @@ -42347,7 +60867,7 @@ index 17dc8c78f7..352fb426df 100644 /* * tx_queue_id is queue id application refers to, while -@@ -1611,6 +1678,11 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) +@@ -1611,6 +1701,11 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); txq = dev->data->tx_queues[tx_queue_id]; @@ -42359,7 +60879,27 @@ index 17dc8c78f7..352fb426df 100644 /* * tx_queue_id is queue id application refers to, while -@@ -2617,23 +2689,23 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq) +@@ -2114,8 +2209,6 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev, + if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) { + vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); + vsi = &vf->vsi; +- if (!vsi) +- return -EINVAL; + reg_idx = queue_idx; + } else { + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); +@@ -2407,6 +2500,10 @@ i40e_reset_rx_queue(struct i40e_rx_queue *rxq) + #endif /* RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC */ + rxq->rx_tail = 0; + rxq->nb_rx_hold = 0; ++ ++ if (rxq->pkt_first_seg != NULL) ++ rte_pktmbuf_free(rxq->pkt_first_seg); ++ + rxq->pkt_first_seg = NULL; + rxq->pkt_last_seg = NULL; + +@@ -2617,23 +2714,23 @@ i40e_rx_queue_config(struct i40e_rx_queue *rxq) RTE_MIN((uint32_t)(hw->func_caps.rx_buf_chain_len * rxq->rx_buf_len), data->dev_conf.rxmode.max_rx_pkt_len); if (data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { @@ -42387,8 +60927,26 @@ index 17dc8c78f7..352fb426df 100644 return I40E_ERR_CONFIG; } } +@@ -2775,7 +2872,7 @@ i40e_fdir_setup_tx_resources(struct i40e_pf *pf) + return I40E_ERR_BAD_PTR; + } + +- dev = pf->adapter->eth_dev; ++ dev = &rte_eth_devices[pf->dev_data->port_id]; + + /* Allocate the TX queue data structure. */ + txq = rte_zmalloc_socket("i40e fdir tx queue", +@@ -2831,7 +2928,7 @@ i40e_fdir_setup_rx_resources(struct i40e_pf *pf) + return I40E_ERR_BAD_PTR; + } + +- dev = pf->adapter->eth_dev; ++ dev = &rte_eth_devices[pf->dev_data->port_id]; + + /* Allocate the RX queue data structure. */ + rxq = rte_zmalloc_socket("i40e fdir rx queue", diff --git a/dpdk/drivers/net/i40e/i40e_rxtx_vec_altivec.c b/dpdk/drivers/net/i40e/i40e_rxtx_vec_altivec.c -index 310ce1ee2d..39f4d60ca8 100644 +index 310ce1ee2d..12dacc31a4 100644 --- a/dpdk/drivers/net/i40e/i40e_rxtx_vec_altivec.c +++ b/dpdk/drivers/net/i40e/i40e_rxtx_vec_altivec.c @@ -13,7 +13,7 @@ @@ -42429,6 +60987,42 @@ index 310ce1ee2d..39f4d60ca8 100644 /* nb_pkts has to be floor-aligned to RTE_I40E_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_I40E_DESCS_PER_LOOP); +@@ -282,22 +281,22 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + * in one XMM reg. + */ + +- /* B.1 load 1 mbuf point */ ++ /* B.1 load 2 mbuf point */ + mbp1 = *(vector unsigned long *)&sw_ring[pos]; + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = *(vector unsigned long *)(rxdp + 3); + rte_compiler_barrier(); + + /* B.2 copy 2 mbuf point into rx_pkts */ + *(vector unsigned long *)&rx_pkts[pos] = mbp1; + +- /* B.1 load 1 mbuf point */ ++ /* B.1 load 2 mbuf point */ + mbp2 = *(vector unsigned long *)&sw_ring[pos + 2]; + ++ /* A.1 load desc[2-0] */ + descs[2] = *(vector unsigned long *)(rxdp + 2); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs[1] = *(vector unsigned long *)(rxdp + 1); + rte_compiler_barrier(); + descs[0] = *(vector unsigned long *)(rxdp); +@@ -399,7 +398,7 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + (vector unsigned char)vec_nor(staterr, staterr), + (vector unsigned char)eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ @@ -459,15 +458,15 @@ i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -42553,7 +61147,7 @@ index 0e6ffa0078..31f73f6054 100644 /* we need to strip crc for the whole packet */ start->pkt_len -= rxq->crc_len; diff --git a/dpdk/drivers/net/i40e/i40e_rxtx_vec_neon.c b/dpdk/drivers/net/i40e/i40e_rxtx_vec_neon.c -index deb185fe2f..5cac418cf0 100644 +index deb185fe2f..0da6b37da9 100644 --- a/dpdk/drivers/net/i40e/i40e_rxtx_vec_neon.c +++ b/dpdk/drivers/net/i40e/i40e_rxtx_vec_neon.c @@ -6,6 +6,7 @@ @@ -42609,7 +61203,93 @@ index deb185fe2f..5cac418cf0 100644 /* nb_pkts has to be floor-aligned to RTE_I40E_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_I40E_DESCS_PER_LOOP); -@@ -437,15 +436,15 @@ i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -280,26 +279,34 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + + int32x4_t len_shl = {0, 0, 0, PKTLEN_SHIFT}; + +- /* B.1 load 1 mbuf point */ ++ /* B.1 load 2 mbuf point */ + mbp1 = vld1q_u64((uint64_t *)&sw_ring[pos]); + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = vld1q_u64((uint64_t *)(rxdp + 3)); + + /* B.2 copy 2 mbuf point into rx_pkts */ + vst1q_u64((uint64_t *)&rx_pkts[pos], mbp1); + +- /* B.1 load 1 mbuf point */ ++ /* B.1 load 2 mbuf point */ + mbp2 = vld1q_u64((uint64_t *)&sw_ring[pos + 2]); + ++ /* A.1 load desc[2-0] */ + descs[2] = vld1q_u64((uint64_t *)(rxdp + 2)); +- /* B.1 load 2 mbuf point */ + descs[1] = vld1q_u64((uint64_t *)(rxdp + 1)); + descs[0] = vld1q_u64((uint64_t *)(rxdp)); + + /* B.2 copy 2 mbuf point into rx_pkts */ + vst1q_u64((uint64_t *)&rx_pkts[pos + 2], mbp2); + ++ /* Use acquire fence to order loads of descriptor qwords */ ++ __atomic_thread_fence(__ATOMIC_ACQUIRE); ++ /* A.2 reload qword0 to make it ordered after qword1 load */ ++ descs[3] = vld1q_lane_u64((uint64_t *)(rxdp + 3), descs[3], 0); ++ descs[2] = vld1q_lane_u64((uint64_t *)(rxdp + 2), descs[2], 0); ++ descs[1] = vld1q_lane_u64((uint64_t *)(rxdp + 1), descs[1], 0); ++ descs[0] = vld1q_lane_u64((uint64_t *)(rxdp), descs[0], 0); ++ + if (split_packet) { + rte_mbuf_prefetch_part2(rx_pkts[pos]); + rte_mbuf_prefetch_part2(rx_pkts[pos + 1]); +@@ -310,10 +317,16 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* pkt 3,4 shift the pktlen field to be 16-bit aligned*/ + uint32x4_t len3 = vshlq_u32(vreinterpretq_u32_u64(descs[3]), + len_shl); +- descs[3] = vreinterpretq_u64_u32(len3); ++ descs[3] = vreinterpretq_u64_u16(vsetq_lane_u16 ++ (vgetq_lane_u16(vreinterpretq_u16_u32(len3), 7), ++ vreinterpretq_u16_u64(descs[3]), ++ 7)); + uint32x4_t len2 = vshlq_u32(vreinterpretq_u32_u64(descs[2]), + len_shl); +- descs[2] = vreinterpretq_u64_u32(len2); ++ descs[2] = vreinterpretq_u64_u16(vsetq_lane_u16 ++ (vgetq_lane_u16(vreinterpretq_u16_u32(len2), 7), ++ vreinterpretq_u16_u64(descs[2]), ++ 7)); + + /* D.1 pkt 3,4 convert format from desc to pktmbuf */ + pkt_mb4 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[3]), shuf_msk); +@@ -341,10 +354,16 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* pkt 1,2 shift the pktlen field to be 16-bit aligned*/ + uint32x4_t len1 = vshlq_u32(vreinterpretq_u32_u64(descs[1]), + len_shl); +- descs[1] = vreinterpretq_u64_u32(len1); ++ descs[1] = vreinterpretq_u64_u16(vsetq_lane_u16 ++ (vgetq_lane_u16(vreinterpretq_u16_u32(len1), 7), ++ vreinterpretq_u16_u64(descs[1]), ++ 7)); + uint32x4_t len0 = vshlq_u32(vreinterpretq_u32_u64(descs[0]), + len_shl); +- descs[0] = vreinterpretq_u64_u32(len0); ++ descs[0] = vreinterpretq_u64_u16(vsetq_lane_u16 ++ (vgetq_lane_u16(vreinterpretq_u16_u32(len0), 7), ++ vreinterpretq_u16_u64(descs[0]), ++ 7)); + + /* D.1 pkt 1,2 convert format from desc to pktmbuf */ + pkt_mb2 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[1]), shuf_msk); +@@ -375,7 +394,7 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + eop_bits = vmvnq_u8(vreinterpretq_u8_u16(staterr)); + eop_bits = vandq_u8(eop_bits, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ +@@ -437,15 +456,15 @@ i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -42631,7 +61311,7 @@ index deb185fe2f..5cac418cf0 100644 { struct i40e_rx_queue *rxq = rx_queue; -@@ -480,6 +479,32 @@ i40e_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -480,6 +499,32 @@ i40e_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, &split_flags[i]); } @@ -42664,7 +61344,7 @@ index deb185fe2f..5cac418cf0 100644 static inline void vtx1(volatile struct i40e_tx_desc *txdp, struct rte_mbuf *pkt, uint64_t flags) -@@ -564,7 +589,8 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts, +@@ -564,7 +609,8 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts, txq->tx_tail = tx_id; @@ -42675,7 +61355,7 @@ index deb185fe2f..5cac418cf0 100644 return nb_pkts; } diff --git a/dpdk/drivers/net/i40e/i40e_rxtx_vec_sse.c b/dpdk/drivers/net/i40e/i40e_rxtx_vec_sse.c -index 6ab0bb0d32..b5c5fdb0a2 100644 +index 6ab0bb0d32..65202a5277 100644 --- a/dpdk/drivers/net/i40e/i40e_rxtx_vec_sse.c +++ b/dpdk/drivers/net/i40e/i40e_rxtx_vec_sse.c @@ -254,16 +254,18 @@ desc_to_olflags_v(struct i40e_rx_queue *rxq, volatile union i40e_rx_desc *rxdp, @@ -42732,6 +61412,35 @@ index 6ab0bb0d32..b5c5fdb0a2 100644 /* nb_pkts has to be floor-aligned to RTE_I40E_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_I40E_DESCS_PER_LOOP); +@@ -462,7 +462,7 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* B.1 load 2 (64 bit) or 4 (32 bit) mbuf points */ + mbp1 = _mm_loadu_si128((__m128i *)&sw_ring[pos]); + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = _mm_loadu_si128((__m128i *)(rxdp + 3)); + rte_compiler_barrier(); + +@@ -474,9 +474,9 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + mbp2 = _mm_loadu_si128((__m128i *)&sw_ring[pos+2]); + #endif + ++ /* A.1 load desc[2-0] */ + descs[2] = _mm_loadu_si128((__m128i *)(rxdp + 2)); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs[1] = _mm_loadu_si128((__m128i *)(rxdp + 1)); + rte_compiler_barrier(); + descs[0] = _mm_loadu_si128((__m128i *)(rxdp)); +@@ -557,7 +557,7 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* and with mask to extract bits, flipping 1-0 */ + __m128i eop_bits = _mm_andnot_si128(staterr, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ @@ -605,15 +605,15 @@ i40e_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -42788,10 +61497,31 @@ index 6ab0bb0d32..b5c5fdb0a2 100644 vtx1(volatile struct i40e_tx_desc *txdp, struct rte_mbuf *pkt, uint64_t flags) diff --git a/dpdk/drivers/net/i40e/i40e_vf_representor.c b/dpdk/drivers/net/i40e/i40e_vf_representor.c -index b07b35c03f..083bc1a5f3 100644 +index b07b35c03f..40065e1524 100644 --- a/dpdk/drivers/net/i40e/i40e_vf_representor.c +++ b/dpdk/drivers/net/i40e/i40e_vf_representor.c -@@ -46,7 +46,8 @@ i40e_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev, +@@ -18,15 +18,18 @@ i40e_vf_representor_link_update(struct rte_eth_dev *ethdev, + int wait_to_complete) + { + struct i40e_vf_representor *representor = ethdev->data->dev_private; ++ struct rte_eth_dev *dev = ++ &rte_eth_devices[representor->adapter->pf.dev_data->port_id]; + +- return i40e_dev_link_update(representor->adapter->eth_dev, +- wait_to_complete); ++ return i40e_dev_link_update(dev, wait_to_complete); + } + static int + i40e_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev, + struct rte_eth_dev_info *dev_info) + { + struct i40e_vf_representor *representor = ethdev->data->dev_private; ++ struct rte_eth_dev_data *pf_dev_data = ++ representor->adapter->pf.dev_data; + + /* get dev info for the vdev */ + dev_info->device = ethdev->device; +@@ -46,7 +49,8 @@ i40e_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev, DEV_RX_OFFLOAD_QINQ_STRIP | DEV_RX_OFFLOAD_IPV4_CKSUM | DEV_RX_OFFLOAD_UDP_CKSUM | @@ -42801,6 +61531,141 @@ index b07b35c03f..083bc1a5f3 100644 dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS | DEV_TX_OFFLOAD_VLAN_INSERT | +@@ -97,7 +101,7 @@ i40e_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev, + }; + + dev_info->switch_info.name = +- representor->adapter->eth_dev->device->name; ++ rte_eth_devices[pf_dev_data->port_id].device->name; + dev_info->switch_info.domain_id = representor->switch_domain_id; + dev_info->switch_info.port_id = representor->vf_id; + +@@ -210,7 +214,7 @@ i40e_vf_representor_stats_get(struct rte_eth_dev *ethdev, + int ret; + + ret = rte_pmd_i40e_get_vf_native_stats( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, &native_stats); + if (ret == 0) { + i40evf_stat_update_48( +@@ -270,7 +274,7 @@ i40e_vf_representor_stats_reset(struct rte_eth_dev *ethdev) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_get_vf_native_stats( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, &representor->stats_offset); + } + +@@ -280,7 +284,7 @@ i40e_vf_representor_promiscuous_enable(struct rte_eth_dev *ethdev) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_unicast_promisc( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, 1); + } + +@@ -290,7 +294,7 @@ i40e_vf_representor_promiscuous_disable(struct rte_eth_dev *ethdev) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_unicast_promisc( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, 0); + } + +@@ -300,7 +304,7 @@ i40e_vf_representor_allmulticast_enable(struct rte_eth_dev *ethdev) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_multicast_promisc( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, 1); + } + +@@ -310,7 +314,7 @@ i40e_vf_representor_allmulticast_disable(struct rte_eth_dev *ethdev) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_multicast_promisc( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, 0); + } + +@@ -320,7 +324,7 @@ i40e_vf_representor_mac_addr_remove(struct rte_eth_dev *ethdev, uint32_t index) + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + rte_pmd_i40e_remove_vf_mac_addr( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, ðdev->data->mac_addrs[index]); + } + +@@ -331,7 +335,7 @@ i40e_vf_representor_mac_addr_set(struct rte_eth_dev *ethdev, + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_mac_addr( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, mac_addr); + } + +@@ -343,7 +347,7 @@ i40e_vf_representor_vlan_filter_set(struct rte_eth_dev *ethdev, + uint64_t vf_mask = 1ULL << representor->vf_id; + + return rte_pmd_i40e_set_vf_vlan_filter( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + vlan_id, vf_mask, on); + } + +@@ -357,7 +361,7 @@ i40e_vf_representor_vlan_offload_set(struct rte_eth_dev *ethdev, int mask) + struct i40e_pf *pf; + uint32_t vfid; + +- pdev = representor->adapter->eth_dev; ++ pdev = &rte_eth_devices[representor->adapter->pf.dev_data->port_id]; + vfid = representor->vf_id; + + if (!is_i40e_supported(pdev)) { +@@ -407,7 +411,7 @@ i40e_vf_representor_vlan_strip_queue_set(struct rte_eth_dev *ethdev, + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + rte_pmd_i40e_set_vf_vlan_stripq( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, on); + } + +@@ -418,7 +422,7 @@ i40e_vf_representor_vlan_pvid_set(struct rte_eth_dev *ethdev, uint16_t vlan_id, + struct i40e_vf_representor *representor = ethdev->data->dev_private; + + return rte_pmd_i40e_set_vf_vlan_insert( +- representor->adapter->eth_dev->data->port_id, ++ representor->adapter->pf.dev_data->port_id, + representor->vf_id, vlan_id); + } + +@@ -484,7 +488,7 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params) + ((struct i40e_vf_representor *)init_params)->adapter; + + pf = I40E_DEV_PRIVATE_TO_PF( +- representor->adapter->eth_dev->data->dev_private); ++ representor->adapter->pf.dev_data->dev_private); + + if (representor->vf_id >= pf->vf_num) + return -ENODEV; +@@ -515,7 +519,7 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params) + ethdev->data->mac_addrs = &vf->mac_addr; + + /* Link state. Inherited from PF */ +- link = &representor->adapter->eth_dev->data->dev_link; ++ link = &representor->adapter->pf.dev_data->dev_link; + + ethdev->data->dev_link.link_speed = link->link_speed; + ethdev->data->dev_link.link_duplex = link->link_duplex; diff --git a/dpdk/drivers/net/i40e/meson.build b/dpdk/drivers/net/i40e/meson.build index b01babba1f..3d5fc71119 100644 --- a/dpdk/drivers/net/i40e/meson.build @@ -42887,7 +61752,7 @@ index f57e1048ff..bc54ab2809 100644 Intel® IAVF driver diff --git a/dpdk/drivers/net/iavf/base/iavf_adminq.c b/dpdk/drivers/net/iavf/base/iavf_adminq.c -index 1ba8b52219..d6943e8260 100644 +index 1ba8b52219..a41402e04e 100644 --- a/dpdk/drivers/net/iavf/base/iavf_adminq.c +++ b/dpdk/drivers/net/iavf/base/iavf_adminq.c @@ -1,5 +1,5 @@ @@ -42925,7 +61790,27 @@ index 1ba8b52219..d6943e8260 100644 init_adminq_exit: return ret_code; -@@ -817,6 +822,8 @@ enum iavf_status_code iavf_asq_send_command(struct iavf_hw *hw, +@@ -426,7 +431,7 @@ enum iavf_status_code iavf_init_arq(struct iavf_hw *hw) + /* initialize base registers */ + ret_code = iavf_config_arq_regs(hw); + if (ret_code != IAVF_SUCCESS) +- goto init_adminq_free_rings; ++ goto init_config_regs; + + /* success! */ + hw->aq.arq.count = hw->aq.num_arq_entries; +@@ -434,6 +439,10 @@ enum iavf_status_code iavf_init_arq(struct iavf_hw *hw) + + init_adminq_free_rings: + iavf_free_adminq_arq(hw); ++ return ret_code; ++ ++init_config_regs: ++ iavf_free_arq_bufs(hw); + + init_adminq_exit: + return ret_code; +@@ -817,6 +826,8 @@ enum iavf_status_code iavf_asq_send_command(struct iavf_hw *hw, cmd_completed = true; if ((enum iavf_admin_queue_err)retval == IAVF_AQ_RC_OK) status = IAVF_SUCCESS; @@ -43000,8 +61885,18 @@ index cb91afb017..a981360af6 100644 */ #ifndef _IAVF_STATUS_H_ +diff --git a/dpdk/drivers/net/iavf/base/meson.build b/dpdk/drivers/net/iavf/base/meson.build +index bcb24b7399..857eed7eb4 100644 +--- a/dpdk/drivers/net/iavf/base/meson.build ++++ b/dpdk/drivers/net/iavf/base/meson.build +@@ -20,4 +20,4 @@ endforeach + base_lib = static_library('iavf_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/iavf/base/virtchnl.h b/dpdk/drivers/net/iavf/base/virtchnl.h -index 50f7c8e49e..fa98417b05 100644 +index 50f7c8e49e..e10a9b3ab7 100644 --- a/dpdk/drivers/net/iavf/base/virtchnl.h +++ b/dpdk/drivers/net/iavf/base/virtchnl.h @@ -1,5 +1,5 @@ @@ -43011,10 +61906,57 @@ index 50f7c8e49e..fa98417b05 100644 */ #ifndef _VIRTCHNL_H_ +@@ -385,9 +385,36 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select); + * PF removes the filters and returns status. + */ + ++/* VIRTCHNL_ETHER_ADDR_LEGACY ++ * Prior to adding the @type member to virtchnl_ether_addr, there were 2 pad ++ * bytes. Moving forward all VF drivers should not set type to ++ * VIRTCHNL_ETHER_ADDR_LEGACY. This is only here to not break previous/legacy ++ * behavior. The control plane function (i.e. PF) can use a best effort method ++ * of tracking the primary/device unicast in this case, but there is no ++ * guarantee and functionality depends on the implementation of the PF. ++ */ ++ ++/* VIRTCHNL_ETHER_ADDR_PRIMARY ++ * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_PRIMARY for the ++ * primary/device unicast MAC address filter for VIRTCHNL_OP_ADD_ETH_ADDR and ++ * VIRTCHNL_OP_DEL_ETH_ADDR. This allows for the underlying control plane ++ * function (i.e. PF) to accurately track and use this MAC address for ++ * displaying on the host and for VM/function reset. ++ */ ++ ++/* VIRTCHNL_ETHER_ADDR_EXTRA ++ * All VF drivers should set @type to VIRTCHNL_ETHER_ADDR_EXTRA for any extra ++ * unicast and/or multicast filters that are being added/deleted via ++ * VIRTCHNL_OP_DEL_ETH_ADDR/VIRTCHNL_OP_ADD_ETH_ADDR respectively. ++ */ + struct virtchnl_ether_addr { + u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; +- u8 pad[2]; ++ u8 type; ++#define VIRTCHNL_ETHER_ADDR_LEGACY 0 ++#define VIRTCHNL_ETHER_ADDR_PRIMARY 1 ++#define VIRTCHNL_ETHER_ADDR_EXTRA 2 ++#define VIRTCHNL_ETHER_ADDR_TYPE_MASK 3 /* first two bits of type are valid */ ++ u8 pad; + }; + + VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr); diff --git a/dpdk/drivers/net/iavf/iavf.h b/dpdk/drivers/net/iavf/iavf.h -index bbd4d75d00..b343f58004 100644 +index bbd4d75d00..297c69775b 100644 --- a/dpdk/drivers/net/iavf/iavf.h +++ b/dpdk/drivers/net/iavf/iavf.h +@@ -10,7 +10,7 @@ + + #define IAVF_AQ_LEN 32 + #define IAVF_AQ_BUF_SZ 4096 +-#define IAVF_RESET_WAIT_CNT 50 ++#define IAVF_RESET_WAIT_CNT 500 + #define IAVF_BUF_SIZE_MIN 1024 + #define IAVF_FRAME_SIZE_MAX 9728 + #define IAVF_QUEUE_BASE_ADDR_UNIT 128 @@ -58,6 +58,7 @@ #define IAVF_VLAN_TAG_SIZE 4 #define IAVF_ETH_OVERHEAD \ @@ -43023,6 +61965,15 @@ index bbd4d75d00..b343f58004 100644 #define IAVF_32_BIT_WIDTH (CHAR_BIT * 4) #define IAVF_48_BIT_WIDTH (CHAR_BIT * 6) +@@ -95,7 +96,7 @@ struct iavf_info { + struct virtchnl_vsi_resource *vsi_res; /* LAN VSI */ + + volatile enum virtchnl_ops pend_cmd; /* pending command not finished */ +- uint32_t cmd_retval; /* return value of the cmd response from PF */ ++ int cmd_retval; /* return value of the cmd response from PF */ + uint8_t *aq_resp; /* buffer to store the adminq response from PF */ + + /* Event from pf */ @@ -103,8 +104,12 @@ struct iavf_info { bool link_up; uint32_t link_speed; @@ -43045,7 +61996,7 @@ index bbd4d75d00..b343f58004 100644 + * _atomic_set_cmd successfully. + */ +static inline void -+_notify_cmd(struct iavf_info *vf, uint32_t msg_ret) ++_notify_cmd(struct iavf_info *vf, int msg_ret) +{ + vf->cmd_retval = msg_ret; + rte_wmb(); @@ -43055,16 +62006,19 @@ index bbd4d75d00..b343f58004 100644 /* clear current command. Only call in case execute * _atomic_set_cmd successfully. */ -@@ -219,4 +235,7 @@ int iavf_config_promisc(struct iavf_adapter *adapter, bool enable_unicast, +@@ -217,6 +233,9 @@ int iavf_query_stats(struct iavf_adapter *adapter, + int iavf_config_promisc(struct iavf_adapter *adapter, bool enable_unicast, + bool enable_multicast); int iavf_add_del_eth_addr(struct iavf_adapter *adapter, - struct rte_ether_addr *addr, bool add); +- struct rte_ether_addr *addr, bool add); ++ struct rte_ether_addr *addr, bool add, uint8_t type); int iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add); +int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter, + struct rte_ether_addr *mc_addrs, + uint32_t mc_addrs_num, bool add); #endif /* _IAVF_ETHDEV_H_ */ diff --git a/dpdk/drivers/net/iavf/iavf_ethdev.c b/dpdk/drivers/net/iavf/iavf_ethdev.c -index a39ba1466c..717d6a242c 100644 +index a39ba1466c..3cb02bd1fb 100644 --- a/dpdk/drivers/net/iavf/iavf_ethdev.c +++ b/dpdk/drivers/net/iavf/iavf_ethdev.c @@ -37,6 +37,7 @@ static int iavf_dev_configure(struct rte_eth_dev *dev); @@ -43161,7 +62115,16 @@ index a39ba1466c..717d6a242c 100644 int ret; rss_conf = &adapter->eth_dev->data->dev_conf.rx_adv_conf.rss_conf; -@@ -216,6 +223,41 @@ iavf_init_rss(struct iavf_adapter *adapter) +@@ -192,7 +199,7 @@ iavf_init_rss(struct iavf_adapter *adapter) + /* configure RSS key */ + if (!rss_conf->rss_key) { + /* Calculate the default hash key */ +- for (i = 0; i <= vf->vf_res->rss_key_size; i++) ++ for (i = 0; i < vf->vf_res->rss_key_size; i++) + vf->rss_key[i] = (uint8_t)rte_rand(); + } else + rte_memcpy(vf->rss_key, rss_conf->rss_key, +@@ -216,47 +223,83 @@ iavf_init_rss(struct iavf_adapter *adapter) return 0; } @@ -43203,7 +62166,21 @@ index a39ba1466c..717d6a242c 100644 static int iavf_init_rxq(struct rte_eth_dev *dev, struct iavf_rx_queue *rxq) { -@@ -233,30 +275,30 @@ iavf_init_rxq(struct rte_eth_dev *dev, struct iavf_rx_queue *rxq) + struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_eth_dev_data *dev_data = dev->data; +- uint16_t buf_size, max_pkt_len, len; ++ uint16_t buf_size, max_pkt_len; + + buf_size = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM; + + /* Calculate the maximum packet length allowed */ +- len = rxq->rx_buf_len * IAVF_MAX_CHAINED_RX_BUFFERS; +- max_pkt_len = RTE_MIN(len, dev->data->dev_conf.rxmode.max_rx_pkt_len); ++ max_pkt_len = RTE_MIN((uint32_t) ++ rxq->rx_buf_len * IAVF_MAX_CHAINED_RX_BUFFERS, ++ dev->data->dev_conf.rxmode.max_rx_pkt_len); + + /* Check if the jumbo frame and maximum packet length are set * correctly. */ if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { @@ -43239,7 +62216,7 @@ index a39ba1466c..717d6a242c 100644 dev_data->scattered_rx = 1; } IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1); -@@ -361,14 +403,14 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev, +@@ -361,14 +404,14 @@ static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev, /* If Rx interrupt is reuquired, and we can use * multi interrupts, then the vec is from 1 */ @@ -43257,7 +62234,56 @@ index a39ba1466c..717d6a242c 100644 vec = IAVF_RX_VEC_START; } PMD_DRV_LOG(DEBUG, -@@ -436,13 +478,6 @@ iavf_dev_start(struct rte_eth_dev *dev) +@@ -390,28 +433,38 @@ iavf_start_queues(struct rte_eth_dev *dev) + struct iavf_rx_queue *rxq; + struct iavf_tx_queue *txq; + int i; ++ uint16_t nb_txq, nb_rxq; + +- for (i = 0; i < dev->data->nb_tx_queues; i++) { +- txq = dev->data->tx_queues[i]; ++ for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) { ++ txq = dev->data->tx_queues[nb_txq]; + if (txq->tx_deferred_start) + continue; +- if (iavf_dev_tx_queue_start(dev, i) != 0) { +- PMD_DRV_LOG(ERR, "Fail to start queue %u", i); +- return -1; ++ if (iavf_dev_tx_queue_start(dev, nb_txq) != 0) { ++ PMD_DRV_LOG(ERR, "Fail to start tx queue %u", nb_txq); ++ goto tx_err; + } + } + +- for (i = 0; i < dev->data->nb_rx_queues; i++) { +- rxq = dev->data->rx_queues[i]; ++ for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) { ++ rxq = dev->data->rx_queues[nb_rxq]; + if (rxq->rx_deferred_start) + continue; +- if (iavf_dev_rx_queue_start(dev, i) != 0) { +- PMD_DRV_LOG(ERR, "Fail to start queue %u", i); +- return -1; ++ if (iavf_dev_rx_queue_start(dev, nb_rxq) != 0) { ++ PMD_DRV_LOG(ERR, "Fail to start rx queue %u", nb_rxq); ++ goto rx_err; + } + } + + return 0; ++ ++rx_err: ++ for (i = 0; i < nb_rxq; i++) ++ iavf_dev_rx_queue_stop(dev, i); ++tx_err: ++ for (i = 0; i < nb_txq; i++) ++ iavf_dev_tx_queue_stop(dev, i); ++ ++ return -1; + } + + static int +@@ -436,13 +489,6 @@ iavf_dev_start(struct rte_eth_dev *dev) return -1; } @@ -43271,7 +62297,7 @@ index a39ba1466c..717d6a242c 100644 if (iavf_configure_queues(adapter) != 0) { PMD_DRV_LOG(ERR, "configure queues failed"); goto err_queue; -@@ -461,6 +496,10 @@ iavf_dev_start(struct rte_eth_dev *dev) +@@ -461,6 +507,10 @@ iavf_dev_start(struct rte_eth_dev *dev) /* Set all mac addrs */ iavf_add_del_all_mac_addr(adapter, TRUE); @@ -43282,7 +62308,7 @@ index a39ba1466c..717d6a242c 100644 if (iavf_start_queues(dev) != 0) { PMD_DRV_LOG(ERR, "enable queues failed"); goto err_mac; -@@ -471,13 +510,13 @@ iavf_dev_start(struct rte_eth_dev *dev) +@@ -471,13 +521,13 @@ iavf_dev_start(struct rte_eth_dev *dev) err_mac: iavf_add_del_all_mac_addr(adapter, FALSE); err_queue: @@ -43297,7 +62323,7 @@ index a39ba1466c..717d6a242c 100644 struct iavf_adapter *adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private); -@@ -500,6 +539,11 @@ iavf_dev_stop(struct rte_eth_dev *dev) +@@ -500,6 +550,11 @@ iavf_dev_stop(struct rte_eth_dev *dev) /* remove all mac addrs */ iavf_add_del_all_mac_addr(adapter, FALSE); @@ -43309,7 +62335,7 @@ index a39ba1466c..717d6a242c 100644 hw->adapter_stopped = 1; } -@@ -593,6 +637,8 @@ iavf_dev_link_update(struct rte_eth_dev *dev, +@@ -593,6 +648,8 @@ iavf_dev_link_update(struct rte_eth_dev *dev, struct rte_eth_link new_link; struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); @@ -43318,7 +62344,7 @@ index a39ba1466c..717d6a242c 100644 /* Only read status info stored in VF, and the info is updated * when receive LINK_CHANGE evnet from PF by Virtchnnl. */ -@@ -657,6 +703,8 @@ iavf_dev_promiscuous_enable(struct rte_eth_dev *dev) +@@ -657,6 +714,8 @@ iavf_dev_promiscuous_enable(struct rte_eth_dev *dev) ret = iavf_config_promisc(adapter, TRUE, vf->promisc_multicast_enabled); if (!ret) vf->promisc_unicast_enabled = TRUE; @@ -43327,7 +62353,7 @@ index a39ba1466c..717d6a242c 100644 else ret = -EAGAIN; -@@ -677,6 +725,8 @@ iavf_dev_promiscuous_disable(struct rte_eth_dev *dev) +@@ -677,6 +736,8 @@ iavf_dev_promiscuous_disable(struct rte_eth_dev *dev) ret = iavf_config_promisc(adapter, FALSE, vf->promisc_multicast_enabled); if (!ret) vf->promisc_unicast_enabled = FALSE; @@ -43336,7 +62362,7 @@ index a39ba1466c..717d6a242c 100644 else ret = -EAGAIN; -@@ -697,6 +747,8 @@ iavf_dev_allmulticast_enable(struct rte_eth_dev *dev) +@@ -697,6 +758,8 @@ iavf_dev_allmulticast_enable(struct rte_eth_dev *dev) ret = iavf_config_promisc(adapter, vf->promisc_unicast_enabled, TRUE); if (!ret) vf->promisc_multicast_enabled = TRUE; @@ -43345,7 +62371,7 @@ index a39ba1466c..717d6a242c 100644 else ret = -EAGAIN; -@@ -717,6 +769,8 @@ iavf_dev_allmulticast_disable(struct rte_eth_dev *dev) +@@ -717,6 +780,8 @@ iavf_dev_allmulticast_disable(struct rte_eth_dev *dev) ret = iavf_config_promisc(adapter, vf->promisc_unicast_enabled, FALSE); if (!ret) vf->promisc_multicast_enabled = FALSE; @@ -43354,7 +62380,25 @@ index a39ba1466c..717d6a242c 100644 else ret = -EAGAIN; -@@ -953,7 +1007,7 @@ iavf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -738,7 +803,7 @@ iavf_dev_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr, + return -EINVAL; + } + +- err = iavf_add_del_eth_addr(adapter, addr, TRUE); ++ err = iavf_add_del_eth_addr(adapter, addr, TRUE, VIRTCHNL_ETHER_ADDR_EXTRA); + if (err) { + PMD_DRV_LOG(ERR, "fail to add MAC address"); + return -EIO; +@@ -760,7 +825,7 @@ iavf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index) + + addr = &dev->data->mac_addrs[index]; + +- err = iavf_add_del_eth_addr(adapter, addr, FALSE); ++ err = iavf_add_del_eth_addr(adapter, addr, FALSE, VIRTCHNL_ETHER_ADDR_EXTRA); + if (err) + PMD_DRV_LOG(ERR, "fail to delete MAC address"); + +@@ -953,7 +1018,7 @@ iavf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EBUSY; } @@ -43363,17 +62407,40 @@ index a39ba1466c..717d6a242c 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else -@@ -978,9 +1032,6 @@ iavf_dev_set_default_mac_addr(struct rte_eth_dev *dev, +@@ -972,20 +1037,15 @@ iavf_dev_set_default_mac_addr(struct rte_eth_dev *dev, + struct iavf_adapter *adapter = + IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter); +- struct rte_ether_addr *perm_addr, *old_addr; ++ struct rte_ether_addr *old_addr; + int ret; + old_addr = (struct rte_ether_addr *)hw->mac.addr; - perm_addr = (struct rte_ether_addr *)hw->mac.perm_addr; +- perm_addr = (struct rte_ether_addr *)hw->mac.perm_addr; - if (rte_is_same_ether_addr(mac_addr, old_addr)) -- return 0; ++ if (rte_is_same_ether_addr(old_addr, mac_addr)) + return 0; + +- /* If the MAC address is configured by host, skip the setting */ +- if (rte_is_valid_assigned_ether_addr(perm_addr)) +- return -EPERM; - - /* If the MAC address is configured by host, skip the setting */ - if (rte_is_valid_assigned_ether_addr(perm_addr)) - return -EPERM; -@@ -1068,7 +1119,7 @@ iavf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +- ret = iavf_add_del_eth_addr(adapter, old_addr, FALSE); ++ ret = iavf_add_del_eth_addr(adapter, old_addr, FALSE, VIRTCHNL_ETHER_ADDR_PRIMARY); + if (ret) + PMD_DRV_LOG(ERR, "Fail to delete old MAC:" + " %02X:%02X:%02X:%02X:%02X:%02X", +@@ -996,7 +1056,7 @@ iavf_dev_set_default_mac_addr(struct rte_eth_dev *dev, + old_addr->addr_bytes[4], + old_addr->addr_bytes[5]); + +- ret = iavf_add_del_eth_addr(adapter, mac_addr, TRUE); ++ ret = iavf_add_del_eth_addr(adapter, mac_addr, TRUE, VIRTCHNL_ETHER_ADDR_PRIMARY); + if (ret) + PMD_DRV_LOG(ERR, "Fail to add new MAC:" + " %02X:%02X:%02X:%02X:%02X:%02X", +@@ -1068,7 +1128,7 @@ iavf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) if (ret == 0) { iavf_update_stats(vsi, pstats); stats->ipackets = pstats->rx_unicast + pstats->rx_multicast + @@ -43382,7 +62449,7 @@ index a39ba1466c..717d6a242c 100644 stats->opackets = pstats->tx_broadcast + pstats->tx_multicast + pstats->tx_unicast; stats->imissed = pstats->rx_discards; -@@ -1079,7 +1130,7 @@ iavf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +@@ -1079,7 +1139,7 @@ iavf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) } else { PMD_DRV_LOG(ERR, "Get statistics failed"); } @@ -43391,7 +62458,7 @@ index a39ba1466c..717d6a242c 100644 } static int -@@ -1240,6 +1291,7 @@ iavf_init_vf(struct rte_eth_dev *dev) +@@ -1240,6 +1300,7 @@ iavf_init_vf(struct rte_eth_dev *dev) goto err_rss; } } @@ -43399,7 +62466,17 @@ index a39ba1466c..717d6a242c 100644 return 0; err_rss: rte_free(vf->rss_key); -@@ -1388,7 +1440,6 @@ static int +@@ -1373,6 +1434,9 @@ iavf_dev_close(struct rte_eth_dev *dev) + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + iavf_dev_stop(dev); + iavf_shutdown_adminq(hw); + /* disable uio intr before callback unregister */ +@@ -1388,7 +1452,6 @@ static int iavf_dev_uninit(struct rte_eth_dev *dev) { struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); @@ -43407,7 +62484,7 @@ index a39ba1466c..717d6a242c 100644 if (rte_eal_process_type() != RTE_PROC_PRIMARY) return -EPERM; -@@ -1396,8 +1447,7 @@ iavf_dev_uninit(struct rte_eth_dev *dev) +@@ -1396,8 +1459,7 @@ iavf_dev_uninit(struct rte_eth_dev *dev) dev->dev_ops = NULL; dev->rx_pkt_burst = NULL; dev->tx_pkt_burst = NULL; @@ -43417,7 +62494,7 @@ index a39ba1466c..717d6a242c 100644 rte_free(vf->vf_res); vf->vsi_res = NULL; -@@ -1415,9 +1465,26 @@ iavf_dev_uninit(struct rte_eth_dev *dev) +@@ -1415,9 +1477,26 @@ iavf_dev_uninit(struct rte_eth_dev *dev) vf->rss_key = NULL; } @@ -43444,12 +62521,35 @@ index a39ba1466c..717d6a242c 100644 static int eth_iavf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { +@@ -1476,13 +1555,15 @@ iavf_allocate_dma_mem_d(__rte_unused struct iavf_hw *hw, + u64 size, + u32 alignment) + { ++ static uint64_t iavf_dma_memzone_id; + const struct rte_memzone *mz = NULL; + char z_name[RTE_MEMZONE_NAMESIZE]; + + if (!mem) + return IAVF_ERR_PARAM; + +- snprintf(z_name, sizeof(z_name), "iavf_dma_%"PRIu64, rte_rand()); ++ snprintf(z_name, sizeof(z_name), "iavf_dma_%" PRIu64, ++ __atomic_fetch_add(&iavf_dma_memzone_id, 1, __ATOMIC_RELAXED)); + mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, + RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M); + if (!mz) diff --git a/dpdk/drivers/net/iavf/iavf_rxtx.c b/dpdk/drivers/net/iavf/iavf_rxtx.c -index 88f79ba379..ae43eb49a6 100644 +index 88f79ba379..eda102a5a0 100644 --- a/dpdk/drivers/net/iavf/iavf_rxtx.c +++ b/dpdk/drivers/net/iavf/iavf_rxtx.c -@@ -167,6 +167,8 @@ reset_rx_queue(struct iavf_rx_queue *rxq) +@@ -165,8 +165,14 @@ reset_rx_queue(struct iavf_rx_queue *rxq) + + rxq->rx_tail = 0; rxq->nb_rx_hold = 0; ++ ++ if (rxq->pkt_first_seg != NULL) ++ rte_pktmbuf_free(rxq->pkt_first_seg); ++ rxq->pkt_first_seg = NULL; rxq->pkt_last_seg = NULL; + rxq->rxrearm_nb = 0; @@ -43457,7 +62557,163 @@ index 88f79ba379..ae43eb49a6 100644 } static inline void -@@ -1506,7 +1508,7 @@ iavf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -289,12 +295,20 @@ release_txq_mbufs(struct iavf_tx_queue *txq) + } + } + +-static const struct iavf_rxq_ops def_rxq_ops = { +- .release_mbufs = release_rxq_mbufs, ++static const ++struct iavf_rxq_ops iavf_rxq_release_mbufs_ops[] = { ++ [IAVF_REL_MBUFS_DEFAULT].release_mbufs = release_rxq_mbufs, ++#ifdef RTE_ARCH_X86 ++ [IAVF_REL_MBUFS_SSE_VEC].release_mbufs = iavf_rx_queue_release_mbufs_sse, ++#endif + }; + +-static const struct iavf_txq_ops def_txq_ops = { +- .release_mbufs = release_txq_mbufs, ++static const ++struct iavf_txq_ops iavf_txq_release_mbufs_ops[] = { ++ [IAVF_REL_MBUFS_DEFAULT].release_mbufs = release_txq_mbufs, ++#ifdef RTE_ARCH_X86 ++ [IAVF_REL_MBUFS_SSE_VEC].release_mbufs = iavf_tx_queue_release_mbufs_sse, ++#endif + }; + + int +@@ -356,7 +370,7 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, + rxq->rx_hdr_len = 0; + + len = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM; +- rxq->rx_buf_len = RTE_ALIGN(len, (1 << IAVF_RXQ_CTX_DBUFF_SHIFT)); ++ rxq->rx_buf_len = RTE_ALIGN_FLOOR(len, (1 << IAVF_RXQ_CTX_DBUFF_SHIFT)); + + /* Allocate the software ring. */ + len = nb_desc + IAVF_RX_MAX_BURST; +@@ -396,7 +410,7 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, + rxq->q_set = TRUE; + dev->data->rx_queues[queue_idx] = rxq; + rxq->qrx_tail = hw->hw_addr + IAVF_QRX_TAIL1(rxq->queue_id); +- rxq->ops = &def_rxq_ops; ++ rxq->rel_mbufs_type = IAVF_REL_MBUFS_DEFAULT; + + if (check_rx_bulk_allow(rxq) == TRUE) { + PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions are " +@@ -447,7 +461,8 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev, + tx_conf->tx_rs_thresh : DEFAULT_TX_RS_THRESH); + tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ? + tx_conf->tx_free_thresh : DEFAULT_TX_FREE_THRESH); +- check_tx_thresh(nb_desc, tx_rs_thresh, tx_rs_thresh); ++ if (check_tx_thresh(nb_desc, tx_rs_thresh, tx_free_thresh) != 0) ++ return -EINVAL; + + /* Free memory if needed. */ + if (dev->data->tx_queues[queue_idx]) { +@@ -506,7 +521,7 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev, + txq->q_set = TRUE; + dev->data->tx_queues[queue_idx] = txq; + txq->qtx_tail = hw->hw_addr + IAVF_QTX_TAIL1(queue_idx); +- txq->ops = &def_txq_ops; ++ txq->rel_mbufs_type = IAVF_REL_MBUFS_DEFAULT; + + if (check_tx_vec_allow(txq) == FALSE) { + struct iavf_adapter *ad = +@@ -611,7 +626,7 @@ iavf_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) + } + + rxq = dev->data->rx_queues[rx_queue_id]; +- rxq->ops->release_mbufs(rxq); ++ iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq); + reset_rx_queue(rxq); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + +@@ -639,7 +654,7 @@ iavf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) + } + + txq = dev->data->tx_queues[tx_queue_id]; +- txq->ops->release_mbufs(txq); ++ iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq); + reset_tx_queue(txq); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + +@@ -654,7 +669,7 @@ iavf_dev_rx_queue_release(void *rxq) + if (!q) + return; + +- q->ops->release_mbufs(q); ++ iavf_rxq_release_mbufs_ops[q->rel_mbufs_type].release_mbufs(q); + rte_free(q->sw_ring); + rte_memzone_free(q->mz); + rte_free(q); +@@ -668,7 +683,7 @@ iavf_dev_tx_queue_release(void *txq) + if (!q) + return; + +- q->ops->release_mbufs(q); ++ iavf_txq_release_mbufs_ops[q->rel_mbufs_type].release_mbufs(q); + rte_free(q->sw_ring); + rte_memzone_free(q->mz); + rte_free(q); +@@ -692,7 +707,7 @@ iavf_stop_queues(struct rte_eth_dev *dev) + txq = dev->data->tx_queues[i]; + if (!txq) + continue; +- txq->ops->release_mbufs(txq); ++ iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq); + reset_tx_queue(txq); + dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; + } +@@ -700,7 +715,7 @@ iavf_stop_queues(struct rte_eth_dev *dev) + rxq = dev->data->rx_queues[i]; + if (!rxq) + continue; +- rxq->ops->release_mbufs(rxq); ++ iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq); + reset_rx_queue(rxq); + dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; + } +@@ -1094,7 +1109,7 @@ iavf_rx_scan_hw_ring(struct iavf_rx_queue *rxq) + uint16_t pkt_len; + uint64_t qword1; + uint32_t rx_status; +- int32_t s[IAVF_LOOK_AHEAD], nb_dd; ++ int32_t s[IAVF_LOOK_AHEAD], var, nb_dd; + int32_t i, j, nb_rx = 0; + uint64_t pkt_flags; + static const uint32_t ptype_tbl[UINT8_MAX + 1] __rte_cache_aligned = { +@@ -1143,9 +1158,27 @@ iavf_rx_scan_hw_ring(struct iavf_rx_queue *rxq) + + rte_smp_rmb(); + +- /* Compute how many status bits were set */ +- for (j = 0, nb_dd = 0; j < IAVF_LOOK_AHEAD; j++) +- nb_dd += s[j] & (1 << IAVF_RX_DESC_STATUS_DD_SHIFT); ++ /* Compute how many contiguous DD bits were set */ ++ for (j = 0, nb_dd = 0; j < IAVF_LOOK_AHEAD; j++) { ++ var = s[j] & (1 << IAVF_RX_DESC_STATUS_DD_SHIFT); ++#ifdef RTE_ARCH_ARM ++ /* For Arm platforms, count only contiguous descriptors ++ * whose DD bit is set to 1. On Arm platforms, reads of ++ * descriptors can be reordered. Since the CPU may ++ * be reading the descriptors as the NIC updates them ++ * in memory, it is possbile that the DD bit for a ++ * descriptor earlier in the queue is read as not set ++ * while the DD bit for a descriptor later in the queue ++ * is read as set. ++ */ ++ if (var) ++ nb_dd += 1; ++ else ++ break; ++#else ++ nb_dd += var; ++#endif ++ } + + nb_rx += nb_dd; + +@@ -1506,7 +1539,7 @@ iavf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* Check if the descriptor ring needs to be cleaned. */ if (txq->nb_free < txq->free_thresh) @@ -43466,11 +62722,23 @@ index 88f79ba379..ae43eb49a6 100644 for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) { td_cmd = 0; +@@ -1581,6 +1614,11 @@ iavf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) + (volatile struct iavf_tx_context_desc *) + &txr[tx_id]; + ++ /* clear QW0 or the previous writeback value ++ * may impact next write ++ */ ++ *(volatile uint64_t *)ctx_txd = 0; ++ + txn = &sw_ring[txe->next_id]; + RTE_MBUF_PREFETCH_TO_FREE(txn->mbuf); + if (txe->mbuf) { diff --git a/dpdk/drivers/net/iavf/iavf_rxtx.h b/dpdk/drivers/net/iavf/iavf_rxtx.h -index 225a0c4c42..60d02c521f 100644 +index 225a0c4c42..6be05deb33 100644 --- a/dpdk/drivers/net/iavf/iavf_rxtx.h +++ b/dpdk/drivers/net/iavf/iavf_rxtx.h -@@ -28,6 +28,7 @@ +@@ -28,12 +28,13 @@ DEV_TX_OFFLOAD_VLAN_INSERT | \ DEV_TX_OFFLOAD_SCTP_CKSUM | \ DEV_TX_OFFLOAD_UDP_CKSUM | \ @@ -43478,6 +62746,51 @@ index 225a0c4c42..60d02c521f 100644 DEV_TX_OFFLOAD_TCP_CKSUM) #define DEFAULT_TX_RS_THRESH 32 + #define DEFAULT_TX_FREE_THRESH 32 + +-#define IAVF_MIN_TSO_MSS 256 ++#define IAVF_MIN_TSO_MSS 88 + #define IAVF_MAX_TSO_MSS 9668 + #define IAVF_TSO_MAX_SEG UINT8_MAX + #define IAVF_TX_MAX_MTU_SEG 8 +@@ -86,6 +87,7 @@ struct iavf_rx_queue { + struct rte_mbuf *pkt_first_seg; /* first segment of current packet */ + struct rte_mbuf *pkt_last_seg; /* last segment of current packet */ + struct rte_mbuf fake_mbuf; /* dummy mbuf */ ++ uint8_t rel_mbufs_type; + + /* used for VPMD */ + uint16_t rxrearm_nb; /* number of remaining to be re-armed */ +@@ -131,6 +133,7 @@ struct iavf_tx_queue { + uint16_t last_desc_cleaned; /* last desc have been cleaned*/ + uint16_t free_thresh; + uint16_t rs_thresh; ++ uint8_t rel_mbufs_type; + + uint16_t port_id; + uint16_t queue_id; +@@ -155,6 +158,12 @@ union iavf_tx_offload { + }; + }; + ++enum iavf_rxtx_rel_mbufs_type { ++ IAVF_REL_MBUFS_DEFAULT = 0, ++ IAVF_REL_MBUFS_SSE_VEC = 1, ++ IAVF_REL_MBUFS_AVX512_VEC = 2, ++}; ++ + int iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, + uint16_t queue_idx, + uint16_t nb_desc, +@@ -214,6 +223,8 @@ int iavf_rx_vec_dev_check(struct rte_eth_dev *dev); + int iavf_tx_vec_dev_check(struct rte_eth_dev *dev); + int iavf_rxq_vec_setup(struct iavf_rx_queue *rxq); + int iavf_txq_vec_setup(struct iavf_tx_queue *txq); ++void iavf_rx_queue_release_mbufs_sse(struct iavf_rx_queue *rxq); ++void iavf_tx_queue_release_mbufs_sse(struct iavf_tx_queue *txq); + + static inline + void iavf_dump_rx_descriptor(struct iavf_rx_queue *rxq, diff --git a/dpdk/drivers/net/iavf/iavf_rxtx_vec_common.h b/dpdk/drivers/net/iavf/iavf_rxtx_vec_common.h index a6ba227584..25bb502de2 100644 --- a/dpdk/drivers/net/iavf/iavf_rxtx_vec_common.h @@ -43491,7 +62804,7 @@ index a6ba227584..25bb502de2 100644 /* we need to strip crc for the whole packet */ start->pkt_len -= rxq->crc_len; diff --git a/dpdk/drivers/net/iavf/iavf_rxtx_vec_sse.c b/dpdk/drivers/net/iavf/iavf_rxtx_vec_sse.c -index 2b16dc1b52..458730e089 100644 +index 2b16dc1b52..3c2eed0cd3 100644 --- a/dpdk/drivers/net/iavf/iavf_rxtx_vec_sse.c +++ b/dpdk/drivers/net/iavf/iavf_rxtx_vec_sse.c @@ -227,10 +227,12 @@ desc_to_ptype_v(__m128i descs[4], struct rte_mbuf **rx_pkts) @@ -43520,6 +62833,35 @@ index 2b16dc1b52..458730e089 100644 /* nb_pkts has to be floor-aligned to IAVF_VPMD_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IAVF_VPMD_DESCS_PER_LOOP); +@@ -342,7 +341,7 @@ _recv_raw_pkts_vec(struct iavf_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* B.1 load 2 (64 bit) or 4 (32 bit) mbuf points */ + mbp1 = _mm_loadu_si128((__m128i *)&sw_ring[pos]); + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = _mm_loadu_si128((__m128i *)(rxdp + 3)); + rte_compiler_barrier(); + +@@ -354,9 +353,9 @@ _recv_raw_pkts_vec(struct iavf_rx_queue *rxq, struct rte_mbuf **rx_pkts, + mbp2 = _mm_loadu_si128((__m128i *)&sw_ring[pos + 2]); + #endif + ++ /* A.1 load desc[2-0] */ + descs[2] = _mm_loadu_si128((__m128i *)(rxdp + 2)); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs[1] = _mm_loadu_si128((__m128i *)(rxdp + 1)); + rte_compiler_barrier(); + descs[0] = _mm_loadu_si128((__m128i *)(rxdp)); +@@ -438,7 +437,7 @@ _recv_raw_pkts_vec(struct iavf_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* and with mask to extract bits, flipping 1-0 */ + __m128i eop_bits = _mm_andnot_si128(staterr, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ @@ -486,15 +485,15 @@ iavf_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -43575,8 +62917,50 @@ index 2b16dc1b52..458730e089 100644 static inline void vtx1(volatile struct iavf_tx_desc *txdp, struct rte_mbuf *pkt, uint64_t flags) { +@@ -643,37 +668,29 @@ iavf_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts, + return nb_tx; + } + +-static void __attribute__((cold)) ++void + iavf_rx_queue_release_mbufs_sse(struct iavf_rx_queue *rxq) + { + _iavf_rx_queue_release_mbufs_vec(rxq); + } + +-static void __attribute__((cold)) ++void + iavf_tx_queue_release_mbufs_sse(struct iavf_tx_queue *txq) + { + _iavf_tx_queue_release_mbufs_vec(txq); + } + +-static const struct iavf_rxq_ops sse_vec_rxq_ops = { +- .release_mbufs = iavf_rx_queue_release_mbufs_sse, +-}; +- +-static const struct iavf_txq_ops sse_vec_txq_ops = { +- .release_mbufs = iavf_tx_queue_release_mbufs_sse, +-}; +- + int __attribute__((cold)) + iavf_txq_vec_setup(struct iavf_tx_queue *txq) + { +- txq->ops = &sse_vec_txq_ops; ++ txq->rel_mbufs_type = IAVF_REL_MBUFS_SSE_VEC; + return 0; + } + + int __attribute__((cold)) + iavf_rxq_vec_setup(struct iavf_rx_queue *rxq) + { +- rxq->ops = &sse_vec_rxq_ops; ++ rxq->rel_mbufs_type = IAVF_REL_MBUFS_SSE_VEC; + return iavf_rxq_vec_setup_default(rxq); + } + diff --git a/dpdk/drivers/net/iavf/iavf_vchnl.c b/dpdk/drivers/net/iavf/iavf_vchnl.c -index 14395fed31..81ad748f4d 100644 +index 14395fed31..ba627f1103 100644 --- a/dpdk/drivers/net/iavf/iavf_vchnl.c +++ b/dpdk/drivers/net/iavf/iavf_vchnl.c @@ -73,6 +73,9 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args) @@ -43589,7 +62973,33 @@ index 14395fed31..81ad748f4d 100644 if (_atomic_set_cmd(vf, args->ops)) return -1; -@@ -132,6 +135,38 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args) +@@ -118,13 +121,19 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args) + rte_delay_ms(ASQ_DELAY_MS); + /* If don't read msg or read sys event, continue */ + } while (i++ < MAX_TRY_TIMES); +- /* If there's no response is received, clear command */ +- if (i >= MAX_TRY_TIMES || +- vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) { +- err = -1; +- PMD_DRV_LOG(ERR, "No response or return failure (%d)" +- " for cmd %d", vf->cmd_retval, args->ops); ++ ++ if (i >= MAX_TRY_TIMES) { ++ PMD_DRV_LOG(ERR, "No response for cmd %d", args->ops); + _clear_cmd(vf); ++ err = -EIO; ++ } else if (vf->cmd_retval == ++ VIRTCHNL_STATUS_NOT_SUPPORTED) { ++ PMD_DRV_LOG(ERR, "Cmd %d not supported", args->ops); ++ err = -ENOTSUP; ++ } else if (vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) { ++ PMD_DRV_LOG(ERR, "Return failure %d for cmd %d", ++ vf->cmd_retval, args->ops); ++ err = -EINVAL; + } + break; + } +@@ -132,6 +141,38 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args) return err; } @@ -43628,7 +63038,7 @@ index 14395fed31..81ad748f4d 100644 static void iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, uint16_t msglen) -@@ -147,13 +182,21 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, +@@ -147,13 +188,21 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, switch (pf_msg->event) { case VIRTCHNL_EVENT_RESET_IMPENDING: PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event"); @@ -43651,7 +63061,7 @@ index 14395fed31..81ad748f4d 100644 iavf_dev_link_update(dev, 0); _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); -@@ -210,12 +253,9 @@ iavf_handle_virtchnl_msg(struct rte_eth_dev *dev) +@@ -210,12 +259,9 @@ iavf_handle_virtchnl_msg(struct rte_eth_dev *dev) info.msg_len); } else { /* read message and it's expected one */ @@ -43667,7 +63077,7 @@ index 14395fed31..81ad748f4d 100644 PMD_DRV_LOG(ERR, "command mismatch," "expect %u, get %u", vf->pend_cmd, msg_opc); -@@ -225,7 +265,7 @@ iavf_handle_virtchnl_msg(struct rte_eth_dev *dev) +@@ -225,7 +271,7 @@ iavf_handle_virtchnl_msg(struct rte_eth_dev *dev) } break; default: @@ -43676,7 +63086,34 @@ index 14395fed31..81ad748f4d 100644 aq_opc); break; } -@@ -808,3 +848,59 @@ iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add) +@@ -668,6 +714,9 @@ iavf_add_del_all_mac_addr(struct iavf_adapter *adapter, bool add) + continue; + rte_memcpy(list->list[j].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); ++ list->list[j].type = (j == 0 ? ++ VIRTCHNL_ETHER_ADDR_PRIMARY : ++ VIRTCHNL_ETHER_ADDR_EXTRA); + PMD_DRV_LOG(DEBUG, "add/rm mac:%x:%x:%x:%x:%x:%x", + addr->addr_bytes[0], addr->addr_bytes[1], + addr->addr_bytes[2], addr->addr_bytes[3], +@@ -754,7 +803,7 @@ iavf_config_promisc(struct iavf_adapter *adapter, + + int + iavf_add_del_eth_addr(struct iavf_adapter *adapter, struct rte_ether_addr *addr, +- bool add) ++ bool add, uint8_t type) + { + struct virtchnl_ether_addr_list *list; + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); +@@ -766,6 +815,7 @@ iavf_add_del_eth_addr(struct iavf_adapter *adapter, struct rte_ether_addr *addr, + list = (struct virtchnl_ether_addr_list *)cmd_buffer; + list->vsi_id = vf->vsi_res->vsi_id; + list->num_elements = 1; ++ list->list[0].type = type; + rte_memcpy(list->list[0].addr, addr->addr_bytes, + sizeof(addr->addr_bytes)); + +@@ -808,3 +858,60 @@ iavf_add_del_vlan(struct iavf_adapter *adapter, uint16_t vlanid, bool add) return err; } @@ -43718,6 +63155,7 @@ index 14395fed31..81ad748f4d 100644 + + memcpy(list->list[i].addr, mc_addrs[i].addr_bytes, + sizeof(list->list[i].addr)); ++ list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA; + } + + args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR; @@ -43736,6 +63174,31 @@ index 14395fed31..81ad748f4d 100644 + + return 0; +} +diff --git a/dpdk/drivers/net/ice/Makefile b/dpdk/drivers/net/ice/Makefile +index 6c4d155268..9935d614c8 100644 +--- a/dpdk/drivers/net/ice/Makefile ++++ b/dpdk/drivers/net/ice/Makefile +@@ -26,6 +26,9 @@ CFLAGS_BASE_DRIVER += + else ifeq ($(CONFIG_RTE_TOOLCHAIN_CLANG),y) + CFLAGS_BASE_DRIVER += -Wno-unused-parameter + CFLAGS_BASE_DRIVER += -Wno-unused-variable ++ifeq ($(shell test $(CLANG_MAJOR_VERSION) -ge 13 && echo 1), 1) ++CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable ++endif + else + CFLAGS_BASE_DRIVER += -Wno-unused-parameter + CFLAGS_BASE_DRIVER += -Wno-unused-variable +@@ -34,6 +37,10 @@ ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1) + CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable + endif + ++ifeq ($(shell test $(GCC_VERSION) -ge 110 && echo 1), 1) ++CFLAGS_BASE_DRIVER += -Wno-maybe-uninitialized ++endif ++ + endif + OBJS_BASE_DRIVER=$(patsubst %.c,%.o,$(notdir $(wildcard $(SRCDIR)/base/*.c))) + $(foreach obj, $(OBJS_BASE_DRIVER), $(eval CFLAGS_$(obj)+=$(CFLAGS_BASE_DRIVER))) diff --git a/dpdk/drivers/net/ice/base/ice_adminq_cmd.h b/dpdk/drivers/net/ice/base/ice_adminq_cmd.h index e6a1350baa..a99670d51e 100644 --- a/dpdk/drivers/net/ice/base/ice_adminq_cmd.h @@ -43808,7 +63271,7 @@ index 32f64cac0c..0344437c9e 100644 #ifndef _ICE_BITOPS_H_ diff --git a/dpdk/drivers/net/ice/base/ice_common.c b/dpdk/drivers/net/ice/base/ice_common.c -index 4ba3ab2028..25e30b937b 100644 +index 4ba3ab2028..2926a1d474 100644 --- a/dpdk/drivers/net/ice/base/ice_common.c +++ b/dpdk/drivers/net/ice/base/ice_common.c @@ -1,5 +1,5 @@ @@ -43855,6 +63318,15 @@ index 4ba3ab2028..25e30b937b 100644 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); } +@@ -2651,7 +2650,7 @@ ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *phy_caps, + + /** + * ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data +- * @caps: PHY ability structure to copy date from ++ * @caps: PHY ability structure to copy data from + * @cfg: PHY configuration structure to copy data to + * + * Helper function to copy AQC PHY get ability data to PHY set configuration diff --git a/dpdk/drivers/net/ice/base/ice_common.h b/dpdk/drivers/net/ice/base/ice_common.h index c73184499f..63b733d74f 100644 --- a/dpdk/drivers/net/ice/base/ice_common.h @@ -44563,7 +64035,7 @@ index 92d432044d..1c9c84dfb4 100644 /* Machine-generated file; do not edit */ diff --git a/dpdk/drivers/net/ice/base/ice_lan_tx_rx.h b/dpdk/drivers/net/ice/base/ice_lan_tx_rx.h -index a97c63cc97..51e30848f8 100644 +index a97c63cc97..d20f5f5748 100644 --- a/dpdk/drivers/net/ice/base/ice_lan_tx_rx.h +++ b/dpdk/drivers/net/ice/base/ice_lan_tx_rx.h @@ -1,5 +1,5 @@ @@ -44573,6 +64045,15 @@ index a97c63cc97..51e30848f8 100644 */ #ifndef _ICE_LAN_TX_RX_H_ +@@ -1307,7 +1307,7 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = { + /* Non Tunneled IPv6 */ + ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), + ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), +- ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3), ++ ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), + ICE_PTT_UNUSED_ENTRY(91), + ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), + ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), diff --git a/dpdk/drivers/net/ice/base/ice_nvm.c b/dpdk/drivers/net/ice/base/ice_nvm.c index 1dbfc2dcc7..434258b14c 100644 --- a/dpdk/drivers/net/ice/base/ice_nvm.c @@ -44596,7 +64077,7 @@ index d5b7b2d196..8624d19b19 100644 #ifndef _ICE_NVM_H_ diff --git a/dpdk/drivers/net/ice/base/ice_osdep.h b/dpdk/drivers/net/ice/base/ice_osdep.h -index 27c1830c5e..32ac8ac397 100644 +index 27c1830c5e..5970c918d1 100644 --- a/dpdk/drivers/net/ice/base/ice_osdep.h +++ b/dpdk/drivers/net/ice/base/ice_osdep.h @@ -1,5 +1,5 @@ @@ -44606,8 +64087,11 @@ index 27c1830c5e..32ac8ac397 100644 */ #ifndef _ICE_OSDEP_H_ -@@ -24,6 +24,8 @@ - #include +@@ -21,9 +21,10 @@ + #include + #include + #include +-#include #include +#include "ice_alloc.h" @@ -44615,7 +64099,13 @@ index 27c1830c5e..32ac8ac397 100644 #include "../ice_logs.h" #define INLINE inline -@@ -176,7 +178,6 @@ struct ice_virt_mem { +@@ -171,12 +172,11 @@ struct ice_virt_mem { + } __attribute__((packed)); + + #define ice_malloc(h, s) rte_zmalloc(NULL, s, 0) +-#define ice_calloc(h, c, s) rte_zmalloc(NULL, (c) * (s), 0) ++#define ice_calloc(h, c, s) rte_calloc(NULL, c, s, 0) + #define ice_free(h, m) rte_free(m) #define ice_memset(a, b, c, d) memset((a), (b), (c)) #define ice_memcpy(a, b, c, d) rte_memcpy((a), (b), (c)) @@ -44623,7 +64113,7 @@ index 27c1830c5e..32ac8ac397 100644 #define CPU_TO_BE16(o) rte_cpu_to_be_16(o) #define CPU_TO_BE32(o) rte_cpu_to_be_32(o) -@@ -223,6 +224,19 @@ ice_destroy_lock(__attribute__((unused)) struct ice_lock *sp) +@@ -223,17 +223,32 @@ ice_destroy_lock(__attribute__((unused)) struct ice_lock *sp) struct ice_hw; @@ -44643,7 +64133,21 @@ index 27c1830c5e..32ac8ac397 100644 static inline void * ice_alloc_dma_mem(__attribute__((unused)) struct ice_hw *hw, struct ice_dma_mem *mem, u64 size) -@@ -343,6 +357,21 @@ static inline void list_add_tail(struct ice_list_entry *entry, + { ++ static uint64_t ice_dma_memzone_id; + const struct rte_memzone *mz = NULL; + char z_name[RTE_MEMZONE_NAMESIZE]; + + if (!mem) + return NULL; + +- snprintf(z_name, sizeof(z_name), "ice_dma_%"PRIu64, rte_rand()); ++ snprintf(z_name, sizeof(z_name), "ice_dma_%" PRIu64, ++ __atomic_fetch_add(&ice_dma_memzone_id, 1, __ATOMIC_RELAXED)); + mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, 0, + 0, RTE_PGSIZE_2M); + if (!mz) +@@ -343,6 +358,21 @@ static inline void list_add_tail(struct ice_list_entry *entry, member) : \ 0) @@ -44665,7 +64169,7 @@ index 27c1830c5e..32ac8ac397 100644 #define LIST_REPLACE_INIT(list_head, head) do { \ (head)->lh_first = (list_head)->lh_first; \ INIT_LIST_HEAD(list_head); \ -@@ -356,8 +385,6 @@ static inline void list_add_tail(struct ice_list_entry *entry, +@@ -356,8 +386,6 @@ static inline void list_add_tail(struct ice_list_entry *entry, #define HLIST_DEL(entry) LIST_DEL(entry) #define HLIST_FOR_EACH_ENTRY(pos, head, type, member) \ LIST_FOR_EACH_ENTRY(pos, head, type, member) @@ -44697,7 +64201,7 @@ index 70a019292a..22bfcebc3c 100644 #ifndef _ICE_SBQ_CMD_H_ diff --git a/dpdk/drivers/net/ice/base/ice_sched.c b/dpdk/drivers/net/ice/base/ice_sched.c -index 553fc28ff3..3669688bd8 100644 +index 553fc28ff3..5b1f3d1b3a 100644 --- a/dpdk/drivers/net/ice/base/ice_sched.c +++ b/dpdk/drivers/net/ice/base/ice_sched.c @@ -1,5 +1,5 @@ @@ -44868,6 +64372,21 @@ index 553fc28ff3..3669688bd8 100644 if (status != ICE_SUCCESS) goto exit_add_rl_prof; +@@ -4712,12 +4759,12 @@ ice_sched_get_node_by_id_type(struct ice_port_info *pi, u32 id, + + case ICE_AGG_TYPE_Q: + /* The current implementation allows single queue to modify */ +- node = ice_sched_get_node(pi, id); ++ node = ice_sched_find_node_by_teid(pi->root, id); + break; + + case ICE_AGG_TYPE_QG: + /* The current implementation allows single qg to modify */ +- child_node = ice_sched_get_node(pi, id); ++ child_node = ice_sched_find_node_by_teid(pi->root, id); + if (!child_node) + break; + node = child_node->parent; diff --git a/dpdk/drivers/net/ice/base/ice_sched.h b/dpdk/drivers/net/ice/base/ice_sched.h index d6b467477c..57bf4b59d6 100644 --- a/dpdk/drivers/net/ice/base/ice_sched.h @@ -44917,7 +64436,7 @@ index ac120fa300..ba28895a17 100644 #ifndef _ICE_STATUS_H_ diff --git a/dpdk/drivers/net/ice/base/ice_switch.c b/dpdk/drivers/net/ice/base/ice_switch.c -index afa4fe30d4..71c6d9821c 100644 +index afa4fe30d4..6899502a93 100644 --- a/dpdk/drivers/net/ice/base/ice_switch.c +++ b/dpdk/drivers/net/ice/base/ice_switch.c @@ -1,5 +1,5 @@ @@ -44972,7 +64491,24 @@ index afa4fe30d4..71c6d9821c 100644 if (status) return status; } -@@ -4748,7 +4750,7 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u16 *id) +@@ -4213,7 +4215,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, + &remove_list_head); + ice_release_lock(rule_lock); + if (status) +- return; ++ goto free_fltr_list; + + switch (lkup) { + case ICE_SW_LKUP_MAC: +@@ -4242,6 +4244,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, + break; + } + ++free_fltr_list: + LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head, + ice_fltr_list_entry, list_entry) { + LIST_DEL(&fm_entry->list_entry); +@@ -4748,7 +4751,7 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u16 *id) { u16 i; @@ -44981,7 +64517,7 @@ index afa4fe30d4..71c6d9821c 100644 if (ice_prot_id_tbl[i].type == type) { *id = ice_prot_id_tbl[i].protocol_id; return true; -@@ -5995,9 +5997,12 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw, +@@ -5995,9 +5998,12 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw, if (status) return status; @@ -44994,7 +64530,7 @@ index afa4fe30d4..71c6d9821c 100644 /* Update the previous switch rule of "forward to VSI" to * "fwd to VSI list" */ -@@ -6238,23 +6243,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, +@@ -6238,23 +6244,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, sw->recp_list[rid].adv_rule = true; rule_head = &sw->recp_list[rid].filt_rules; @@ -45019,7 +64555,7 @@ index afa4fe30d4..71c6d9821c 100644 /* Add rule entry to book keeping list */ LIST_ADD(&adv_fltr->list_entry, rule_head); -@@ -6325,6 +6315,8 @@ ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, +@@ -6325,6 +6316,8 @@ ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, lkup_type); if (status) return status; @@ -45028,7 +64564,7 @@ index afa4fe30d4..71c6d9821c 100644 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; tmp_fltr.fltr_act = ICE_FWD_TO_VSI; -@@ -6343,6 +6335,7 @@ ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, +@@ -6343,6 +6336,7 @@ ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, tmp_fltr.fwd_id.hw_vsi_id, status); return status; } @@ -45036,7 +64572,7 @@ index afa4fe30d4..71c6d9821c 100644 /* Remove the VSI list since it is no longer used */ status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); -@@ -6421,7 +6414,6 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, +@@ -6421,7 +6415,6 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { remove_rule = true; } else if (list_elem->vsi_count > 1) { @@ -45044,7 +64580,7 @@ index afa4fe30d4..71c6d9821c 100644 remove_rule = false; vsi_handle = rinfo->sw_act.vsi_handle; status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); -@@ -6497,7 +6489,8 @@ ice_rem_adv_rule_by_id(struct ice_hw *hw, +@@ -6497,7 +6490,8 @@ ice_rem_adv_rule_by_id(struct ice_hw *hw, list_itr->lkups_cnt, &rinfo); } } @@ -45095,7 +64631,7 @@ index a8e4229a19..bf3c5ffd0a 100644 enum ice_mac_type mac_type; diff --git a/dpdk/drivers/net/ice/base/meson.build b/dpdk/drivers/net/ice/base/meson.build -index eff155574d..46c4ffb500 100644 +index eff155574d..3f50052ece 100644 --- a/dpdk/drivers/net/ice/base/meson.build +++ b/dpdk/drivers/net/ice/base/meson.build @@ -1,5 +1,5 @@ @@ -45105,11 +64641,48 @@ index eff155574d..46c4ffb500 100644 sources = [ 'ice_controlq.c', +@@ -18,6 +18,12 @@ error_cflags = ['-Wno-unused-value', + '-Wno-unused-variable', + '-Wno-unused-parameter', + ] ++ ++# Bugzilla ID: 678 ++if (toolchain == 'gcc' and cc.version().version_compare('>=11.0.0')) ++ error_cflags += ['-Wno-array-bounds'] ++endif ++ + c_args = cflags + + foreach flag: error_cflags +@@ -29,4 +35,4 @@ endforeach + base_lib = static_library('ice_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/ice/ice_ethdev.c b/dpdk/drivers/net/ice/ice_ethdev.c -index de189daba9..c2e659303c 100644 +index de189daba9..5d40f359b9 100644 --- a/dpdk/drivers/net/ice/ice_ethdev.c +++ b/dpdk/drivers/net/ice/ice_ethdev.c -@@ -870,7 +870,7 @@ ice_add_mac_filter(struct ice_vsi *vsi, struct rte_ether_addr *mac_addr) +@@ -10,6 +10,8 @@ + #include + #include + ++#include ++ + #include "base/ice_sched.h" + #include "base/ice_flow.h" + #include "base/ice_dcb.h" +@@ -795,7 +797,7 @@ ice_init_mac_address(struct rte_eth_dev *dev) + (struct rte_ether_addr *)hw->port_info[0].mac.perm_addr); + + dev->data->mac_addrs = +- rte_zmalloc(NULL, sizeof(struct rte_ether_addr), 0); ++ rte_zmalloc(NULL, sizeof(struct rte_ether_addr) * ICE_NUM_MACADDR_MAX, 0); + if (!dev->data->mac_addrs) { + PMD_INIT_LOG(ERR, + "Failed to allocate memory to store mac address"); +@@ -870,7 +872,7 @@ ice_add_mac_filter(struct ice_vsi *vsi, struct rte_ether_addr *mac_addr) ret = -ENOMEM; goto DONE; } @@ -45118,7 +64691,31 @@ index de189daba9..c2e659303c 100644 TAILQ_INSERT_TAIL(&vsi->mac_list, f, next); vsi->mac_num++; -@@ -1573,7 +1573,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) +@@ -1078,12 +1080,13 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi) + { + struct ice_mac_filter *m_f; + struct ice_vlan_filter *v_f; ++ void *temp; + int ret = 0; + + if (!vsi || !vsi->mac_num) + return -EINVAL; + +- TAILQ_FOREACH(m_f, &vsi->mac_list, next) { ++ TAILQ_FOREACH_SAFE(m_f, &vsi->mac_list, next, temp) { + ret = ice_remove_mac_filter(vsi, &m_f->mac_info.mac_addr); + if (ret != ICE_SUCCESS) { + ret = -EINVAL; +@@ -1094,7 +1097,7 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi) + if (vsi->vlan_num == 0) + return 0; + +- TAILQ_FOREACH(v_f, &vsi->vlan_list, next) { ++ TAILQ_FOREACH_SAFE(v_f, &vsi->vlan_list, next, temp) { + ret = ice_remove_vlan_filter(vsi, v_f->vlan_info.vlan_id); + if (ret != ICE_SUCCESS) { + ret = -EINVAL; +@@ -1573,7 +1576,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) cfg = ICE_AQ_VSI_PROP_SECURITY_VALID | ICE_AQ_VSI_PROP_FLOW_DIR_VALID; vsi_ctx.info.valid_sections |= rte_cpu_to_le_16(cfg); @@ -45127,7 +64724,7 @@ index de189daba9..c2e659303c 100644 vsi_ctx.info.fd_options = rte_cpu_to_le_16(cfg); vsi_ctx.info.max_fd_fltr_dedicated = rte_cpu_to_le_16(hw->func_caps.fd_fltr_guar); -@@ -1601,9 +1601,10 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) +@@ -1601,9 +1604,10 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) cfg = ICE_AQ_VSI_PROP_FLOW_DIR_VALID; vsi_ctx.info.valid_sections |= rte_cpu_to_le_16(cfg); @@ -45139,7 +64736,7 @@ index de189daba9..c2e659303c 100644 ret = ice_vsi_config_tc_queue_mapping(vsi, &vsi_ctx.info, ICE_DEFAULT_TCMAP); -@@ -1657,16 +1658,16 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) +@@ -1657,16 +1661,16 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type) if (type == ICE_VSI_PF) { /* MAC configuration */ @@ -45161,7 +64758,87 @@ index de189daba9..c2e659303c 100644 ret = ice_add_mac_filter(vsi, &mac_addr); if (ret != ICE_SUCCESS) PMD_INIT_LOG(ERR, "Failed to add MAC filter"); -@@ -2287,9 +2288,10 @@ ice_release_vsi(struct ice_vsi *vsi) +@@ -1799,8 +1803,14 @@ ice_pkg_file_search_path(struct rte_pci_device *pci_dev, char *pkg_file) + pos = ice_pci_find_next_ext_capability(pci_dev, PCI_EXT_CAP_ID_DSN); + + if (pos) { +- rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4); +- rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8); ++ if (rte_pci_read_config(pci_dev, &dsn_low, 4, pos + 4) < 0) { ++ PMD_INIT_LOG(ERR, "Failed to read pci config space\n"); ++ return -1; ++ } ++ if (rte_pci_read_config(pci_dev, &dsn_high, 4, pos + 8) < 0) { ++ PMD_INIT_LOG(ERR, "Failed to read pci config space\n"); ++ return -1; ++ } + snprintf(opt_ddp_filename, ICE_MAX_PKG_FILENAME_SIZE, + "ice-%08x%08x.pkg", dsn_high, dsn_low); + } else { +@@ -1862,7 +1872,11 @@ static int ice_load_pkg(struct rte_eth_dev *dev) + struct ice_adapter *ad = + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + +- ice_pkg_file_search_path(pci_dev, pkg_file); ++ err = ice_pkg_file_search_path(pci_dev, pkg_file); ++ if (err) { ++ PMD_INIT_LOG(ERR, "failed to search file path\n"); ++ return err; ++ } + + file = fopen(pkg_file, "rb"); + if (!file) { +@@ -2181,7 +2195,7 @@ ice_dev_init(struct rte_eth_dev *dev) + if (ad->devargs.safe_mode_support == 0) { + PMD_INIT_LOG(ERR, "Failed to load the DDP package," + "Use safe-mode-support=1 to enter Safe Mode"); +- return ret; ++ goto err_init_fw; + } + + PMD_INIT_LOG(WARNING, "Failed to load the DDP package," +@@ -2255,28 +2269,35 @@ ice_dev_init(struct rte_eth_dev *dev) + ret = ice_flow_init(ad); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to initialize flow"); +- return ret; ++ goto err_flow_init; + } + } + + ret = ice_reset_fxp_resource(hw); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to reset fxp resource"); +- return ret; ++ goto err_flow_init; + } + + return 0; + ++err_flow_init: ++ ice_flow_uninit(ad); ++ rte_intr_disable(intr_handle); ++ ice_pf_disable_irq0(hw); ++ rte_intr_callback_unregister(intr_handle, ++ ice_interrupt_handler, dev); + err_pf_setup: + ice_res_pool_destroy(&pf->msix_pool); + err_msix_pool_init: + rte_free(dev->data->mac_addrs); + dev->data->mac_addrs = NULL; + err_init_mac: +- ice_sched_cleanup_all(hw); +- rte_free(hw->port_info); +- ice_shutdown_all_ctrlq(hw); + rte_free(pf->proto_xtr); ++#ifndef RTE_EXEC_ENV_WINDOWS ++err_init_fw: ++#endif ++ ice_deinit_hw(hw); + + return ret; + } +@@ -2287,9 +2308,10 @@ ice_release_vsi(struct ice_vsi *vsi) struct ice_hw *hw; struct ice_vsi_ctx vsi_ctx; enum ice_status ret; @@ -45173,7 +64850,7 @@ index de189daba9..c2e659303c 100644 hw = ICE_VSI_TO_HW(vsi); -@@ -2302,12 +2304,13 @@ ice_release_vsi(struct ice_vsi *vsi) +@@ -2302,12 +2324,13 @@ ice_release_vsi(struct ice_vsi *vsi) ret = ice_free_vsi(hw, vsi->idx, &vsi_ctx, false, NULL); if (ret != ICE_SUCCESS) { PMD_INIT_LOG(ERR, "Failed to free vsi by aq, %u", vsi->vsi_id); @@ -45190,16 +64867,32 @@ index de189daba9..c2e659303c 100644 } void -@@ -2439,24 +2442,6 @@ ice_dev_uninit(struct rte_eth_dev *dev) +@@ -2391,6 +2414,9 @@ ice_dev_close(struct rte_eth_dev *dev) + struct ice_adapter *ad = + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + /* Since stop will make link down, then the link event will be + * triggered, disable the irq firstly to avoid the port_infoe etc + * resources deallocation causing the interrupt service thread +@@ -2439,22 +2465,29 @@ ice_dev_uninit(struct rte_eth_dev *dev) return 0; } -static int -ice_dev_configure(struct rte_eth_dev *dev) --{ ++static void ++ice_get_default_rss_key(uint8_t *rss_key, uint32_t rss_key_size) + { - struct ice_adapter *ad = - ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); -- ++ static struct ice_aqc_get_set_rss_keys default_key; ++ static bool default_key_done; ++ uint8_t *key = (uint8_t *)&default_key; ++ size_t i; + - /* Initialize to TRUE. If any of Rx queues doesn't meet the - * bulk allocation or vector Rx preconditions we will reset it. - */ @@ -45208,14 +64901,26 @@ index de189daba9..c2e659303c 100644 - - if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) - dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; -- ++ if (rss_key_size > sizeof(default_key)) { ++ PMD_DRV_LOG(WARNING, ++ "requested size %u is larger than default %zu, " ++ "only %zu bytes are gotten for key\n", ++ rss_key_size, sizeof(default_key), ++ sizeof(default_key)); ++ } + - return 0; --} -- ++ if (!default_key_done) { ++ /* Calculate the default hash key */ ++ for (i = 0; i < sizeof(default_key); i++) ++ key[i] = (uint8_t)rte_rand(); ++ default_key_done = true; ++ } ++ rte_memcpy(rss_key, key, RTE_MIN(rss_key_size, sizeof(default_key))); + } + static int ice_init_rss(struct ice_pf *pf) - { - struct ice_hw *hw = ICE_PF_TO_HW(pf); -@@ -2474,18 +2459,35 @@ static int ice_init_rss(struct ice_pf *pf) +@@ -2474,32 +2507,48 @@ static int ice_init_rss(struct ice_pf *pf) vsi->rss_key_size = ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE; vsi->rss_lut_size = pf->hash_lut_size; @@ -45252,10 +64957,22 @@ index de189daba9..c2e659303c 100644 + } + } /* configure RSS key */ - if (!rss_conf->rss_key) { - /* Calculate the default hash key */ -@@ -2499,7 +2501,7 @@ static int ice_init_rss(struct ice_pf *pf) - rte_memcpy(key.standard_rss_key, vsi->rss_key, vsi->rss_key_size); +- if (!rss_conf->rss_key) { +- /* Calculate the default hash key */ +- for (i = 0; i <= vsi->rss_key_size; i++) +- vsi->rss_key[i] = (uint8_t)rte_rand(); +- } else { ++ if (!rss_conf->rss_key) ++ ice_get_default_rss_key(vsi->rss_key, vsi->rss_key_size); ++ else + rte_memcpy(vsi->rss_key, rss_conf->rss_key, + RTE_MIN(rss_conf->rss_key_len, + vsi->rss_key_size)); +- } +- rte_memcpy(key.standard_rss_key, vsi->rss_key, vsi->rss_key_size); ++ ++ rte_memcpy(key.standard_rss_key, vsi->rss_key, ++ RTE_MIN(sizeof(key.standard_rss_key), vsi->rss_key_size)); ret = ice_aq_set_rss_key(hw, vsi->idx, &key); if (ret) - return -EINVAL; @@ -45263,7 +64980,7 @@ index de189daba9..c2e659303c 100644 /* init RSS LUT table */ for (i = 0; i < vsi->rss_lut_size; i++) -@@ -2509,7 +2511,7 @@ static int ice_init_rss(struct ice_pf *pf) +@@ -2509,7 +2558,7 @@ static int ice_init_rss(struct ice_pf *pf) ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF, vsi->rss_lut, vsi->rss_lut_size); if (ret) @@ -45272,7 +64989,7 @@ index de189daba9..c2e659303c 100644 /* Enable registers for symmetric_toeplitz function. */ reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id)); -@@ -2584,6 +2586,40 @@ static int ice_init_rss(struct ice_pf *pf) +@@ -2584,6 +2633,40 @@ static int ice_init_rss(struct ice_pf *pf) PMD_DRV_LOG(ERR, "%s PPPoE/PPPoD_SessionID rss flow fail %d", __func__, ret); @@ -45313,7 +65030,7 @@ index de189daba9..c2e659303c 100644 return 0; } -@@ -2598,14 +2634,14 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect, +@@ -2598,14 +2681,14 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect, for (i = 0; i < nb_queue; i++) { /*do actual bind*/ val = (msix_vect & QINT_RQCTL_MSIX_INDX_M) | @@ -45331,7 +65048,7 @@ index de189daba9..c2e659303c 100644 ICE_WRITE_REG(hw, QINT_RQCTL(base_queue + i), val); ICE_WRITE_REG(hw, QINT_TQCTL(base_queue + i), val_tx); } -@@ -2790,12 +2826,6 @@ ice_dev_start(struct rte_eth_dev *dev) +@@ -2790,12 +2873,6 @@ ice_dev_start(struct rte_eth_dev *dev) } } @@ -45344,7 +65061,25 @@ index de189daba9..c2e659303c 100644 ice_set_rx_function(dev); ice_set_tx_function(dev); -@@ -3217,7 +3247,7 @@ ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -2835,7 +2912,7 @@ ice_dev_start(struct rte_eth_dev *dev) + ice_dev_set_link_up(dev); + + /* Call get_link_info aq commond to enable/disable LSE */ +- ice_link_update(dev, 0); ++ ice_link_update(dev, 1); + + pf->adapter_stopped = false; + +@@ -2937,7 +3014,7 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + } + + dev_info->rx_queue_offload_capa = 0; +- dev_info->tx_queue_offload_capa = 0; ++ dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE; + + dev_info->reta_size = pf->hash_lut_size; + dev_info->hash_key_size = (VSIQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t); +@@ -3217,7 +3294,7 @@ ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EBUSY; } @@ -45353,7 +65088,7 @@ index de189daba9..c2e659303c 100644 dev_data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else -@@ -3264,7 +3294,7 @@ static int ice_macaddr_set(struct rte_eth_dev *dev, +@@ -3264,7 +3341,7 @@ static int ice_macaddr_set(struct rte_eth_dev *dev, PMD_DRV_LOG(ERR, "Failed to add mac filter"); return -EIO; } @@ -45362,7 +65097,46 @@ index de189daba9..c2e659303c 100644 flags = ICE_AQC_MAN_MAC_UPDATE_LAA_WOL; ret = ice_aq_manage_mac_write(hw, mac_addr->addr_bytes, flags, NULL); -@@ -4058,6 +4088,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi) +@@ -3344,20 +3421,16 @@ ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on) + { + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_vsi_ctx ctxt; +- uint8_t sec_flags, sw_flags2; ++ uint8_t sw_flags2; + int ret = 0; + +- sec_flags = ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA << +- ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S; + sw_flags2 = ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; + +- if (on) { +- vsi->info.sec_flags |= sec_flags; ++ if (on) + vsi->info.sw_flags2 |= sw_flags2; +- } else { +- vsi->info.sec_flags &= ~sec_flags; ++ else + vsi->info.sw_flags2 &= ~sw_flags2; +- } ++ + vsi->info.sw_id = hw->port_info->sw_id; + (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); + ctxt.info.valid_sections = +@@ -3739,8 +3812,11 @@ ice_promisc_disable(struct rte_eth_dev *dev) + uint8_t pmask; + int ret = 0; + +- pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX | +- ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX; ++ if (dev->data->all_multicast == 1) ++ pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX; ++ else ++ pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX | ++ ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX; + + status = ice_clear_vsi_promisc(hw, vsi->idx, pmask, 0); + if (status != ICE_SUCCESS) { +@@ -4058,6 +4134,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi) ice_stat_update_40(hw, GLV_BPRCH(idx), GLV_BPRCL(idx), vsi->offset_loaded, &oes->rx_broadcast, &nes->rx_broadcast); @@ -45376,7 +65150,7 @@ index de189daba9..c2e659303c 100644 /* exclude CRC bytes */ nes->rx_bytes -= (nes->rx_unicast + nes->rx_multicast + nes->rx_broadcast) * RTE_ETHER_CRC_LEN; -@@ -4084,6 +4121,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi) +@@ -4084,6 +4167,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi) /* GLV_TDPC not supported */ ice_stat_update_32(hw, GLV_TEPC(idx), vsi->offset_loaded, &oes->tx_errors, &nes->tx_errors); @@ -45390,7 +65164,7 @@ index de189daba9..c2e659303c 100644 vsi->offset_loaded = true; PMD_DRV_LOG(DEBUG, "************** VSI[%u] stats start **************", -@@ -4131,6 +4175,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw) +@@ -4131,6 +4221,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw) ice_stat_update_32(hw, PRTRPB_RDPC, pf->offset_loaded, &os->eth.rx_discards, &ns->eth.rx_discards); @@ -45404,7 +65178,7 @@ index de189daba9..c2e659303c 100644 /* Workaround: CRC size should not be included in byte statistics, * so subtract RTE_ETHER_CRC_LEN from the byte counter for each rx -@@ -4161,6 +4212,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw) +@@ -4161,6 +4258,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw) GLPRT_BPTCL(hw->port_info->lport), pf->offset_loaded, &os->eth.tx_broadcast, &ns->eth.tx_broadcast); @@ -45419,7 +65193,7 @@ index de189daba9..c2e659303c 100644 ns->eth.tx_broadcast) * RTE_ETHER_CRC_LEN; diff --git a/dpdk/drivers/net/ice/ice_ethdev.h b/dpdk/drivers/net/ice/ice_ethdev.h -index f2186e1ff9..cce0b5f2d6 100644 +index f2186e1ff9..21647ca450 100644 --- a/dpdk/drivers/net/ice/ice_ethdev.h +++ b/dpdk/drivers/net/ice/ice_ethdev.h @@ -123,6 +123,10 @@ @@ -45433,6 +65207,15 @@ index f2186e1ff9..cce0b5f2d6 100644 /* DDP package type */ enum ice_pkg_type { +@@ -203,7 +207,7 @@ struct ice_vsi { + * needs to add, HW needs to know the layout that VSIs are organized. + * Besides that, VSI isan element and can't switch packets, which needs + * to add new component VEB to perform switching. So, a new VSI needs +- * to specify the the uplink VSI (Parent VSI) before created. The ++ * to specify the uplink VSI (Parent VSI) before created. The + * uplink VSI will check whether it had a VEB to switch packets. If no, + * it will try to create one. Then, uplink VSI will move the new VSI + * into its' sib_vsi_list to manage all the downlink VSI. @@ -239,6 +243,8 @@ struct ice_vsi { struct ice_eth_stats eth_stats_offset; struct ice_eth_stats eth_stats; @@ -45908,7 +65691,7 @@ index b145a3f0d5..23c455762b 100644 static int diff --git a/dpdk/drivers/net/ice/ice_rxtx.c b/dpdk/drivers/net/ice/ice_rxtx.c -index 2db1744562..ccb391c04b 100644 +index 2db1744562..53f336e85e 100644 --- a/dpdk/drivers/net/ice/ice_rxtx.c +++ b/dpdk/drivers/net/ice/ice_rxtx.c @@ -85,23 +85,23 @@ ice_program_hw_rx_queue(struct ice_rx_queue *rxq) @@ -46039,7 +65822,14 @@ index 2db1744562..ccb391c04b 100644 /* Allocate the maximum number of RX ring hardware descriptor. */ ring_size = sizeof(union ice_rx_flex_desc) * len; -@@ -952,11 +929,8 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, +@@ -946,17 +923,15 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, + return -ENOMEM; + } + ++ rxq->mz = rz; + /* Zero all the descriptors in the ring. */ + memset(rz->addr, 0, ring_size); + rxq->rx_ring_dma = rz->iova; rxq->rx_ring = rz->addr; @@ -46052,7 +65842,7 @@ index 2db1744562..ccb391c04b 100644 /* Allocate the software ring. */ rxq->sw_ring = rte_zmalloc_socket(NULL, -@@ -977,17 +951,14 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, +@@ -977,17 +952,14 @@ ice_rx_queue_setup(struct rte_eth_dev *dev, use_def_burst_func = ice_check_rx_burst_bulk_alloc_preconditions(rxq); if (!use_def_burst_func) { @@ -46072,7 +65862,31 @@ index 2db1744562..ccb391c04b 100644 rxq->port_id, rxq->queue_id); ad->rx_bulk_alloc_allowed = false; } -@@ -1307,6 +1278,11 @@ ice_rxd_error_to_pkt_flags(uint16_t stat_err0) +@@ -1007,6 +979,7 @@ ice_rx_queue_release(void *rxq) + + ice_rx_queue_release_mbufs(q); + rte_free(q->sw_ring); ++ rte_memzone_free(q->mz); + rte_free(q); + } + +@@ -1153,6 +1126,7 @@ ice_tx_queue_setup(struct rte_eth_dev *dev, + return -ENOMEM; + } + ++ txq->mz = tz; + txq->nb_tx_desc = nb_desc; + txq->tx_rs_thresh = tx_rs_thresh; + txq->tx_free_thresh = tx_free_thresh; +@@ -1203,6 +1177,7 @@ ice_tx_queue_release(void *txq) + + ice_tx_queue_release_mbufs(q); + rte_free(q->sw_ring); ++ rte_memzone_free(q->mz); + rte_free(q); + } + +@@ -1307,6 +1282,11 @@ ice_rxd_error_to_pkt_flags(uint16_t stat_err0) if (unlikely(stat_err0 & (1 << ICE_RX_FLEX_DESC_STATUS0_XSUM_EIPE_S))) flags |= PKT_RX_EIP_CKSUM_BAD; @@ -46084,7 +65898,7 @@ index 2db1744562..ccb391c04b 100644 return flags; } -@@ -1399,7 +1375,6 @@ ice_rxd_to_pkt_fields(struct rte_mbuf *mb, +@@ -1399,7 +1379,6 @@ ice_rxd_to_pkt_fields(struct rte_mbuf *mb, #endif } @@ -46092,7 +65906,7 @@ index 2db1744562..ccb391c04b 100644 #define ICE_LOOK_AHEAD 8 #if (ICE_LOOK_AHEAD != 8) #error "PMD ICE: ICE_LOOK_AHEAD must be 8\n" -@@ -1620,15 +1595,6 @@ ice_recv_pkts_bulk_alloc(void *rx_queue, +@@ -1620,15 +1599,6 @@ ice_recv_pkts_bulk_alloc(void *rx_queue, return nb_rx; } @@ -46108,7 +65922,7 @@ index 2db1744562..ccb391c04b 100644 static uint16_t ice_recv_scattered_pkts(void *rx_queue, -@@ -1872,9 +1838,7 @@ ice_dev_supported_ptypes_get(struct rte_eth_dev *dev) +@@ -1872,9 +1842,7 @@ ice_dev_supported_ptypes_get(struct rte_eth_dev *dev) ptypes = ptypes_os; if (dev->rx_pkt_burst == ice_recv_pkts || @@ -46118,7 +65932,23 @@ index 2db1744562..ccb391c04b 100644 dev->rx_pkt_burst == ice_recv_scattered_pkts) return ptypes; -@@ -2256,8 +2220,11 @@ ice_parse_tunneling_params(uint64_t ol_flags, +@@ -2029,6 +1997,7 @@ ice_fdir_setup_tx_resources(struct ice_pf *pf) + return -ENOMEM; + } + ++ txq->mz = tz; + txq->nb_tx_desc = ICE_FDIR_NUM_TX_DESC; + txq->queue_id = ICE_FDIR_QUEUE_ID; + txq->reg_idx = pf->fdir.fdir_vsi->base_queue; +@@ -2087,6 +2056,7 @@ ice_fdir_setup_rx_resources(struct ice_pf *pf) + return -ENOMEM; + } + ++ rxq->mz = rz; + rxq->nb_rx_desc = ICE_FDIR_NUM_RX_DESC; + rxq->queue_id = ICE_FDIR_QUEUE_ID; + rxq->reg_idx = pf->fdir.fdir_vsi->base_queue; +@@ -2256,8 +2226,11 @@ ice_parse_tunneling_params(uint64_t ol_flags, *cd_tunneling |= (tx_offload.l2_len >> 1) << ICE_TXD_CTX_QW0_NATLEN_S; @@ -46132,7 +65962,7 @@ index 2db1744562..ccb391c04b 100644 (*cd_tunneling & ICE_TXD_CTX_UDP_TUNNELING)) *cd_tunneling |= ICE_TXD_CTX_QW0_L4T_CS_M; } -@@ -2421,6 +2388,24 @@ ice_set_tso_ctx(struct rte_mbuf *mbuf, union ice_tx_offload tx_offload) +@@ -2421,6 +2394,24 @@ ice_set_tso_ctx(struct rte_mbuf *mbuf, union ice_tx_offload tx_offload) return ctx_desc; } @@ -46157,7 +65987,7 @@ index 2db1744562..ccb391c04b 100644 uint16_t ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { -@@ -2440,6 +2425,7 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2440,6 +2431,7 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) uint32_t td_offset = 0; uint32_t td_tag = 0; uint16_t tx_last; @@ -46165,7 +65995,7 @@ index 2db1744562..ccb391c04b 100644 uint64_t buf_dma_addr; uint64_t ol_flags; union ice_tx_offload tx_offload = {0}; -@@ -2452,12 +2438,14 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2452,12 +2444,14 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* Check if the descriptor ring needs to be cleaned. */ if (txq->nb_tx_free < txq->tx_free_thresh) @@ -46181,7 +66011,7 @@ index 2db1744562..ccb391c04b 100644 ol_flags = tx_pkt->ol_flags; tx_offload.l2_len = tx_pkt->l2_len; tx_offload.l3_len = tx_pkt->l3_len; -@@ -2471,8 +2459,15 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2471,8 +2465,15 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) /* The number of descriptors that must be allocated for * a packet equals to the number of the segments of that * packet plus the number of context descriptor if needed. @@ -46198,7 +66028,7 @@ index 2db1744562..ccb391c04b 100644 tx_last = (uint16_t)(tx_id + nb_used - 1); /* Circular ring */ -@@ -2509,10 +2504,9 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2509,10 +2510,9 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) &cd_tunneling_params); /* Enable checksum offloading */ @@ -46210,7 +66040,7 @@ index 2db1744562..ccb391c04b 100644 if (nb_ctx) { /* Setup TX context descriptor if required */ -@@ -2562,15 +2556,37 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2562,15 +2562,37 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) txe->mbuf = m_seg; /* Setup TX Descriptor */ @@ -46252,7 +66082,7 @@ index 2db1744562..ccb391c04b 100644 txe->last_id = tx_last; tx_id = txe->next_id; -@@ -3268,7 +3284,7 @@ ice_get_default_pkt_type(uint16_t ptype) +@@ -3268,7 +3290,7 @@ ice_get_default_pkt_type(uint16_t ptype) RTE_PTYPE_L4_TCP, [93] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP, @@ -46262,7 +66092,7 @@ index 2db1744562..ccb391c04b 100644 /* IPv6 --> IPv4 */ diff --git a/dpdk/drivers/net/ice/ice_rxtx.h b/dpdk/drivers/net/ice/ice_rxtx.h -index 9e3d2cd076..f80fdc1d6b 100644 +index 9e3d2cd076..16fd9cbaf9 100644 --- a/dpdk/drivers/net/ice/ice_rxtx.h +++ b/dpdk/drivers/net/ice/ice_rxtx.h @@ -31,7 +31,7 @@ @@ -46283,7 +66113,15 @@ index 9e3d2cd076..f80fdc1d6b 100644 uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */ uint16_t queue_id; /* RX queue index */ uint16_t reg_idx; /* RX queue register index */ -@@ -109,7 +109,7 @@ struct ice_tx_queue { +@@ -80,6 +80,7 @@ struct ice_rx_queue { + bool rx_deferred_start; /* don't start this queue in dev start */ + uint8_t proto_xtr; /* Protocol extraction from flexible descriptor */ + ice_rx_release_mbufs_t rx_rel_mbufs; ++ const struct rte_memzone *mz; + }; + + struct ice_tx_entry { +@@ -109,7 +110,7 @@ struct ice_tx_queue { uint8_t pthresh; /**< Prefetch threshold register. */ uint8_t hthresh; /**< Host threshold register. */ uint8_t wthresh; /**< Write-back threshold reg. */ @@ -46292,6 +66130,14 @@ index 9e3d2cd076..f80fdc1d6b 100644 uint16_t queue_id; /* TX queue index. */ uint32_t q_teid; /* TX schedule node id. */ uint16_t reg_idx; +@@ -120,6 +121,7 @@ struct ice_tx_queue { + bool tx_deferred_start; /* don't start this queue in dev start */ + bool q_set; /* indicate if tx queue has been configured */ + ice_tx_release_mbufs_t tx_rel_mbufs; ++ const struct rte_memzone *mz; + }; + + /* Offload features */ diff --git a/dpdk/drivers/net/ice/ice_rxtx_vec_avx2.c b/dpdk/drivers/net/ice/ice_rxtx_vec_avx2.c index be50677c2f..1acda1a383 100644 --- a/dpdk/drivers/net/ice/ice_rxtx_vec_avx2.c @@ -46457,7 +66303,7 @@ index 5e6f89642a..97e26d2968 100644 static inline int diff --git a/dpdk/drivers/net/ice/ice_rxtx_vec_sse.c b/dpdk/drivers/net/ice/ice_rxtx_vec_sse.c -index 9d5f1f194f..4e6b0a0aa8 100644 +index 9d5f1f194f..71320d82aa 100644 --- a/dpdk/drivers/net/ice/ice_rxtx_vec_sse.c +++ b/dpdk/drivers/net/ice/ice_rxtx_vec_sse.c @@ -95,39 +95,67 @@ ice_rx_desc_to_olflags_v(struct ice_rx_queue *rxq, __m128i descs[4], @@ -46622,6 +66468,35 @@ index 9d5f1f194f..4e6b0a0aa8 100644 /* nb_pkts has to be floor-aligned to ICE_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, ICE_DESCS_PER_LOOP); +@@ -332,7 +366,7 @@ _ice_recv_raw_pkts_vec(struct ice_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* B.1 load 2 (64 bit) or 4 (32 bit) mbuf points */ + mbp1 = _mm_loadu_si128((__m128i *)&sw_ring[pos]); + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = _mm_loadu_si128((__m128i *)(rxdp + 3)); + rte_compiler_barrier(); + +@@ -344,9 +378,9 @@ _ice_recv_raw_pkts_vec(struct ice_rx_queue *rxq, struct rte_mbuf **rx_pkts, + mbp2 = _mm_loadu_si128((__m128i *)&sw_ring[pos + 2]); + #endif + ++ /* A.1 load desc[2-0] */ + descs[2] = _mm_loadu_si128((__m128i *)(rxdp + 2)); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs[1] = _mm_loadu_si128((__m128i *)(rxdp + 1)); + rte_compiler_barrier(); + descs[0] = _mm_loadu_si128((__m128i *)(rxdp)); +@@ -405,7 +439,7 @@ _ice_recv_raw_pkts_vec(struct ice_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* and with mask to extract bits, flipping 1-0 */ + __m128i eop_bits = _mm_andnot_si128(staterr, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ @@ -454,15 +488,15 @@ ice_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _ice_recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -46678,7 +66553,7 @@ index 9d5f1f194f..4e6b0a0aa8 100644 ice_vtx1(volatile struct ice_tx_desc *txdp, struct rte_mbuf *pkt, uint64_t flags) diff --git a/dpdk/drivers/net/ice/ice_switch_filter.c b/dpdk/drivers/net/ice/ice_switch_filter.c -index 4a9356b317..03493ee464 100644 +index 4a9356b317..24ed232e88 100644 --- a/dpdk/drivers/net/ice/ice_switch_filter.c +++ b/dpdk/drivers/net/ice/ice_switch_filter.c @@ -25,7 +25,8 @@ @@ -46691,7 +66566,7 @@ index 4a9356b317..03493ee464 100644 #define ICE_SW_INSET_ETHER ( \ ICE_INSET_DMAC | ICE_INSET_SMAC | ICE_INSET_ETHERTYPE) -@@ -97,12 +98,47 @@ struct sw_meta { +@@ -97,12 +98,68 @@ struct sw_meta { static struct ice_flow_parser ice_switch_dist_parser_os; static struct ice_flow_parser ice_switch_dist_parser_comms; @@ -46699,6 +66574,27 @@ index 4a9356b317..03493ee464 100644 +static struct ice_flow_parser ice_switch_perm_parser_os; +static struct ice_flow_parser ice_switch_perm_parser_comms; + ++enum ice_sw_fltr_status { ++ ICE_SW_FLTR_ADDED, ++ ICE_SW_FLTR_RMV_FAILED_ON_RIDRECT, ++ ICE_SW_FLTR_ADD_FAILED_ON_RIDRECT, ++}; ++ ++struct ice_switch_filter_conf { ++ enum ice_sw_fltr_status fltr_status; ++ ++ struct ice_rule_query_data sw_query_data; ++ ++ /* ++ * The lookup elements and rule info are saved here when filter creation ++ * succeeds. ++ */ ++ uint16_t vsi_num; ++ uint16_t lkups_num; ++ struct ice_adv_lkup_elem *lkups; ++ struct ice_adv_rule_info rule_info; ++}; ++ +static struct +ice_pattern_match_item ice_switch_pattern_dist_os[] = { + {pattern_ethertype, @@ -46740,7 +66636,7 @@ index 4a9356b317..03493ee464 100644 {pattern_eth_ipv4, ICE_SW_INSET_MAC_IPV4, ICE_INSET_NONE}, {pattern_eth_ipv4_udp, -@@ -138,7 +174,7 @@ ice_pattern_match_item ice_switch_pattern_dist_comms[] = { +@@ -138,7 +195,7 @@ ice_pattern_match_item ice_switch_pattern_dist_comms[] = { }; static struct @@ -46749,7 +66645,7 @@ index 4a9356b317..03493ee464 100644 {pattern_ethertype, ICE_SW_INSET_ETHER, ICE_INSET_NONE}, {pattern_eth_arp, -@@ -156,21 +192,25 @@ ice_pattern_match_item ice_switch_pattern_dist_os[] = { +@@ -156,21 +213,25 @@ ice_pattern_match_item ice_switch_pattern_dist_os[] = { {pattern_eth_ipv6_tcp, ICE_SW_INSET_MAC_IPV6_TCP, ICE_INSET_NONE}, {pattern_eth_ipv4_udp_vxlan_eth_ipv4, @@ -46782,7 +66678,124 @@ index 4a9356b317..03493ee464 100644 {pattern_eth_ipv4, ICE_SW_INSET_MAC_IPV4, ICE_INSET_NONE}, {pattern_eth_ipv4_udp, -@@ -320,6 +360,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -207,7 +268,7 @@ ice_switch_create(struct ice_adapter *ad, + struct ice_pf *pf = &ad->pf; + struct ice_hw *hw = ICE_PF_TO_HW(pf); + struct ice_rule_query_data rule_added = {0}; +- struct ice_rule_query_data *filter_ptr; ++ struct ice_switch_filter_conf *filter_conf_ptr; + struct ice_adv_lkup_elem *list = + ((struct sw_meta *)meta)->list; + uint16_t lkups_cnt = +@@ -229,18 +290,26 @@ ice_switch_create(struct ice_adapter *ad, + } + ret = ice_add_adv_rule(hw, list, lkups_cnt, rule_info, &rule_added); + if (!ret) { +- filter_ptr = rte_zmalloc("ice_switch_filter", +- sizeof(struct ice_rule_query_data), 0); +- if (!filter_ptr) { ++ filter_conf_ptr = rte_zmalloc("ice_switch_filter", ++ sizeof(struct ice_switch_filter_conf), 0); ++ if (!filter_conf_ptr) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "No memory for ice_switch_filter"); + goto error; + } +- flow->rule = filter_ptr; +- rte_memcpy(filter_ptr, +- &rule_added, +- sizeof(struct ice_rule_query_data)); ++ ++ filter_conf_ptr->sw_query_data = rule_added; ++ ++ filter_conf_ptr->vsi_num = ++ ice_get_hw_vsi_num(hw, rule_info->sw_act.vsi_handle); ++ filter_conf_ptr->lkups = list; ++ filter_conf_ptr->lkups_num = lkups_cnt; ++ filter_conf_ptr->rule_info = *rule_info; ++ ++ filter_conf_ptr->fltr_status = ICE_SW_FLTR_ADDED; ++ ++ flow->rule = filter_conf_ptr; + } else { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, +@@ -248,7 +317,6 @@ ice_switch_create(struct ice_adapter *ad, + goto error; + } + +- rte_free(list); + rte_free(meta); + return 0; + +@@ -259,6 +327,18 @@ ice_switch_create(struct ice_adapter *ad, + return -rte_errno; + } + ++static inline void ++ice_switch_filter_rule_free(struct rte_flow *flow) ++{ ++ struct ice_switch_filter_conf *filter_conf_ptr = ++ (struct ice_switch_filter_conf *)flow->rule; ++ ++ if (filter_conf_ptr) ++ rte_free(filter_conf_ptr->lkups); ++ ++ rte_free(filter_conf_ptr); ++} ++ + static int + ice_switch_destroy(struct ice_adapter *ad, + struct rte_flow *flow, +@@ -266,20 +346,24 @@ ice_switch_destroy(struct ice_adapter *ad, + { + struct ice_hw *hw = &ad->hw; + int ret; +- struct ice_rule_query_data *filter_ptr; ++ struct ice_switch_filter_conf *filter_conf_ptr; + +- filter_ptr = (struct ice_rule_query_data *) ++ filter_conf_ptr = (struct ice_switch_filter_conf *) + flow->rule; + +- if (!filter_ptr) { ++ if (!filter_conf_ptr || ++ filter_conf_ptr->fltr_status == ICE_SW_FLTR_ADD_FAILED_ON_RIDRECT) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "no such flow" + " create by switch filter"); ++ ++ ice_switch_filter_rule_free(flow); ++ + return -rte_errno; + } + +- ret = ice_rem_adv_rule_by_id(hw, filter_ptr); ++ ret = ice_rem_adv_rule_by_id(hw, &filter_conf_ptr->sw_query_data); + if (ret) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, +@@ -287,16 +371,10 @@ ice_switch_destroy(struct ice_adapter *ad, + return -rte_errno; + } + +- rte_free(filter_ptr); ++ ice_switch_filter_rule_free(flow); + return ret; + } + +-static void +-ice_switch_filter_rule_free(struct rte_flow *flow) +-{ +- rte_free(flow->rule); +-} +- + static uint64_t + ice_switch_inset_get(const struct rte_flow_item pattern[], + struct rte_flow_error *error, +@@ -320,6 +398,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint64_t input_set = ICE_INSET_NONE; @@ -46790,7 +66803,7 @@ index 4a9356b317..03493ee464 100644 uint16_t j, t = 0; uint16_t tunnel_valid = 0; -@@ -369,6 +410,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -369,6 +448,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], m->src_addr[j] = eth_mask->src.addr_bytes[j]; i = 1; @@ -46798,7 +66811,7 @@ index 4a9356b317..03493ee464 100644 } if (eth_mask->dst.addr_bytes[j] == UINT8_MAX) { -@@ -377,6 +419,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -377,6 +457,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], m->dst_addr[j] = eth_mask->dst.addr_bytes[j]; i = 1; @@ -46806,7 +66819,7 @@ index 4a9356b317..03493ee464 100644 } } if (i) -@@ -387,6 +430,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -387,6 +468,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], eth_spec->type; list[t].m_u.ethertype.ethtype_id = UINT16_MAX; @@ -46814,7 +66827,7 @@ index 4a9356b317..03493ee464 100644 t++; } } else if (!eth_spec && !eth_mask) { -@@ -458,30 +502,35 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -458,30 +540,35 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], ipv4_spec->hdr.src_addr; list[t].m_u.ipv4_hdr.src_addr = UINT32_MAX; @@ -46850,7 +66863,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!ipv4_spec && !ipv4_mask) { -@@ -563,6 +612,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -563,6 +650,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], ipv6_spec->hdr.src_addr[j]; s->src_addr[j] = ipv6_mask->hdr.src_addr[j]; @@ -46858,7 +66871,7 @@ index 4a9356b317..03493ee464 100644 } if (ipv6_mask->hdr.dst_addr[j] == UINT8_MAX) { -@@ -570,17 +620,20 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -570,17 +658,20 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], ipv6_spec->hdr.dst_addr[j]; s->dst_addr[j] = ipv6_mask->hdr.dst_addr[j]; @@ -46879,7 +66892,7 @@ index 4a9356b317..03493ee464 100644 } if ((ipv6_mask->hdr.vtc_flow & rte_cpu_to_be_32 -@@ -597,6 +650,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -597,6 +688,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], f->be_ver_tc_flow = CPU_TO_BE32(vtf.u.val); vtf.u.fld.tc = UINT8_MAX; s->be_ver_tc_flow = CPU_TO_BE32(vtf.u.val); @@ -46887,7 +66900,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!ipv6_spec && !ipv6_mask) { -@@ -648,14 +702,16 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -648,14 +740,16 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], udp_spec->hdr.src_port; list[t].m_u.l4_hdr.src_port = udp_mask->hdr.src_port; @@ -46905,7 +66918,7 @@ index 4a9356b317..03493ee464 100644 } else if (!udp_spec && !udp_mask) { list[t].type = ICE_UDP_ILOS; } -@@ -705,12 +761,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -705,12 +799,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], tcp_spec->hdr.src_port; list[t].m_u.l4_hdr.src_port = tcp_mask->hdr.src_port; @@ -46920,7 +66933,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!tcp_spec && !tcp_mask) { -@@ -756,12 +814,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -756,12 +852,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], sctp_spec->hdr.src_port; list[t].m_u.sctp_hdr.src_port = sctp_mask->hdr.src_port; @@ -46935,7 +66948,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!sctp_spec && !sctp_mask) { -@@ -799,6 +859,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -799,6 +897,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], UINT32_MAX; input_set |= ICE_INSET_TUN_VXLAN_VNI; @@ -46943,7 +66956,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!vxlan_spec && !vxlan_mask) { -@@ -835,6 +896,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -835,6 +934,7 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], UINT32_MAX; input_set |= ICE_INSET_TUN_NVGRE_TNI; @@ -46951,7 +66964,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!nvgre_spec && !nvgre_mask) { -@@ -865,13 +927,15 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -865,13 +965,15 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], list[t].m_u.vlan_hdr.vlan = UINT16_MAX; input_set |= ICE_INSET_VLAN_OUTER; @@ -46968,7 +66981,7 @@ index 4a9356b317..03493ee464 100644 } t++; } else if (!vlan_spec && !vlan_mask) { -@@ -906,6 +970,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], +@@ -906,6 +1008,14 @@ ice_switch_inset_get(const struct rte_flow_item pattern[], } } @@ -46983,7 +66996,7 @@ index 4a9356b317..03493ee464 100644 *lkups_num = t; return input_set; -@@ -937,6 +1009,8 @@ ice_switch_parse_action(struct ice_pf *pf, +@@ -937,6 +1047,8 @@ ice_switch_parse_action(struct ice_pf *pf, switch (action_type) { case RTE_FLOW_ACTION_TYPE_RSS: act_qgrop = action->conf; @@ -46992,7 +67005,7 @@ index 4a9356b317..03493ee464 100644 rule_info->sw_act.fltr_act = ICE_FWD_TO_QGRP; rule_info->sw_act.fwd_id.q_id = -@@ -997,6 +1071,46 @@ ice_switch_parse_action(struct ice_pf *pf, +@@ -997,6 +1109,46 @@ ice_switch_parse_action(struct ice_pf *pf, return -rte_errno; } @@ -47039,7 +67052,7 @@ index 4a9356b317..03493ee464 100644 static int ice_switch_parse_pattern_action(struct ice_adapter *ad, struct ice_pattern_match_item *array, -@@ -1015,7 +1129,8 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, +@@ -1015,7 +1167,8 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, uint16_t lkups_num = 0; const struct rte_flow_item *item = pattern; uint16_t item_num = 0; @@ -47049,7 +67062,7 @@ index 4a9356b317..03493ee464 100644 struct ice_pattern_match_item *pattern_match_item = NULL; for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { -@@ -1051,6 +1166,7 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, +@@ -1051,6 +1204,7 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, return -rte_errno; } @@ -47057,7 +67070,7 @@ index 4a9356b317..03493ee464 100644 rule_info.tun_type = tun_type; sw_meta_ptr = -@@ -1081,6 +1197,14 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, +@@ -1081,6 +1235,14 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, goto error; } @@ -47072,7 +67085,7 @@ index 4a9356b317..03493ee464 100644 ret = ice_switch_parse_action(pf, actions, error, &rule_info); if (ret) { rte_flow_error_set(error, EINVAL, -@@ -1088,10 +1212,17 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, +@@ -1088,10 +1250,17 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, "Invalid input action"); goto error; } @@ -47094,7 +67107,7 @@ index 4a9356b317..03493ee464 100644 rte_free(pattern_match_item); return 0; -@@ -1123,7 +1254,7 @@ ice_switch_init(struct ice_adapter *ad) +@@ -1123,7 +1292,7 @@ ice_switch_init(struct ice_adapter *ad) { int ret = 0; struct ice_flow_parser *dist_parser; @@ -47103,7 +67116,7 @@ index 4a9356b317..03493ee464 100644 if (ad->active_pkg_type == ICE_PKG_TYPE_COMMS) dist_parser = &ice_switch_dist_parser_comms; -@@ -1132,10 +1263,16 @@ ice_switch_init(struct ice_adapter *ad) +@@ -1132,10 +1301,16 @@ ice_switch_init(struct ice_adapter *ad) else return -EINVAL; @@ -47122,7 +67135,7 @@ index 4a9356b317..03493ee464 100644 return ret; } -@@ -1143,17 +1280,25 @@ static void +@@ -1143,17 +1318,25 @@ static void ice_switch_uninit(struct ice_adapter *ad) { struct ice_flow_parser *dist_parser; @@ -47152,7 +67165,7 @@ index 4a9356b317..03493ee464 100644 } static struct -@@ -1186,10 +1331,19 @@ ice_flow_parser ice_switch_dist_parser_comms = { +@@ -1186,10 +1369,19 @@ ice_flow_parser ice_switch_dist_parser_comms = { }; static struct @@ -47175,6 +67188,106 @@ index 4a9356b317..03493ee464 100644 .parse_pattern_action = ice_switch_parse_pattern_action, .stage = ICE_FLOW_STAGE_PERMISSION, }; +diff --git a/dpdk/drivers/net/ice/meson.build b/dpdk/drivers/net/ice/meson.build +index f9e897bbc2..3c62ed7306 100644 +--- a/dpdk/drivers/net/ice/meson.build ++++ b/dpdk/drivers/net/ice/meson.build +@@ -18,6 +18,10 @@ sources = files( + deps += ['hash'] + includes += include_directories('base') + ++if (toolchain == 'gcc' and cc.version().version_compare('>=11.0.0')) ++ cflags += '-Wno-array-bounds' ++endif ++ + if arch_subdir == 'x86' + sources += files('ice_rxtx_vec_sse.c') + +diff --git a/dpdk/drivers/net/ifc/base/ifcvf.c b/dpdk/drivers/net/ifc/base/ifcvf.c +index 3c0b2dff66..f3c29f94b3 100644 +--- a/dpdk/drivers/net/ifc/base/ifcvf.c ++++ b/dpdk/drivers/net/ifc/base/ifcvf.c +@@ -65,8 +65,13 @@ ifcvf_init_hw(struct ifcvf_hw *hw, PCI_DEV *dev) + hw->common_cfg = get_cap_addr(hw, &cap); + break; + case IFCVF_PCI_CAP_NOTIFY_CFG: +- PCI_READ_CONFIG_DWORD(dev, &hw->notify_off_multiplier, ++ ret = PCI_READ_CONFIG_DWORD(dev, ++ &hw->notify_off_multiplier, + pos + sizeof(cap)); ++ if (ret < 0) { ++ DEBUGOUT("failed to read notify_off_multiplier\n"); ++ return -1; ++ } + hw->notify_base = get_cap_addr(hw, &cap); + hw->notify_region = cap.bar; + break; +@@ -82,6 +87,8 @@ ifcvf_init_hw(struct ifcvf_hw *hw, PCI_DEV *dev) + } + + hw->lm_cfg = hw->mem_resource[4].addr; ++ if (!hw->lm_cfg) ++ WARNINGOUT("HW support live migration not support!\n"); + + if (hw->common_cfg == NULL || hw->notify_base == NULL || + hw->isr == NULL || hw->dev_cfg == NULL) { +@@ -89,12 +96,14 @@ ifcvf_init_hw(struct ifcvf_hw *hw, PCI_DEV *dev) + return -1; + } + +- DEBUGOUT("capability mapping:\ncommon cfg: %p\n" +- "notify base: %p\nisr cfg: %p\ndevice cfg: %p\n" +- "multiplier: %u\n", +- hw->common_cfg, hw->dev_cfg, +- hw->isr, hw->notify_base, +- hw->notify_off_multiplier); ++ DEBUGOUT("capability mapping:\n" ++ "common cfg: %p\n" ++ "notify base: %p\n" ++ "isr cfg: %p\n" ++ "device cfg: %p\n" ++ "multiplier: %u\n", ++ hw->common_cfg, hw->notify_base, hw->isr, hw->dev_cfg, ++ hw->notify_off_multiplier); + + return 0; + } +@@ -211,10 +220,12 @@ ifcvf_hw_enable(struct ifcvf_hw *hw) + &cfg->queue_used_hi); + IFCVF_WRITE_REG16(hw->vring[i].size, &cfg->queue_size); + +- *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET + +- (i / 2) * IFCVF_LM_CFG_SIZE + (i % 2) * 4) = +- (u32)hw->vring[i].last_avail_idx | +- ((u32)hw->vring[i].last_used_idx << 16); ++ if (lm_cfg) { ++ *(u32 *)(lm_cfg + IFCVF_LM_RING_STATE_OFFSET + ++ (i / 2) * IFCVF_LM_CFG_SIZE + (i % 2) * 4) = ++ (u32)hw->vring[i].last_avail_idx | ++ ((u32)hw->vring[i].last_used_idx << 16); ++ } + + IFCVF_WRITE_REG16(i + 1, &cfg->queue_msix_vector); + if (IFCVF_READ_REG16(&cfg->queue_msix_vector) == +@@ -284,6 +295,8 @@ ifcvf_enable_logging(struct ifcvf_hw *hw, u64 log_base, u64 log_size) + u8 *lm_cfg; + + lm_cfg = hw->lm_cfg; ++ if (!lm_cfg) ++ return; + + *(u32 *)(lm_cfg + IFCVF_LM_BASE_ADDR_LOW) = + log_base & IFCVF_32_BIT_MASK; +@@ -306,6 +319,9 @@ ifcvf_disable_logging(struct ifcvf_hw *hw) + u8 *lm_cfg; + + lm_cfg = hw->lm_cfg; ++ if (!lm_cfg) ++ return; ++ + *(u32 *)(lm_cfg + IFCVF_LM_LOGGING_CTRL) = IFCVF_LM_DISABLE; + } + diff --git a/dpdk/drivers/net/ifc/base/ifcvf.h b/dpdk/drivers/net/ifc/base/ifcvf.h index 9be2770fea..3f7497bd02 100644 --- a/dpdk/drivers/net/ifc/base/ifcvf.h @@ -47190,6 +67303,31 @@ index 9be2770fea..3f7497bd02 100644 /* Common configuration */ #define IFCVF_PCI_CAP_COMMON_CFG 1 +diff --git a/dpdk/drivers/net/ifc/base/ifcvf_osdep.h b/dpdk/drivers/net/ifc/base/ifcvf_osdep.h +index 6aef25ea45..3d567695cc 100644 +--- a/dpdk/drivers/net/ifc/base/ifcvf_osdep.h ++++ b/dpdk/drivers/net/ifc/base/ifcvf_osdep.h +@@ -14,6 +14,7 @@ + #include + #include + ++#define WARNINGOUT(S, args...) RTE_LOG(WARNING, PMD, S, ##args) + #define DEBUGOUT(S, args...) RTE_LOG(DEBUG, PMD, S, ##args) + #define STATIC static + +diff --git a/dpdk/drivers/net/ifc/ifcvf_vdpa.c b/dpdk/drivers/net/ifc/ifcvf_vdpa.c +index da4667ba54..e0044ec29e 100644 +--- a/dpdk/drivers/net/ifc/ifcvf_vdpa.c ++++ b/dpdk/drivers/net/ifc/ifcvf_vdpa.c +@@ -356,6 +356,8 @@ vdpa_enable_vfio_intr(struct ifcvf_internal *internal, bool m_rx) + vring.callfd = -1; + + nr_vring = rte_vhost_get_vring_num(internal->vid); ++ if (nr_vring > IFCVF_MAX_QUEUES * 2) ++ return -1; + + irq_set = (struct vfio_irq_set *)irq_set_buf; + irq_set->argsz = sizeof(irq_set_buf); diff --git a/dpdk/drivers/net/ipn3ke/ipn3ke_ethdev.h b/dpdk/drivers/net/ipn3ke/ipn3ke_ethdev.h index 9b0cf309c8..a6815a9cca 100644 --- a/dpdk/drivers/net/ipn3ke/ipn3ke_ethdev.h @@ -47203,10 +67341,20 @@ index 9b0cf309c8..a6815a9cca 100644 #define IPN3KE_MAC_FRAME_SIZE_MAX 9728 #define IPN3KE_MAC_RX_FRAME_MAXLENGTH 0x00AE diff --git a/dpdk/drivers/net/ipn3ke/ipn3ke_representor.c b/dpdk/drivers/net/ipn3ke/ipn3ke_representor.c -index 8d9ebef915..d7dada7bde 100644 +index 8d9ebef915..31a6957868 100644 --- a/dpdk/drivers/net/ipn3ke/ipn3ke_representor.c +++ b/dpdk/drivers/net/ipn3ke/ipn3ke_representor.c -@@ -701,7 +701,7 @@ struct ipn3ke_rpst_hw_port_stats *hw_stats) +@@ -214,6 +214,9 @@ ipn3ke_rpst_dev_close(struct rte_eth_dev *dev) + struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(dev); + struct ipn3ke_rpst *rpst = IPN3KE_DEV_PRIVATE_TO_RPST(dev); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) { + /* Disable the TX path */ + ipn3ke_xmac_tx_disable(hw, rpst->port_id, 0); +@@ -701,7 +704,7 @@ struct ipn3ke_rpst_hw_port_stats *hw_stats) &tmp, IPN3KE_25G_TX_STATISTICS_STATUS, port_id, @@ -47215,6 +67363,16 @@ index 8d9ebef915..d7dada7bde 100644 if (tmp & IPN3KE_25G_TX_STATISTICS_STATUS_SHADOW_REQUEST_MASK) { tmp = 0x00000000; (*hw->f_mac_read)(hw, +@@ -2221,9 +2224,6 @@ ipn3ke_rpst_xstats_get + struct ipn3ke_rpst_hw_port_stats hw_stats; + struct rte_eth_stats stats; + +- if (!xstats) +- return 0; +- + if (!ethdev) { + IPN3KE_AFU_PMD_ERR("ethernet device to get statistics is NULL"); + return -EINVAL; @@ -2598,7 +2598,8 @@ ipn3ke_rpst_scan_check(void) int ret; @@ -47265,10 +67423,20 @@ index e3c8a6768c..0d1dc9866b 100644 + deps += ['bus_ifpga', 'ethdev', 'sched'] endif diff --git a/dpdk/drivers/net/ixgbe/Makefile b/dpdk/drivers/net/ixgbe/Makefile -index 85762e2f2a..31523025b3 100644 +index 85762e2f2a..c730bbddb4 100644 --- a/dpdk/drivers/net/ixgbe/Makefile +++ b/dpdk/drivers/net/ixgbe/Makefile -@@ -57,6 +57,7 @@ endif +@@ -29,6 +29,9 @@ else ifeq ($(CONFIG_RTE_TOOLCHAIN_CLANG),y) + # + CFLAGS_BASE_DRIVER = -Wno-unused-parameter -Wno-unused-value + CFLAGS_BASE_DRIVER += -Wno-strict-aliasing -Wno-format-extra-args ++ifeq ($(shell test $(CLANG_MAJOR_VERSION) -ge 13 && echo 1), 1) ++CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable ++endif + + else + # +@@ -57,6 +60,7 @@ endif LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash LDLIBS += -lrte_bus_pci @@ -47684,7 +67852,7 @@ index 3bd98f243d..10086ab423 100644 #ifndef _IXGBE_X550_H_ diff --git a/dpdk/drivers/net/ixgbe/base/meson.build b/dpdk/drivers/net/ixgbe/base/meson.build -index bbd0f51ea5..20677ab034 100644 +index bbd0f51ea5..4d04e77471 100644 --- a/dpdk/drivers/net/ixgbe/base/meson.build +++ b/dpdk/drivers/net/ixgbe/base/meson.build @@ -1,5 +1,5 @@ @@ -47694,11 +67862,31 @@ index bbd0f51ea5..20677ab034 100644 sources = [ 'ixgbe_82598.c', +@@ -34,4 +34,4 @@ endforeach + base_lib = static_library('ixgbe_base', sources, + dependencies: static_rte_eal, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c b/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c -index 2c6fd0f131..dcd7291b97 100644 +index 2c6fd0f131..65d81c6cec 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c -@@ -229,7 +229,9 @@ static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev); +@@ -128,6 +128,13 @@ + #define IXGBE_EXVET_VET_EXT_SHIFT 16 + #define IXGBE_DMATXCTL_VT_MASK 0xFFFF0000 + ++#define IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE "fiber_sdp3_no_tx_disable" ++ ++static const char * const ixgbe_valid_arguments[] = { ++ IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE, ++ NULL ++}; ++ + #define IXGBEVF_DEVARG_PFLINK_FULLCHK "pflink_fullchk" + + static const char * const ixgbevf_valid_arguments[] = { +@@ -229,7 +236,9 @@ static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev); static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev); static void ixgbe_dev_interrupt_handler(void *param); static void ixgbe_dev_interrupt_delayed_handler(void *param); @@ -47709,15 +67897,68 @@ index 2c6fd0f131..dcd7291b97 100644 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, -@@ -378,6 +380,7 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, +@@ -378,6 +387,9 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, struct rte_eth_udp_tunnel *udp_tunnel); static int ixgbe_filter_restore(struct rte_eth_dev *dev); static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev); +static int ixgbe_wait_for_link_up(struct ixgbe_hw *hw); ++static int devarg_handle_int(__rte_unused const char *key, const char *value, ++ void *extra_args); /* * Define VF Stats MACRO for Non "cleared on read" register -@@ -1075,6 +1078,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw) +@@ -831,6 +843,20 @@ ixgbe_is_sfp(struct ixgbe_hw *hw) + case ixgbe_phy_sfp_passive_unknown: + return 1; + default: ++ /* x550em devices may be SFP, check media type */ ++ switch (hw->mac.type) { ++ case ixgbe_mac_X550EM_x: ++ case ixgbe_mac_X550EM_a: ++ switch (ixgbe_get_media_type(hw)) { ++ case ixgbe_media_type_fiber: ++ case ixgbe_media_type_fiber_qsfp: ++ return 1; ++ default: ++ break; ++ } ++ default: ++ break; ++ } + return 0; + } + } +@@ -1068,6 +1094,29 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw) + ixgbe_release_swfw_semaphore(hw, mask); + } + ++static void ++ixgbe_parse_devargs(struct ixgbe_adapter *adapter, ++ struct rte_devargs *devargs) ++{ ++ struct rte_kvargs *kvlist; ++ uint16_t sdp3_no_tx_disable; ++ ++ if (devargs == NULL) ++ return; ++ ++ kvlist = rte_kvargs_parse(devargs->args, ixgbe_valid_arguments); ++ if (kvlist == NULL) ++ return; ++ ++ if (rte_kvargs_count(kvlist, IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE) == 1 && ++ rte_kvargs_process(kvlist, IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE, ++ devarg_handle_int, &sdp3_no_tx_disable) == 0 && ++ sdp3_no_tx_disable == 1) ++ adapter->sdp3_no_tx_disable = 1; ++ ++ rte_kvargs_free(kvlist); ++} ++ + /* + * This function is based on code in ixgbe_attach() in base/ixgbe.c. + * It returns 0 on success. +@@ -1075,6 +1124,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw) static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) { @@ -47725,7 +67966,7 @@ index 2c6fd0f131..dcd7291b97 100644 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; struct ixgbe_hw *hw = -@@ -1091,7 +1095,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1091,7 +1141,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) IXGBE_DEV_PRIVATE_TO_BW_CONF(eth_dev->data->dev_private); uint32_t ctrl_ext; uint16_t csum; @@ -47734,15 +67975,17 @@ index 2c6fd0f131..dcd7291b97 100644 PMD_INIT_FUNC_TRACE(); -@@ -1126,6 +1130,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1126,6 +1176,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return 0; } + rte_atomic32_clear(&ad->link_thread_running); ++ ixgbe_parse_devargs(eth_dev->data->dev_private, ++ pci_dev->device.devargs); rte_eth_copy_pci_info(eth_dev, pci_dev); /* Vendor and Device ID need to be set before init of shared code */ -@@ -1170,8 +1175,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1170,8 +1223,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) memset(dcb_config, 0, sizeof(struct ixgbe_dcb_config)); ixgbe_dcb_init(hw, dcb_config); /* Get Hardware Flow Control setting */ @@ -47753,7 +67996,7 @@ index 2c6fd0f131..dcd7291b97 100644 hw->fc.pause_time = IXGBE_FC_PAUSE; for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) { hw->fc.low_water[i] = IXGBE_FC_LO; -@@ -1190,7 +1195,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1190,7 +1243,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) diag = ixgbe_bypass_init_hw(hw); #else diag = ixgbe_init_hw(hw); @@ -47761,23 +68004,27 @@ index 2c6fd0f131..dcd7291b97 100644 #endif /* RTE_LIBRTE_IXGBE_BYPASS */ /* -@@ -1270,7 +1274,14 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1255,6 +1307,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) + PMD_INIT_LOG(ERR, + "Failed to allocate %d bytes needed to store MAC addresses", + RTE_ETHER_ADDR_LEN * IXGBE_VMDQ_NUM_UC_MAC); ++ rte_free(eth_dev->data->mac_addrs); ++ eth_dev->data->mac_addrs = NULL; + return -ENOMEM; + } + +@@ -1270,7 +1324,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) memset(hwstrip, 0, sizeof(*hwstrip)); /* initialize PF if max_vfs not zero */ - ixgbe_pf_host_init(eth_dev); + ret = ixgbe_pf_host_init(eth_dev); -+ if (ret) { -+ rte_free(eth_dev->data->mac_addrs); -+ eth_dev->data->mac_addrs = NULL; -+ rte_free(eth_dev->data->hash_mac_addrs); -+ eth_dev->data->hash_mac_addrs = NULL; -+ return ret; -+ } ++ if (ret) ++ goto err_pf_host_init; ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); /* let hardware know driver is loaded */ -@@ -1301,8 +1312,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) +@@ -1301,8 +1357,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) /* enable support intr */ ixgbe_enable_intr(eth_dev); @@ -47786,7 +68033,62 @@ index 2c6fd0f131..dcd7291b97 100644 /* initialize filter info */ memset(filter_info, 0, sizeof(struct ixgbe_filter_info)); -@@ -1564,6 +1573,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1311,10 +1365,14 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) + TAILQ_INIT(&filter_info->fivetuple_list); + + /* initialize flow director filter list & hash */ +- ixgbe_fdir_filter_init(eth_dev); ++ ret = ixgbe_fdir_filter_init(eth_dev); ++ if (ret) ++ goto err_fdir_filter_init; + + /* initialize l2 tunnel filter list & hash */ +- ixgbe_l2_tn_filter_init(eth_dev); ++ ret = ixgbe_l2_tn_filter_init(eth_dev); ++ if (ret) ++ goto err_l2_tn_filter_init; + + /* initialize flow filter lists */ + ixgbe_filterlist_init(); +@@ -1326,6 +1384,21 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) + ixgbe_tm_conf_init(eth_dev); + + return 0; ++ ++err_l2_tn_filter_init: ++ ixgbe_fdir_filter_uninit(eth_dev); ++err_fdir_filter_init: ++ ixgbe_disable_intr(hw); ++ rte_intr_disable(intr_handle); ++ rte_intr_callback_unregister(intr_handle, ++ ixgbe_dev_interrupt_handler, eth_dev); ++ ixgbe_pf_host_uninit(eth_dev); ++err_pf_host_init: ++ rte_free(eth_dev->data->mac_addrs); ++ eth_dev->data->mac_addrs = NULL; ++ rte_free(eth_dev->data->hash_mac_addrs); ++ eth_dev->data->hash_mac_addrs = NULL; ++ return ret; + } + + static int +@@ -1430,6 +1503,7 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev) + if (!fdir_info->hash_map) { + PMD_INIT_LOG(ERR, + "Failed to allocate memory for fdir hash map!"); ++ rte_hash_free(fdir_info->hash_handle); + return -ENOMEM; + } + fdir_info->mask_added = FALSE; +@@ -1466,6 +1540,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev) + if (!l2_tn_info->hash_map) { + PMD_INIT_LOG(ERR, + "Failed to allocate memory for L2 TN hash map!"); ++ rte_hash_free(l2_tn_info->hash_handle); + return -ENOMEM; + } + l2_tn_info->e_tag_en = FALSE; +@@ -1564,6 +1639,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) { int diag; uint32_t tc, tcs; @@ -47794,7 +68096,7 @@ index 2c6fd0f131..dcd7291b97 100644 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; struct ixgbe_hw *hw = -@@ -1604,6 +1614,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) +@@ -1604,6 +1680,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) return 0; } @@ -47802,7 +68104,16 @@ index 2c6fd0f131..dcd7291b97 100644 ixgbevf_parse_devargs(eth_dev->data->dev_private, pci_dev->device.devargs); -@@ -2530,6 +2541,41 @@ ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf, +@@ -1706,6 +1783,8 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) + + default: + PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", diag); ++ rte_free(eth_dev->data->mac_addrs); ++ eth_dev->data->mac_addrs = NULL; + return -EIO; + } + +@@ -2530,6 +2609,41 @@ ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf, return 0; } @@ -47844,7 +68155,7 @@ index 2c6fd0f131..dcd7291b97 100644 /* * Configure device link speed and setup link. * It returns 0 on success. -@@ -2558,19 +2604,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev) +@@ -2558,19 +2672,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); @@ -47865,7 +68176,7 @@ index 2c6fd0f131..dcd7291b97 100644 /* disable uio/vfio intr/eventfd mapping */ rte_intr_disable(intr_handle); -@@ -2666,6 +2701,12 @@ ixgbe_dev_start(struct rte_eth_dev *dev) +@@ -2666,6 +2769,12 @@ ixgbe_dev_start(struct rte_eth_dev *dev) ixgbe_restore_statistics_mapping(dev); @@ -47878,7 +68189,7 @@ index 2c6fd0f131..dcd7291b97 100644 err = ixgbe_dev_rxtx_start(dev); if (err < 0) { PMD_INIT_LOG(ERR, "Unable to start rxtx queues"); -@@ -2724,7 +2765,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev) +@@ -2724,7 +2833,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev) } link_speeds = &dev->data->dev_conf.link_speeds; @@ -47891,7 +68202,7 @@ index 2c6fd0f131..dcd7291b97 100644 PMD_INIT_LOG(ERR, "Invalid link setting"); goto error; } -@@ -2801,6 +2846,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev) +@@ -2801,6 +2914,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev) "please call hierarchy_commit() " "before starting the port"); @@ -47903,7 +68214,7 @@ index 2c6fd0f131..dcd7291b97 100644 /* * Update link status right before return, because it may * start link configuration process in a separate thread. -@@ -2842,7 +2892,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev) +@@ -2842,7 +2960,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); @@ -47912,7 +68223,46 @@ index 2c6fd0f131..dcd7291b97 100644 /* disable interrupts */ ixgbe_disable_intr(hw); -@@ -4095,16 +4145,46 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, +@@ -2972,6 +3090,8 @@ ixgbe_dev_close(struct rte_eth_dev *dev) + int ret; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + ixgbe_pf_reset_hw(hw); + +@@ -3030,6 +3150,7 @@ ixgbe_dev_close(struct rte_eth_dev *dev) + + #ifdef RTE_LIBRTE_SECURITY + rte_free(dev->security_ctx); ++ dev->security_ctx = NULL; + #endif + + } +@@ -3332,6 +3453,13 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) + hw_stats->fccrc + + hw_stats->fclast; + ++ /* ++ * 82599 errata, UDP frames with a 0 checksum can be marked as checksum ++ * errors. ++ */ ++ if (hw->mac.type != ixgbe_mac_82599EB) ++ stats->ierrors += hw_stats->xec; ++ + /* Tx Errors */ + stats->oerrors = 0; + return 0; +@@ -3778,6 +3906,7 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev) + hw_stats->vfgorc = 0; + hw_stats->vfgptc = 0; + hw_stats->vfgotc = 0; ++ hw_stats->vfmprc = 0; + + return 0; + } +@@ -4095,16 +4224,46 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return ret_val; } @@ -47961,7 +68311,7 @@ index 2c6fd0f131..dcd7291b97 100644 speed = hw->phy.autoneg_advertised; if (!speed) ixgbe_get_link_capabilities(hw, &speed, &autoneg); -@@ -4112,6 +4192,40 @@ ixgbe_dev_setup_link_alarm_handler(void *param) +@@ -4112,6 +4271,40 @@ ixgbe_dev_setup_link_alarm_handler(void *param) ixgbe_setup_link(hw, speed, true); intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; @@ -48002,7 +68352,7 @@ index 2c6fd0f131..dcd7291b97 100644 } /* return 0 means link status changed, -1 means not changed */ -@@ -4120,6 +4234,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, +@@ -4120,6 +4313,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, int wait_to_complete, int vf) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -48010,7 +68360,7 @@ index 2c6fd0f131..dcd7291b97 100644 struct rte_eth_link link; ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; struct ixgbe_interrupt *intr = -@@ -4133,7 +4248,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, +@@ -4133,7 +4327,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, link.link_status = ETH_LINK_DOWN; link.link_speed = ETH_SPEED_NUM_NONE; link.link_duplex = ETH_LINK_HALF_DUPLEX; @@ -48020,7 +68370,7 @@ index 2c6fd0f131..dcd7291b97 100644 hw->mac.get_link_status = true; -@@ -4144,6 +4260,11 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, +@@ -4144,6 +4339,11 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0) wait = 0; @@ -48032,14 +68382,15 @@ index 2c6fd0f131..dcd7291b97 100644 if (vf) diag = ixgbevf_check_link(hw, &link_speed, &link_up, wait); else -@@ -4155,15 +4276,34 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, +@@ -4155,15 +4355,35 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, return rte_eth_linkstatus_set(dev, &link); } - esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); - if ((esdp_reg & IXGBE_ESDP_SDP3)) - link_up = 0; -+ if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) { ++ if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber && ++ !ad->sdp3_no_tx_disable) { + esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + if ((esdp_reg & IXGBE_ESDP_SDP3)) + link_up = 0; @@ -48073,7 +68424,7 @@ index 2c6fd0f131..dcd7291b97 100644 } return rte_eth_linkstatus_set(dev, &link); } -@@ -4181,6 +4321,10 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, +@@ -4181,6 +4401,10 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, link.link_speed = ETH_SPEED_NUM_100M; break; @@ -48084,7 +68435,7 @@ index 2c6fd0f131..dcd7291b97 100644 case IXGBE_LINK_SPEED_100_FULL: link.link_speed = ETH_SPEED_NUM_100M; break; -@@ -4615,6 +4759,11 @@ ixgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +@@ -4615,6 +4839,11 @@ ixgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) * MFLCN register. */ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); @@ -48096,7 +68447,7 @@ index 2c6fd0f131..dcd7291b97 100644 if (mflcn_reg & (IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_RFCE)) rx_pause = 1; else -@@ -4646,10 +4795,10 @@ static int +@@ -4646,10 +4875,10 @@ static int ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { struct ixgbe_hw *hw; @@ -48108,7 +68459,7 @@ index 2c6fd0f131..dcd7291b97 100644 enum ixgbe_fc_mode rte_fcmode_2_ixgbe_fcmode[] = { ixgbe_fc_none, ixgbe_fc_rx_pause, -@@ -4682,31 +4831,14 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) +@@ -4682,31 +4911,14 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) hw->fc.low_water[0] = fc_conf->low_water; hw->fc.send_xon = fc_conf->send_xon; hw->fc.disable_fc_autoneg = !fc_conf->autoneg; @@ -48146,7 +68497,27 @@ index 2c6fd0f131..dcd7291b97 100644 } /** -@@ -5090,7 +5222,7 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -4924,11 +5136,19 @@ ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev, + uint32_t reta, r; + uint16_t idx, shift; + struct ixgbe_adapter *adapter = dev->data->dev_private; ++ struct rte_eth_dev_data *dev_data = dev->data; + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t reta_reg; + + PMD_INIT_FUNC_TRACE(); + ++ if (!dev_data->dev_started) { ++ PMD_DRV_LOG(ERR, ++ "port %d must be started before rss reta update", ++ dev_data->port_id); ++ return -EIO; ++ } ++ + if (!ixgbe_rss_update_sp(hw->mac.type)) { + PMD_DRV_LOG(ERR, "RSS reta update is not supported on this " + "NIC."); +@@ -5090,7 +5310,7 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); /* switch to jumbo mode if needed */ @@ -48155,7 +68526,7 @@ index 2c6fd0f131..dcd7291b97 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; hlreg0 |= IXGBE_HLREG0_JUMBOEN; -@@ -5207,13 +5339,19 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) +@@ -5207,13 +5427,19 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); /* Stop the link setup handler before resetting the HW. */ @@ -48177,7 +68548,27 @@ index 2c6fd0f131..dcd7291b97 100644 hw->mac.get_link_status = true; /* negotiate mailbox API version to use with the PF. */ -@@ -5305,7 +5443,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev) +@@ -5251,8 +5477,10 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) + * now only one vector is used for Rx queue + */ + intr_vector = 1; +- if (rte_intr_efd_enable(intr_handle, intr_vector)) ++ if (rte_intr_efd_enable(intr_handle, intr_vector)) { ++ ixgbe_dev_clear_queues(dev); + return -1; ++ } + } + + if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { +@@ -5262,6 +5490,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) + if (intr_handle->intr_vec == NULL) { + PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues" + " intr_vec", dev->data->nb_rx_queues); ++ ixgbe_dev_clear_queues(dev); + return -ENOMEM; + } + } +@@ -5305,7 +5534,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); @@ -48186,7 +68577,16 @@ index 2c6fd0f131..dcd7291b97 100644 ixgbevf_intr_disable(dev); -@@ -6520,7 +6658,8 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) +@@ -5341,6 +5570,8 @@ ixgbevf_dev_close(struct rte_eth_dev *dev) + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + ixgbe_reset_hw(hw); + +@@ -6520,7 +6751,8 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) * prior to 3.11.33 which contains the following change: * "ixgbe: Enable jumbo frames support w/ SR-IOV" */ @@ -48196,8 +68596,27 @@ index 2c6fd0f131..dcd7291b97 100644 /* update max frame size */ dev->data->dev_conf.rxmode.max_rx_pkt_len = max_frame; +@@ -7481,9 +7713,6 @@ ixgbe_get_module_eeprom(struct rte_eth_dev *dev, + uint8_t *data = info->data; + uint32_t i = 0; + +- if (info->length == 0) +- return -EINVAL; +- + for (i = info->offset; i < info->offset + info->length; i++) { + if (i < RTE_ETH_MODULE_SFF_8079_LEN) + status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte); +@@ -8989,6 +9218,8 @@ ixgbe_dev_macsec_register_disable(struct rte_eth_dev *dev) + RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd); + RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map); + RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio-pci"); ++RTE_PMD_REGISTER_PARAM_STRING(net_ixgbe, ++ IXGBE_DEVARG_FIBER_SDP3_NOT_TX_DISABLE "=<0|1>"); + RTE_PMD_REGISTER_PCI(net_ixgbe_vf, rte_ixgbevf_pmd); + RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe_vf, pci_id_ixgbevf_map); + RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe_vf, "* igb_uio | vfio-pci"); diff --git a/dpdk/drivers/net/ixgbe/ixgbe_ethdev.h b/dpdk/drivers/net/ixgbe/ixgbe_ethdev.h -index 76a1b9d184..e406b754e8 100644 +index 76a1b9d184..77ed07cf4c 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_ethdev.h +++ b/dpdk/drivers/net/ixgbe/ixgbe_ethdev.h @@ -104,6 +104,9 @@ @@ -48210,7 +68629,14 @@ index 76a1b9d184..e406b754e8 100644 /* bit of VXLAN tunnel type | 7 bits of zeros | 8 bits of zeros*/ #define IXGBE_FDIR_VXLAN_TUNNEL_TYPE 0x8000 /* bit of NVGRE tunnel type | 7 bits of zeros | 8 bits of zeros*/ -@@ -510,6 +513,9 @@ struct ixgbe_adapter { +@@ -506,10 +509,16 @@ struct ixgbe_adapter { + /* For RSS reta table update */ + uint8_t rss_reta_updated; + ++ /* Used for limiting SDP3 TX_DISABLE checks */ ++ uint8_t sdp3_no_tx_disable; ++ + /* Used for VF link sync with PF's physical and logical (by checking * mailbox status) link status. */ uint8_t pflink_fullchk; @@ -48220,7 +68646,7 @@ index 76a1b9d184..e406b754e8 100644 }; struct ixgbe_vf_representor { -@@ -709,7 +715,7 @@ void ixgbe_vlan_hw_filter_disable(struct rte_eth_dev *dev); +@@ -709,7 +718,7 @@ void ixgbe_vlan_hw_filter_disable(struct rte_eth_dev *dev); void ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev); @@ -48280,7 +68706,7 @@ index 166dae1e03..9ff5aa8c72 100644 } diff --git a/dpdk/drivers/net/ixgbe/ixgbe_flow.c b/dpdk/drivers/net/ixgbe/ixgbe_flow.c -index b2a2bfc02f..d539951896 100644 +index b2a2bfc02f..6bc2767ea1 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_flow.c +++ b/dpdk/drivers/net/ixgbe/ixgbe_flow.c @@ -870,15 +870,6 @@ ixgbe_parse_ethertype_filter(struct rte_eth_dev *dev, @@ -48330,6 +68756,14 @@ index b2a2bfc02f..d539951896 100644 goto out; } } +@@ -3445,6 +3437,7 @@ ixgbe_flow_destroy(struct rte_eth_dev *dev, + TAILQ_REMOVE(&ixgbe_flow_list, + ixgbe_flow_mem_ptr, entries); + rte_free(ixgbe_flow_mem_ptr); ++ break; + } + } + rte_free(flow); diff --git a/dpdk/drivers/net/ixgbe/ixgbe_pf.c b/dpdk/drivers/net/ixgbe/ixgbe_pf.c index d0d85e1386..2e46e30b79 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_pf.c @@ -48455,7 +68889,7 @@ index d0d85e1386..2e46e30b79 100644 } diff --git a/dpdk/drivers/net/ixgbe/ixgbe_rxtx.c b/dpdk/drivers/net/ixgbe/ixgbe_rxtx.c -index fa572d184d..8b9b009396 100644 +index fa572d184d..26b49a20da 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_rxtx.c +++ b/dpdk/drivers/net/ixgbe/ixgbe_rxtx.c @@ -87,11 +87,6 @@ @@ -48541,7 +68975,18 @@ index fa572d184d..8b9b009396 100644 pkt_flags |= ixgbe_rxd_pkt_info_to_pkt_flags((uint16_t)pkt_info); head->ol_flags = pkt_flags; head->packet_type = -@@ -2980,6 +2996,13 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev, +@@ -2822,6 +2838,10 @@ ixgbe_reset_rx_queue(struct ixgbe_adapter *adapter, struct ixgbe_rx_queue *rxq) + rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1); + rxq->rx_tail = 0; + rxq->nb_rx_hold = 0; ++ ++ if (rxq->pkt_first_seg != NULL) ++ rte_pktmbuf_free(rxq->pkt_first_seg); ++ + rxq->pkt_first_seg = NULL; + rxq->pkt_last_seg = NULL; + +@@ -2980,6 +3000,13 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev, else rxq->pkt_type_mask = IXGBE_PACKET_TYPE_MASK_82599; @@ -48555,7 +69000,7 @@ index fa572d184d..8b9b009396 100644 /* * Allocate RX ring hardware descriptors. A memzone large enough to * handle the maximum ring size is allocated in order to allow for -@@ -4785,15 +4808,11 @@ ixgbe_set_rsc(struct rte_eth_dev *dev) +@@ -4785,15 +4812,11 @@ ixgbe_set_rsc(struct rte_eth_dev *dev) /* RFCTL configuration */ rfctl = IXGBE_READ_REG(hw, IXGBE_RFCTL); if ((rsc_capable) && (rx_conf->offloads & DEV_RX_OFFLOAD_TCP_LRO)) @@ -48574,18 +69019,16 @@ index fa572d184d..8b9b009396 100644 IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl); /* If LRO hasn't been requested - we are done here. */ -@@ -5521,8 +5540,12 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev) +@@ -5521,8 +5544,10 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev) * ixgbevf_rlpml_set_vf even if jumbo frames are not used. This way, * VF packets received can work in all cases. */ - ixgbevf_rlpml_set_vf(hw, - (uint16_t)dev->data->dev_conf.rxmode.max_rx_pkt_len); + if (ixgbevf_rlpml_set_vf(hw, -+ (uint16_t)dev->data->dev_conf.rxmode.max_rx_pkt_len)) { ++ (uint16_t)dev->data->dev_conf.rxmode.max_rx_pkt_len)) + PMD_INIT_LOG(ERR, "Set max packet length to %d failed.", + dev->data->dev_conf.rxmode.max_rx_pkt_len); -+ return -EINVAL; -+ } /* * Assume no header split and no VLAN strip support @@ -48611,6 +69054,36 @@ index 505d344b9c..4adfbb3089 100644 /** flags to set in mbuf when a vlan is detected. */ uint64_t vlan_flags; uint64_t offloads; /**< Rx offloads with DEV_RX_OFFLOAD_* */ +diff --git a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h b/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h +index a97c27189b..e650feac82 100644 +--- a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h ++++ b/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h +@@ -152,7 +152,7 @@ _ixgbe_tx_queue_release_mbufs_vec(struct ixgbe_tx_queue *txq) + /* release the used mbufs in sw_ring */ + for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1); + i != txq->tx_tail; +- i = (i + 1) & max_desc) { ++ i = (i + 1) % txq->nb_tx_desc) { + txe = &txq->sw_ring_v[i]; + rte_pktmbuf_free_seg(txe->mbuf); + } +@@ -168,7 +168,6 @@ _ixgbe_tx_queue_release_mbufs_vec(struct ixgbe_tx_queue *txq) + static inline void + _ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq) + { +- const unsigned int mask = rxq->nb_rx_desc - 1; + unsigned int i; + + if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_rx_desc) +@@ -183,7 +182,7 @@ _ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq) + } else { + for (i = rxq->rx_tail; + i != rxq->rxrearm_start; +- i = (i + 1) & mask) { ++ i = (i + 1) % rxq->nb_rx_desc) { + if (rxq->sw_ring[i].mbuf != NULL) + rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf); + } diff --git a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c b/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c index feb86c61ee..d6d941cbc6 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c @@ -48886,7 +69359,7 @@ index feb86c61ee..d6d941cbc6 100644 return ixgbe_rx_vec_dev_conf_condition_check_default(dev); } diff --git a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c b/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c -index 599ba30e51..4b658605bf 100644 +index 599ba30e51..ac7bcb59c3 100644 --- a/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c +++ b/dpdk/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c @@ -132,9 +132,9 @@ desc_to_olflags_v_ipsec(__m128i descs[4], struct rte_mbuf **rx_pkts) @@ -48964,18 +69437,28 @@ index 599ba30e51..4b658605bf 100644 * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two */ static inline uint16_t -@@ -343,9 +362,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, +@@ -343,9 +362,18 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, __m128i dd_check, eop_check; __m128i mbuf_init; uint8_t vlan_flags; -- ++ uint16_t udp_p_flag = 0; /* Rx Descriptor UDP header present */ + - /* nb_pkts shall be less equal than RTE_IXGBE_MAX_RX_BURST */ - nb_pkts = RTE_MIN(nb_pkts, RTE_IXGBE_MAX_RX_BURST); -+ uint16_t udp_p_flag = 0; /* Rx Descriptor UDP header present */ ++ /* ++ * Under the circumstance that `rx_tail` wrap back to zero ++ * and the advance speed of `rx_tail` is greater than `rxrearm_start`, ++ * `rx_tail` will catch up with `rxrearm_start` and surpass it. ++ * This may cause some mbufs be reused by application. ++ * ++ * So we need to make some restrictions to ensure that ++ * `rx_tail` will not exceed `rxrearm_start`. ++ */ ++ nb_pkts = RTE_MIN(nb_pkts, RTE_IXGBE_RXQ_REARM_THRESH); /* nb_pkts has to be floor-aligned to RTE_IXGBE_DESCS_PER_LOOP */ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_IXGBE_DESCS_PER_LOOP); -@@ -370,6 +387,9 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, +@@ -370,6 +398,9 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, rte_cpu_to_le_32(IXGBE_RXDADV_STAT_DD))) return 0; @@ -48985,7 +69468,27 @@ index 599ba30e51..4b658605bf 100644 /* 4 packets DD mask */ dd_check = _mm_set_epi64x(0x0000000100000001LL, 0x0000000100000001LL); -@@ -482,7 +502,8 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, +@@ -434,7 +465,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, + mbp1 = _mm_loadu_si128((__m128i *)&sw_ring[pos]); + + /* Read desc statuses backwards to avoid race condition */ +- /* A.1 load 4 pkts desc */ ++ /* A.1 load desc[3] */ + descs[3] = _mm_loadu_si128((__m128i *)(rxdp + 3)); + rte_compiler_barrier(); + +@@ -446,9 +477,9 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, + mbp2 = _mm_loadu_si128((__m128i *)&sw_ring[pos+2]); + #endif + ++ /* A.1 load desc[2-0] */ + descs[2] = _mm_loadu_si128((__m128i *)(rxdp + 2)); + rte_compiler_barrier(); +- /* B.1 load 2 mbuf point */ + descs[1] = _mm_loadu_si128((__m128i *)(rxdp + 1)); + rte_compiler_barrier(); + descs[0] = _mm_loadu_si128((__m128i *)(rxdp)); +@@ -482,7 +513,8 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]); /* set ol_flags with vlan packet type */ @@ -48995,7 +69498,16 @@ index 599ba30e51..4b658605bf 100644 #ifdef RTE_LIBRTE_SECURITY if (unlikely(use_ipsec)) -@@ -556,13 +577,11 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, +@@ -519,7 +551,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, + /* and with mask to extract bits, flipping 1-0 */ + __m128i eop_bits = _mm_andnot_si128(staterr, eop_check); + /* the staterr values are not in order, as the count +- * count of dd bits doesn't care. However, for end of ++ * of dd bits doesn't care. However, for end of + * packet tracking, we do care, so shuffle. This also + * compresses the 32-bit values to 8-bit + */ +@@ -556,13 +588,11 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct rte_mbuf **rx_pkts, return nb_pkts_recd; } @@ -49010,7 +69522,7 @@ index 599ba30e51..4b658605bf 100644 * - floor align nb_pkts to a RTE_IXGBE_DESC_PER_LOOP power-of-two */ uint16_t -@@ -572,18 +591,16 @@ ixgbe_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -572,18 +602,16 @@ ixgbe_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL); } @@ -49033,7 +69545,7 @@ index 599ba30e51..4b658605bf 100644 { struct ixgbe_rx_queue *rxq = rx_queue; uint8_t split_flags[RTE_IXGBE_MAX_RX_BURST] = {0}; -@@ -615,6 +632,32 @@ ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, +@@ -615,6 +643,32 @@ ixgbe_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, &split_flags[i]); } @@ -49106,7 +69618,7 @@ index f62fd761dd..d1017c7b1a 100644 /** * Notify VF when PF link status changes. diff --git a/dpdk/drivers/net/kni/rte_eth_kni.c b/dpdk/drivers/net/kni/rte_eth_kni.c -index d88cb1778e..c3345f5cb7 100644 +index d88cb1778e..82256afd6b 100644 --- a/dpdk/drivers/net/kni/rte_eth_kni.c +++ b/dpdk/drivers/net/kni/rte_eth_kni.c @@ -47,6 +47,7 @@ struct pmd_queue { @@ -49129,7 +69641,17 @@ index d88cb1778e..c3345f5cb7 100644 kni_q->rx.pkts += nb_pkts; -@@ -372,6 +376,7 @@ eth_kni_create(struct rte_vdev_device *vdev, +@@ -200,6 +204,9 @@ eth_kni_close(struct rte_eth_dev *eth_dev) + struct pmd_internals *internals; + int ret; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + eth_kni_dev_stop(eth_dev); + + /* mac_addrs must not be freed alone because part of dev_private */ +@@ -372,6 +379,7 @@ eth_kni_create(struct rte_vdev_device *vdev, return NULL; internals = eth_dev->data->dev_private; @@ -49137,8 +69659,24 @@ index d88cb1778e..c3345f5cb7 100644 data = eth_dev->data; data->nb_rx_queues = 1; data->nb_tx_queues = 1; +@@ -394,8 +402,13 @@ eth_kni_create(struct rte_vdev_device *vdev, + static int + kni_init(void) + { +- if (is_kni_initialized == 0) +- rte_kni_init(MAX_KNI_PORTS); ++ int ret; ++ ++ if (is_kni_initialized == 0) { ++ ret = rte_kni_init(MAX_KNI_PORTS); ++ if (ret < 0) ++ return ret; ++ } + + is_kni_initialized++; + diff --git a/dpdk/drivers/net/liquidio/lio_ethdev.c b/dpdk/drivers/net/liquidio/lio_ethdev.c -index ad4a51ecda..ac0472967c 100644 +index ad4a51ecda..b0e90ea08a 100644 --- a/dpdk/drivers/net/liquidio/lio_ethdev.c +++ b/dpdk/drivers/net/liquidio/lio_ethdev.c @@ -484,7 +484,7 @@ lio_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) @@ -49150,6 +69688,16 @@ index ad4a51ecda..ac0472967c 100644 eth_dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else +@@ -1558,6 +1558,9 @@ lio_dev_close(struct rte_eth_dev *eth_dev) + { + struct lio_device *lio_dev = LIO_DEV(eth_dev); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + lio_dev_info(lio_dev, "closing port %d\n", eth_dev->data->port_id); + + if (lio_dev->intf_open) diff --git a/dpdk/drivers/net/liquidio/lio_ethdev.h b/dpdk/drivers/net/liquidio/lio_ethdev.h index 74cd2fb6c6..d33be1c44d 100644 --- a/dpdk/drivers/net/liquidio/lio_ethdev.h @@ -49164,8 +69712,28 @@ index 74cd2fb6c6..d33be1c44d 100644 #define LIO_DEV(_eth_dev) ((_eth_dev)->data->dev_private) /* LIO Response condition variable */ +diff --git a/dpdk/drivers/net/liquidio/lio_rxtx.c b/dpdk/drivers/net/liquidio/lio_rxtx.c +index 8d705bfe7f..f57b7712b5 100644 +--- a/dpdk/drivers/net/liquidio/lio_rxtx.c ++++ b/dpdk/drivers/net/liquidio/lio_rxtx.c +@@ -1050,7 +1050,6 @@ lio_update_read_index(struct lio_instr_queue *iq) + int + lio_flush_iq(struct lio_device *lio_dev, struct lio_instr_queue *iq) + { +- uint32_t tot_inst_processed = 0; + uint32_t inst_processed = 0; + int tx_done = 1; + +@@ -1073,7 +1072,6 @@ lio_flush_iq(struct lio_device *lio_dev, struct lio_instr_queue *iq) + iq->stats.instr_processed += inst_processed; + } + +- tot_inst_processed += inst_processed; + inst_processed = 0; + + } while (1); diff --git a/dpdk/drivers/net/memif/memif_socket.c b/dpdk/drivers/net/memif/memif_socket.c -index ad5e30b96e..c1967c67bf 100644 +index ad5e30b96e..ff6317574d 100644 --- a/dpdk/drivers/net/memif/memif_socket.c +++ b/dpdk/drivers/net/memif/memif_socket.c @@ -204,6 +204,13 @@ memif_msg_receive_init(struct memif_control_channel *cc, memif_msg_t *msg) @@ -49195,7 +69763,20 @@ index ad5e30b96e..c1967c67bf 100644 strlcpy(pmd->remote_name, (char *)i->name, sizeof(pmd->remote_name)); -@@ -765,6 +766,7 @@ memif_intr_handler(void *arg) +@@ -395,11 +396,10 @@ memif_msg_enq_init(struct rte_eth_dev *dev) + { + struct pmd_internals *pmd = dev->data->dev_private; + struct memif_msg_queue_elt *e = memif_msg_enq(pmd->cc); +- memif_msg_init_t *i = &e->msg.init; ++ memif_msg_init_t *i; + + if (e == NULL) + return -1; +- + i = &e->msg.init; + e->msg.type = MEMIF_MSG_TYPE_INIT; + i->version = MEMIF_VERSION; +@@ -765,6 +765,7 @@ memif_intr_handler(void *arg) ret = memif_msg_receive(cc); /* if driver failed to assign device */ if (cc->dev == NULL) { @@ -49204,10 +69785,33 @@ index ad5e30b96e..c1967c67bf 100644 memif_intr_handler, cc, diff --git a/dpdk/drivers/net/memif/rte_eth_memif.c b/dpdk/drivers/net/memif/rte_eth_memif.c -index 8dd1d0d63d..aa75a04278 100644 +index 8dd1d0d63d..10aebadbd0 100644 --- a/dpdk/drivers/net/memif/rte_eth_memif.c +++ b/dpdk/drivers/net/memif/rte_eth_memif.c -@@ -398,7 +398,11 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) +@@ -190,6 +190,7 @@ memif_dev_info(struct rte_eth_dev *dev __rte_unused, struct rte_eth_dev_info *de + dev_info->max_rx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS; + dev_info->max_tx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS; + dev_info->min_rx_bufsize = 0; ++ dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS; + + return 0; + } +@@ -333,13 +334,13 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + goto no_free_bufs; + mbuf = mbuf_head; + mbuf->port = mq->in_port; ++ dst_off = 0; + + next_slot: + s0 = cur_slot & mask; + d0 = &ring->desc[s0]; + + src_len = d0->length; +- dst_off = 0; + src_off = 0; + + do { +@@ -398,7 +399,11 @@ eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) refill: if (type == MEMIF_RING_M2S) { @@ -49220,7 +69824,16 @@ index 8dd1d0d63d..aa75a04278 100644 n_slots = ring_size - head + mq->last_tail; while (n_slots--) { -@@ -561,14 +565,24 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) +@@ -536,7 +541,7 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + rte_eth_devices[mq->in_port].process_private; + memif_ring_t *ring = memif_get_ring_from_queue(proc_private, mq); + uint16_t slot, saved_slot, n_free, ring_size, mask, n_tx_pkts = 0; +- uint16_t src_len, src_off, dst_len, dst_off, cp_len; ++ uint16_t src_len, src_off, dst_len, dst_off, cp_len, nb_segs; + memif_ring_type_t type = mq->type; + memif_desc_t *d0; + struct rte_mbuf *mbuf; +@@ -561,19 +566,30 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) ring_size = 1 << mq->log2_ring_size; mask = ring_size - 1; @@ -49251,7 +69864,80 @@ index 8dd1d0d63d..aa75a04278 100644 n_free = __atomic_load_n(&ring->head, __ATOMIC_ACQUIRE) - slot; } -@@ -1501,7 +1515,7 @@ memif_create(struct rte_vdev_device *vdev, enum memif_role_t role, + while (n_tx_pkts < nb_pkts && n_free) { + mbuf_head = *bufs++; ++ nb_segs = mbuf_head->nb_segs; + mbuf = mbuf_head; + + saved_slot = slot; +@@ -617,7 +633,7 @@ eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) + d0->length = dst_off; + } + +- if (rte_pktmbuf_is_contiguous(mbuf) == 0) { ++ if (--nb_segs > 0) { + mbuf = mbuf->next; + goto next_in_chain; + } +@@ -654,6 +670,7 @@ memif_tx_one_zc(struct pmd_process_private *proc_private, struct memif_queue *mq + uint16_t slot, uint16_t n_free) + { + memif_desc_t *d0; ++ uint16_t nb_segs = mbuf->nb_segs; + int used_slots = 1; + + next_in_chain: +@@ -666,6 +683,7 @@ memif_tx_one_zc(struct pmd_process_private *proc_private, struct memif_queue *mq + /* populate descriptor */ + d0 = &ring->desc[slot & mask]; + d0->length = rte_pktmbuf_data_len(mbuf); ++ mq->n_bytes += rte_pktmbuf_data_len(mbuf); + /* FIXME: get region index */ + d0->region = 1; + d0->offset = rte_pktmbuf_mtod(mbuf, uint8_t *) - +@@ -673,7 +691,7 @@ memif_tx_one_zc(struct pmd_process_private *proc_private, struct memif_queue *mq + d0->flags = 0; + + /* check if buffer is chained */ +- if (rte_pktmbuf_is_contiguous(mbuf) == 0) { ++ if (--nb_segs > 0) { + if (n_free < 2) + return 0; + /* mark buffer as chained */ +@@ -1394,23 +1412,6 @@ memif_stats_reset(struct rte_eth_dev *dev) + return 0; + } + +-static int +-memif_rx_queue_intr_enable(struct rte_eth_dev *dev __rte_unused, +- uint16_t qid __rte_unused) +-{ +- MIF_LOG(WARNING, "Interrupt mode not supported."); +- +- return -1; +-} +- +-static int +-memif_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t qid __rte_unused) +-{ +- struct pmd_internals *pmd __rte_unused = dev->data->dev_private; +- +- return 0; +-} +- + static const struct eth_dev_ops ops = { + .dev_start = memif_dev_start, + .dev_close = memif_dev_close, +@@ -1420,8 +1421,6 @@ static const struct eth_dev_ops ops = { + .rx_queue_setup = memif_rx_queue_setup, + .rx_queue_release = memif_queue_release, + .tx_queue_release = memif_queue_release, +- .rx_queue_intr_enable = memif_rx_queue_intr_enable, +- .rx_queue_intr_disable = memif_rx_queue_intr_disable, + .link_update = memif_link_update, + .stats_get = memif_stats_get, + .stats_reset = memif_stats_reset, +@@ -1501,7 +1500,7 @@ memif_create(struct rte_vdev_device *vdev, enum memif_role_t role, } @@ -49337,7 +70023,7 @@ index 9eb4988420..a03ab930cc 100644 dlopen_lib_name = driver_name_fmt.format(dlopen_name) dlopen_so_version = LIB_GLUE_VERSION diff --git a/dpdk/drivers/net/mlx4/mlx4.c b/dpdk/drivers/net/mlx4/mlx4.c -index ab5e6c66cb..4479022a42 100644 +index ab5e6c66cb..8397f408f4 100644 --- a/dpdk/drivers/net/mlx4/mlx4.c +++ b/dpdk/drivers/net/mlx4/mlx4.c @@ -49,6 +49,10 @@ @@ -49351,7 +70037,7 @@ index ab5e6c66cb..4479022a42 100644 static const char *MZ_MLX4_PMD_SHARED_DATA = "mlx4_pmd_shared_data"; /* Shared memory between primary and secondary processes. */ -@@ -194,7 +198,7 @@ mlx4_free_verbs_buf(void *ptr, void *data __rte_unused) +@@ -194,25 +198,26 @@ mlx4_free_verbs_buf(void *ptr, void *data __rte_unused) * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ @@ -49360,7 +70046,12 @@ index ab5e6c66cb..4479022a42 100644 mlx4_proc_priv_init(struct rte_eth_dev *dev) { struct mlx4_proc_priv *ppriv; -@@ -206,13 +210,13 @@ mlx4_proc_priv_init(struct rte_eth_dev *dev) + size_t ppriv_size; + ++ mlx4_proc_priv_uninit(dev); + /* + * UAR register table follows the process private structure. BlueFlame + * registers for Tx queues are stored in the table. */ ppriv_size = sizeof(struct mlx4_proc_priv) + dev->data->nb_tx_queues * sizeof(void *); @@ -49377,7 +70068,7 @@ index ab5e6c66cb..4479022a42 100644 dev->process_private = ppriv; return 0; } -@@ -223,7 +227,7 @@ mlx4_proc_priv_init(struct rte_eth_dev *dev) +@@ -223,7 +228,7 @@ mlx4_proc_priv_init(struct rte_eth_dev *dev) * @param dev * Pointer to Ethernet device structure. */ @@ -49386,7 +70077,7 @@ index ab5e6c66cb..4479022a42 100644 mlx4_proc_priv_uninit(struct rte_eth_dev *dev) { if (!dev->process_private) -@@ -248,9 +252,6 @@ mlx4_dev_configure(struct rte_eth_dev *dev) +@@ -248,9 +253,6 @@ mlx4_dev_configure(struct rte_eth_dev *dev) struct rte_flow_error error; int ret; @@ -49396,7 +70087,16 @@ index ab5e6c66cb..4479022a42 100644 /* Prepare internal flow rules. */ ret = mlx4_flow_sync(priv, &error); if (ret) { -@@ -461,6 +462,7 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, +@@ -375,6 +377,8 @@ mlx4_dev_close(struct rte_eth_dev *dev) + struct mlx4_priv *priv = dev->data->dev_private; + unsigned int i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + DEBUG("%p: closing device \"%s\"", + (void *)dev, + ((priv->ctx != NULL) ? priv->ctx->device->name : "")); +@@ -461,6 +465,7 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, { FILE *file; char line[32]; @@ -49404,7 +70104,7 @@ index ab5e6c66cb..4479022a42 100644 MKSTR(path, "%s/device/uevent", device->ibdev_path); file = fopen(path, "rb"); -@@ -470,16 +472,18 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, +@@ -470,16 +475,18 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, } while (fgets(line, sizeof(line), file) == line) { size_t len = strlen(line); @@ -49427,7 +70127,7 @@ index ab5e6c66cb..4479022a42 100644 /* Extract information. */ if (sscanf(line, "PCI_SLOT_NAME=" -@@ -488,12 +492,15 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, +@@ -488,12 +495,15 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device, &pci_addr->bus, &pci_addr->devid, &pci_addr->function) == 4) { @@ -49445,7 +70145,7 @@ index ab5e6c66cb..4479022a42 100644 } /** -@@ -760,6 +767,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -760,6 +770,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) struct ibv_context *attr_ctx = NULL; struct ibv_device_attr device_attr; struct ibv_device_attr_ex device_attr_ex; @@ -49453,7 +70153,7 @@ index ab5e6c66cb..4479022a42 100644 struct mlx4_conf conf = { .ports.present = 0, .mr_ext_memseg_en = 1, -@@ -874,7 +882,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -874,7 +885,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) ERROR("can not attach rte ethdev"); rte_errno = ENOMEM; err = rte_errno; @@ -49462,7 +70162,7 @@ index ab5e6c66cb..4479022a42 100644 } priv = eth_dev->data->dev_private; if (!priv->verbs_alloc_ctx.enabled) { -@@ -883,24 +891,24 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -883,24 +894,24 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) " from Verbs"); rte_errno = ENOTSUP; err = rte_errno; @@ -49491,7 +70191,7 @@ index ab5e6c66cb..4479022a42 100644 } /* * Ethdev pointer is still required as input since -@@ -912,7 +920,14 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -912,7 +923,14 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) claim_zero(mlx4_glue->close_device(ctx)); rte_eth_copy_pci_info(eth_dev, pci_dev); rte_eth_dev_probing_finish(eth_dev); @@ -49506,7 +70206,7 @@ index ab5e6c66cb..4479022a42 100644 } /* Check port status. */ err = mlx4_glue->query_port(ctx, port, &port_attr); -@@ -1029,10 +1044,9 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -1029,10 +1047,9 @@ mlx4_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); /* Initialize local interrupt handle for current port. */ @@ -49520,7 +70220,7 @@ index ab5e6c66cb..4479022a42 100644 /* * Override ethdev interrupt handle pointer with private * handle instead of that of the parent PCI device used by -@@ -1088,6 +1102,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -1088,6 +1105,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) priv, mem_event_cb); rte_rwlock_write_unlock(&mlx4_shared_data->mem_event_rwlock); rte_eth_dev_probing_finish(eth_dev); @@ -49528,7 +70228,7 @@ index ab5e6c66cb..4479022a42 100644 continue; port_error: rte_free(priv); -@@ -1102,14 +1117,10 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) +@@ -1102,14 +1120,10 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) eth_dev->data->mac_addrs = NULL; rte_eth_dev_release_port(eth_dev); } @@ -49561,10 +70261,30 @@ index c6cb29493e..87710d3996 100644 int mlx4_get_ifname(const struct mlx4_priv *priv, char (*ifname)[IF_NAMESIZE]); diff --git a/dpdk/drivers/net/mlx4/mlx4_flow.c b/dpdk/drivers/net/mlx4/mlx4_flow.c -index 96479b83dd..2da4f6d965 100644 +index 96479b83dd..927715ba0f 100644 --- a/dpdk/drivers/net/mlx4/mlx4_flow.c +++ b/dpdk/drivers/net/mlx4/mlx4_flow.c -@@ -981,12 +981,13 @@ mlx4_drop_get(struct mlx4_priv *priv) +@@ -714,7 +714,8 @@ mlx4_flow_prepare(struct mlx4_priv *priv, + flow->internal = 1; + continue; + } +- if (flow->promisc || flow->allmulti) { ++ if ((item->type != RTE_FLOW_ITEM_TYPE_VLAN && flow->promisc) || ++ flow->allmulti) { + msg = "mlx4 does not support additional matching" + " criteria combined with indiscriminate" + " matching on Ethernet headers"; +@@ -792,7 +793,8 @@ mlx4_flow_prepare(struct mlx4_priv *priv, + rss = action->conf; + /* Default RSS configuration if none is provided. */ + if (rss->key_len) { +- rss_key = rss->key; ++ rss_key = rss->key ? ++ rss->key : mlx4_rss_hash_key_default; + rss_key_len = rss->key_len; + } else { + rss_key = mlx4_rss_hash_key_default; +@@ -981,12 +983,13 @@ mlx4_drop_get(struct mlx4_priv *priv) priv->drop = drop; return drop; error: @@ -49596,7 +70316,7 @@ index 668ca86700..5d9e985495 100644 #endif /* MLX4_GLUE_H_ */ diff --git a/dpdk/drivers/net/mlx4/mlx4_mp.c b/dpdk/drivers/net/mlx4/mlx4_mp.c -index cdb648517a..4da743d9e3 100644 +index cdb648517a..1e9b4de500 100644 --- a/dpdk/drivers/net/mlx4/mlx4_mp.c +++ b/dpdk/drivers/net/mlx4/mlx4_mp.c @@ -112,6 +112,9 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) @@ -49609,8 +70329,11 @@ index cdb648517a..4da743d9e3 100644 int ret; assert(rte_eal_process_type() == RTE_PROC_SECONDARY); -@@ -127,6 +130,21 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) - rte_mb(); +@@ -124,9 +127,24 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) + switch (param->type) { + case MLX4_MP_REQ_START_RXTX: + INFO("port %u starting datapath", dev->data->port_id); +- rte_mb(); dev->tx_pkt_burst = mlx4_tx_burst; dev->rx_pkt_burst = mlx4_rx_burst; +#ifdef HAVE_IBV_MLX4_UAR_MMAP_OFFSET @@ -49628,6 +70351,7 @@ index cdb648517a..4da743d9e3 100644 + } + } +#endif ++ rte_mb(); mp_init_msg(dev, &mp_res, param->type); res->result = 0; ret = rte_mp_reply(&mp_res, peer); @@ -49651,6 +70375,21 @@ index cdb648517a..4da743d9e3 100644 ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); if (ret) { if (rte_errno != ENOTSUP) +diff --git a/dpdk/drivers/net/mlx4/mlx4_rxtx.c b/dpdk/drivers/net/mlx4/mlx4_rxtx.c +index 4dc0adb938..3c1eea3af7 100644 +--- a/dpdk/drivers/net/mlx4/mlx4_rxtx.c ++++ b/dpdk/drivers/net/mlx4/mlx4_rxtx.c +@@ -922,10 +922,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n) + if (likely(elt->buf != NULL)) { + struct rte_mbuf *tmp = elt->buf; + +-#ifndef NDEBUG +- /* Poisoning. */ +- memset(&elt->buf, 0x66, sizeof(struct rte_mbuf *)); +-#endif + /* Faster than rte_pktmbuf_free(). */ + do { + struct rte_mbuf *next = tmp->next; diff --git a/dpdk/drivers/net/mlx4/mlx4_rxtx.h b/dpdk/drivers/net/mlx4/mlx4_rxtx.h index 8baf33fa94..136ca56ca4 100644 --- a/dpdk/drivers/net/mlx4/mlx4_rxtx.h @@ -49673,7 +70412,7 @@ index 8baf33fa94..136ca56ca4 100644 int mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, unsigned int socket, diff --git a/dpdk/drivers/net/mlx4/mlx4_txq.c b/dpdk/drivers/net/mlx4/mlx4_txq.c -index 01a5efd80d..824ddbd827 100644 +index 01a5efd80d..8559eaf82c 100644 --- a/dpdk/drivers/net/mlx4/mlx4_txq.c +++ b/dpdk/drivers/net/mlx4/mlx4_txq.c @@ -158,6 +158,27 @@ mlx4_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd) @@ -49718,6 +70457,35 @@ index 01a5efd80d..824ddbd827 100644 #endif /** +@@ -179,19 +207,18 @@ mlx4_tx_uar_init_secondary(struct rte_eth_dev *dev __rte_unused, + static void + mlx4_txq_free_elts(struct txq *txq) + { +- unsigned int elts_head = txq->elts_head; +- unsigned int elts_tail = txq->elts_tail; + struct txq_elt (*elts)[txq->elts_n] = txq->elts; +- unsigned int elts_m = txq->elts_n - 1; ++ unsigned int n = txq->elts_n; + +- DEBUG("%p: freeing WRs", (void *)txq); +- while (elts_tail != elts_head) { +- struct txq_elt *elt = &(*elts)[elts_tail++ & elts_m]; ++ DEBUG("%p: freeing WRs, %u", (void *)txq, n); ++ while (n--) { ++ struct txq_elt *elt = &(*elts)[n]; + +- assert(elt->buf != NULL); +- rte_pktmbuf_free(elt->buf); +- elt->buf = NULL; +- elt->wqe = NULL; ++ if (elt->buf) { ++ rte_pktmbuf_free(elt->buf); ++ elt->buf = NULL; ++ elt->wqe = NULL; ++ } + } + txq->elts_tail = txq->elts_head; + } diff --git a/dpdk/drivers/net/mlx4/mlx4_utils.h b/dpdk/drivers/net/mlx4/mlx4_utils.h index 74b9d2ecdc..5718b9c742 100644 --- a/dpdk/drivers/net/mlx4/mlx4_utils.h @@ -49736,10 +70504,27 @@ index 74b9d2ecdc..5718b9c742 100644 /** Generate a string out of the provided arguments. */ #define MLX4_STR(...) # __VA_ARGS__ diff --git a/dpdk/drivers/net/mlx5/Makefile b/dpdk/drivers/net/mlx5/Makefile -index c5cf4397ac..605975c245 100644 +index c5cf4397ac..d62bfd6875 100644 --- a/dpdk/drivers/net/mlx5/Makefile +++ b/dpdk/drivers/net/mlx5/Makefile -@@ -193,6 +193,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh +@@ -178,6 +178,16 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh + infiniband/mlx5dv.h \ + func mlx5dv_query_devx_port \ + $(AUTOCONF_OUTPUT) ++ $Q sh -- '$<' '$@' \ ++ HAVE_MLX5DV_DR_DEVX_PORT_V35 \ ++ infiniband/mlx5dv.h \ ++ func mlx5dv_query_port \ ++ $(AUTOCONF_OUTPUT) ++ $Q sh -- '$<' '$@' \ ++ HAVE_MLX5DV_DR_CREATE_DEST_IB_PORT \ ++ infiniband/mlx5dv.h \ ++ func mlx5dv_dr_action_create_dest_ib_port \ ++ $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVX_OBJ \ + infiniband/mlx5dv.h \ +@@ -193,6 +203,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh infiniband/mlx5dv.h \ func mlx5dv_devx_obj_query_async \ $(AUTOCONF_OUTPUT) @@ -49752,7 +70537,7 @@ index c5cf4397ac..605975c245 100644 HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR \ infiniband/mlx5dv.h \ diff --git a/dpdk/drivers/net/mlx5/meson.build b/dpdk/drivers/net/mlx5/meson.build -index d6b32db794..139056cbe8 100644 +index d6b32db794..81126d6a1b 100644 --- a/dpdk/drivers/net/mlx5/meson.build +++ b/dpdk/drivers/net/mlx5/meson.build @@ -9,11 +9,12 @@ if not is_linux @@ -49818,7 +70603,17 @@ index d6b32db794..139056cbe8 100644 sources += files('mlx5_glue.c') endif cflags_options = [ -@@ -130,6 +144,8 @@ if build +@@ -124,12 +138,18 @@ if build + 'IBV_WQ_FLAG_RX_END_PADDING' ], + [ 'HAVE_MLX5DV_DR_DEVX_PORT', 'infiniband/mlx5dv.h', + 'mlx5dv_query_devx_port' ], ++ [ 'HAVE_MLX5DV_DR_DEVX_PORT_V35', 'infiniband/mlx5dv.h', ++ 'mlx5dv_query_port' ], ++ [ 'HAVE_MLX5DV_DR_CREATE_DEST_IB_PORT', 'infiniband/mlx5dv.h', ++ 'mlx5dv_dr_action_create_dest_ib_port' ], + [ 'HAVE_IBV_DEVX_OBJ', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_obj_create' ], + [ 'HAVE_IBV_FLOW_DEVX_COUNTERS', 'infiniband/mlx5dv.h', 'MLX5DV_FLOW_ACTION_COUNTERS_DEVX' ], [ 'HAVE_IBV_DEVX_ASYNC', 'infiniband/mlx5dv.h', 'mlx5dv_devx_obj_query_async' ], @@ -49827,7 +70622,7 @@ index d6b32db794..139056cbe8 100644 [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', 'mlx5dv_dr_action_create_dest_devx_tir' ], [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', -@@ -200,7 +216,7 @@ if build +@@ -200,7 +220,7 @@ if build configure_file(output : 'mlx5_autoconf.h', configuration : config) endif # Build Glue Library @@ -49837,7 +70632,7 @@ index d6b32db794..139056cbe8 100644 dlopen_lib_name = driver_name_fmt.format(dlopen_name) dlopen_so_version = LIB_GLUE_VERSION diff --git a/dpdk/drivers/net/mlx5/mlx5.c b/dpdk/drivers/net/mlx5/mlx5.c -index d84a6f91b4..f8de9e329e 100644 +index d84a6f91b4..dee018bbba 100644 --- a/dpdk/drivers/net/mlx5/mlx5.c +++ b/dpdk/drivers/net/mlx5/mlx5.c @@ -12,7 +12,7 @@ @@ -49903,10 +70698,44 @@ index d84a6f91b4..f8de9e329e 100644 rte_errno = ENOMEM; DRV_LOG(ERR, "no free id"); return -rte_errno; -@@ -459,6 +470,85 @@ mlx5_restore_doorbell_mapping_env(int value) +@@ -459,6 +470,124 @@ mlx5_restore_doorbell_mapping_env(int value) setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1); } ++static int ++mlx5_os_dev_shared_handler_install_lsc(struct mlx5_ibv_shared *sh) ++{ ++ int nlsk_fd, flags, ret; ++ ++ nlsk_fd = mlx5_nl_init(NETLINK_ROUTE, RTMGRP_LINK); ++ if (nlsk_fd < 0) { ++ DRV_LOG(ERR, "Failed to create a socket for Netlink events: %s", ++ rte_strerror(rte_errno)); ++ return -1; ++ } ++ flags = fcntl(nlsk_fd, F_GETFL); ++ ret = fcntl(nlsk_fd, F_SETFL, flags | O_NONBLOCK); ++ if (ret != 0) { ++ DRV_LOG(ERR, "Failed to make Netlink event socket non-blocking: %s", ++ strerror(errno)); ++ rte_errno = errno; ++ goto error; ++ } ++ sh->intr_handle_nl.type = RTE_INTR_HANDLE_EXT; ++ sh->intr_handle_nl.fd = nlsk_fd; ++ if (rte_intr_callback_register(&sh->intr_handle_nl, ++ mlx5_dev_interrupt_handler_nl, ++ sh) != 0) { ++ DRV_LOG(ERR, "Failed to register Netlink events interrupt"); ++ sh->intr_handle_nl.fd = -1; ++ goto error; ++ } ++ return 0; ++error: ++ close(nlsk_fd); ++ return -1; ++} ++ +/** + * Install shared asynchronous device events handler. + * This function is implemented to support event sharing @@ -49936,6 +70765,11 @@ index d84a6f91b4..f8de9e329e 100644 + sh->intr_handle.fd = -1; + } + } ++ sh->intr_handle_nl.fd = -1; ++ if (mlx5_os_dev_shared_handler_install_lsc(sh) < 0) { ++ DRV_LOG(INFO, "Fail to install the shared Netlink event handler."); ++ sh->intr_handle_nl.fd = -1; ++ } + if (sh->devx) { +#ifdef HAVE_IBV_DEVX_ASYNC + sh->intr_handle_devx.fd = -1; @@ -49989,7 +70823,7 @@ index d84a6f91b4..f8de9e329e 100644 /** * Allocate shared IB device context. If there is multiport device the * master and representors will share this context, if there is single -@@ -553,7 +643,6 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, +@@ -553,7 +682,6 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, sizeof(sh->ibdev_name)); strncpy(sh->ibdev_path, sh->ctx->device->ibdev_path, sizeof(sh->ibdev_path)); @@ -49997,7 +70831,15 @@ index d84a6f91b4..f8de9e329e 100644 /* * Setting port_id to max unallowed value means * there is no interrupt subhandler installed for -@@ -590,13 +679,19 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, +@@ -562,6 +690,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, + for (i = 0; i < sh->max_port; i++) { + sh->port[i].ih_port_id = RTE_MAX_ETHPORTS; + sh->port[i].devx_ih_port_id = RTE_MAX_ETHPORTS; ++ sh->port[i].nl_ih_port_id = RTE_MAX_ETHPORTS; + } + sh->pd = mlx5_glue->alloc_pd(sh->ctx); + if (sh->pd == NULL) { +@@ -590,13 +719,19 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, goto error; } } @@ -50018,7 +70860,7 @@ index d84a6f91b4..f8de9e329e 100644 /* * Once the device is added to the list of memory event * callback, its global MR cache table cannot be expanded -@@ -613,6 +708,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, +@@ -613,6 +748,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn, err = rte_errno; goto error; } @@ -50026,7 +70868,7 @@ index d84a6f91b4..f8de9e329e 100644 mlx5_flow_counters_mng_init(sh); /* Add device to memory callback list. */ rte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock); -@@ -673,12 +769,12 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) +@@ -673,12 +809,12 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) assert(rte_eal_process_type() == RTE_PROC_PRIMARY); if (--sh->refcnt) goto exit; @@ -50041,7 +70883,7 @@ index d84a6f91b4..f8de9e329e 100644 /* Remove context from the global device list. */ LIST_REMOVE(sh, next); /* -@@ -686,20 +782,7 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) +@@ -686,20 +822,7 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh) * Only primary process handles async device events. **/ mlx5_flow_counters_mng_close(sh); @@ -50063,7 +70905,15 @@ index d84a6f91b4..f8de9e329e 100644 if (sh->pd) claim_zero(mlx5_glue->dealloc_pd(sh->pd)); if (sh->tis) -@@ -789,7 +872,7 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv) +@@ -766,6 +889,7 @@ mlx5_free_table_hash_list(struct mlx5_priv *priv) + rte_free(tbl_data); + } + mlx5_hlist_destroy(sh->flow_tbls, NULL, NULL); ++ sh->flow_tbls = NULL; + } + + /** +@@ -789,7 +913,7 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv) snprintf(s, sizeof(s), "%s_flow_table", priv->sh->ibdev_name); sh->flow_tbls = mlx5_hlist_create(s, MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE); if (!sh->flow_tbls) { @@ -50072,7 +70922,7 @@ index d84a6f91b4..f8de9e329e 100644 err = ENOMEM; return err; } -@@ -868,27 +951,25 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) +@@ -868,27 +992,25 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) { struct mlx5_ibv_shared *sh = priv->sh; char s[MLX5_HLIST_NAMESIZE]; @@ -50106,7 +70956,23 @@ index d84a6f91b4..f8de9e329e 100644 /* Reference counter is zero, we should initialize structures. */ domain = mlx5_glue->dr_create_domain(sh->ctx, MLX5DV_DR_DOMAIN_TYPE_NIC_RX); -@@ -922,8 +1003,6 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) +@@ -917,13 +1039,21 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) + goto error; + } + sh->fdb_domain = domain; +- sh->esw_drop_action = mlx5_glue->dr_create_flow_action_drop(); ++ } ++ /* ++ * The drop action is just some dummy placeholder in rdma-core. It ++ * does not belong to domains and has no any attributes, and, can be ++ * shared by the entire device. ++ */ ++ sh->dr_drop_action = mlx5_glue->dr_create_flow_action_drop(); ++ if (!sh->dr_drop_action) { ++ DRV_LOG(ERR, "FDB mlx5dv_dr_create_flow_action_drop"); ++ err = errno; ++ goto error; + } #endif sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan(); #endif /* HAVE_MLX5DV_DR */ @@ -50115,7 +70981,20 @@ index d84a6f91b4..f8de9e329e 100644 return 0; error: /* Rollback the created objects. */ -@@ -965,17 +1044,12 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) +@@ -939,9 +1069,9 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) + mlx5_glue->dr_destroy_domain(sh->fdb_domain); + sh->fdb_domain = NULL; + } +- if (sh->esw_drop_action) { +- mlx5_glue->destroy_flow_action(sh->esw_drop_action); +- sh->esw_drop_action = NULL; ++ if (sh->dr_drop_action) { ++ mlx5_glue->destroy_flow_action(sh->dr_drop_action); ++ sh->dr_drop_action = NULL; + } + if (sh->pop_vlan_action) { + mlx5_glue->destroy_flow_action(sh->pop_vlan_action); +@@ -965,17 +1095,12 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv) static void mlx5_free_shared_dr(struct mlx5_priv *priv) { @@ -50136,7 +71015,27 @@ index d84a6f91b4..f8de9e329e 100644 if (sh->rx_domain) { mlx5_glue->dr_destroy_domain(sh->rx_domain); sh->rx_domain = NULL; -@@ -1177,13 +1251,13 @@ mlx5_proc_priv_init(struct rte_eth_dev *dev) +@@ -989,9 +1114,9 @@ mlx5_free_shared_dr(struct mlx5_priv *priv) + mlx5_glue->dr_destroy_domain(sh->fdb_domain); + sh->fdb_domain = NULL; + } +- if (sh->esw_drop_action) { +- mlx5_glue->destroy_flow_action(sh->esw_drop_action); +- sh->esw_drop_action = NULL; ++ if (sh->dr_drop_action) { ++ mlx5_glue->destroy_flow_action(sh->dr_drop_action); ++ sh->dr_drop_action = NULL; + } + #endif + if (sh->pop_vlan_action) { +@@ -1171,19 +1296,20 @@ mlx5_proc_priv_init(struct rte_eth_dev *dev) + struct mlx5_proc_priv *ppriv; + size_t ppriv_size; + ++ mlx5_proc_priv_uninit(dev); + /* + * UAR register table follows the process private structure. BlueFlame + * registers for Tx queues are stored in the table. */ ppriv_size = sizeof(struct mlx5_proc_priv) + priv->txqs_n * sizeof(void *); @@ -50152,7 +71051,7 @@ index d84a6f91b4..f8de9e329e 100644 dev->process_private = ppriv; return 0; } -@@ -1194,7 +1268,7 @@ mlx5_proc_priv_init(struct rte_eth_dev *dev) +@@ -1194,7 +1320,7 @@ mlx5_proc_priv_init(struct rte_eth_dev *dev) * @param dev * Pointer to Ethernet device structure. */ @@ -50161,7 +71060,7 @@ index d84a6f91b4..f8de9e329e 100644 mlx5_proc_priv_uninit(struct rte_eth_dev *dev) { if (!dev->process_private) -@@ -1218,12 +1292,20 @@ mlx5_dev_close(struct rte_eth_dev *dev) +@@ -1218,12 +1344,20 @@ mlx5_dev_close(struct rte_eth_dev *dev) unsigned int i; int ret; @@ -50185,7 +71084,19 @@ index d84a6f91b4..f8de9e329e 100644 mlx5_traffic_disable(dev); mlx5_flow_flush(dev, NULL); mlx5_flow_meter_flush(dev, NULL); -@@ -1266,16 +1348,13 @@ mlx5_dev_close(struct rte_eth_dev *dev) +@@ -1241,6 +1375,11 @@ mlx5_dev_close(struct rte_eth_dev *dev) + priv->rxqs_n = 0; + priv->rxqs = NULL; + } ++ if (priv->representor) { ++ /* Each representor has a dedicated interrupts handler */ ++ rte_free(dev->intr_handle); ++ dev->intr_handle = NULL; ++ } + if (priv->txqs != NULL) { + /* XXX race condition if mlx5_tx_burst() is still running. */ + usleep(1000); +@@ -1266,16 +1405,13 @@ mlx5_dev_close(struct rte_eth_dev *dev) close(priv->nl_socket_rdma); if (priv->vmwa_context) mlx5_vlan_vmwa_exit(priv->vmwa_context); @@ -50209,16 +71120,18 @@ index d84a6f91b4..f8de9e329e 100644 ret = mlx5_hrxq_verify(dev); if (ret) DRV_LOG(WARNING, "port %u some hash Rx queue still remain", -@@ -1490,6 +1569,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque) +@@ -1489,7 +1625,9 @@ mlx5_args_check(const char *key, const char *val, void *opaque) + } else if (strcmp(MLX5_RX_MPRQ_EN, key) == 0) { config->mprq.enabled = !!tmp; } else if (strcmp(MLX5_RX_MPRQ_LOG_STRIDE_NUM, key) == 0) { - config->mprq.stride_num_n = tmp; +- config->mprq.stride_num_n = tmp; ++ config->mprq.log_stride_num = tmp; + } else if (strcmp(MLX5_RX_MPRQ_LOG_STRIDE_SIZE, key) == 0) { -+ config->mprq.stride_size_n = tmp; ++ config->mprq.log_stride_size = tmp; } else if (strcmp(MLX5_RX_MPRQ_MAX_MEMCPY_LEN, key) == 0) { config->mprq.max_memcpy_len = tmp; } else if (strcmp(MLX5_RXQS_MIN_MPRQ, key) == 0) { -@@ -1582,6 +1663,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs) +@@ -1582,6 +1720,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs) MLX5_RXQ_PKT_PAD_EN, MLX5_RX_MPRQ_EN, MLX5_RX_MPRQ_LOG_STRIDE_NUM, @@ -50226,7 +71139,7 @@ index d84a6f91b4..f8de9e329e 100644 MLX5_RX_MPRQ_MAX_MEMCPY_LEN, MLX5_RXQS_MIN_MPRQ, MLX5_TXQ_INLINE, -@@ -1697,7 +1779,7 @@ mlx5_init_once(void) +@@ -1697,7 +1836,7 @@ mlx5_init_once(void) * key is specified in devargs * - if DevX is enabled the inline mode is queried from the * device (HCA attributes and NIC vport context if needed). @@ -50235,7 +71148,7 @@ index d84a6f91b4..f8de9e329e 100644 * and none (0 bytes) for other NICs * * @param spawn -@@ -1931,12 +2013,12 @@ mlx5_get_dbr(struct rte_eth_dev *dev, struct mlx5_devx_dbr_page **dbr_page) +@@ -1931,12 +2070,12 @@ mlx5_get_dbr(struct rte_eth_dev *dev, struct mlx5_devx_dbr_page **dbr_page) i++) ; /* Empty. */ /* Find the first clear bit. */ @@ -50251,7 +71164,7 @@ index d84a6f91b4..f8de9e329e 100644 } /** -@@ -1978,7 +2060,7 @@ mlx5_release_dbr(struct rte_eth_dev *dev, uint32_t umem_id, uint64_t offset) +@@ -1978,7 +2117,7 @@ mlx5_release_dbr(struct rte_eth_dev *dev, uint32_t umem_id, uint64_t offset) int i = offset / 64; int j = offset % 64; @@ -50260,7 +71173,61 @@ index d84a6f91b4..f8de9e329e 100644 } return ret; } -@@ -2145,11 +2227,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +@@ -2036,6 +2175,33 @@ mlx5_dev_check_sibling_config(struct mlx5_priv *priv, + } + return 0; + } ++ ++/** ++ * DR flow drop action support detect. ++ * ++ * @param dev ++ * Pointer to rte_eth_dev structure. ++ * ++ */ ++static void ++mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused) ++{ ++#ifdef HAVE_MLX5DV_DR ++ struct mlx5_priv *priv = dev->data->dev_private; ++ ++ if (!priv->config.dv_flow_en || !priv->sh->dr_drop_action) ++ return; ++ /** ++ * DR supports drop action placeholder when it is supported; ++ * otherwise, use the queue drop action. ++ */ ++ if (mlx5_flow_discover_dr_action_support(dev)) ++ priv->root_verbs_drop_action = 1; ++ else ++ priv->root_verbs_drop_action = 0; ++#endif ++} ++ + /** + * Spawn an Ethernet device from Verbs information. + * +@@ -2073,18 +2239,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + unsigned int mpls_en = 0; + unsigned int swp = 0; + unsigned int mprq = 0; +- unsigned int mprq_min_stride_size_n = 0; +- unsigned int mprq_max_stride_size_n = 0; +- unsigned int mprq_min_stride_num_n = 0; +- unsigned int mprq_max_stride_num_n = 0; + struct rte_ether_addr mac; + char name[RTE_ETH_NAME_MAX_LEN]; + int own_domain_id = 0; + uint16_t port_id; + unsigned int i; +-#ifdef HAVE_MLX5DV_DR_DEVX_PORT +- struct mlx5dv_devx_port devx_port = { .comp_mask = 0 }; +-#endif ++ struct mlx5_port_info vport_info = { .query_flags = 0 }; + + /* Determine if this port representor is supposed to be spawned. */ + if (switch_info->representor && dpdk_dev->devargs) { +@@ -2145,11 +2305,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, /* Receive command fd from primary process */ err = mlx5_mp_req_verbs_cmd_fd(eth_dev); if (err < 0) @@ -50274,7 +71241,7 @@ index d84a6f91b4..f8de9e329e 100644 /* * Ethdev pointer is still required as input since * the primary device is not accessible from the -@@ -2158,6 +2240,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +@@ -2158,6 +2318,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, eth_dev->rx_pkt_burst = mlx5_select_rx_function(eth_dev); eth_dev->tx_pkt_burst = mlx5_select_tx_function(eth_dev); return eth_dev; @@ -50284,16 +71251,28 @@ index d84a6f91b4..f8de9e329e 100644 } /* * Some parameters ("tx_db_nc" in particularly) are needed in -@@ -2236,8 +2321,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +@@ -2228,16 +2391,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + mprq_caps.supported_qpts); + DRV_LOG(DEBUG, "device supports Multi-Packet RQ"); + mprq = 1; +- mprq_min_stride_size_n = ++ config.mprq.log_min_stride_size = + mprq_caps.min_single_stride_log_num_of_bytes; +- mprq_max_stride_size_n = ++ config.mprq.log_max_stride_size = + mprq_caps.max_single_stride_log_num_of_bytes; +- mprq_min_stride_num_n = ++ config.mprq.log_min_stride_num = mprq_caps.min_single_wqe_log_num_of_strides; - mprq_max_stride_num_n = +- mprq_max_stride_num_n = ++ config.mprq.log_max_stride_num = mprq_caps.max_single_wqe_log_num_of_strides; - config.mprq.stride_num_n = RTE_MAX(MLX5_MPRQ_STRIDE_NUM_N, - mprq_min_stride_num_n); } #endif if (RTE_CACHE_LINE_SIZE == 128 && -@@ -2307,12 +2390,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +@@ -2307,15 +2468,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->ibv_port = spawn->ibv_port; priv->pci_dev = spawn->pci_dev; priv->mtu = RTE_ETHER_MTU; @@ -50304,9 +71283,123 @@ index d84a6f91b4..f8de9e329e 100644 - rte_spinlock_init(&priv->uar_lock[i]); -#endif /* Some internal functions rely on Netlink sockets, open them now. */ - priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA); - priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE); -@@ -2543,6 +2620,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +- priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA); +- priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE); ++ priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA, 0); ++ priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE, 0); + priv->nl_sn = 0; + priv->representor = !!switch_info->representor; + priv->master = !!switch_info->master; +@@ -2323,28 +2478,26 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + priv->vport_meta_tag = 0; + priv->vport_meta_mask = 0; + priv->pf_bond = spawn->pf_bond; +-#ifdef HAVE_MLX5DV_DR_DEVX_PORT + /* +- * The DevX port query API is implemented. E-Switch may use +- * either vport or reg_c[0] metadata register to match on +- * vport index. The engaged part of metadata register is +- * defined by mask. ++ * If we have E-Switch we should determine the vport attributes. ++ * E-Switch may use either source vport field or reg_c[0] metadata ++ * register to match on vport index. The engaged part of metadata ++ * register is defined by mask. + */ + if (switch_info->representor || switch_info->master) { +- devx_port.comp_mask = MLX5DV_DEVX_PORT_VPORT | +- MLX5DV_DEVX_PORT_MATCH_REG_C_0; +- err = mlx5_glue->devx_port_query(sh->ctx, spawn->ibv_port, +- &devx_port); ++ err = mlx5_glue->devx_port_query(sh->ctx, ++ spawn->ibv_port, ++ &vport_info); + if (err) { + DRV_LOG(WARNING, + "can't query devx port %d on device %s", + spawn->ibv_port, spawn->ibv_dev->name); +- devx_port.comp_mask = 0; ++ vport_info.query_flags = 0; + } + } +- if (devx_port.comp_mask & MLX5DV_DEVX_PORT_MATCH_REG_C_0) { +- priv->vport_meta_tag = devx_port.reg_c_0.value; +- priv->vport_meta_mask = devx_port.reg_c_0.mask; ++ if (vport_info.query_flags & MLX5_PORT_QUERY_REG_C0) { ++ priv->vport_meta_tag = vport_info.vport_meta_tag; ++ priv->vport_meta_mask = vport_info.vport_meta_mask; + if (!priv->vport_meta_mask) { + DRV_LOG(ERR, "vport zero mask for port %d" + " on bonding device %s", +@@ -2360,34 +2513,31 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + goto error; + } + } +- if (devx_port.comp_mask & MLX5DV_DEVX_PORT_VPORT) { +- priv->vport_id = devx_port.vport_num; +- } else if (spawn->pf_bond >= 0) { ++ if (vport_info.query_flags & MLX5_PORT_QUERY_VPORT) { ++ priv->vport_id = vport_info.vport_id; ++ } else if (spawn->pf_bond >= 0 && ++ (switch_info->representor || switch_info->master)) { + DRV_LOG(ERR, "can't deduce vport index for port %d" + " on bonding device %s", + spawn->ibv_port, spawn->ibv_dev->name); + err = ENOTSUP; + goto error; + } else { +- /* Suppose vport index in compatible way. */ ++ /* ++ * Suppose vport index in compatible way. Kernel/rdma_core ++ * support single E-Switch per PF configurations only and ++ * vport_id field contains the vport index for associated VF, ++ * which is deduced from representor port name. ++ * For example, let's have the IB device port 10, it has ++ * attached network device eth0, which has port name attribute ++ * pf0vf2, we can deduce the VF number as 2, and set vport index ++ * as 3 (2+1). This assigning schema should be changed if the ++ * multiple E-Switch instances per PF configurations or/and PCI ++ * subfunctions are added. ++ */ + priv->vport_id = switch_info->representor ? + switch_info->port_name + 1 : -1; + } +-#else +- /* +- * Kernel/rdma_core support single E-Switch per PF configurations +- * only and vport_id field contains the vport index for +- * associated VF, which is deduced from representor port name. +- * For example, let's have the IB device port 10, it has +- * attached network device eth0, which has port name attribute +- * pf0vf2, we can deduce the VF number as 2, and set vport index +- * as 3 (2+1). This assigning schema should be changed if the +- * multiple E-Switch instances per PF configurations or/and PCI +- * subfunctions are added. +- */ +- priv->vport_id = switch_info->representor ? +- switch_info->port_name + 1 : -1; +-#endif + /* representor_id field keeps the unmodified VF index. */ + priv->representor_id = switch_info->representor ? + switch_info->port_name : -1; +@@ -2494,6 +2644,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + } else if (config.cqe_pad) { + DRV_LOG(INFO, "Rx CQE padding is enabled"); + } ++ config.mprq.log_min_stride_wqe_size = MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE; ++ config.mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM; + if (config.devx) { + priv->counter_fallback = 0; + err = mlx5_devx_cmd_query_hca_attr(sh->ctx, &config.hca_attr); +@@ -2501,6 +2653,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + err = -err; + goto error; + } ++ config.mprq.log_min_stride_wqe_size = ++ config.hca_attr.log_min_stride_wqe_sz; + if (!config.hca_attr.flow_counters_dump) + priv->counter_fallback = 1; + #ifndef HAVE_IBV_DEVX_ASYNC +@@ -2543,27 +2697,15 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->mtr_color_reg = ffs(reg_c_mask) - 1 + REG_C_0; priv->mtr_en = 1; @@ -50315,44 +71408,48 @@ index d84a6f91b4..f8de9e329e 100644 DRV_LOG(DEBUG, "The REG_C meter uses is %d", priv->mtr_color_reg); } -@@ -2550,17 +2629,32 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + } #endif } - if (config.mprq.enabled && mprq) { +- if (config.mprq.enabled && mprq) { - if (config.mprq.stride_num_n > mprq_max_stride_num_n || - config.mprq.stride_num_n < mprq_min_stride_num_n) { -+ if (config.mprq.stride_num_n && -+ (config.mprq.stride_num_n > mprq_max_stride_num_n || -+ config.mprq.stride_num_n < mprq_min_stride_num_n)) { - config.mprq.stride_num_n = +- config.mprq.stride_num_n = - RTE_MAX(MLX5_MPRQ_STRIDE_NUM_N, - mprq_min_stride_num_n); -+ RTE_MIN(RTE_MAX(MLX5_MPRQ_STRIDE_NUM_N, -+ mprq_min_stride_num_n), -+ mprq_max_stride_num_n); - DRV_LOG(WARNING, - "the number of strides" - " for Multi-Packet RQ is out of range," - " setting default value (%u)", - 1 << config.mprq.stride_num_n); - } -+ if (config.mprq.stride_size_n && -+ (config.mprq.stride_size_n > mprq_max_stride_size_n || -+ config.mprq.stride_size_n < mprq_min_stride_size_n)) { -+ config.mprq.stride_size_n = -+ RTE_MIN(RTE_MAX(MLX5_MPRQ_STRIDE_SIZE_N, -+ mprq_min_stride_size_n), -+ mprq_max_stride_size_n); -+ DRV_LOG(WARNING, -+ "the size of a stride" -+ " for Multi-Packet RQ is out of range," -+ " setting default value (%u)", -+ 1 << config.mprq.stride_size_n); -+ } - config.mprq.min_stride_size_n = mprq_min_stride_size_n; - config.mprq.max_stride_size_n = mprq_max_stride_size_n; - } else if (config.mprq.enabled && !mprq) { -@@ -2675,7 +2769,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, +- DRV_LOG(WARNING, +- "the number of strides" +- " for Multi-Packet RQ is out of range," +- " setting default value (%u)", +- 1 << config.mprq.stride_num_n); +- } +- config.mprq.min_stride_size_n = mprq_min_stride_size_n; +- config.mprq.max_stride_size_n = mprq_max_stride_size_n; +- } else if (config.mprq.enabled && !mprq) { ++ if (config.mprq.enabled && !mprq) { + DRV_LOG(WARNING, "Multi-Packet RQ isn't supported"); + config.mprq.enabled = 0; + } +@@ -2651,13 +2793,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + /* Bring Ethernet device up. */ + DRV_LOG(DEBUG, "port %u forcing Ethernet interface up", + eth_dev->data->port_id); +- mlx5_set_link_up(eth_dev); +- /* +- * Even though the interrupt handler is not installed yet, +- * interrupts will still trigger on the async_fd from +- * Verbs context returned by ibv_open_device(). +- */ ++ /* Read link status in case it is up and there will be no event. */ + mlx5_link_update(eth_dev, 0); ++ /* Watch LSC interrupts between port probe and port start. */ ++ priv->sh->port[priv->ibv_port - 1].nl_ih_port_id = ++ eth_dev->data->port_id; ++ mlx5_set_link_up(eth_dev); + #ifdef HAVE_MLX5DV_DR_ESWITCH + if (!(config.hca_attr.eswitch_manager && config.dv_flow_en && + (switch_info->representor || switch_info->master))) +@@ -2675,7 +2816,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, err = mlx5_alloc_shared_dr(priv); if (err) goto error; @@ -50366,7 +71463,46 @@ index d84a6f91b4..f8de9e329e 100644 if (!priv->qrss_id_pool) { DRV_LOG(ERR, "can't create flow id pool"); err = ENOMEM; -@@ -3074,7 +3173,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +@@ -2733,6 +2879,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, + goto error; + } + } ++ mlx5_flow_drop_action_config(eth_dev); + return eth_dev; + error: + if (priv) { +@@ -2968,8 +3115,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + * matching ones, gathering into the list. + */ + struct ibv_device *ibv_match[ret + 1]; +- int nl_route = mlx5_nl_init(NETLINK_ROUTE); +- int nl_rdma = mlx5_nl_init(NETLINK_RDMA); ++ int nl_route = mlx5_nl_init(NETLINK_ROUTE, 0); ++ int nl_rdma = mlx5_nl_init(NETLINK_RDMA, 0); + unsigned int i; + + while (ret-- > 0) { +@@ -3043,19 +3190,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + goto exit; + } + } +-#ifndef HAVE_MLX5DV_DR_DEVX_PORT +- if (bd >= 0) { +- /* +- * This may happen if there is VF LAG kernel support and +- * application is compiled with older rdma_core library. +- */ +- DRV_LOG(ERR, +- "No kernel/verbs support for VF LAG bonding found."); +- rte_errno = ENOTSUP; +- ret = -rte_errno; +- goto exit; +- } +-#endif + /* + * Now we can determine the maximal + * amount of devices to be spawned. +@@ -3074,7 +3208,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, /* * Single IB device with multiple ports found, * it may be E-Switch master device and representors. @@ -50375,17 +71511,52 @@ index d84a6f91b4..f8de9e329e 100644 */ assert(nl_rdma >= 0); assert(ns == 0); -@@ -3274,7 +3373,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +@@ -3119,6 +3253,15 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + if (!ret && bd >= 0) { + switch (list[ns].info.name_type) { + case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: ++ if (np == 1) { ++ /* ++ * Force standalone bonding ++ * device for ROCE LAG ++ * confgiurations. ++ */ ++ list[ns].info.master = 0; ++ list[ns].info.representor = 0; ++ } + if (list[ns].info.port_name == bd) + ns++; + break; +@@ -3253,6 +3396,18 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + ret = -rte_errno; + goto exit; + } ++ /* ++ * New kernels may add the switch_id attribute for the case ++ * there is no E-Switch and we wrongly recognized the ++ * only device as master. Override this if there is the ++ * single device with single port and new device name ++ * format present. ++ */ ++ if (nd == 1 && ++ list[0].info.name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) { ++ list[0].info.master = 0; ++ list[0].info.representor = 0; ++ } + } + assert(ns); + /* +@@ -3274,7 +3429,8 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, .mr_ext_memseg_en = 1, .mprq = { .enabled = 0, /* Disabled by default. */ - .stride_num_n = MLX5_MPRQ_STRIDE_NUM_N, -+ .stride_num_n = 0, -+ .stride_size_n = 0, ++ .log_stride_num = 0, ++ .log_stride_size = 0, .max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN, .min_rxqs_num = MLX5_MPRQ_MIN_RXQS, }, -@@ -3289,7 +3389,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +@@ -3289,7 +3445,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF: case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF: case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF: @@ -50394,15 +71565,42 @@ index d84a6f91b4..f8de9e329e 100644 dev_config.vf = 1; break; default: -@@ -3311,7 +3411,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, +@@ -3309,9 +3465,33 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + } + restore = list[i].eth_dev->data->dev_flags; rte_eth_copy_pci_info(list[i].eth_dev, pci_dev); ++ /** ++ * Each representor has a dedicated interrupts vector. ++ * rte_eth_copy_pci_info() assigns PF interrupts handle to ++ * representor eth_dev object because representor and PF ++ * share the same PCI address. ++ * Override representor device with a dedicated ++ * interrupts handle here. ++ * Representor interrupts handle is released in ++ * mlx5_dev_stop(). ++ */ ++ if (list[i].info.representor) { ++ struct rte_intr_handle *intr_handle; ++ intr_handle = rte_zmalloc("representor interrupts", ++ sizeof(*intr_handle), 0); ++ if (!intr_handle) { ++ DRV_LOG(ERR, ++ "port %u failed to allocate memory for interrupt handler " ++ "Rx interrupts will not be supported", ++ i); ++ rte_errno = ENOMEM; ++ ret = -rte_errno; ++ goto exit; ++ } ++ list[i].eth_dev->intr_handle = intr_handle; ++ } /* Restore non-PCI flags cleared by the above call. */ list[i].eth_dev->data->dev_flags |= restore; - mlx5_dev_interrupt_handler_devx_install(list[i].eth_dev); rte_eth_dev_probing_finish(list[i].eth_dev); } if (i != ns) { -@@ -3405,8 +3504,16 @@ mlx5_pci_remove(struct rte_pci_device *pci_dev) +@@ -3405,8 +3585,16 @@ mlx5_pci_remove(struct rte_pci_device *pci_dev) { uint16_t port_id; @@ -50421,7 +71619,7 @@ index d84a6f91b4..f8de9e329e 100644 return 0; } -@@ -3465,7 +3572,7 @@ static const struct rte_pci_id mlx5_pci_id_map[] = { +@@ -3465,7 +3653,7 @@ static const struct rte_pci_id mlx5_pci_id_map[] = { }, { RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, @@ -50431,10 +71629,18 @@ index d84a6f91b4..f8de9e329e 100644 { .vendor_id = 0 diff --git a/dpdk/drivers/net/mlx5/mlx5.h b/dpdk/drivers/net/mlx5/mlx5.h -index 0c3a90e1bf..0e4a5f870d 100644 +index 0c3a90e1bf..bb1e291716 100644 --- a/dpdk/drivers/net/mlx5/mlx5.h +++ b/dpdk/drivers/net/mlx5/mlx5.h -@@ -57,7 +57,7 @@ enum { +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + + /* Verbs header. */ +@@ -57,7 +58,7 @@ enum { PCI_DEVICE_ID_MELLANOX_CONNECTX6 = 0x101b, PCI_DEVICE_ID_MELLANOX_CONNECTX6VF = 0x101c, PCI_DEVICE_ID_MELLANOX_CONNECTX6DX = 0x101d, @@ -50443,7 +71649,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 }; /* Request types for IPC. */ -@@ -148,12 +148,15 @@ struct mlx5_xstats_ctrl { +@@ -148,12 +149,15 @@ struct mlx5_xstats_ctrl { /* Index in the device counters table. */ uint16_t dev_table_idx[MLX5_MAX_XSTATS]; uint64_t base[MLX5_MAX_XSTATS]; @@ -50459,7 +71665,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 }; /* devX creation object */ -@@ -173,6 +176,8 @@ struct mlx5_devx_mkey_attr { +@@ -173,6 +177,8 @@ struct mlx5_devx_mkey_attr { struct mlx5_hca_qos_attr { uint32_t sup:1; /* Whether QOS is supported. */ uint32_t srtcm_sup:1; /* Whether srTCM mode is supported. */ @@ -50468,15 +71674,33 @@ index 0c3a90e1bf..0e4a5f870d 100644 uint8_t log_max_flow_meter; /* Power of the maximum supported meters. */ uint8_t flow_meter_reg_c_ids; -@@ -262,6 +267,7 @@ struct mlx5_dev_config { +@@ -187,6 +193,7 @@ struct mlx5_hca_qos_attr { + struct mlx5_hca_attr { + uint32_t eswitch_manager:1; + uint32_t flow_counters_dump:1; ++ uint32_t log_min_stride_wqe_sz:5; + uint8_t flow_counter_bulk_alloc_bitmap; + uint32_t eth_net_offloads:1; + uint32_t eth_virt:1; +@@ -261,9 +268,14 @@ struct mlx5_dev_config { + unsigned int dest_tir:1; /* Whether advanced DR API is available. */ struct { unsigned int enabled:1; /* Whether MPRQ is enabled. */ - unsigned int stride_num_n; /* Number of strides. */ -+ unsigned int stride_size_n; /* Size of a stride. */ - unsigned int min_stride_size_n; /* Min size of a stride. */ - unsigned int max_stride_size_n; /* Max size of a stride. */ +- unsigned int stride_num_n; /* Number of strides. */ +- unsigned int min_stride_size_n; /* Min size of a stride. */ +- unsigned int max_stride_size_n; /* Max size of a stride. */ ++ unsigned int log_stride_num; /* Log number of strides. */ ++ unsigned int log_stride_size; /* Log size of a stride. */ ++ unsigned int log_min_stride_size; /* Log min size of a stride.*/ ++ unsigned int log_max_stride_size; /* Log max size of a stride.*/ ++ unsigned int log_min_stride_num; /* Log min num of strides. */ ++ unsigned int log_max_stride_num; /* Log max num of strides. */ ++ unsigned int log_min_stride_wqe_size; ++ /* Log min WQE size, (size of single stride)*(num of strides).*/ unsigned int max_memcpy_len; -@@ -364,7 +370,7 @@ struct mlx5_devx_tir_attr { + /* Maximum packet size to memcpy Rx packets. */ + unsigned int min_rxqs_num; +@@ -364,7 +376,7 @@ struct mlx5_devx_tir_attr { uint32_t rx_hash_fn:4; uint32_t self_lb_block:2; uint32_t transport_domain:24; @@ -50485,7 +71709,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 struct mlx5_rx_hash_field_select rx_hash_field_selector_outer; struct mlx5_rx_hash_field_select rx_hash_field_selector_inner; }; -@@ -480,7 +486,8 @@ struct mlx5_flow_counter { +@@ -480,7 +492,8 @@ struct mlx5_flow_counter { uint32_t shared:1; /**< Share counter ID with other flow rules. */ uint32_t batch: 1; /**< Whether the counter was allocated by batch command. */ @@ -50495,7 +71719,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 uint32_t id; /**< Counter ID. */ union { /**< Holds the counters for the rule. */ #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) -@@ -512,6 +519,7 @@ struct mlx5_flow_counter_pool { +@@ -512,6 +525,7 @@ struct mlx5_flow_counter_pool { /* The devx object of the minimum counter ID. */ rte_atomic64_t query_gen; uint32_t n_counters: 16; /* Number of devx allocated counters. */ @@ -50503,7 +71727,15 @@ index 0c3a90e1bf..0e4a5f870d 100644 rte_spinlock_t sl; /* The pool lock. */ struct mlx5_counter_stats_raw *raw; struct mlx5_counter_stats_raw *raw_hw; /* The raw on HW working. */ -@@ -594,20 +602,22 @@ struct mlx5_flow_tbl_resource { +@@ -566,6 +580,7 @@ struct mlx5_flow_counter_mng { + struct mlx5_ibv_shared_port { + uint32_t ih_port_id; + uint32_t devx_ih_port_id; ++ uint32_t nl_ih_port_id; + /* + * Interrupt handler port_id. Used by shared interrupt + * handler to find the corresponding rte_eth device +@@ -594,20 +609,22 @@ struct mlx5_flow_tbl_resource { }; #define MLX5_MAX_TABLES UINT16_MAX @@ -50533,7 +71765,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 struct mlx5_devx_dbr_page { /* Door-bell records, must be first member in structure. */ -@@ -626,6 +636,7 @@ struct mlx5_flow_id_pool { +@@ -626,6 +643,7 @@ struct mlx5_flow_id_pool { /**< The next index that can be used without any free elements. */ uint32_t *curr; /**< Pointer to the index to pop. */ uint32_t *last; /**< Pointer to the last element in the empty arrray. */ @@ -50541,7 +71773,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 }; /* -@@ -658,16 +669,14 @@ struct mlx5_ibv_shared { +@@ -658,19 +676,17 @@ struct mlx5_ibv_shared { uint32_t dv_meta_mask; /* flow META metadata supported mask. */ uint32_t dv_mark_mask; /* flow MARK metadata supported mask. */ uint32_t dv_regc0_mask; /* available bits of metatada reg_c[0]. */ @@ -50562,8 +71794,12 @@ index 0c3a90e1bf..0e4a5f870d 100644 +#endif struct mlx5_hlist *flow_tbls; /* Direct Rules tables for FDB, NIC TX+RX */ - void *esw_drop_action; /* Pointer to DR E-Switch drop action. */ -@@ -681,10 +690,7 @@ struct mlx5_ibv_shared { +- void *esw_drop_action; /* Pointer to DR E-Switch drop action. */ ++ void *dr_drop_action; /* Pointer to DR drop action, any domain. */ + void *pop_vlan_action; /* Pointer to DR pop VLAN action. */ + LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps; + LIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds; +@@ -681,11 +697,9 @@ struct mlx5_ibv_shared { push_vlan_action_list; /* List of push VLAN actions. */ struct mlx5_flow_counter_mng cmng; /* Counters management structure. */ /* Shared interrupt handler section. */ @@ -50572,9 +71808,11 @@ index 0c3a90e1bf..0e4a5f870d 100644 struct rte_intr_handle intr_handle; /* Interrupt handler for device. */ - uint32_t devx_intr_cnt; /* Devx interrupt handler reference counter. */ struct rte_intr_handle intr_handle_devx; /* DEVX interrupt handler. */ ++ struct rte_intr_handle intr_handle_nl; /* Netlink interrupt handler. */ struct mlx5dv_devx_cmd_comp *devx_comp; /* DEVX async comp obj. */ struct mlx5_devx_obj *tis; /* TIS object. */ -@@ -693,7 +699,10 @@ struct mlx5_ibv_shared { + struct mlx5_devx_obj *td; /* Transport domain. */ +@@ -693,7 +707,10 @@ struct mlx5_ibv_shared { struct mlx5_ibv_shared_port port[]; /* per device port data array. */ }; @@ -50586,7 +71824,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 struct mlx5_proc_priv { size_t uar_table_sz; /* Size of UAR register table. */ -@@ -724,9 +733,9 @@ struct mlx5_priv { +@@ -724,9 +741,11 @@ struct mlx5_priv { unsigned int isolated:1; /* Whether isolated mode is enabled. */ unsigned int representor:1; /* Device is a port representor. */ unsigned int master:1; /* Device is a E-Switch master. */ @@ -50594,10 +71832,12 @@ index 0c3a90e1bf..0e4a5f870d 100644 unsigned int counter_fallback:1; /* Use counter fallback management. */ unsigned int mtr_en:1; /* Whether support meter. */ + unsigned int mtr_reg_share:1; /* Whether support meter REG_C share. */ ++ uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */ ++ unsigned int root_verbs_drop_action; /* Root uses verbs drop action. */ uint16_t domain_id; /* Switch domain identifier. */ uint16_t vport_id; /* Associated VF vport index (if any). */ uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */ -@@ -778,12 +787,8 @@ struct mlx5_priv { +@@ -778,12 +797,8 @@ struct mlx5_priv { uint8_t mtr_color_reg; /* Meter color match REG_C. */ struct mlx5_mtr_profiles flow_meter_profiles; /* MTR profile list. */ struct mlx5_flow_meters flow_meters; /* MTR list. */ @@ -50611,7 +71851,7 @@ index 0c3a90e1bf..0e4a5f870d 100644 }; #define PORT_ID(priv) ((priv)->dev_data->port_id) -@@ -797,6 +802,7 @@ int64_t mlx5_get_dbr(struct rte_eth_dev *dev, +@@ -797,6 +812,7 @@ int64_t mlx5_get_dbr(struct rte_eth_dev *dev, struct mlx5_devx_dbr_page **dbr_page); int32_t mlx5_release_dbr(struct rte_eth_dev *dev, uint32_t umem_id, uint64_t offset); @@ -50619,8 +71859,11 @@ index 0c3a90e1bf..0e4a5f870d 100644 int mlx5_udp_tunnel_port_add(struct rte_eth_dev *dev, struct rte_eth_udp_tunnel *udp_tunnel); uint16_t mlx5_eth_find_next(uint16_t port_id, struct rte_pci_device *pci_dev); -@@ -835,8 +841,6 @@ void mlx5_dev_interrupt_handler(void *arg); +@@ -833,10 +849,9 @@ int mlx5_dev_to_pci_addr(const char *dev_path, + void mlx5_dev_link_status_handler(void *arg); + void mlx5_dev_interrupt_handler(void *arg); void mlx5_dev_interrupt_handler_devx(void *arg); ++void mlx5_dev_interrupt_handler_nl(void *arg); void mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev); void mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev); -void mlx5_dev_interrupt_handler_devx_uninstall(struct rte_eth_dev *dev); @@ -50628,7 +71871,16 @@ index 0c3a90e1bf..0e4a5f870d 100644 int mlx5_set_link_down(struct rte_eth_dev *dev); int mlx5_set_link_up(struct rte_eth_dev *dev); int mlx5_is_removed(struct rte_eth_dev *dev); -@@ -972,6 +976,7 @@ struct mlx5_flow_counter *mlx5_counter_alloc(struct rte_eth_dev *dev); +@@ -962,8 +977,6 @@ int mlx5_ctrl_flow(struct rte_eth_dev *dev, + struct rte_flow_item_eth *eth_spec, + struct rte_flow_item_eth *eth_mask); + struct rte_flow *mlx5_flow_create_esw_table_zero_flow(struct rte_eth_dev *dev); +-int mlx5_flow_create_drop_queue(struct rte_eth_dev *dev); +-void mlx5_flow_delete_drop_queue(struct rte_eth_dev *dev); + void mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, + uint64_t async_id, int status); + void mlx5_set_query_alarm(struct mlx5_ibv_shared *sh); +@@ -972,6 +985,7 @@ struct mlx5_flow_counter *mlx5_counter_alloc(struct rte_eth_dev *dev); void mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt); int mlx5_counter_query(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt, bool clear, uint64_t *pkts, uint64_t *bytes); @@ -50636,8 +71888,28 @@ index 0c3a90e1bf..0e4a5f870d 100644 /* mlx5_mp.c */ void mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev); +@@ -987,7 +1001,9 @@ void mlx5_mp_uninit_secondary(void); + + /* mlx5_nl.c */ + +-int mlx5_nl_init(int protocol); ++typedef void (mlx5_nl_event_cb)(struct nlmsghdr *hdr, void *user_data); ++ ++int mlx5_nl_init(int protocol, int groups); + int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, + uint32_t index); + int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac, +@@ -1002,6 +1018,8 @@ int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev, + struct rte_ether_addr *mac, int vf_index); + int mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info); ++int mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg); ++int mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex); + + struct mlx5_vlan_vmwa_context *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, + uint32_t ifindex); diff --git a/dpdk/drivers/net/mlx5/mlx5_defs.h b/dpdk/drivers/net/mlx5/mlx5_defs.h -index 042e1f31ee..2836099b75 100644 +index 042e1f31ee..52fb62f93c 100644 --- a/dpdk/drivers/net/mlx5/mlx5_defs.h +++ b/dpdk/drivers/net/mlx5/mlx5_defs.h @@ -61,7 +61,7 @@ @@ -50649,16 +71921,27 @@ index 042e1f31ee..2836099b75 100644 /* Alarm timeout. */ #define MLX5_ALARM_TIMEOUT_US 100000 -@@ -146,6 +146,9 @@ - /* Log 2 of the default number of strides per WQE for Multi-Packet RQ. */ - #define MLX5_MPRQ_STRIDE_NUM_N 6U +@@ -70,7 +70,7 @@ + #define MLX5_MAX_XSTATS 32 -+/* Log 2 of the default size of a stride per WQE for Multi-Packet RQ. */ -+#define MLX5_MPRQ_STRIDE_SIZE_N 11U + /* Maximum Packet headers size (L2+L3+L4) for TSO. */ +-#define MLX5_MAX_TSO_HEADER (128u + 34u) ++#define MLX5_MAX_TSO_HEADER 192U + + /* Inline data size required by NICs. */ + #define MLX5_INLINE_HSIZE_NONE 0 +@@ -144,7 +144,10 @@ + #endif + + /* Log 2 of the default number of strides per WQE for Multi-Packet RQ. */ +-#define MLX5_MPRQ_STRIDE_NUM_N 6U ++#define MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM 6U + ++/* Log 2 of the default size of a stride per WQE for Multi-Packet RQ. */ ++#define MLX5_MPRQ_DEFAULT_LOG_STRIDE_SIZE 11U + /* Two-byte shift is disabled for Multi-Packet RQ. */ #define MLX5_MPRQ_TWO_BYTE_SHIFT 0 - @@ -176,6 +179,10 @@ #define MLX5_FLOW_MREG_HNAME "MARK_COPY_TABLE" #define MLX5_DEFAULT_COPY_ID UINT32_MAX @@ -50671,10 +71954,59 @@ index 042e1f31ee..2836099b75 100644 #ifndef HAVE_STATIC_ASSERT #define static_assert _Static_assert diff --git a/dpdk/drivers/net/mlx5/mlx5_devx_cmds.c b/dpdk/drivers/net/mlx5/mlx5_devx_cmds.c -index 9893287ba8..f9c4043c11 100644 +index 9893287ba8..f6977315d0 100644 --- a/dpdk/drivers/net/mlx5/mlx5_devx_cmds.c +++ b/dpdk/drivers/net/mlx5/mlx5_devx_cmds.c -@@ -362,6 +362,8 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, +@@ -303,6 +303,7 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; + void *hcattr; + int status, syndrome, rc; ++ bool hca_cap_2_sup; + + MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); + MLX5_SET(query_hca_cap_in, in, op_mod, +@@ -322,6 +323,7 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + return -1; + } + hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); ++ hca_cap_2_sup = MLX5_GET(cmd_hca_cap, hcattr, hca_cap_2); + attr->flow_counter_bulk_alloc_bitmap = + MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc); + attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, +@@ -341,6 +343,32 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, + flex_parser_protocols); + attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); ++ if (hca_cap_2_sup) { ++ memset(in, 0, sizeof(in)); ++ memset(out, 0, sizeof(out)); ++ MLX5_SET(query_hca_cap_in, in, opcode, ++ MLX5_CMD_OP_QUERY_HCA_CAP); ++ MLX5_SET(query_hca_cap_in, in, op_mod, ++ MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 | ++ MLX5_HCA_CAP_OPMOD_GET_CUR); ++ rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), ++ out, sizeof(out)); ++ if (rc) ++ goto error; ++ status = MLX5_GET(query_hca_cap_out, out, status); ++ syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); ++ if (status) { ++ DRV_LOG(DEBUG, ++ "Failed to query DevX HCA capabilities 2," ++ " status %x, syndrome = %x", status, syndrome); ++ return -1; ++ } ++ hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); ++ attr->log_min_stride_wqe_sz = MLX5_GET(cmd_hca_cap_2, hcattr, ++ log_min_stride_wqe_sz); ++ } ++ if (attr->log_min_stride_wqe_sz == 0) ++ attr->log_min_stride_wqe_sz = MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE; + if (attr->qos.sup) { + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | +@@ -362,6 +390,8 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, MLX5_GET(qos_cap, hcattr, log_max_flow_meter); attr->qos.flow_meter_reg_c_ids = MLX5_GET(qos_cap, hcattr, flow_meter_reg_id); @@ -50683,7 +72015,7 @@ index 9893287ba8..f9c4043c11 100644 } if (!attr->eth_net_offloads) return 0; -@@ -633,9 +635,8 @@ mlx5_devx_cmd_create_tir(struct ibv_context *ctx, +@@ -633,9 +663,8 @@ mlx5_devx_cmd_create_tir(struct ibv_context *ctx, { uint32_t in[MLX5_ST_SZ_DW(create_tir_in)] = {0}; uint32_t out[MLX5_ST_SZ_DW(create_tir_out)] = {0}; @@ -50694,7 +72026,7 @@ index 9893287ba8..f9c4043c11 100644 tir = rte_calloc(__func__, 1, sizeof(*tir), 0); if (!tir) { -@@ -658,10 +659,8 @@ mlx5_devx_cmd_create_tir(struct ibv_context *ctx, +@@ -658,10 +687,8 @@ mlx5_devx_cmd_create_tir(struct ibv_context *ctx, MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn); MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block); MLX5_SET(tirc, tir_ctx, transport_domain, tir_attr->transport_domain); @@ -50707,7 +72039,7 @@ index 9893287ba8..f9c4043c11 100644 outer = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_outer); MLX5_SET(rx_hash_field_select, outer, l3_prot_type, tir_attr->rx_hash_field_selector_outer.l3_prot_type); -@@ -779,7 +778,7 @@ mlx5_devx_cmd_create_sq(struct ibv_context *ctx, +@@ -779,7 +806,7 @@ mlx5_devx_cmd_create_sq(struct ibv_context *ctx, MLX5_SET(sqc, sq_ctx, fre, sq_attr->fre); MLX5_SET(sqc, sq_ctx, flush_in_error_en, sq_attr->flush_in_error_en); MLX5_SET(sqc, sq_ctx, allow_multi_pkt_send_wqe, @@ -50717,7 +72049,7 @@ index 9893287ba8..f9c4043c11 100644 sq_attr->min_wqe_inline_mode); MLX5_SET(sqc, sq_ctx, state, sq_attr->state); diff --git a/dpdk/drivers/net/mlx5/mlx5_ethdev.c b/dpdk/drivers/net/mlx5/mlx5_ethdev.c -index d80ae458bc..efcc69ca44 100644 +index d80ae458bc..5334377c10 100644 --- a/dpdk/drivers/net/mlx5/mlx5_ethdev.c +++ b/dpdk/drivers/net/mlx5/mlx5_ethdev.c @@ -405,9 +405,6 @@ mlx5_dev_configure(struct rte_eth_dev *dev) @@ -50813,7 +72145,84 @@ index d80ae458bc..efcc69ca44 100644 } /** -@@ -1475,249 +1486,6 @@ mlx5_dev_interrupt_handler_devx(void *cb_arg) +@@ -1290,6 +1301,57 @@ mlx5_dev_interrupt_device_fatal(struct mlx5_ibv_shared *sh) + } + } + ++static void ++mlx5_dev_interrupt_nl_cb(struct nlmsghdr *hdr, void *cb_arg) ++{ ++ struct mlx5_ibv_shared *sh = cb_arg; ++ uint32_t i; ++ uint32_t if_index; ++ ++ if (mlx5_nl_parse_link_status_update(hdr, &if_index) < 0) ++ return; ++ for (i = 0; i < sh->max_port; i++) { ++ struct mlx5_ibv_shared_port *port = &sh->port[i]; ++ struct rte_eth_dev *dev; ++ struct mlx5_priv *priv; ++ bool configured; ++ ++ if (port->nl_ih_port_id >= RTE_MAX_ETHPORTS) ++ continue; ++ dev = &rte_eth_devices[port->nl_ih_port_id]; ++ configured = dev->process_private != NULL; ++ /* Probing may initiate an LSC before configuration is done. */ ++ if (configured && !dev->data->dev_conf.intr_conf.lsc) ++ break; ++ priv = dev->data->dev_private; ++ if (priv->if_index == if_index) { ++ /* Block logical LSC events. */ ++ uint16_t prev_status = dev->data->dev_link.link_status; ++ ++ if (mlx5_link_update(dev, 0) < 0) ++ DRV_LOG(ERR, "Failed to update link status: %s", ++ rte_strerror(rte_errno)); ++ else if (prev_status != dev->data->dev_link.link_status) ++ _rte_eth_dev_callback_process ++ (dev, RTE_ETH_EVENT_INTR_LSC, NULL); ++ break; ++ } ++ } ++} ++ ++void ++mlx5_dev_interrupt_handler_nl(void *arg) ++{ ++ struct mlx5_ibv_shared *sh = arg; ++ int nlsk_fd = sh->intr_handle_nl.fd; ++ ++ if (nlsk_fd < 0) ++ return; ++ if (mlx5_nl_read_events(nlsk_fd, mlx5_dev_interrupt_nl_cb, sh) < 0) ++ DRV_LOG(ERR, "Failed to process Netlink events: %s", ++ rte_strerror(rte_errno)); ++} ++ + /** + * Handle shared asynchronous events the NIC (removal event + * and link status change). Supports multiport IB device. +@@ -1353,18 +1415,6 @@ mlx5_dev_interrupt_handler(void *cb_arg) + tmp = sh->port[tmp - 1].ih_port_id; + dev = &rte_eth_devices[tmp]; + assert(dev); +- if ((event.event_type == IBV_EVENT_PORT_ACTIVE || +- event.event_type == IBV_EVENT_PORT_ERR) && +- dev->data->dev_conf.intr_conf.lsc) { +- mlx5_glue->ack_async_event(&event); +- if (mlx5_link_update(dev, 0) == -EAGAIN) { +- usleep(0); +- continue; +- } +- _rte_eth_dev_callback_process +- (dev, RTE_ETH_EVENT_INTR_LSC, NULL); +- continue; +- } + DRV_LOG(DEBUG, + "port %u cannot handle an unknown event (type %d)", + dev->data->port_id, event.event_type); +@@ -1475,249 +1525,6 @@ mlx5_dev_interrupt_handler_devx(void *cb_arg) #endif /* HAVE_IBV_DEVX_ASYNC */ } @@ -51063,7 +72472,25 @@ index d80ae458bc..efcc69ca44 100644 /** * DPDK callback to bring the link DOWN. * -@@ -2189,12 +1957,13 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, +@@ -2115,7 +1922,7 @@ mlx5_get_module_info(struct rte_eth_dev *dev, + }; + int ret = 0; + +- if (!dev || !modinfo) { ++ if (!dev) { + DRV_LOG(WARNING, "missing argument, cannot get module info"); + rte_errno = EINVAL; + return -rte_errno; +@@ -2149,7 +1956,7 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, + struct ifreq ifr; + int ret = 0; + +- if (!dev || !info) { ++ if (!dev) { + DRV_LOG(WARNING, "missing argument, cannot get module eeprom"); + rte_errno = EINVAL; + return -rte_errno; +@@ -2189,12 +1996,13 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev, * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ @@ -51081,10 +72508,57 @@ index d80ae458bc..efcc69ca44 100644 return -rte_errno; } diff --git a/dpdk/drivers/net/mlx5/mlx5_flow.c b/dpdk/drivers/net/mlx5/mlx5_flow.c -index 008716367c..74f17d3710 100644 +index 008716367c..4d13bbb06c 100644 --- a/dpdk/drivers/net/mlx5/mlx5_flow.c +++ b/dpdk/drivers/net/mlx5/mlx5_flow.c -@@ -165,7 +165,9 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { +@@ -72,6 +72,7 @@ enum mlx5_expansion { + MLX5_EXPANSION_VXLAN, + MLX5_EXPANSION_VXLAN_GPE, + MLX5_EXPANSION_GRE, ++ MLX5_EXPANSION_GRE_KEY, + MLX5_EXPANSION_MPLS, + MLX5_EXPANSION_ETH, + MLX5_EXPANSION_ETH_VLAN, +@@ -108,8 +109,7 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { + }, + [MLX5_EXPANSION_OUTER_ETH] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4, +- MLX5_EXPANSION_OUTER_IPV6, +- MLX5_EXPANSION_MPLS), ++ MLX5_EXPANSION_OUTER_IPV6), + .type = RTE_FLOW_ITEM_TYPE_ETH, + .rss_types = 0, + }, +@@ -136,7 +136,8 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { + }, + [MLX5_EXPANSION_OUTER_IPV4_UDP] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN, +- MLX5_EXPANSION_VXLAN_GPE), ++ MLX5_EXPANSION_VXLAN_GPE, ++ MLX5_EXPANSION_MPLS), + .type = RTE_FLOW_ITEM_TYPE_UDP, + .rss_types = ETH_RSS_NONFRAG_IPV4_UDP, + }, +@@ -149,14 +150,16 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { + (MLX5_EXPANSION_OUTER_IPV6_UDP, + MLX5_EXPANSION_OUTER_IPV6_TCP, + MLX5_EXPANSION_IPV4, +- MLX5_EXPANSION_IPV6), ++ MLX5_EXPANSION_IPV6, ++ MLX5_EXPANSION_GRE), + .type = RTE_FLOW_ITEM_TYPE_IPV6, + .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | + ETH_RSS_NONFRAG_IPV6_OTHER, + }, + [MLX5_EXPANSION_OUTER_IPV6_UDP] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN, +- MLX5_EXPANSION_VXLAN_GPE), ++ MLX5_EXPANSION_VXLAN_GPE, ++ MLX5_EXPANSION_MPLS), + .type = RTE_FLOW_ITEM_TYPE_UDP, + .rss_types = ETH_RSS_NONFRAG_IPV6_UDP, + }, +@@ -165,7 +168,9 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { .rss_types = ETH_RSS_NONFRAG_IPV6_TCP, }, [MLX5_EXPANSION_VXLAN] = { @@ -51095,7 +72569,35 @@ index 008716367c..74f17d3710 100644 .type = RTE_FLOW_ITEM_TYPE_VXLAN, }, [MLX5_EXPANSION_VXLAN_GPE] = { -@@ -336,7 +338,7 @@ static struct mlx5_flow_tunnel_info tunnels_info[] = { +@@ -175,13 +180,25 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { + .type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE, + }, + [MLX5_EXPANSION_GRE] = { +- .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4), ++ .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, ++ MLX5_EXPANSION_IPV6, ++ MLX5_EXPANSION_GRE_KEY, ++ MLX5_EXPANSION_MPLS), + .type = RTE_FLOW_ITEM_TYPE_GRE, + }, ++ [MLX5_EXPANSION_GRE_KEY] = { ++ .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, ++ MLX5_EXPANSION_IPV6, ++ MLX5_EXPANSION_MPLS), ++ .type = RTE_FLOW_ITEM_TYPE_GRE_KEY, ++ .optional = 1, ++ }, + [MLX5_EXPANSION_MPLS] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, +- MLX5_EXPANSION_IPV6), ++ MLX5_EXPANSION_IPV6, ++ MLX5_EXPANSION_ETH), + .type = RTE_FLOW_ITEM_TYPE_MPLS, ++ .optional = 1, + }, + [MLX5_EXPANSION_ETH] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, +@@ -336,7 +353,7 @@ static struct mlx5_flow_tunnel_info tunnels_info[] = { * The request register on success, a negative errno * value otherwise and rte_errno is set. */ @@ -51104,7 +72606,7 @@ index 008716367c..74f17d3710 100644 mlx5_flow_get_reg_id(struct rte_eth_dev *dev, enum mlx5_feature_name feature, uint32_t id, -@@ -345,6 +347,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, +@@ -345,6 +362,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_dev_config *config = &priv->config; enum modify_reg start_reg; @@ -51112,7 +72614,7 @@ index 008716367c..74f17d3710 100644 switch (feature) { case MLX5_HAIRPIN_RX: -@@ -383,30 +386,37 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, +@@ -383,30 +401,37 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, return REG_C_0; } break; @@ -51161,7 +72663,7 @@ index 008716367c..74f17d3710 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, NULL, "invalid tag id"); -@@ -420,12 +430,16 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, +@@ -420,12 +445,16 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev, * If the available index REG_C_y >= REG_C_x, skip the * color register. */ @@ -51183,7 +72685,99 @@ index 008716367c..74f17d3710 100644 return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL, "unsupported tag id"); -@@ -859,6 +873,35 @@ flow_rxq_flags_clear(struct rte_eth_dev *dev) +@@ -698,12 +727,11 @@ flow_rxq_tunnel_ptype_update(struct mlx5_rxq_ctrl *rxq_ctrl) + * Pointer to device flow structure. + */ + static void +-flow_drv_rxq_flags_set(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) ++flow_drv_rxq_flags_set(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow, ++ int mark) + { + struct mlx5_priv *priv = dev->data->dev_private; + struct rte_flow *flow = dev_flow->flow; +- const int mark = !!(dev_flow->actions & +- (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK)); + const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); + unsigned int i; + +@@ -722,10 +750,8 @@ flow_drv_rxq_flags_set(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) + priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY && + mlx5_flow_ext_mreg_supported(dev)) { + rxq_ctrl->rxq.mark = 1; +- rxq_ctrl->flow_mark_n = 1; + } else if (mark) { + rxq_ctrl->rxq.mark = 1; +- rxq_ctrl->flow_mark_n++; + } + if (tunnel) { + unsigned int j; +@@ -744,6 +770,20 @@ flow_drv_rxq_flags_set(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) + } + } + ++static void ++flow_rxq_mark_flag_set(struct rte_eth_dev *dev) ++{ ++ struct mlx5_priv *priv = dev->data->dev_private; ++ struct mlx5_rxq_ctrl *rxq_ctrl; ++ ++ if (priv->mark_enabled) ++ return; ++ LIST_FOREACH(rxq_ctrl, &priv->rxqsctrl, next) { ++ rxq_ctrl->rxq.mark = 1; ++ } ++ priv->mark_enabled = 1; ++} ++ + /** + * Set the Rx queue flags (Mark/Flag and Tunnel Ptypes) for a flow + * +@@ -756,9 +796,14 @@ static void + flow_rxq_flags_set(struct rte_eth_dev *dev, struct rte_flow *flow) + { + struct mlx5_flow *dev_flow; +- ++ int mark = 0; ++ LIST_FOREACH(dev_flow, &flow->dev_flows, next) ++ mark = mark | (!!(dev_flow->actions & (MLX5_FLOW_ACTION_FLAG | ++ MLX5_FLOW_ACTION_MARK))); ++ if (mark) ++ flow_rxq_mark_flag_set(dev); + LIST_FOREACH(dev_flow, &flow->dev_flows, next) +- flow_drv_rxq_flags_set(dev, dev_flow); ++ flow_drv_rxq_flags_set(dev, dev_flow, mark); + } + + /** +@@ -775,8 +820,6 @@ flow_drv_rxq_flags_trim(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) + { + struct mlx5_priv *priv = dev->data->dev_private; + struct rte_flow *flow = dev_flow->flow; +- const int mark = !!(dev_flow->actions & +- (MLX5_FLOW_ACTION_FLAG | MLX5_FLOW_ACTION_MARK)); + const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); + unsigned int i; + +@@ -791,10 +834,6 @@ flow_drv_rxq_flags_trim(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow) + priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY && + mlx5_flow_ext_mreg_supported(dev)) { + rxq_ctrl->rxq.mark = 1; +- rxq_ctrl->flow_mark_n = 1; +- } else if (mark) { +- rxq_ctrl->flow_mark_n--; +- rxq_ctrl->rxq.mark = !!rxq_ctrl->flow_mark_n; + } + if (tunnel) { + unsigned int j; +@@ -851,7 +890,6 @@ flow_rxq_flags_clear(struct rte_eth_dev *dev) + continue; + rxq_ctrl = container_of((*priv->rxqs)[i], + struct mlx5_rxq_ctrl, rxq); +- rxq_ctrl->flow_mark_n = 0; + rxq_ctrl->rxq.mark = 0; + for (j = 0; j != MLX5_FLOW_TUNNEL; ++j) + rxq_ctrl->flow_tunnels_n[j] = 0; +@@ -859,6 +897,39 @@ flow_rxq_flags_clear(struct rte_eth_dev *dev) } } @@ -51208,10 +72802,14 @@ index 008716367c..74f17d3710 100644 + data->dynf_meta = 0; + data->flow_meta_mask = 0; + data->flow_meta_offset = -1; ++ data->flow_meta_port_mask = 0; + } else { + data->dynf_meta = 1; + data->flow_meta_mask = rte_flow_dynf_metadata_mask; + data->flow_meta_offset = rte_flow_dynf_metadata_offs; ++ data->flow_meta_port_mask = (uint32_t)~0; ++ if (priv->config.dv_xmeta_en == MLX5_XMETA_MODE_META16) ++ data->flow_meta_port_mask >>= 16; + } + } +} @@ -51219,7 +72817,7 @@ index 008716367c..74f17d3710 100644 /* * return a pointer to the desired action in the list of actions. * -@@ -900,11 +943,6 @@ mlx5_flow_validate_action_flag(uint64_t action_flags, +@@ -900,11 +971,6 @@ mlx5_flow_validate_action_flag(uint64_t action_flags, const struct rte_flow_attr *attr, struct rte_flow_error *error) { @@ -51231,7 +72829,7 @@ index 008716367c..74f17d3710 100644 if (action_flags & MLX5_FLOW_ACTION_MARK) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -956,10 +994,6 @@ mlx5_flow_validate_action_mark(const struct rte_flow_action *action, +@@ -956,10 +1022,6 @@ mlx5_flow_validate_action_mark(const struct rte_flow_action *action, &mark->id, "mark id must in 0 <= id < " RTE_STR(MLX5_FLOW_MARK_MAX)); @@ -51242,7 +72840,7 @@ index 008716367c..74f17d3710 100644 if (action_flags & MLX5_FLOW_ACTION_FLAG) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -991,24 +1025,10 @@ mlx5_flow_validate_action_mark(const struct rte_flow_action *action, +@@ -991,24 +1053,10 @@ mlx5_flow_validate_action_mark(const struct rte_flow_action *action, * 0 on success, a negative errno value otherwise and rte_errno is set. */ int @@ -51268,7 +72866,7 @@ index 008716367c..74f17d3710 100644 if (attr->egress) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, -@@ -1101,6 +1121,7 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, +@@ -1101,6 +1149,7 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, struct mlx5_priv *priv = dev->data->dev_private; const struct rte_flow_action_rss *rss = action->conf; int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); @@ -51276,7 +72874,7 @@ index 008716367c..74f17d3710 100644 unsigned int i; if (action_flags & MLX5_FLOW_FATE_ACTIONS) -@@ -1159,6 +1180,8 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, +@@ -1159,6 +1208,8 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, "No queues configured"); for (i = 0; i != rss->queue_num; ++i) { @@ -51285,7 +72883,7 @@ index 008716367c..74f17d3710 100644 if (rss->queue[i] >= priv->rxqs_n) return rte_flow_error_set (error, EINVAL, -@@ -1168,6 +1191,15 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, +@@ -1168,6 +1219,15 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, return rte_flow_error_set (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF, &rss->queue[i], "queue is not configured"); @@ -51301,7 +72899,30 @@ index 008716367c..74f17d3710 100644 } if (attr->egress) return rte_flow_error_set(error, ENOTSUP, -@@ -1634,7 +1666,6 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, +@@ -1179,6 +1239,13 @@ mlx5_flow_validate_action_rss(const struct rte_flow_action *action, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, + "inner RSS is not supported for " + "non-tunnel flows"); ++ if ((item_flags & MLX5_FLOW_LAYER_MPLS) && ++ !(item_flags & ++ (MLX5_FLOW_LAYER_INNER_L2 | MLX5_FLOW_LAYER_INNER_L3)) && ++ rss->level > 1) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, NULL, ++ "MPLS inner RSS needs to specify inner L2/L3 items after MPLS in pattern"); + return 0; + } + +@@ -1551,7 +1618,7 @@ mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "IPv4 cannot follow L2/VLAN layer " + "which ether type is not IPv4"); +- if (item_flags & MLX5_FLOW_LAYER_IPIP) { ++ if (item_flags & MLX5_FLOW_LAYER_TUNNEL) { + if (mask && spec) + next_proto = mask->hdr.next_proto_id & + spec->hdr.next_proto_id; +@@ -1634,7 +1701,6 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, "\xff\xff\xff\xff\xff\xff\xff\xff", .vtc_flow = RTE_BE32(0xffffffff), .proto = 0xff, @@ -51309,7 +72930,16 @@ index 008716367c..74f17d3710 100644 }, }; const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); -@@ -1831,7 +1862,6 @@ mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item, +@@ -1654,7 +1720,7 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "IPv6 cannot follow L2/VLAN layer " + "which ether type is not IPv6"); +- if (item_flags & MLX5_FLOW_LAYER_IPV6_ENCAP) { ++ if (item_flags & MLX5_FLOW_LAYER_TUNNEL) { + if (mask && spec) + next_proto = mask->hdr.proto & spec->hdr.proto; + if (next_proto == IPPROTO_IPIP || next_proto == IPPROTO_IPV6) +@@ -1831,7 +1897,6 @@ mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item, uint32_t vlan_id; uint8_t vni[4]; } id = { .vlan_id = 0, }; @@ -51317,7 +72947,7 @@ index 008716367c..74f17d3710 100644 if (item_flags & MLX5_FLOW_LAYER_TUNNEL) -@@ -1858,23 +1888,8 @@ mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item, +@@ -1858,23 +1923,8 @@ mlx5_flow_validate_item_vxlan(const struct rte_flow_item *item, return ret; if (spec) { memcpy(&id.vni[1], spec->vni, 3); @@ -51341,7 +72971,7 @@ index 008716367c..74f17d3710 100644 if (!(item_flags & MLX5_FLOW_LAYER_OUTER)) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, -@@ -1913,7 +1928,6 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, +@@ -1913,7 +1963,6 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, uint32_t vlan_id; uint8_t vni[4]; } id = { .vlan_id = 0, }; @@ -51349,7 +72979,7 @@ index 008716367c..74f17d3710 100644 if (!priv->config.l3_vxlan_en) return rte_flow_error_set(error, ENOTSUP, -@@ -1951,22 +1965,8 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, +@@ -1951,22 +2000,8 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, "VxLAN-GPE protocol" " not supported"); memcpy(&id.vni[1], spec->vni, 3); @@ -51372,7 +73002,7 @@ index 008716367c..74f17d3710 100644 if (!(item_flags & MLX5_FLOW_LAYER_OUTER)) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, -@@ -2131,9 +2131,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, +@@ -2131,9 +2166,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, .protocol = RTE_BE16(UINT16_MAX), }; @@ -51383,17 +73013,22 @@ index 008716367c..74f17d3710 100644 return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, "L3 Geneve is not enabled by device" -@@ -2223,7 +2221,8 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused, - /* MPLS over IP, UDP, GRE is allowed */ - if (!(prev_layer & (MLX5_FLOW_LAYER_OUTER_L3 | - MLX5_FLOW_LAYER_OUTER_L4_UDP | +@@ -2220,10 +2253,10 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused, + "MPLS not supported or" + " disabled in firmware" + " configuration."); +- /* MPLS over IP, UDP, GRE is allowed */ +- if (!(prev_layer & (MLX5_FLOW_LAYER_OUTER_L3 | +- MLX5_FLOW_LAYER_OUTER_L4_UDP | - MLX5_FLOW_LAYER_GRE))) ++ /* MPLS over UDP, GRE is allowed */ ++ if (!(prev_layer & (MLX5_FLOW_LAYER_OUTER_L4_UDP | + MLX5_FLOW_LAYER_GRE | + MLX5_FLOW_LAYER_GRE_KEY))) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "protocol filtering not compatible" -@@ -2244,11 +2243,12 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused, +@@ -2244,11 +2277,12 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused, if (ret < 0) return ret; return 0; @@ -51407,7 +73042,7 @@ index 008716367c..74f17d3710 100644 } /** -@@ -2349,6 +2349,7 @@ flow_null_validate(struct rte_eth_dev *dev __rte_unused, +@@ -2349,6 +2383,7 @@ flow_null_validate(struct rte_eth_dev *dev __rte_unused, const struct rte_flow_item items[] __rte_unused, const struct rte_flow_action actions[] __rte_unused, bool external __rte_unused, @@ -51415,7 +73050,7 @@ index 008716367c..74f17d3710 100644 struct rte_flow_error *error) { return rte_flow_error_set(error, ENOTSUP, -@@ -2463,6 +2464,8 @@ flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr) +@@ -2463,6 +2498,8 @@ flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr) * Pointer to the list of actions. * @param[in] external * This flow rule is created by request external to PMD. @@ -51424,7 +73059,7 @@ index 008716367c..74f17d3710 100644 * @param[out] error * Pointer to the error structure. * -@@ -2474,13 +2477,14 @@ flow_drv_validate(struct rte_eth_dev *dev, +@@ -2474,13 +2511,14 @@ flow_drv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], @@ -51441,7 +73076,7 @@ index 008716367c..74f17d3710 100644 } /** -@@ -2638,47 +2642,6 @@ flow_drv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) +@@ -2638,47 +2676,6 @@ flow_drv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) fops->destroy(dev, flow); } @@ -51489,7 +73124,7 @@ index 008716367c..74f17d3710 100644 /** * Get RSS action from the action list. * -@@ -2723,7 +2686,44 @@ find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) +@@ -2723,7 +2720,44 @@ find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) } /** @@ -51535,7 +73170,7 @@ index 008716367c..74f17d3710 100644 * * @param[in] actions * Pointer to the list of actions. -@@ -2732,18 +2732,38 @@ find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) +@@ -2732,18 +2766,38 @@ find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) * @param[out] qrss_type * Pointer to the action type to return. RTE_FLOW_ACTION_TYPE_END is returned * if no QUEUE/RSS is found. @@ -51576,7 +73211,7 @@ index 008716367c..74f17d3710 100644 case RTE_FLOW_ACTION_TYPE_QUEUE: case RTE_FLOW_ACTION_TYPE_RSS: *qrss = actions; -@@ -2753,6 +2773,8 @@ flow_parse_qrss_action(const struct rte_flow_action actions[], +@@ -2753,6 +2807,8 @@ flow_parse_qrss_action(const struct rte_flow_action actions[], } actions_n++; } @@ -51585,7 +73220,7 @@ index 008716367c..74f17d3710 100644 /* Count RTE_FLOW_ACTION_TYPE_END. */ return actions_n + 1; } -@@ -2790,10 +2812,10 @@ flow_check_meter_action(const struct rte_flow_action actions[], uint32_t *mtr) +@@ -2790,10 +2846,10 @@ flow_check_meter_action(const struct rte_flow_action actions[], uint32_t *mtr) } /** @@ -51599,7 +73234,7 @@ index 008716367c..74f17d3710 100644 * * @param dev * Pointer to Ethernet device. -@@ -2813,7 +2835,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, +@@ -2813,7 +2869,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, { int queue_action = 0; int action_n = 0; @@ -51608,7 +73243,7 @@ index 008716367c..74f17d3710 100644 const struct rte_flow_action_queue *queue; const struct rte_flow_action_rss *rss; const struct rte_flow_action_raw_encap *raw_encap; -@@ -2844,7 +2866,10 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, +@@ -2844,7 +2900,10 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: @@ -51620,7 +73255,7 @@ index 008716367c..74f17d3710 100644 action_n++; break; case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: -@@ -2852,7 +2877,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, +@@ -2852,7 +2911,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, if (raw_encap->size > (sizeof(struct rte_flow_item_eth) + sizeof(struct rte_flow_item_ipv4))) @@ -51629,7 +73264,7 @@ index 008716367c..74f17d3710 100644 action_n++; break; default: -@@ -2860,7 +2885,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, +@@ -2860,7 +2919,7 @@ flow_check_hairpin_split(struct rte_eth_dev *dev, break; } } @@ -51638,7 +73273,7 @@ index 008716367c..74f17d3710 100644 return action_n; return 0; } -@@ -2922,7 +2947,7 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, +@@ -2922,7 +2981,7 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, }; struct mlx5_flow_action_copy_mreg cp_mreg = { .dst = REG_B, @@ -51647,7 +73282,7 @@ index 008716367c..74f17d3710 100644 }; struct rte_flow_action_jump jump = { .group = MLX5_FLOW_MREG_ACT_TABLE_GROUP, -@@ -2958,18 +2983,21 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, +@@ -2958,18 +3017,21 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, /* Build a new flow. */ if (mark_id != MLX5_DEFAULT_COPY_ID) { items[0] = (struct rte_flow_item){ @@ -51672,7 +73307,7 @@ index 008716367c..74f17d3710 100644 .conf = &cp_mreg, }; actions[2] = (struct rte_flow_action){ -@@ -2986,7 +3014,8 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, +@@ -2986,7 +3048,8 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id, .type = RTE_FLOW_ITEM_TYPE_END, }; actions[0] = (struct rte_flow_action){ @@ -51682,7 +73317,7 @@ index 008716367c..74f17d3710 100644 .conf = &cp_mreg, }; actions[1] = (struct rte_flow_action){ -@@ -3263,7 +3292,8 @@ flow_mreg_update_copy_table(struct rte_eth_dev *dev, +@@ -3263,7 +3326,8 @@ flow_mreg_update_copy_table(struct rte_eth_dev *dev, /** * Split the hairpin flow. @@ -51692,7 +73327,7 @@ index 008716367c..74f17d3710 100644 * If the count action is after the encap then we also * move the count action. in this case the count will also measure * the outer bytes. -@@ -3307,6 +3337,9 @@ flow_hairpin_split(struct rte_eth_dev *dev, +@@ -3307,6 +3371,9 @@ flow_hairpin_split(struct rte_eth_dev *dev, switch (actions->type) { case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: @@ -51702,7 +73337,7 @@ index 008716367c..74f17d3710 100644 rte_memcpy(actions_tx, actions, sizeof(struct rte_flow_action)); actions_tx++; -@@ -3360,7 +3393,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, +@@ -3360,7 +3427,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, } /* Add set meta action and end action for the Rx flow. */ tag_action = actions_rx; @@ -51712,7 +73347,7 @@ index 008716367c..74f17d3710 100644 actions_rx++; rte_memcpy(actions_rx, actions, sizeof(struct rte_flow_action)); actions_rx++; -@@ -3373,7 +3407,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, +@@ -3373,7 +3441,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, rte_memcpy(actions_tx, actions, sizeof(struct rte_flow_action)); addr = (void *)&pattern_tx[2]; item = pattern_tx; @@ -51722,7 +73357,7 @@ index 008716367c..74f17d3710 100644 tag_item = (void *)addr; tag_item->data = *flow_id; tag_item->id = mlx5_flow_get_reg_id(dev, MLX5_HAIRPIN_TX, 0, NULL); -@@ -3384,7 +3419,6 @@ flow_hairpin_split(struct rte_eth_dev *dev, +@@ -3384,7 +3453,6 @@ flow_hairpin_split(struct rte_eth_dev *dev, tag_item->data = UINT32_MAX; tag_item->id = UINT16_MAX; item->mask = tag_item; @@ -51730,7 +73365,7 @@ index 008716367c..74f17d3710 100644 item->last = NULL; item++; item->type = RTE_FLOW_ITEM_TYPE_END; -@@ -3401,6 +3435,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, +@@ -3401,6 +3469,8 @@ flow_hairpin_split(struct rte_eth_dev *dev, * Parent flow structure pointer. * @param[in, out] sub_flow * Pointer to return the created subflow, may be NULL. @@ -51739,7 +73374,7 @@ index 008716367c..74f17d3710 100644 * @param[in] attr * Flow rule attributes. * @param[in] items -@@ -3418,6 +3454,7 @@ static int +@@ -3418,6 +3488,7 @@ static int flow_create_split_inner(struct rte_eth_dev *dev, struct rte_flow *flow, struct mlx5_flow **sub_flow, @@ -51747,7 +73382,7 @@ index 008716367c..74f17d3710 100644 const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], -@@ -3432,6 +3469,12 @@ flow_create_split_inner(struct rte_eth_dev *dev, +@@ -3432,6 +3503,12 @@ flow_create_split_inner(struct rte_eth_dev *dev, dev_flow->external = external; /* Subflow object was created, we must include one in the list. */ LIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next); @@ -51760,7 +73395,7 @@ index 008716367c..74f17d3710 100644 if (sub_flow) *sub_flow = dev_flow; return flow_drv_translate(dev, dev_flow, attr, items, actions, error); -@@ -3451,6 +3494,10 @@ flow_create_split_inner(struct rte_eth_dev *dev, +@@ -3451,6 +3528,10 @@ flow_create_split_inner(struct rte_eth_dev *dev, * * @param dev * Pointer to Ethernet device. @@ -51771,7 +73406,7 @@ index 008716367c..74f17d3710 100644 * @param[in] actions * Associated actions (list terminated by the END action). * @param[out] actions_sfx -@@ -3467,66 +3514,61 @@ flow_create_split_inner(struct rte_eth_dev *dev, +@@ -3467,66 +3548,61 @@ flow_create_split_inner(struct rte_eth_dev *dev, */ static int flow_meter_split_prep(struct rte_eth_dev *dev, @@ -51867,7 +73502,7 @@ index 008716367c..74f17d3710 100644 } /* Add end action to the actions. */ actions_sfx->type = RTE_FLOW_ACTION_TYPE_END; -@@ -3539,8 +3581,47 @@ flow_meter_split_prep(struct rte_eth_dev *dev, +@@ -3539,8 +3615,47 @@ flow_meter_split_prep(struct rte_eth_dev *dev, * Get the id from the qrss_pool to make qrss share the id with meter. */ tag_id = flow_qrss_get_id(dev); @@ -51916,7 +73551,47 @@ index 008716367c..74f17d3710 100644 return tag_id; } -@@ -3640,7 +3721,8 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, +@@ -3578,6 +3693,8 @@ flow_meter_split_prep(struct rte_eth_dev *dev, + * Pointer to the Q/RSS action. + * @param[in] actions_n + * Number of original actions. ++ * @param[in] mtr_sfx ++ * Check if it is in meter suffix table. + * @param[out] error + * Perform verbose error reporting if not NULL. + * +@@ -3590,7 +3707,8 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, + struct rte_flow_action *split_actions, + const struct rte_flow_action *actions, + const struct rte_flow_action *qrss, +- int actions_n, struct rte_flow_error *error) ++ int actions_n, int mtr_sfx, ++ struct rte_flow_error *error) + { + struct mlx5_rte_flow_action_set_tag *set_tag; + struct rte_flow_action_jump *jump; +@@ -3604,15 +3722,15 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, + * - Add jump to mreg CP_TBL. + * As a result, there will be one more action. + */ +- ++actions_n; + memcpy(split_actions, actions, sizeof(*split_actions) * actions_n); ++ /* Count MLX5_RTE_FLOW_ACTION_TYPE_TAG. */ ++ ++actions_n; + set_tag = (void *)(split_actions + actions_n); + /* +- * If tag action is not set to void(it means we are not the meter +- * suffix flow), add the tag action. Since meter suffix flow already +- * has the tag added. ++ * If we are not the meter suffix flow, add the tag action. ++ * Since meter suffix flow already has the tag added. + */ +- if (split_actions[qrss_idx].type != RTE_FLOW_ACTION_TYPE_VOID) { ++ if (!mtr_sfx) { + /* + * Allocate the new subflow ID. This one is unique within + * device and not shared with representors. Otherwise, +@@ -3640,9 +3758,16 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, /* Construct new actions array. */ /* Replace QUEUE/RSS action. */ split_actions[qrss_idx] = (struct rte_flow_action){ @@ -51925,8 +73600,16 @@ index 008716367c..74f17d3710 100644 + MLX5_RTE_FLOW_ACTION_TYPE_TAG, .conf = set_tag, }; ++ } else { ++ /* ++ * If we are the suffix flow of meter, tag already exist. ++ * Set the QUEUE/RSS action to void. ++ */ ++ split_actions[qrss_idx].type = RTE_FLOW_ACTION_TYPE_VOID; } -@@ -3673,6 +3755,8 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, + /* JUMP action to jump to mreg copy table (CP_TBL). */ + jump = (void *)(set_tag + 1); +@@ -3673,6 +3798,8 @@ flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, * Number of actions in the list. * @param[out] error * Perform verbose error reporting if not NULL. @@ -51935,7 +73618,7 @@ index 008716367c..74f17d3710 100644 * * @return * 0 on success, negative value otherwise -@@ -3681,7 +3765,8 @@ static int +@@ -3681,7 +3808,8 @@ static int flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, struct rte_flow_action *ext_actions, const struct rte_flow_action *actions, @@ -51945,7 +73628,7 @@ index 008716367c..74f17d3710 100644 { struct mlx5_flow_action_copy_mreg *cp_mreg = (struct mlx5_flow_action_copy_mreg *) -@@ -3696,15 +3781,26 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, +@@ -3696,15 +3824,26 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, if (ret < 0) return ret; cp_mreg->src = ret; @@ -51981,7 +73664,7 @@ index 008716367c..74f17d3710 100644 return 0; } -@@ -3722,6 +3818,8 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, +@@ -3722,6 +3861,8 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, * Pointer to Ethernet device. * @param[in] flow * Parent flow structure pointer. @@ -51990,7 +73673,7 @@ index 008716367c..74f17d3710 100644 * @param[in] attr * Flow rule attributes. * @param[in] items -@@ -3738,6 +3836,7 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, +@@ -3738,6 +3879,7 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, static int flow_create_split_metadata(struct rte_eth_dev *dev, struct rte_flow *flow, @@ -51998,7 +73681,7 @@ index 008716367c..74f17d3710 100644 const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], -@@ -3752,15 +3851,18 @@ flow_create_split_metadata(struct rte_eth_dev *dev, +@@ -3752,15 +3894,18 @@ flow_create_split_metadata(struct rte_eth_dev *dev, int mtr_sfx = 0; size_t act_size; int actions_n; @@ -52020,15 +73703,34 @@ index 008716367c..74f17d3710 100644 if (qrss) { /* Exclude hairpin flows from splitting. */ if (qrss->type == RTE_FLOW_ACTION_TYPE_QUEUE) { -@@ -3807,6 +3909,7 @@ flow_create_split_metadata(struct rte_eth_dev *dev, - RTE_FLOW_ACTION_TYPE_VOID; - else - ext_actions[qrss - actions].type = -+ (enum rte_flow_action_type) - MLX5_RTE_FLOW_ACTION_TYPE_TAG; +@@ -3798,16 +3943,6 @@ flow_create_split_metadata(struct rte_eth_dev *dev, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "no memory to split " + "metadata flow"); +- /* +- * If we are the suffix flow of meter, tag already exist. +- * Set the tag action to void. +- */ +- if (mtr_sfx) +- ext_actions[qrss - actions].type = +- RTE_FLOW_ACTION_TYPE_VOID; +- else +- ext_actions[qrss - actions].type = +- MLX5_RTE_FLOW_ACTION_TYPE_TAG; /* * Create the new actions list with removed Q/RSS action -@@ -3835,14 +3938,14 @@ flow_create_split_metadata(struct rte_eth_dev *dev, + * and appended set tag and jump to register copy table +@@ -3815,7 +3950,8 @@ flow_create_split_metadata(struct rte_eth_dev *dev, + * in advance, because it is needed for set tag action. + */ + qrss_id = flow_mreg_split_qrss_prep(dev, ext_actions, actions, +- qrss, actions_n, error); ++ qrss, actions_n, ++ mtr_sfx, error); + if (!mtr_sfx && !qrss_id) { + ret = -rte_errno; + goto exit; +@@ -3835,14 +3971,14 @@ flow_create_split_metadata(struct rte_eth_dev *dev, "metadata flow"); /* Create the action list appended with copy register. */ ret = flow_mreg_tx_copy_prep(dev, ext_actions, actions, @@ -52047,7 +73749,7 @@ index 008716367c..74f17d3710 100644 if (ret < 0) goto exit; assert(dev_flow); -@@ -3854,11 +3957,12 @@ flow_create_split_metadata(struct rte_eth_dev *dev, +@@ -3854,11 +3990,12 @@ flow_create_split_metadata(struct rte_eth_dev *dev, /* Internal PMD action to set register. */ struct mlx5_rte_flow_item_tag q_tag_spec = { .data = qrss_id, @@ -52062,7 +73764,7 @@ index 008716367c..74f17d3710 100644 .spec = &q_tag_spec, .last = NULL, .mask = NULL, -@@ -3876,7 +3980,7 @@ flow_create_split_metadata(struct rte_eth_dev *dev, +@@ -3876,7 +4013,7 @@ flow_create_split_metadata(struct rte_eth_dev *dev, .type = RTE_FLOW_ACTION_TYPE_END, }, }; @@ -52071,7 +73773,7 @@ index 008716367c..74f17d3710 100644 /* * Configure the tag item only if there is no meter subflow. -@@ -3903,14 +4007,13 @@ flow_create_split_metadata(struct rte_eth_dev *dev, +@@ -3903,14 +4040,13 @@ flow_create_split_metadata(struct rte_eth_dev *dev, } dev_flow = NULL; /* Add suffix subflow to execute Q/RSS. */ @@ -52087,7 +73789,7 @@ index 008716367c..74f17d3710 100644 } exit: -@@ -3963,7 +4066,6 @@ flow_create_split_meter(struct rte_eth_dev *dev, +@@ -3963,7 +4099,6 @@ flow_create_split_meter(struct rte_eth_dev *dev, struct rte_flow_action *sfx_actions = NULL; struct rte_flow_action *pre_actions = NULL; struct rte_flow_item *sfx_items = NULL; @@ -52095,7 +73797,7 @@ index 008716367c..74f17d3710 100644 struct mlx5_flow *dev_flow = NULL; struct rte_flow_attr sfx_attr = *attr; uint32_t mtr = 0; -@@ -3976,63 +4078,47 @@ flow_create_split_meter(struct rte_eth_dev *dev, +@@ -3976,63 +4111,47 @@ flow_create_split_meter(struct rte_eth_dev *dev, if (priv->mtr_en) actions_n = flow_check_meter_action(actions, &mtr); if (mtr) { @@ -52174,7 +73876,7 @@ index 008716367c..74f17d3710 100644 sfx_items ? sfx_items : items, sfx_actions ? sfx_actions : actions, external, error); -@@ -4146,14 +4232,18 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, +@@ -4146,14 +4265,18 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, } items_tx; struct rte_flow_expand_rss *buf = &expand_buffer.buf; const struct rte_flow_action *p_actions_rx = actions; @@ -52195,7 +73897,7 @@ index 008716367c..74f17d3710 100644 if (hairpin_flow > 0) { if (hairpin_flow > MLX5_MAX_SPLIT_ACTIONS) { rte_errno = EINVAL; -@@ -4164,10 +4254,6 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, +@@ -4164,10 +4287,6 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, &hairpin_id); p_actions_rx = actions_rx.actions; } @@ -52206,7 +73908,7 @@ index 008716367c..74f17d3710 100644 flow_size = sizeof(struct rte_flow); rss = flow_get_rss_action(p_actions_rx); if (rss) -@@ -4334,6 +4420,26 @@ mlx5_flow_create_esw_table_zero_flow(struct rte_eth_dev *dev) +@@ -4334,6 +4453,26 @@ mlx5_flow_create_esw_table_zero_flow(struct rte_eth_dev *dev) actions, false, &error); } @@ -52233,7 +73935,7 @@ index 008716367c..74f17d3710 100644 /** * Create a flow. * -@@ -4518,7 +4624,8 @@ mlx5_ctrl_flow_source_queue(struct rte_eth_dev *dev, +@@ -4518,7 +4657,8 @@ mlx5_ctrl_flow_source_queue(struct rte_eth_dev *dev, }; struct rte_flow_item items[] = { { @@ -52243,7 +73945,7 @@ index 008716367c..74f17d3710 100644 .spec = &queue_spec, .last = NULL, .mask = &queue_mask, -@@ -4623,6 +4730,8 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, +@@ -4623,6 +4763,8 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, if (!priv->reta_idx_n || !priv->rxqs_n) { return 0; } @@ -52252,7 +73954,7 @@ index 008716367c..74f17d3710 100644 for (i = 0; i != priv->reta_idx_n; ++i) queue[i] = (*priv->reta_idx)[i]; flow = flow_list_create(dev, &priv->ctrl_flows, -@@ -5498,6 +5607,11 @@ mlx5_flow_query_alarm(void *arg) +@@ -5498,6 +5640,11 @@ mlx5_flow_query_alarm(void *arg) goto set_alarm; dcs = (struct mlx5_devx_obj *)(uintptr_t)rte_atomic64_read (&pool->a64_dcs); @@ -52264,7 +73966,7 @@ index 008716367c..74f17d3710 100644 offset = batch ? 0 : dcs->id % MLX5_COUNTERS_PER_POOL; ret = mlx5_devx_cmd_flow_counter_query(dcs, 0, MLX5_COUNTERS_PER_POOL - offset, NULL, NULL, -@@ -5515,6 +5629,7 @@ mlx5_flow_query_alarm(void *arg) +@@ -5515,6 +5662,7 @@ mlx5_flow_query_alarm(void *arg) pool->raw_hw->min_dcs_id = dcs->id; LIST_REMOVE(pool->raw_hw, next); sh->cmng.pending_queries++; @@ -52272,7 +73974,7 @@ index 008716367c..74f17d3710 100644 pool_index++; if (pool_index >= rte_atomic16_read(&cont->n_valid)) { batch ^= 0x1; -@@ -5570,6 +5685,8 @@ mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, +@@ -5570,6 +5718,8 @@ mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, * Value is part of flow rule created by request external to PMD. * @param[in] group * rte_flow group index value. @@ -52281,7 +73983,7 @@ index 008716367c..74f17d3710 100644 * @param[out] table * HW table value. * @param[out] error -@@ -5580,10 +5697,10 @@ mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, +@@ -5580,10 +5730,10 @@ mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, */ int mlx5_flow_group_to_table(const struct rte_flow_attr *attributes, bool external, @@ -52294,7 +73996,7 @@ index 008716367c..74f17d3710 100644 if (group == UINT32_MAX) return rte_flow_error_set (error, EINVAL, -@@ -5633,7 +5750,8 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev) +@@ -5633,7 +5783,8 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev) }; struct rte_flow_action actions[] = { [0] = { @@ -52305,7 +74007,7 @@ index 008716367c..74f17d3710 100644 .src = REG_C_1, .dst = idx, diff --git a/dpdk/drivers/net/mlx5/mlx5_flow.h b/dpdk/drivers/net/mlx5/mlx5_flow.h -index 3fff5dd7da..4300e62fad 100644 +index 3fff5dd7da..f9f4149895 100644 --- a/dpdk/drivers/net/mlx5/mlx5_flow.h +++ b/dpdk/drivers/net/mlx5/mlx5_flow.h @@ -33,6 +33,7 @@ enum mlx5_rte_flow_item_type { @@ -52413,7 +74115,7 @@ index 3fff5dd7da..4300e62fad 100644 +#define MLX5_ACT_NUM_MDF_IPV6 4 +#define MLX5_ACT_NUM_MDF_MAC 2 +#define MLX5_ACT_NUM_MDF_VID 1 -+#define MLX5_ACT_NUM_MDF_PORT 2 ++#define MLX5_ACT_NUM_MDF_PORT 1 +#define MLX5_ACT_NUM_MDF_TTL 1 +#define MLX5_ACT_NUM_DEC_TTL MLX5_ACT_NUM_MDF_TTL +#define MLX5_ACT_NUM_MDF_TCPSEQ 1 @@ -52503,8 +74205,14 @@ index 3fff5dd7da..4300e62fad 100644 enum mlx5_feature_name feature, uint32_t id, struct rte_flow_error *error); +@@ -853,4 +893,5 @@ int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr); + int mlx5_flow_meter_flush(struct rte_eth_dev *dev, + struct rte_mtr_error *error); ++int mlx5_flow_discover_dr_action_support(struct rte_eth_dev *dev); + #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/dpdk/drivers/net/mlx5/mlx5_flow_dv.c b/dpdk/drivers/net/mlx5/mlx5_flow_dv.c -index 73aaea4536..a1b805c105 100644 +index 73aaea4536..e4808abd64 100644 --- a/dpdk/drivers/net/mlx5/mlx5_flow_dv.c +++ b/dpdk/drivers/net/mlx5/mlx5_flow_dv.c @@ -27,6 +27,7 @@ @@ -52524,7 +74232,7 @@ index 73aaea4536..a1b805c105 100644 /* VLAN header definitions */ #define MLX5DV_FLOW_VLAN_PCP_SHIFT 13 #define MLX5DV_FLOW_VLAN_PCP_MASK (0x7 << MLX5DV_FLOW_VLAN_PCP_SHIFT) -@@ -72,6 +71,10 @@ union flow_dv_attr { +@@ -72,6 +71,24 @@ union flow_dv_attr { uint32_t attr; }; @@ -52532,10 +74240,24 @@ index 73aaea4536..a1b805c105 100644 +flow_dv_tbl_resource_release(struct rte_eth_dev *dev, + struct mlx5_flow_tbl_resource *tbl); + ++static inline uint16_t ++mlx5_translate_tunnel_etypes(uint64_t pattern_flags) ++{ ++ if (pattern_flags & MLX5_FLOW_LAYER_INNER_L2) ++ return RTE_ETHER_TYPE_TEB; ++ else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV4) ++ return RTE_ETHER_TYPE_IPV4; ++ else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV6) ++ return RTE_ETHER_TYPE_IPV6; ++ else if (pattern_flags & MLX5_FLOW_LAYER_MPLS) ++ return RTE_ETHER_TYPE_MPLS; ++ return 0; ++} ++ /** * Initialize flow attributes structure according to flow items' types. * -@@ -82,19 +85,74 @@ union flow_dv_attr { +@@ -82,19 +99,75 @@ union flow_dv_attr { * Pointer to item specification. * @param[out] attr * Pointer to flow attributes structure. @@ -52576,6 +74298,7 @@ index 73aaea4536..a1b805c105 100644 + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + case RTE_FLOW_ITEM_TYPE_GENEVE: + case RTE_FLOW_ITEM_TYPE_MPLS: ++ case RTE_FLOW_ITEM_TYPE_GTP: + if (tunnel_decap) + attr->attr = 0; + break; @@ -52611,7 +74334,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ITEM_TYPE_UDP: if (!attr->tcp) -@@ -222,7 +280,7 @@ flow_dv_shared_lock(struct rte_eth_dev *dev) +@@ -222,7 +295,7 @@ flow_dv_shared_lock(struct rte_eth_dev *dev) struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_ibv_shared *sh = priv->sh; @@ -52620,7 +74343,7 @@ index 73aaea4536..a1b805c105 100644 int ret; ret = pthread_mutex_lock(&sh->dv_mutex); -@@ -237,7 +295,7 @@ flow_dv_shared_unlock(struct rte_eth_dev *dev) +@@ -237,7 +310,7 @@ flow_dv_shared_unlock(struct rte_eth_dev *dev) struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_ibv_shared *sh = priv->sh; @@ -52629,7 +74352,7 @@ index 73aaea4536..a1b805c105 100644 int ret; ret = pthread_mutex_unlock(&sh->dv_mutex); -@@ -363,7 +421,7 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, +@@ -363,7 +436,7 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, uint32_t mask; uint32_t data; @@ -52638,7 +74361,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "too many items to modify"); -@@ -380,10 +438,12 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, +@@ -380,10 +453,12 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, off_b - __builtin_clz(mask); assert(size_b); size_b = size_b == sizeof(uint32_t) * CHAR_BIT ? 0 : size_b; @@ -52655,7 +74378,7 @@ index 73aaea4536..a1b805c105 100644 /* Convert entire record to expected big-endian format. */ actions[i].data0 = rte_cpu_to_be_32(actions[i].data0); if (type == MLX5_MODIFICATION_TYPE_COPY) { -@@ -404,11 +464,11 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, +@@ -404,11 +479,11 @@ flow_dv_convert_modify_action(struct rte_flow_item *item, ++i; ++field; } while (field->size); @@ -52669,7 +74392,7 @@ index 73aaea4536..a1b805c105 100644 return 0; } -@@ -566,17 +626,19 @@ flow_dv_convert_action_modify_vlan_vid +@@ -566,17 +641,19 @@ flow_dv_convert_action_modify_vlan_vid const struct rte_flow_action_of_set_vlan_vid *conf = (const struct rte_flow_action_of_set_vlan_vid *)(action->conf); int i = resource->actions_num; @@ -52695,7 +74418,7 @@ index 73aaea4536..a1b805c105 100644 actions[i].data0 = rte_cpu_to_be_32(actions[i].data0); actions[i].data1 = conf->vlan_vid; actions[i].data1 = actions[i].data1 << 16; -@@ -595,6 +657,10 @@ flow_dv_convert_action_modify_vlan_vid +@@ -595,6 +672,10 @@ flow_dv_convert_action_modify_vlan_vid * Pointer to rte_flow_item objects list. * @param[in] attr * Pointer to flow attributes structure. @@ -52706,7 +74429,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to the error structure. * -@@ -606,8 +672,8 @@ flow_dv_convert_action_modify_tp +@@ -606,8 +687,8 @@ flow_dv_convert_action_modify_tp (struct mlx5_flow_dv_modify_hdr_resource *resource, const struct rte_flow_action *action, const struct rte_flow_item *items, @@ -52717,7 +74440,7 @@ index 73aaea4536..a1b805c105 100644 { const struct rte_flow_action_set_tp *conf = (const struct rte_flow_action_set_tp *)(action->conf); -@@ -619,7 +685,7 @@ flow_dv_convert_action_modify_tp +@@ -619,7 +700,7 @@ flow_dv_convert_action_modify_tp struct field_modify_info *field; if (!attr->valid) @@ -52726,7 +74449,7 @@ index 73aaea4536..a1b805c105 100644 if (attr->udp) { memset(&udp, 0, sizeof(udp)); memset(&udp_mask, 0, sizeof(udp_mask)); -@@ -636,8 +702,8 @@ flow_dv_convert_action_modify_tp +@@ -636,8 +717,8 @@ flow_dv_convert_action_modify_tp item.spec = &udp; item.mask = &udp_mask; field = modify_udp; @@ -52737,7 +74460,7 @@ index 73aaea4536..a1b805c105 100644 memset(&tcp, 0, sizeof(tcp)); memset(&tcp_mask, 0, sizeof(tcp_mask)); if (action->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC) { -@@ -669,6 +735,10 @@ flow_dv_convert_action_modify_tp +@@ -669,6 +750,10 @@ flow_dv_convert_action_modify_tp * Pointer to rte_flow_item objects list. * @param[in] attr * Pointer to flow attributes structure. @@ -52748,7 +74471,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to the error structure. * -@@ -680,8 +750,8 @@ flow_dv_convert_action_modify_ttl +@@ -680,8 +765,8 @@ flow_dv_convert_action_modify_ttl (struct mlx5_flow_dv_modify_hdr_resource *resource, const struct rte_flow_action *action, const struct rte_flow_item *items, @@ -52759,7 +74482,7 @@ index 73aaea4536..a1b805c105 100644 { const struct rte_flow_action_set_ttl *conf = (const struct rte_flow_action_set_ttl *)(action->conf); -@@ -693,7 +763,7 @@ flow_dv_convert_action_modify_ttl +@@ -693,7 +778,7 @@ flow_dv_convert_action_modify_ttl struct field_modify_info *field; if (!attr->valid) @@ -52768,7 +74491,7 @@ index 73aaea4536..a1b805c105 100644 if (attr->ipv4) { memset(&ipv4, 0, sizeof(ipv4)); memset(&ipv4_mask, 0, sizeof(ipv4_mask)); -@@ -703,8 +773,8 @@ flow_dv_convert_action_modify_ttl +@@ -703,8 +788,8 @@ flow_dv_convert_action_modify_ttl item.spec = &ipv4; item.mask = &ipv4_mask; field = modify_ipv4; @@ -52779,7 +74502,7 @@ index 73aaea4536..a1b805c105 100644 memset(&ipv6, 0, sizeof(ipv6)); memset(&ipv6_mask, 0, sizeof(ipv6_mask)); ipv6.hdr.hop_limits = conf->ttl_value; -@@ -729,6 +799,10 @@ flow_dv_convert_action_modify_ttl +@@ -729,6 +814,10 @@ flow_dv_convert_action_modify_ttl * Pointer to rte_flow_item objects list. * @param[in] attr * Pointer to flow attributes structure. @@ -52790,7 +74513,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to the error structure. * -@@ -739,8 +813,8 @@ static int +@@ -739,8 +828,8 @@ static int flow_dv_convert_action_modify_dec_ttl (struct mlx5_flow_dv_modify_hdr_resource *resource, const struct rte_flow_item *items, @@ -52801,7 +74524,7 @@ index 73aaea4536..a1b805c105 100644 { struct rte_flow_item item; struct rte_flow_item_ipv4 ipv4; -@@ -750,7 +824,7 @@ flow_dv_convert_action_modify_dec_ttl +@@ -750,7 +839,7 @@ flow_dv_convert_action_modify_dec_ttl struct field_modify_info *field; if (!attr->valid) @@ -52810,7 +74533,7 @@ index 73aaea4536..a1b805c105 100644 if (attr->ipv4) { memset(&ipv4, 0, sizeof(ipv4)); memset(&ipv4_mask, 0, sizeof(ipv4_mask)); -@@ -760,8 +834,8 @@ flow_dv_convert_action_modify_dec_ttl +@@ -760,8 +849,8 @@ flow_dv_convert_action_modify_dec_ttl item.spec = &ipv4; item.mask = &ipv4_mask; field = modify_ipv4; @@ -52821,7 +74544,7 @@ index 73aaea4536..a1b805c105 100644 memset(&ipv6, 0, sizeof(ipv6)); memset(&ipv6_mask, 0, sizeof(ipv6_mask)); ipv6.hdr.hop_limits = 0xFF; -@@ -902,22 +976,20 @@ flow_dv_convert_action_set_reg +@@ -902,22 +991,20 @@ flow_dv_convert_action_set_reg struct mlx5_modification_cmd *actions = resource->actions; uint32_t i = resource->actions_num; @@ -52850,7 +74573,7 @@ index 73aaea4536..a1b805c105 100644 return 0; } -@@ -1075,10 +1147,9 @@ flow_dv_convert_action_mark(struct rte_eth_dev *dev, +@@ -1075,10 +1162,9 @@ flow_dv_convert_action_mark(struct rte_eth_dev *dev, .mask = &mask, }; struct field_modify_info reg_c_x[] = { @@ -52863,7 +74586,7 @@ index 73aaea4536..a1b805c105 100644 if (!mask) return rte_flow_error_set(error, EINVAL, -@@ -1088,7 +1159,15 @@ flow_dv_convert_action_mark(struct rte_eth_dev *dev, +@@ -1088,7 +1174,15 @@ flow_dv_convert_action_mark(struct rte_eth_dev *dev, if (reg < 0) return reg; assert(reg > 0); @@ -52880,7 +74603,7 @@ index 73aaea4536..a1b805c105 100644 return flow_dv_convert_modify_action(&item, reg_c_x, NULL, resource, MLX5_MODIFICATION_TYPE_SET, error); } -@@ -1112,7 +1191,7 @@ flow_dv_get_metadata_reg(struct rte_eth_dev *dev, +@@ -1112,7 +1206,7 @@ flow_dv_get_metadata_reg(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, struct rte_flow_error *error) { @@ -52889,7 +74612,7 @@ index 73aaea4536..a1b805c105 100644 mlx5_flow_get_reg_id(dev, attr->transfer ? MLX5_METADATA_FDB : attr->egress ? -@@ -1160,7 +1239,7 @@ flow_dv_convert_action_set_meta +@@ -1160,7 +1254,7 @@ flow_dv_convert_action_set_meta struct field_modify_info reg_c_x[] = { [1] = {0, 0, 0}, }; @@ -52898,7 +74621,7 @@ index 73aaea4536..a1b805c105 100644 if (reg < 0) return reg; -@@ -1250,6 +1329,11 @@ flow_dv_validate_item_mark(struct rte_eth_dev *dev, +@@ -1250,6 +1344,11 @@ flow_dv_validate_item_mark(struct rte_eth_dev *dev, "mark id exceeds the limit"); if (!mask) mask = &nic_mask; @@ -52910,7 +74633,7 @@ index 73aaea4536..a1b805c105 100644 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, (const uint8_t *)&nic_mask, sizeof(struct rte_flow_item_mark), -@@ -1287,7 +1371,7 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, +@@ -1287,7 +1386,7 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, struct rte_flow_item_meta nic_mask = { .data = UINT32_MAX }; @@ -52919,7 +74642,7 @@ index 73aaea4536..a1b805c105 100644 int ret; if (!spec) -@@ -1295,10 +1379,6 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, +@@ -1295,10 +1394,6 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, item->spec, "data cannot be empty"); @@ -52930,17 +74653,24 @@ index 73aaea4536..a1b805c105 100644 if (config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) { if (!mlx5_flow_ext_mreg_supported(dev)) return rte_flow_error_set(error, ENOTSUP, -@@ -1315,9 +1395,21 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, +@@ -1315,9 +1410,28 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, "isn't supported"); if (reg != REG_A) nic_mask.data = priv->sh->dv_meta_mask; -+ } else if (attr->transfer) { -+ return rte_flow_error_set(error, ENOTSUP, ++ } else { ++ if (attr->transfer) ++ return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "extended metadata feature " + "should be enabled when " + "meta item is requested " + "with e-switch mode "); ++ if (attr->ingress) ++ return rte_flow_error_set(error, ENOTSUP, ++ RTE_FLOW_ERROR_TYPE_ITEM, item, ++ "match on metadata for ingress " ++ "is not supported in legacy " ++ "metadata mode"); } if (!mask) mask = &rte_flow_item_meta_mask; @@ -52952,7 +74682,7 @@ index 73aaea4536..a1b805c105 100644 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, (const uint8_t *)&nic_mask, sizeof(struct rte_flow_item_meta), -@@ -1366,6 +1458,11 @@ flow_dv_validate_item_tag(struct rte_eth_dev *dev, +@@ -1366,6 +1480,11 @@ flow_dv_validate_item_tag(struct rte_eth_dev *dev, "data cannot be empty"); if (!mask) mask = &rte_flow_item_tag_mask; @@ -52964,7 +74694,7 @@ index 73aaea4536..a1b805c105 100644 ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, (const uint8_t *)&nic_mask, sizeof(struct rte_flow_item_tag), -@@ -1465,6 +1562,79 @@ flow_dv_validate_item_port_id(struct rte_eth_dev *dev, +@@ -1465,6 +1584,79 @@ flow_dv_validate_item_port_id(struct rte_eth_dev *dev, return 0; } @@ -53044,7 +74774,7 @@ index 73aaea4536..a1b805c105 100644 /** * Validate the pop VLAN action. * -@@ -1492,7 +1662,7 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, +@@ -1492,7 +1684,7 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, struct rte_flow_error *error) { @@ -53053,7 +74783,7 @@ index 73aaea4536..a1b805c105 100644 (void)action; (void)attr; -@@ -1501,19 +1671,28 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, +@@ -1501,19 +1693,28 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "pop vlan action is not supported"); @@ -53092,7 +74822,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -@@ -1524,20 +1703,21 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, +@@ -1524,20 +1725,21 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_ACTION, action, "wrong action order, port_id should " "be after pop VLAN action"); @@ -53119,7 +74849,7 @@ index 73aaea4536..a1b805c105 100644 * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. -@@ -1554,19 +1734,26 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, +@@ -1554,19 +1756,26 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, if (items == NULL) return; @@ -53151,7 +74881,7 @@ index 73aaea4536..a1b805c105 100644 vlan->vlan_tci |= rte_be_to_cpu_16(vlan_v->tci & MLX5DV_FLOW_VLAN_PCP_MASK_BE); -@@ -1587,10 +1774,14 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, +@@ -1587,10 +1796,14 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, /** * Validate the push VLAN action. * @@ -53167,7 +74897,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] attr * Pointer to flow attributes * @param[out] error -@@ -1600,38 +1791,57 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, +@@ -1600,38 +1813,57 @@ flow_dev_get_vlan_info_from_items(const struct rte_flow_item *items, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int @@ -53241,7 +74971,7 @@ index 73aaea4536..a1b805c105 100644 (void)attr; return 0; } -@@ -1643,8 +1853,6 @@ flow_dv_validate_action_push_vlan(uint64_t action_flags, +@@ -1643,8 +1875,6 @@ flow_dv_validate_action_push_vlan(uint64_t action_flags, * Holds the actions detected until now. * @param[in] actions * Pointer to the list of actions remaining in the flow rule. @@ -53250,7 +74980,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to error structure. * -@@ -1686,10 +1894,10 @@ flow_dv_validate_action_set_vlan_pcp(uint64_t action_flags, +@@ -1686,10 +1916,10 @@ flow_dv_validate_action_set_vlan_pcp(uint64_t action_flags, * * @param[in] item_flags * Holds the items detected in this rule. @@ -53263,7 +74993,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to error structure. * -@@ -1705,37 +1913,21 @@ flow_dv_validate_action_set_vlan_vid(uint64_t item_flags, +@@ -1705,37 +1935,21 @@ flow_dv_validate_action_set_vlan_vid(uint64_t item_flags, const struct rte_flow_action *action = actions; const struct rte_flow_action_of_set_vlan_vid *conf = action->conf; @@ -53308,7 +75038,7 @@ index 73aaea4536..a1b805c105 100644 if (action_flags & MLX5_FLOW_ACTION_PORT_ID) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, -@@ -1788,10 +1980,6 @@ flow_dv_validate_action_flag(struct rte_eth_dev *dev, +@@ -1788,10 +2002,6 @@ flow_dv_validate_action_flag(struct rte_eth_dev *dev, if (ret < 0) return ret; assert(ret > 0); @@ -53319,7 +75049,7 @@ index 73aaea4536..a1b805c105 100644 if (action_flags & MLX5_FLOW_ACTION_MARK) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -1861,10 +2049,6 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev, +@@ -1861,10 +2071,6 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_ACTION_CONF, &mark->id, "mark id exceeds the limit"); @@ -53330,7 +75060,7 @@ index 73aaea4536..a1b805c105 100644 if (action_flags & MLX5_FLOW_ACTION_FLAG) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -1883,7 +2067,7 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev, +@@ -1883,7 +2089,7 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev, * @param[in] dev * Pointer to the rte_eth_dev structure. * @param[in] action @@ -53339,7 +75069,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] action_flags * Holds the actions detected until now. * @param[in] attr -@@ -1903,7 +2087,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, +@@ -1903,7 +2109,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, { const struct rte_flow_action_set_meta *conf; uint32_t nic_mask = UINT32_MAX; @@ -53348,7 +75078,7 @@ index 73aaea4536..a1b805c105 100644 if (!mlx5_flow_ext_mreg_supported(dev)) return rte_flow_error_set(error, ENOTSUP, -@@ -1931,10 +2115,6 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, +@@ -1931,10 +2137,6 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, "meta data must be within reg C0"); @@ -53359,7 +75089,7 @@ index 73aaea4536..a1b805c105 100644 return 0; } -@@ -1944,7 +2124,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, +@@ -1944,7 +2146,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev, * @param[in] dev * Pointer to the rte_eth_dev structure. * @param[in] action @@ -53368,7 +75098,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] action_flags * Holds the actions detected until now. * @param[in] attr -@@ -1998,7 +2178,7 @@ flow_dv_validate_action_set_tag(struct rte_eth_dev *dev, +@@ -1998,7 +2200,7 @@ flow_dv_validate_action_set_tag(struct rte_eth_dev *dev, * Validate count action. * * @param[in] dev @@ -53377,7 +75107,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to error structure. * -@@ -2027,12 +2207,14 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, +@@ -2027,12 +2229,14 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, /** * Validate the L2 encap action. * @@ -53394,7 +75124,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to error structure. * -@@ -2040,38 +2222,42 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, +@@ -2040,38 +2244,42 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int @@ -53451,7 +75181,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] attr * Pointer to flow attributes * @param[out] error -@@ -2081,19 +2267,22 @@ flow_dv_validate_action_l2_encap(uint64_t action_flags, +@@ -2081,19 +2289,22 @@ flow_dv_validate_action_l2_encap(uint64_t action_flags, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int @@ -53485,7 +75215,7 @@ index 73aaea4536..a1b805c105 100644 if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -2105,69 +2294,40 @@ flow_dv_validate_action_l2_decap(uint64_t action_flags, +@@ -2105,69 +2316,40 @@ flow_dv_validate_action_l2_decap(uint64_t action_flags, NULL, "decap action not supported for " "egress"); @@ -53579,7 +75309,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to error structure. * -@@ -2175,41 +2335,73 @@ flow_dv_validate_action_raw_encap(uint64_t action_flags, +@@ -2175,41 +2357,73 @@ flow_dv_validate_action_raw_encap(uint64_t action_flags, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int @@ -53601,9 +75331,8 @@ index 73aaea4536..a1b805c105 100644 + int ret; - if (action_flags & MLX5_FLOW_ACTION_DROP) -+ if (encap && (!encap->size || !encap->data)) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, NULL, +- return rte_flow_error_set(error, EINVAL, +- RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "can't drop and decap in same flow"); - if (action_flags & MLX5_FLOW_ENCAP_ACTIONS) - return rte_flow_error_set(error, EINVAL, @@ -53611,8 +75340,9 @@ index 73aaea4536..a1b805c105 100644 - "can't have encap action before" - " decap action"); - if (action_flags & MLX5_FLOW_DECAP_ACTIONS) -- return rte_flow_error_set(error, EINVAL, -- RTE_FLOW_ERROR_TYPE_ACTION, NULL, ++ if (encap && (!encap->size || !encap->data)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "can only have a single decap" - " action in a flow"); - /* decap action is valid on egress only if it is followed by encap */ @@ -53685,7 +75415,7 @@ index 73aaea4536..a1b805c105 100644 } return 0; } -@@ -2248,7 +2440,6 @@ flow_dv_encap_decap_resource_register +@@ -2248,7 +2462,6 @@ flow_dv_encap_decap_resource_register domain = sh->rx_domain; else domain = sh->tx_domain; @@ -53693,7 +75423,7 @@ index 73aaea4536..a1b805c105 100644 /* Lookup a matching resource from cache. */ LIST_FOREACH(cache_resource, &sh->encaps_decaps, next) { if (resource->reformat_type == cache_resource->reformat_type && -@@ -2334,6 +2525,8 @@ flow_dv_jump_tbl_resource_register +@@ -2334,6 +2547,8 @@ flow_dv_jump_tbl_resource_register DRV_LOG(DEBUG, "new jump table resource %p: refcnt %d++", (void *)&tbl_data->jump, cnt); } else { @@ -53702,7 +75432,7 @@ index 73aaea4536..a1b805c105 100644 assert(tbl_data->jump.action); DRV_LOG(DEBUG, "existed jump table resource %p: refcnt %d++", (void *)&tbl_data->jump, cnt); -@@ -2484,7 +2677,7 @@ flow_dv_push_vlan_action_resource_register +@@ -2484,7 +2699,7 @@ flow_dv_push_vlan_action_resource_register return 0; } /** @@ -53711,7 +75441,7 @@ index 73aaea4536..a1b805c105 100644 * * @param[in] item_type * Tested rte_flow_item_type. -@@ -2493,43 +2686,39 @@ flow_dv_push_vlan_action_resource_register +@@ -2493,43 +2708,39 @@ flow_dv_push_vlan_action_resource_register * sizeof struct item_type, 0 if void or irrelevant. */ static size_t @@ -53766,7 +75496,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ITEM_TYPE_VOID: /* Fall through. */ default: -@@ -2582,7 +2771,7 @@ flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf, +@@ -2582,7 +2793,7 @@ flow_dv_convert_encap_data(const struct rte_flow_item *items, uint8_t *buf, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "invalid empty data"); for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { @@ -53775,7 +75505,7 @@ index 73aaea4536..a1b805c105 100644 if (len + temp_size > MLX5_ENCAP_MAX_LEN) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, -@@ -2799,8 +2988,6 @@ flow_dv_create_action_l2_encap(struct rte_eth_dev *dev, +@@ -2799,8 +3010,6 @@ flow_dv_create_action_l2_encap(struct rte_eth_dev *dev, (const struct rte_flow_action_raw_encap *)action->conf; res.size = raw_encap_data->size; memcpy(res.buf, raw_encap_data->data, res.size); @@ -53784,7 +75514,7 @@ index 73aaea4536..a1b805c105 100644 } else { if (action->type == RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP) encap_data = -@@ -2814,6 +3001,8 @@ flow_dv_create_action_l2_encap(struct rte_eth_dev *dev, +@@ -2814,6 +3023,8 @@ flow_dv_create_action_l2_encap(struct rte_eth_dev *dev, &res.size, error)) return -rte_errno; } @@ -53793,7 +75523,7 @@ index 73aaea4536..a1b805c105 100644 if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow, error)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, -@@ -2907,12 +3096,12 @@ flow_dv_create_action_raw_encap(struct rte_eth_dev *dev, +@@ -2907,12 +3118,12 @@ flow_dv_create_action_raw_encap(struct rte_eth_dev *dev, * * @param[in] dev * Pointer to rte_eth_dev structure. @@ -53810,7 +75540,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to the error structure. * -@@ -2962,7 +3151,7 @@ flow_dv_validate_action_modify_hdr(const uint64_t action_flags, +@@ -2962,7 +3173,7 @@ flow_dv_validate_action_modify_hdr(const uint64_t action_flags, return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, "action configuration not set"); @@ -53819,7 +75549,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have encap action before" -@@ -3026,10 +3215,14 @@ flow_dv_validate_action_modify_ipv4(const uint64_t action_flags, +@@ -3026,10 +3237,14 @@ flow_dv_validate_action_modify_ipv4(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53835,7 +75565,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -3060,10 +3253,14 @@ flow_dv_validate_action_modify_ipv6(const uint64_t action_flags, +@@ -3060,10 +3275,14 @@ flow_dv_validate_action_modify_ipv6(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53851,7 +75581,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -3094,10 +3291,14 @@ flow_dv_validate_action_modify_tp(const uint64_t action_flags, +@@ -3094,10 +3313,14 @@ flow_dv_validate_action_modify_tp(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53867,7 +75597,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "no transport layer " -@@ -3129,10 +3330,14 @@ flow_dv_validate_action_modify_tcp_seq(const uint64_t action_flags, +@@ -3129,10 +3352,14 @@ flow_dv_validate_action_modify_tcp_seq(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53883,7 +75613,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "no TCP item in" -@@ -3174,10 +3379,14 @@ flow_dv_validate_action_modify_tcp_ack(const uint64_t action_flags, +@@ -3174,10 +3401,14 @@ flow_dv_validate_action_modify_tcp_ack(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53899,7 +75629,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "no TCP item in" -@@ -3218,10 +3427,14 @@ flow_dv_validate_action_modify_ttl(const uint64_t action_flags, +@@ -3218,10 +3449,14 @@ flow_dv_validate_action_modify_ttl(const uint64_t action_flags, struct rte_flow_error *error) { int ret = 0; @@ -53915,7 +75645,16 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -3273,7 +3486,7 @@ flow_dv_validate_action_jump(const struct rte_flow_action *action, +@@ -3253,7 +3488,7 @@ flow_dv_validate_action_jump(const struct rte_flow_action *action, + const struct rte_flow_attr *attributes, + bool external, struct rte_flow_error *error) + { +- uint32_t target_group, table; ++ uint32_t target_group, table = 0; + int ret = 0; + + if (action_flags & (MLX5_FLOW_FATE_ACTIONS | +@@ -3273,7 +3508,7 @@ flow_dv_validate_action_jump(const struct rte_flow_action *action, target_group = ((const struct rte_flow_action_jump *)action->conf)->group; ret = mlx5_flow_group_to_table(attributes, external, target_group, @@ -53924,7 +75663,18 @@ index 73aaea4536..a1b805c105 100644 if (ret) return ret; if (attributes->group == target_group) -@@ -3359,21 +3572,24 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev, +@@ -3281,6 +3516,10 @@ flow_dv_validate_action_jump(const struct rte_flow_action *action, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "target group must be other than" + " the current flow group"); ++ if (table == 0) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ACTION_CONF, ++ NULL, "root table shouldn't be destination"); + return 0; + } + +@@ -3359,21 +3598,24 @@ flow_dv_validate_action_port_id(struct rte_eth_dev *dev, * * @param dev * Pointer to rte_eth_dev structure. @@ -53957,7 +75707,7 @@ index 73aaea4536..a1b805c105 100644 } /** -@@ -3402,7 +3618,12 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev, +@@ -3402,7 +3644,12 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; const struct rte_flow_action_meter *am = action->conf; @@ -53971,7 +75721,7 @@ index 73aaea4536..a1b805c105 100644 if (action_flags & MLX5_FLOW_ACTION_METER) return rte_flow_error_set(error, ENOTSUP, -@@ -3417,6 +3638,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev, +@@ -3417,6 +3664,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "meter action not supported"); @@ -53979,7 +75729,7 @@ index 73aaea4536..a1b805c105 100644 if (!fm) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, -@@ -3458,8 +3680,12 @@ flow_dv_modify_hdr_resource_register +@@ -3458,8 +3706,12 @@ flow_dv_modify_hdr_resource_register struct mlx5_ibv_shared *sh = priv->sh; struct mlx5_flow_dv_modify_hdr_resource *cache_resource; struct mlx5dv_dr_domain *ns; @@ -53993,7 +75743,7 @@ index 73aaea4536..a1b805c105 100644 return rte_flow_error_set(error, EOVERFLOW, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "too many modify header items"); -@@ -3469,17 +3695,15 @@ flow_dv_modify_hdr_resource_register +@@ -3469,17 +3721,15 @@ flow_dv_modify_hdr_resource_register ns = sh->tx_domain; else ns = sh->rx_domain; @@ -54013,7 +75763,7 @@ index 73aaea4536..a1b805c105 100644 DRV_LOG(DEBUG, "modify-header resource %p: refcnt %d++", (void *)cache_resource, rte_atomic32_read(&cache_resource->refcnt)); -@@ -3489,18 +3713,18 @@ flow_dv_modify_hdr_resource_register +@@ -3489,18 +3739,18 @@ flow_dv_modify_hdr_resource_register } } /* Register new modify-header resource. */ @@ -54037,7 +75787,7 @@ index 73aaea4536..a1b805c105 100644 (uint64_t *)cache_resource->actions); if (!cache_resource->verbs_action) { rte_free(cache_resource); -@@ -3846,11 +4070,13 @@ _flow_dv_query_count(struct rte_eth_dev *dev, +@@ -3846,11 +4096,13 @@ _flow_dv_query_count(struct rte_eth_dev *dev, * The devX counter handle. * @param[in] batch * Whether the pool is for counter that was allocated by batch command. @@ -54053,7 +75803,7 @@ index 73aaea4536..a1b805c105 100644 flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs, uint32_t batch) { -@@ -3884,12 +4110,69 @@ flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs, +@@ -3884,12 +4136,69 @@ flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs, */ rte_atomic64_set(&pool->query_gen, 0x2); TAILQ_INIT(&pool->counters); @@ -54125,7 +75875,7 @@ index 73aaea4536..a1b805c105 100644 } /** -@@ -3903,42 +4186,77 @@ flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs, +@@ -3903,42 +4212,77 @@ flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs, * Whether the pool is for counter that was allocated by batch command. * * @return @@ -54212,7 +75962,7 @@ index 73aaea4536..a1b805c105 100644 } /* bulk_bitmap is in 128 counters units. */ if (priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4) -@@ -3947,18 +4265,19 @@ flow_dv_counter_pool_prepare(struct rte_eth_dev *dev, +@@ -3947,18 +4291,19 @@ flow_dv_counter_pool_prepare(struct rte_eth_dev *dev, rte_errno = ENODATA; return NULL; } @@ -54235,7 +75985,7 @@ index 73aaea4536..a1b805c105 100644 } /** -@@ -4059,9 +4378,10 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, +@@ -4059,9 +4404,10 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, cnt_free = NULL; } if (!cnt_free) { @@ -54248,7 +75998,7 @@ index 73aaea4536..a1b805c105 100644 } cnt_free->batch = batch; /* Create a DV counter action only in the first time usage. */ -@@ -4146,7 +4466,9 @@ flow_dv_counter_release(struct rte_eth_dev *dev, +@@ -4146,7 +4492,9 @@ flow_dv_counter_release(struct rte_eth_dev *dev, * Pointer to error structure. * * @return @@ -54259,7 +76009,7 @@ index 73aaea4536..a1b805c105 100644 */ static int flow_dv_validate_attributes(struct rte_eth_dev *dev, -@@ -4156,6 +4478,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, +@@ -4156,6 +4504,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; uint32_t priority_max = priv->config.flow_prio - 1; @@ -54267,7 +76017,7 @@ index 73aaea4536..a1b805c105 100644 #ifndef HAVE_MLX5DV_DR if (attributes->group) -@@ -4164,14 +4487,15 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, +@@ -4164,14 +4513,15 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, NULL, "groups are not supported"); #else @@ -54286,7 +76036,7 @@ index 73aaea4536..a1b805c105 100644 #endif if (attributes->priority != MLX5_FLOW_PRIO_RSVD && attributes->priority >= priority_max) -@@ -4201,7 +4525,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, +@@ -4201,7 +4551,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_ATTR, NULL, "must specify exactly one of " "ingress or egress"); @@ -54295,7 +76045,7 @@ index 73aaea4536..a1b805c105 100644 } /** -@@ -4217,6 +4541,8 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, +@@ -4217,6 +4567,8 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, * Pointer to the list of actions. * @param[in] external * This flow rule is created by request external to PMD. @@ -54304,7 +76054,7 @@ index 73aaea4536..a1b805c105 100644 * @param[out] error * Pointer to the error structure. * -@@ -4227,7 +4553,7 @@ static int +@@ -4227,7 +4579,7 @@ static int flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], @@ -54313,7 +76063,7 @@ index 73aaea4536..a1b805c105 100644 { int ret; uint64_t action_flags = 0; -@@ -4236,7 +4562,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4236,7 +4588,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, uint8_t next_protocol = 0xff; uint16_t ether_type = 0; int actions_n = 0; @@ -54325,7 +76075,7 @@ index 73aaea4536..a1b805c105 100644 struct rte_flow_item_tcp nic_tcp_mask = { .hdr = { .tcp_flags = 0xFF, -@@ -4246,12 +4576,17 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4246,12 +4602,17 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, }; struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_dev_config *dev_conf = &priv->config; @@ -54343,7 +76093,7 @@ index 73aaea4536..a1b805c105 100644 for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); int type = items->type; -@@ -4286,8 +4621,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4286,8 +4647,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, } break; case RTE_FLOW_ITEM_TYPE_VLAN: @@ -54354,7 +76104,7 @@ index 73aaea4536..a1b805c105 100644 if (ret < 0) return ret; last_item = tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : -@@ -4303,6 +4638,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4303,6 +4664,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, } else { ether_type = 0; } @@ -54364,7 +76114,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ITEM_TYPE_IPV4: mlx5_flow_tunnel_ip_check(items, next_protocol, -@@ -4343,6 +4681,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4343,6 +4707,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, if (items->mask != NULL && ((const struct rte_flow_item_ipv6 *) items->mask)->hdr.proto) { @@ -54374,7 +76124,7 @@ index 73aaea4536..a1b805c105 100644 next_protocol = ((const struct rte_flow_item_ipv6 *) items->spec)->hdr.proto; -@@ -4418,7 +4759,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4418,7 +4785,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, error); if (ret < 0) return ret; @@ -54383,7 +76133,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ITEM_TYPE_MPLS: ret = mlx5_flow_validate_item_mpls(dev, items, -@@ -4457,6 +4798,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4457,6 +4824,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, error); if (ret < 0) return ret; @@ -54391,7 +76141,19 @@ index 73aaea4536..a1b805c105 100644 last_item = MLX5_FLOW_LAYER_ICMP6; break; case RTE_FLOW_ITEM_TYPE_TAG: -@@ -4512,6 +4854,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4466,8 +4834,10 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + return ret; + last_item = MLX5_FLOW_ITEM_TAG; + break; ++ case MLX5_RTE_FLOW_ITEM_TYPE_TX_QUEUE: ++ last_item = MLX5_FLOW_ITEM_TX_QUEUE; ++ break; + case MLX5_RTE_FLOW_ITEM_TYPE_TAG: +- case MLX5_RTE_FLOW_ITEM_TYPE_TX_QUEUE: + break; + default: + return rte_flow_error_set(error, ENOTSUP, +@@ -4512,6 +4882,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, action_flags |= MLX5_FLOW_ACTION_FLAG; ++actions_n; } @@ -54399,7 +76161,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_MARK: ret = flow_dv_validate_action_mark(dev, actions, -@@ -4530,6 +4873,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4530,6 +4901,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, action_flags |= MLX5_FLOW_ACTION_MARK; ++actions_n; } @@ -54407,7 +76169,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_SET_META: ret = flow_dv_validate_action_set_meta(dev, actions, -@@ -4541,6 +4885,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4541,6 +4913,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)) ++actions_n; action_flags |= MLX5_FLOW_ACTION_SET_META; @@ -54415,7 +76177,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_SET_TAG: ret = flow_dv_validate_action_set_tag(dev, actions, -@@ -4552,6 +4897,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4552,6 +4925,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)) ++actions_n; action_flags |= MLX5_FLOW_ACTION_SET_TAG; @@ -54423,7 +76185,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_DROP: ret = mlx5_flow_validate_action_drop(action_flags, -@@ -4567,16 +4913,21 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4567,16 +4941,21 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, attr, error); if (ret < 0) return ret; @@ -54445,7 +76207,7 @@ index 73aaea4536..a1b805c105 100644 action_flags |= MLX5_FLOW_ACTION_RSS; ++actions_n; break; -@@ -4598,8 +4949,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4598,8 +4977,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, ++actions_n; break; case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: @@ -54457,7 +76219,7 @@ index 73aaea4536..a1b805c105 100644 actions, attr, error); if (ret < 0) -@@ -4623,49 +4975,53 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4623,49 +5003,53 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; /* Count VID with push_vlan command. */ action_flags |= MLX5_FLOW_ACTION_OF_SET_VLAN_VID; @@ -54532,7 +76294,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: -@@ -4682,8 +5038,15 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4682,8 +5066,15 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ? MLX5_FLOW_ACTION_SET_MAC_SRC : MLX5_FLOW_ACTION_SET_MAC_DST; @@ -54549,7 +76311,7 @@ index 73aaea4536..a1b805c105 100644 case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: ret = flow_dv_validate_action_modify_ipv4(action_flags, -@@ -4699,6 +5062,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4699,6 +5090,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ? MLX5_FLOW_ACTION_SET_IPV4_SRC : MLX5_FLOW_ACTION_SET_IPV4_DST; @@ -54557,7 +76319,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: -@@ -4708,6 +5072,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4708,6 +5100,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, error); if (ret < 0) return ret; @@ -54570,7 +76332,7 @@ index 73aaea4536..a1b805c105 100644 /* Count all modify-header actions as one action. */ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS)) ++actions_n; -@@ -4715,6 +5085,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4715,6 +5113,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ? MLX5_FLOW_ACTION_SET_IPV6_SRC : MLX5_FLOW_ACTION_SET_IPV6_DST; @@ -54578,7 +76340,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: case RTE_FLOW_ACTION_TYPE_SET_TP_DST: -@@ -4731,6 +5102,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4731,6 +5130,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_SET_TP_SRC ? MLX5_FLOW_ACTION_SET_TP_SRC : MLX5_FLOW_ACTION_SET_TP_DST; @@ -54586,7 +76348,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_DEC_TTL: case RTE_FLOW_ACTION_TYPE_SET_TTL: -@@ -4747,6 +5119,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4747,6 +5147,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_SET_TTL ? MLX5_FLOW_ACTION_SET_TTL : MLX5_FLOW_ACTION_DEC_TTL; @@ -54594,7 +76356,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_JUMP: ret = flow_dv_validate_action_jump(actions, -@@ -4774,6 +5147,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4774,6 +5175,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ? MLX5_FLOW_ACTION_INC_TCP_SEQ : MLX5_FLOW_ACTION_DEC_TCP_SEQ; @@ -54602,7 +76364,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK: case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK: -@@ -4791,10 +5165,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4791,10 +5193,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ? MLX5_FLOW_ACTION_INC_TCP_ACK : MLX5_FLOW_ACTION_DEC_TCP_ACK; @@ -54617,7 +76379,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_METER: ret = mlx5_flow_validate_action_meter(dev, -@@ -4805,6 +5182,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4805,6 +5210,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; action_flags |= MLX5_FLOW_ACTION_METER; ++actions_n; @@ -54626,7 +76388,7 @@ index 73aaea4536..a1b805c105 100644 break; default: return rte_flow_error_set(error, ENOTSUP, -@@ -4813,13 +5192,18 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4813,13 +5220,18 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, "action not supported"); } } @@ -54652,7 +76414,7 @@ index 73aaea4536..a1b805c105 100644 /* Eswitch has few restrictions on using items and actions */ if (attr->transfer) { if (!mlx5_flow_ext_mreg_supported(dev) && -@@ -4856,6 +5240,54 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, +@@ -4856,6 +5268,66 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, actions, "no fate action is found"); } @@ -54704,10 +76466,22 @@ index 73aaea4536..a1b805c105 100644 + NULL, "too many header modify" + " actions to support"); + } ++ /* ++ * Validation the NIC Egress flow on representor, except implicit ++ * hairpin default egress flow with TX_QUEUE item, other flows not ++ * work due to metadata regC0 mismatch. ++ */ ++ if ((!attr->transfer && attr->egress) && priv->representor && ++ !(item_flags & MLX5_FLOW_ITEM_TX_QUEUE)) ++ return rte_flow_error_set(error, EINVAL, ++ RTE_FLOW_ERROR_TYPE_ITEM, ++ NULL, ++ "NIC egress rules on representors" ++ " is not supported"); return 0; } -@@ -4984,6 +5416,23 @@ flow_dv_translate_item_eth(void *matcher, void *key, +@@ -4984,6 +5456,23 @@ flow_dv_translate_item_eth(void *matcher, void *key, /* The value must be in the range of the mask. */ for (i = 0; i < sizeof(eth_m->dst); ++i) l24_v[i] = eth_m->src.addr_bytes[i] & eth_v->src.addr_bytes[i]; @@ -54731,7 +76505,7 @@ index 73aaea4536..a1b805c105 100644 MLX5_SET(fte_match_set_lyr_2_4, headers_m, ethertype, rte_be_to_cpu_16(eth_m->type)); l24_v = MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, ethertype); -@@ -5017,10 +5466,6 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, +@@ -5017,10 +5506,6 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, uint16_t tci_m; uint16_t tci_v; @@ -54742,7 +76516,7 @@ index 73aaea4536..a1b805c105 100644 if (inner) { headers_m = MLX5_ADDR_OF(fte_match_param, matcher, inner_headers); -@@ -5033,13 +5478,22 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, +@@ -5033,13 +5518,22 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, * This is workaround, masks are not supported, * and pre-validated. */ @@ -54769,7 +76543,7 @@ index 73aaea4536..a1b805c105 100644 MLX5_SET(fte_match_set_lyr_2_4, headers_m, first_vid, tci_m); MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, tci_v); MLX5_SET(fte_match_set_lyr_2_4, headers_m, first_cfi, tci_m >> 12); -@@ -5061,6 +5515,8 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, +@@ -5061,6 +5555,8 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, * Flow matcher value. * @param[in] item * Flow pattern to translate. @@ -54778,7 +76552,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] inner * Item is inner pattern. * @param[in] group -@@ -5069,6 +5525,7 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, +@@ -5069,6 +5565,7 @@ flow_dv_translate_item_vlan(struct mlx5_flow *dev_flow, static void flow_dv_translate_item_ipv4(void *matcher, void *key, const struct rte_flow_item *item, @@ -54786,7 +76560,7 @@ index 73aaea4536..a1b805c105 100644 int inner, uint32_t group) { const struct rte_flow_item_ipv4 *ipv4_m = item->mask; -@@ -5101,6 +5558,13 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, +@@ -5101,6 +5598,13 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, else MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_version, 0x4); MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_version, 4); @@ -54800,7 +76574,7 @@ index 73aaea4536..a1b805c105 100644 if (!ipv4_v) return; if (!ipv4_m) -@@ -5139,6 +5603,8 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, +@@ -5139,6 +5643,8 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, * Flow matcher value. * @param[in] item * Flow pattern to translate. @@ -54809,7 +76583,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] inner * Item is inner pattern. * @param[in] group -@@ -5147,6 +5613,7 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, +@@ -5147,6 +5653,7 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, static void flow_dv_translate_item_ipv6(void *matcher, void *key, const struct rte_flow_item *item, @@ -54817,7 +76591,7 @@ index 73aaea4536..a1b805c105 100644 int inner, uint32_t group) { const struct rte_flow_item_ipv6 *ipv6_m = item->mask; -@@ -5189,6 +5656,13 @@ flow_dv_translate_item_ipv6(void *matcher, void *key, +@@ -5189,6 +5696,13 @@ flow_dv_translate_item_ipv6(void *matcher, void *key, else MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_version, 0x6); MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_version, 6); @@ -54831,7 +76605,7 @@ index 73aaea4536..a1b805c105 100644 if (!ipv6_v) return; if (!ipv6_m) -@@ -5354,13 +5828,13 @@ flow_dv_translate_item_gre_key(void *matcher, void *key, +@@ -5354,13 +5868,13 @@ flow_dv_translate_item_gre_key(void *matcher, void *key, void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); @@ -54848,7 +76622,100 @@ index 73aaea4536..a1b805c105 100644 MLX5_SET(fte_match_set_misc, misc_m, gre_key_h, rte_be_to_cpu_32(*key_m) >> 8); MLX5_SET(fte_match_set_misc, misc_v, gre_key_h, -@@ -5468,8 +5942,8 @@ flow_dv_translate_item_nvgre(void *matcher, void *key, +@@ -5380,18 +5894,19 @@ flow_dv_translate_item_gre_key(void *matcher, void *key, + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. +- * @param[in] inner +- * Item is inner pattern. ++ * @param[in] pattern_flags ++ * Accumulated pattern flags. + */ + static void + flow_dv_translate_item_gre(void *matcher, void *key, + const struct rte_flow_item *item, +- int inner) ++ uint64_t pattern_flags) + { ++ static const struct rte_flow_item_gre empty_gre = {0,}; + const struct rte_flow_item_gre *gre_m = item->mask; + const struct rte_flow_item_gre *gre_v = item->spec; +- void *headers_m; +- void *headers_v; ++ void *headers_m = MLX5_ADDR_OF(fte_match_param, matcher, outer_headers); ++ void *headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); + void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters); + void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); + struct { +@@ -5408,26 +5923,17 @@ flow_dv_translate_item_gre(void *matcher, void *key, + uint16_t value; + }; + } gre_crks_rsvd0_ver_m, gre_crks_rsvd0_ver_v; ++ uint16_t protocol_m, protocol_v; + +- if (inner) { +- headers_m = MLX5_ADDR_OF(fte_match_param, matcher, +- inner_headers); +- headers_v = MLX5_ADDR_OF(fte_match_param, key, inner_headers); +- } else { +- headers_m = MLX5_ADDR_OF(fte_match_param, matcher, +- outer_headers); +- headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); +- } + MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_protocol, 0xff); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, IPPROTO_GRE); +- if (!gre_v) +- return; +- if (!gre_m) +- gre_m = &rte_flow_item_gre_mask; +- MLX5_SET(fte_match_set_misc, misc_m, gre_protocol, +- rte_be_to_cpu_16(gre_m->protocol)); +- MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, +- rte_be_to_cpu_16(gre_v->protocol & gre_m->protocol)); ++ if (!gre_v) { ++ gre_v = &empty_gre; ++ gre_m = &empty_gre; ++ } else { ++ if (!gre_m) ++ gre_m = &rte_flow_item_gre_mask; ++ } + gre_crks_rsvd0_ver_m.value = rte_be_to_cpu_16(gre_m->c_rsvd0_ver); + gre_crks_rsvd0_ver_v.value = rte_be_to_cpu_16(gre_v->c_rsvd0_ver); + MLX5_SET(fte_match_set_misc, misc_m, gre_c_present, +@@ -5445,6 +5951,17 @@ flow_dv_translate_item_gre(void *matcher, void *key, + MLX5_SET(fte_match_set_misc, misc_v, gre_s_present, + gre_crks_rsvd0_ver_v.s_present & + gre_crks_rsvd0_ver_m.s_present); ++ protocol_m = rte_be_to_cpu_16(gre_m->protocol); ++ protocol_v = rte_be_to_cpu_16(gre_v->protocol); ++ if (!protocol_m) { ++ /* Force next protocol to prevent matchers duplication */ ++ protocol_v = mlx5_translate_tunnel_etypes(pattern_flags); ++ if (protocol_v) ++ protocol_m = 0xFFFF; ++ } ++ MLX5_SET(fte_match_set_misc, misc_m, gre_protocol, protocol_m); ++ MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, ++ protocol_m & protocol_v); + } + + /** +@@ -5456,20 +5973,20 @@ flow_dv_translate_item_gre(void *matcher, void *key, + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. +- * @param[in] inner +- * Item is inner pattern. ++ * @param[in] pattern_flags ++ * Accumulated pattern flags. + */ + static void + flow_dv_translate_item_nvgre(void *matcher, void *key, + const struct rte_flow_item *item, +- int inner) ++ unsigned long pattern_flags) + { + const struct rte_flow_item_nvgre *nvgre_m = item->mask; const struct rte_flow_item_nvgre *nvgre_v = item->spec; void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters); void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); @@ -54859,7 +76726,13 @@ index 73aaea4536..a1b805c105 100644 char *gre_key_m; char *gre_key_v; int size; -@@ -5494,6 +5968,8 @@ flow_dv_translate_item_nvgre(void *matcher, void *key, +@@ -5489,11 +6006,13 @@ flow_dv_translate_item_nvgre(void *matcher, void *key, + .mask = &gre_mask, + .last = NULL, + }; +- flow_dv_translate_item_gre(matcher, key, &gre_item, inner); ++ flow_dv_translate_item_gre(matcher, key, &gre_item, pattern_flags); + if (!nvgre_v) return; if (!nvgre_m) nvgre_m = &rte_flow_item_nvgre_mask; @@ -54868,7 +76741,7 @@ index 73aaea4536..a1b805c105 100644 size = sizeof(nvgre_m->tni) + sizeof(nvgre_m->flow_id); gre_key_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, gre_key_h); gre_key_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, gre_key_h); -@@ -5558,6 +6034,76 @@ flow_dv_translate_item_vxlan(void *matcher, void *key, +@@ -5558,6 +6077,83 @@ flow_dv_translate_item_vxlan(void *matcher, void *key, vni_v[i] = vni_m[i] & vxlan_v->vni[i]; } @@ -54887,46 +76760,40 @@ index 73aaea4536..a1b805c105 100644 + +static void +flow_dv_translate_item_vxlan_gpe(void *matcher, void *key, -+ const struct rte_flow_item *item, int inner) ++ const struct rte_flow_item *item, ++ const uint64_t pattern_flags) +{ ++ static const struct rte_flow_item_vxlan_gpe dummy_vxlan_gpe_hdr = {0, }; + const struct rte_flow_item_vxlan_gpe *vxlan_m = item->mask; + const struct rte_flow_item_vxlan_gpe *vxlan_v = item->spec; -+ void *headers_m; -+ void *headers_v; ++ /* The item was validated to be on the outer side */ ++ void *headers_m = MLX5_ADDR_OF(fte_match_param, matcher, outer_headers); ++ void *headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); + void *misc_m = + MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_3); + void *misc_v = + MLX5_ADDR_OF(fte_match_param, key, misc_parameters_3); -+ char *vni_m; -+ char *vni_v; -+ uint16_t dport; -+ int size; -+ int i; ++ char *vni_m = ++ MLX5_ADDR_OF(fte_match_set_misc3, misc_m, outer_vxlan_gpe_vni); ++ char *vni_v = ++ MLX5_ADDR_OF(fte_match_set_misc3, misc_v, outer_vxlan_gpe_vni); ++ int i, size = sizeof(vxlan_m->vni); + uint8_t flags_m = 0xff; + uint8_t flags_v = 0xc; ++ uint8_t m_protocol, v_protocol; + -+ if (inner) { -+ headers_m = MLX5_ADDR_OF(fte_match_param, matcher, -+ inner_headers); -+ headers_v = MLX5_ADDR_OF(fte_match_param, key, inner_headers); -+ } else { -+ headers_m = MLX5_ADDR_OF(fte_match_param, matcher, -+ outer_headers); -+ headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); -+ } -+ dport = item->type == RTE_FLOW_ITEM_TYPE_VXLAN ? -+ MLX5_UDP_PORT_VXLAN : MLX5_UDP_PORT_VXLAN_GPE; + if (!MLX5_GET16(fte_match_set_lyr_2_4, headers_v, udp_dport)) { + MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xFFFF); -+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, dport); ++ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, ++ MLX5_UDP_PORT_VXLAN_GPE); ++ } ++ if (!vxlan_v) { ++ vxlan_v = &dummy_vxlan_gpe_hdr; ++ vxlan_m = &dummy_vxlan_gpe_hdr; ++ } else { ++ if (!vxlan_m) ++ vxlan_m = &rte_flow_item_vxlan_gpe_mask; + } -+ if (!vxlan_v) -+ return; -+ if (!vxlan_m) -+ vxlan_m = &rte_flow_item_vxlan_gpe_mask; -+ size = sizeof(vxlan_m->vni); -+ vni_m = MLX5_ADDR_OF(fte_match_set_misc3, misc_m, outer_vxlan_gpe_vni); -+ vni_v = MLX5_ADDR_OF(fte_match_set_misc3, misc_v, outer_vxlan_gpe_vni); + memcpy(vni_m, vxlan_m->vni, size); + for (i = 0; i < size; ++i) + vni_v[i] = vni_m[i] & vxlan_v->vni[i]; @@ -54936,16 +76803,150 @@ index 73aaea4536..a1b805c105 100644 + } + MLX5_SET(fte_match_set_misc3, misc_m, outer_vxlan_gpe_flags, flags_m); + MLX5_SET(fte_match_set_misc3, misc_v, outer_vxlan_gpe_flags, flags_v); -+ MLX5_SET(fte_match_set_misc3, misc_m, outer_vxlan_gpe_next_protocol, -+ vxlan_m->protocol); -+ MLX5_SET(fte_match_set_misc3, misc_v, outer_vxlan_gpe_next_protocol, -+ vxlan_v->protocol); ++ m_protocol = vxlan_m->protocol; ++ v_protocol = vxlan_v->protocol; ++ if (!m_protocol) { ++ /* Force next protocol to ensure next headers parsing. */ ++ if (pattern_flags & MLX5_FLOW_LAYER_INNER_L2) ++ v_protocol = RTE_VXLAN_GPE_TYPE_ETH; ++ else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV4) ++ v_protocol = RTE_VXLAN_GPE_TYPE_IPV4; ++ else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV6) ++ v_protocol = RTE_VXLAN_GPE_TYPE_IPV6; ++ if (v_protocol) ++ m_protocol = 0xFF; ++ } ++ MLX5_SET(fte_match_set_misc3, misc_m, ++ outer_vxlan_gpe_next_protocol, m_protocol); ++ MLX5_SET(fte_match_set_misc3, misc_v, ++ outer_vxlan_gpe_next_protocol, m_protocol & v_protocol); +} + /** * Add Geneve item to matcher and to the value. * -@@ -5742,6 +6288,7 @@ flow_dv_match_meta_reg(void *matcher, void *key, +@@ -5573,49 +6169,39 @@ flow_dv_translate_item_vxlan(void *matcher, void *key, + + static void + flow_dv_translate_item_geneve(void *matcher, void *key, +- const struct rte_flow_item *item, int inner) ++ const struct rte_flow_item *item, ++ uint64_t pattern_flags) + { ++ static const struct rte_flow_item_geneve empty_geneve = {0,}; + const struct rte_flow_item_geneve *geneve_m = item->mask; + const struct rte_flow_item_geneve *geneve_v = item->spec; +- void *headers_m; +- void *headers_v; ++ /* GENEVE flow item validation allows single tunnel item */ ++ void *headers_m = MLX5_ADDR_OF(fte_match_param, matcher, outer_headers); ++ void *headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); + void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters); + void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); +- uint16_t dport; + uint16_t gbhdr_m; + uint16_t gbhdr_v; +- char *vni_m; +- char *vni_v; +- size_t size, i; ++ char *vni_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, geneve_vni); ++ char *vni_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, geneve_vni); ++ size_t size = sizeof(geneve_m->vni), i; ++ uint16_t protocol_m, protocol_v; + +- if (inner) { +- headers_m = MLX5_ADDR_OF(fte_match_param, matcher, +- inner_headers); +- headers_v = MLX5_ADDR_OF(fte_match_param, key, inner_headers); +- } else { +- headers_m = MLX5_ADDR_OF(fte_match_param, matcher, +- outer_headers); +- headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); +- } +- dport = MLX5_UDP_PORT_GENEVE; + if (!MLX5_GET16(fte_match_set_lyr_2_4, headers_v, udp_dport)) { + MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xFFFF); +- MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, dport); ++ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, ++ MLX5_UDP_PORT_GENEVE); ++ } ++ if (!geneve_v) { ++ geneve_v = &empty_geneve; ++ geneve_m = &empty_geneve; ++ } else { ++ if (!geneve_m) ++ geneve_m = &rte_flow_item_geneve_mask; + } +- if (!geneve_v) +- return; +- if (!geneve_m) +- geneve_m = &rte_flow_item_geneve_mask; +- size = sizeof(geneve_m->vni); +- vni_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, geneve_vni); +- vni_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, geneve_vni); + memcpy(vni_m, geneve_m->vni, size); + for (i = 0; i < size; ++i) + vni_v[i] = vni_m[i] & geneve_v->vni[i]; +- MLX5_SET(fte_match_set_misc, misc_m, geneve_protocol_type, +- rte_be_to_cpu_16(geneve_m->protocol)); +- MLX5_SET(fte_match_set_misc, misc_v, geneve_protocol_type, +- rte_be_to_cpu_16(geneve_v->protocol & geneve_m->protocol)); + gbhdr_m = rte_be_to_cpu_16(geneve_m->ver_opt_len_o_c_rsvd0); + gbhdr_v = rte_be_to_cpu_16(geneve_v->ver_opt_len_o_c_rsvd0); + MLX5_SET(fte_match_set_misc, misc_m, geneve_oam, +@@ -5627,6 +6213,17 @@ flow_dv_translate_item_geneve(void *matcher, void *key, + MLX5_SET(fte_match_set_misc, misc_v, geneve_opt_len, + MLX5_GENEVE_OPTLEN_VAL(gbhdr_v) & + MLX5_GENEVE_OPTLEN_VAL(gbhdr_m)); ++ protocol_m = rte_be_to_cpu_16(geneve_m->protocol); ++ protocol_v = rte_be_to_cpu_16(geneve_v->protocol); ++ if (!protocol_m) { ++ /* Force next protocol to prevent matchers duplication */ ++ protocol_v = mlx5_translate_tunnel_etypes(pattern_flags); ++ if (protocol_v) ++ protocol_m = 0xFFFF; ++ } ++ MLX5_SET(fte_match_set_misc, misc_m, geneve_protocol_type, protocol_m); ++ MLX5_SET(fte_match_set_misc, misc_v, geneve_protocol_type, ++ protocol_m & protocol_v); + } + + /** +@@ -5663,19 +6260,24 @@ flow_dv_translate_item_mpls(void *matcher, void *key, + + switch (prev_layer) { + case MLX5_FLOW_LAYER_OUTER_L4_UDP: +- MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xffff); +- MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, +- MLX5_UDP_PORT_MPLS); ++ if (!MLX5_GET16(fte_match_set_lyr_2_4, headers_v, udp_dport)) { ++ MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, ++ 0xffff); ++ MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, ++ MLX5_UDP_PORT_MPLS); ++ } + break; + case MLX5_FLOW_LAYER_GRE: +- MLX5_SET(fte_match_set_misc, misc_m, gre_protocol, 0xffff); +- MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, +- RTE_ETHER_TYPE_MPLS); ++ /* Fall-through. */ ++ case MLX5_FLOW_LAYER_GRE_KEY: ++ if (!MLX5_GET16(fte_match_set_misc, misc_v, gre_protocol)) { ++ MLX5_SET(fte_match_set_misc, misc_m, gre_protocol, ++ 0xffff); ++ MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, ++ RTE_ETHER_TYPE_MPLS); ++ } + break; + default: +- MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_protocol, 0xff); +- MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, +- IPPROTO_MPLS); + break; + } + if (!in_mpls_v) +@@ -5742,6 +6344,7 @@ flow_dv_match_meta_reg(void *matcher, void *key, MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2); void *misc2_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2); @@ -54953,7 +76954,7 @@ index 73aaea4536..a1b805c105 100644 data &= mask; switch (reg_type) { -@@ -5754,8 +6301,18 @@ flow_dv_match_meta_reg(void *matcher, void *key, +@@ -5754,8 +6357,18 @@ flow_dv_match_meta_reg(void *matcher, void *key, MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_b, data); break; case REG_C_0: @@ -54974,7 +76975,7 @@ index 73aaea4536..a1b805c105 100644 break; case REG_C_1: MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_1, mask); -@@ -5825,6 +6382,15 @@ flow_dv_translate_item_mark(struct rte_eth_dev *dev, +@@ -5825,6 +6438,15 @@ flow_dv_translate_item_mark(struct rte_eth_dev *dev, /* Get the metadata register index for the mark. */ reg = mlx5_flow_get_reg_id(dev, MLX5_FLOW_MARK, 0, NULL); assert(reg > 0); @@ -54990,7 +76991,7 @@ index 73aaea4536..a1b805c105 100644 flow_dv_match_meta_reg(matcher, key, reg, value, mask); } } -@@ -5857,7 +6423,7 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev, +@@ -5857,7 +6479,7 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev, meta_m = &rte_flow_item_meta_mask; meta_v = (const void *)item->spec; if (meta_v) { @@ -54999,7 +77000,7 @@ index 73aaea4536..a1b805c105 100644 uint32_t value = meta_v->data; uint32_t mask = meta_m->data; -@@ -5875,8 +6441,12 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev, +@@ -5875,8 +6497,12 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev, struct mlx5_priv *priv = dev->data->dev_private; uint32_t msk_c0 = priv->sh->dv_regc0_mask; uint32_t shl_c0 = rte_bsf32(msk_c0); @@ -55013,7 +77014,7 @@ index 73aaea4536..a1b805c105 100644 value <<= shl_c0; mask <<= shl_c0; assert(msk_c0); -@@ -5906,6 +6476,8 @@ flow_dv_translate_item_meta_vport(void *matcher, void *key, +@@ -5906,6 +6532,8 @@ flow_dv_translate_item_meta_vport(void *matcher, void *key, /** * Add tag item to matcher * @@ -55022,7 +77023,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in, out] matcher * Flow matcher. * @param[in, out] key -@@ -5914,15 +6486,27 @@ flow_dv_translate_item_meta_vport(void *matcher, void *key, +@@ -5914,15 +6542,27 @@ flow_dv_translate_item_meta_vport(void *matcher, void *key, * Flow pattern to translate. */ static void @@ -55053,7 +77054,7 @@ index 73aaea4536..a1b805c105 100644 } /** -@@ -6056,6 +6640,12 @@ flow_dv_translate_item_icmp6(void *matcher, void *key, +@@ -6056,6 +6696,12 @@ flow_dv_translate_item_icmp6(void *matcher, void *key, return; if (!icmp6_m) icmp6_m = &rte_flow_item_icmp6_mask; @@ -55066,7 +77067,7 @@ index 73aaea4536..a1b805c105 100644 MLX5_SET(fte_match_set_misc3, misc3_m, icmpv6_type, icmp6_m->type); MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_type, icmp6_v->type & icmp6_m->type); -@@ -6103,6 +6693,12 @@ flow_dv_translate_item_icmp(void *matcher, void *key, +@@ -6103,6 +6749,12 @@ flow_dv_translate_item_icmp(void *matcher, void *key, return; if (!icmp_m) icmp_m = &rte_flow_item_icmp_mask; @@ -55079,7 +77080,16 @@ index 73aaea4536..a1b805c105 100644 MLX5_SET(fte_match_set_misc3, misc3_m, icmp_type, icmp_m->hdr.icmp_type); MLX5_SET(fte_match_set_misc3, misc3_v, icmp_type, -@@ -6618,10 +7214,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6514,7 +7166,7 @@ flow_dv_translate_action_port_id(struct rte_eth_dev *dev, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "No eswitch info was found for port"); +-#ifdef HAVE_MLX5DV_DR_DEVX_PORT ++#ifdef HAVE_MLX5DV_DR_CREATE_DEST_IB_PORT + /* + * This parameter is transferred to + * mlx5dv_dr_action_create_dest_ib_port(). +@@ -6618,10 +7270,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, }; int actions_n = 0; bool actions_end = false; @@ -55097,9 +77107,11 @@ index 73aaea4536..a1b805c105 100644 union flow_dv_attr flow_attr = { .attr = 0 }; uint32_t tag_be; union mlx5_flow_tbl_key tbl_key; -@@ -6633,15 +7232,19 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6632,16 +7287,21 @@ __flow_dv_translate(struct rte_eth_dev *dev, + struct rte_vlan_hdr vlan = { 0 }; uint32_t table; int ret = 0; ++ const struct rte_flow_item *tunnel_item = NULL; + mhdr_res->ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX : + MLX5DV_FLOW_TABLE_TYPE_NIC_RX; @@ -55119,7 +77131,7 @@ index 73aaea4536..a1b805c105 100644 for (; !actions_end ; actions++) { const struct rte_flow_action_queue *queue; const struct rte_flow_action_rss *rss; -@@ -6679,7 +7282,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6679,7 +7339,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, }; if (flow_dv_convert_action_mark(dev, &mark, @@ -55128,7 +77140,7 @@ index 73aaea4536..a1b805c105 100644 error)) return -rte_errno; action_flags |= MLX5_FLOW_ACTION_MARK_EXT; -@@ -6701,7 +7304,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6701,7 +7361,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, actions->conf; if (flow_dv_convert_action_mark(dev, mark, @@ -55137,7 +77149,7 @@ index 73aaea4536..a1b805c105 100644 error)) return -rte_errno; action_flags |= MLX5_FLOW_ACTION_MARK_EXT; -@@ -6722,7 +7325,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6722,7 +7382,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_SET_META: if (flow_dv_convert_action_set_meta @@ -55146,7 +77158,7 @@ index 73aaea4536..a1b805c105 100644 (const struct rte_flow_action_set_meta *) actions->conf, error)) return -rte_errno; -@@ -6730,7 +7333,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6730,7 +7390,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_SET_TAG: if (flow_dv_convert_action_set_tag @@ -55155,7 +77167,27 @@ index 73aaea4536..a1b805c105 100644 (const struct rte_flow_action_set_tag *) actions->conf, error)) return -rte_errno; -@@ -6798,7 +7401,9 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6767,12 +7427,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, + rte_errno = ENOTSUP; + goto cnt_err; + } +- flow->counter = flow_dv_counter_alloc(dev, +- count->shared, +- count->id, +- dev_flow->group); +- if (flow->counter == NULL) +- goto cnt_err; ++ if (!flow->counter) { ++ flow->counter = flow_dv_counter_alloc ++ (dev, count->shared, ++ count->id, dev_flow->group); ++ if (flow->counter == NULL) ++ goto cnt_err; ++ } + dev_flow->dv.actions[actions_n++] = + flow->counter->action; + action_flags |= MLX5_FLOW_ACTION_COUNT; +@@ -6798,7 +7459,9 @@ __flow_dv_translate(struct rte_eth_dev *dev, action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; break; case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: @@ -55166,7 +77198,7 @@ index 73aaea4536..a1b805c105 100644 vlan.eth_proto = rte_be_to_cpu_16 ((((const struct rte_flow_action_of_push_vlan *) actions->conf)->ethertype)); -@@ -6830,7 +7435,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6830,7 +7493,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, mlx5_update_vlan_vid_pcp(actions, &vlan); /* If no VLAN push - this is a modify header action */ if (flow_dv_convert_action_modify_vlan_vid @@ -55175,7 +77207,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= MLX5_FLOW_ACTION_OF_SET_VLAN_VID; break; -@@ -6843,10 +7448,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6843,10 +7506,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, return -rte_errno; dev_flow->dv.actions[actions_n++] = dev_flow->dv.encap_decap->verbs_action; @@ -55187,7 +77219,7 @@ index 73aaea4536..a1b805c105 100644 break; case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: -@@ -6856,14 +7458,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6856,14 +7516,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, return -rte_errno; dev_flow->dv.actions[actions_n++] = dev_flow->dv.encap_decap->verbs_action; @@ -55204,7 +77236,7 @@ index 73aaea4536..a1b805c105 100644 if (flow_dv_create_action_raw_encap (dev, actions, dev_flow, attr, error)) return -rte_errno; -@@ -6878,15 +7477,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6878,15 +7535,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, dev_flow->dv.actions[actions_n++] = dev_flow->dv.encap_decap->verbs_action; } @@ -55223,7 +77255,7 @@ index 73aaea4536..a1b805c105 100644 if (action->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { if (flow_dv_create_action_l2_decap (dev, dev_flow, attr->transfer, error)) -@@ -6895,13 +7490,14 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6895,13 +7548,14 @@ __flow_dv_translate(struct rte_eth_dev *dev, dev_flow->dv.encap_decap->verbs_action; } /* If decap is followed by encap, handle it at encap. */ @@ -55241,7 +77273,7 @@ index 73aaea4536..a1b805c105 100644 if (ret) return ret; tbl = flow_dv_tbl_resource_get(dev, table, -@@ -6929,7 +7525,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6929,7 +7583,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: if (flow_dv_convert_action_modify_mac @@ -55250,7 +77282,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ? -@@ -6939,7 +7535,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6939,7 +7593,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: if (flow_dv_convert_action_modify_ipv4 @@ -55259,7 +77291,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ? -@@ -6949,7 +7545,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6949,7 +7603,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: if (flow_dv_convert_action_modify_ipv6 @@ -55268,7 +77300,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ? -@@ -6959,8 +7555,9 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6959,8 +7613,9 @@ __flow_dv_translate(struct rte_eth_dev *dev, case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: case RTE_FLOW_ACTION_TYPE_SET_TP_DST: if (flow_dv_convert_action_modify_tp @@ -55280,7 +77312,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_SET_TP_SRC ? -@@ -6969,21 +7566,24 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6969,21 +7624,24 @@ __flow_dv_translate(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_DEC_TTL: if (flow_dv_convert_action_modify_dec_ttl @@ -55309,7 +77341,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ? -@@ -6994,7 +7594,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -6994,7 +7652,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK: case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK: if (flow_dv_convert_action_modify_tcp_ack @@ -55318,7 +77350,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= actions->type == RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ? -@@ -7003,13 +7603,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7003,13 +7661,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, break; case MLX5_RTE_FLOW_ACTION_TYPE_TAG: if (flow_dv_convert_action_set_reg @@ -55334,7 +77366,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; action_flags |= MLX5_FLOW_ACTION_SET_TAG; break; -@@ -7034,10 +7634,10 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7034,10 +7692,10 @@ __flow_dv_translate(struct rte_eth_dev *dev, break; case RTE_FLOW_ACTION_TYPE_END: actions_end = true; @@ -55347,7 +77379,7 @@ index 73aaea4536..a1b805c105 100644 return -rte_errno; dev_flow->dv.actions[modify_action_position] = dev_flow->dv.modify_hdr->verbs_action; -@@ -7046,7 +7646,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7046,7 +7704,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, default: break; } @@ -55356,7 +77388,7 @@ index 73aaea4536..a1b805c105 100644 modify_action_position == UINT32_MAX) modify_action_position = actions_n++; } -@@ -7083,7 +7683,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7083,7 +7741,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, mlx5_flow_tunnel_ip_check(items, next_protocol, &item_flags, &tunnel); flow_dv_translate_item_ipv4(match_mask, match_value, @@ -55365,7 +77397,7 @@ index 73aaea4536..a1b805c105 100644 dev_flow->group); matcher.priority = MLX5_PRIORITY_MAP_L3; dev_flow->hash_fields |= -@@ -7111,7 +7711,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7111,7 +7769,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, mlx5_flow_tunnel_ip_check(items, next_protocol, &item_flags, &tunnel); flow_dv_translate_item_ipv6(match_mask, match_value, @@ -55374,22 +77406,29 @@ index 73aaea4536..a1b805c105 100644 dev_flow->group); matcher.priority = MLX5_PRIORITY_MAP_L3; dev_flow->hash_fields |= -@@ -7162,6 +7762,8 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7160,9 +7818,10 @@ __flow_dv_translate(struct rte_eth_dev *dev, + MLX5_FLOW_LAYER_OUTER_L4_UDP; + break; case RTE_FLOW_ITEM_TYPE_GRE: - flow_dv_translate_item_gre(match_mask, match_value, - items, tunnel); +- flow_dv_translate_item_gre(match_mask, match_value, +- items, tunnel); + matcher.priority = flow->rss.level >= 2 ? + MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4; last_item = MLX5_FLOW_LAYER_GRE; ++ tunnel_item = items; break; case RTE_FLOW_ITEM_TYPE_GRE_KEY: -@@ -7172,26 +7774,37 @@ __flow_dv_translate(struct rte_eth_dev *dev, + flow_dv_translate_item_gre_key(match_mask, +@@ -7170,28 +7829,35 @@ __flow_dv_translate(struct rte_eth_dev *dev, + last_item = MLX5_FLOW_LAYER_GRE_KEY; + break; case RTE_FLOW_ITEM_TYPE_NVGRE: - flow_dv_translate_item_nvgre(match_mask, match_value, - items, tunnel); +- flow_dv_translate_item_nvgre(match_mask, match_value, +- items, tunnel); + matcher.priority = flow->rss.level >= 2 ? + MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4; last_item = MLX5_FLOW_LAYER_GRE; ++ tunnel_item = items; break; case RTE_FLOW_ITEM_TYPE_VXLAN: flow_dv_translate_item_vxlan(match_mask, match_value, @@ -55401,19 +77440,18 @@ index 73aaea4536..a1b805c105 100644 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - flow_dv_translate_item_vxlan(match_mask, match_value, - items, tunnel); -+ flow_dv_translate_item_vxlan_gpe(match_mask, -+ match_value, items, -+ tunnel); + matcher.priority = flow->rss.level >= 2 ? + MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4; last_item = MLX5_FLOW_LAYER_VXLAN_GPE; ++ tunnel_item = items; break; case RTE_FLOW_ITEM_TYPE_GENEVE: - flow_dv_translate_item_geneve(match_mask, match_value, - items, tunnel); +- flow_dv_translate_item_geneve(match_mask, match_value, +- items, tunnel); + matcher.priority = flow->rss.level >= 2 ? + MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4; last_item = MLX5_FLOW_LAYER_GENEVE; ++ tunnel_item = items; break; case RTE_FLOW_ITEM_TYPE_MPLS: flow_dv_translate_item_mpls(match_mask, match_value, @@ -55423,7 +77461,21 @@ index 73aaea4536..a1b805c105 100644 last_item = MLX5_FLOW_LAYER_MPLS; break; case RTE_FLOW_ITEM_TYPE_MARK: -@@ -7220,7 +7833,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7207,11 +7873,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, + case RTE_FLOW_ITEM_TYPE_ICMP: + flow_dv_translate_item_icmp(match_mask, match_value, + items, tunnel); ++ matcher.priority = MLX5_PRIORITY_MAP_L4; + last_item = MLX5_FLOW_LAYER_ICMP; + break; + case RTE_FLOW_ITEM_TYPE_ICMP6: + flow_dv_translate_item_icmp6(match_mask, match_value, + items, tunnel); ++ matcher.priority = MLX5_PRIORITY_MAP_L4; + last_item = MLX5_FLOW_LAYER_ICMP6; + break; + case RTE_FLOW_ITEM_TYPE_TAG: +@@ -7220,7 +7888,7 @@ __flow_dv_translate(struct rte_eth_dev *dev, last_item = MLX5_FLOW_ITEM_TAG; break; case MLX5_RTE_FLOW_ITEM_TYPE_TAG: @@ -55432,25 +77484,47 @@ index 73aaea4536..a1b805c105 100644 match_value, items); last_item = MLX5_FLOW_ITEM_TAG; break; -@@ -7236,13 +7849,13 @@ __flow_dv_translate(struct rte_eth_dev *dev, +@@ -7236,21 +7904,43 @@ __flow_dv_translate(struct rte_eth_dev *dev, item_flags |= last_item; } /* - * In case of ingress traffic when E-Switch mode is enabled, - * we have two cases where we need to set the source port manually. +- * The first one, is in case of Nic steering rule, and the second is +- * E-Switch rule where no port_id item was found. In both cases +- * the source port is set according the current port in use. + * When E-Switch mode is enabled, we have two cases where we need to + * set the source port manually. - * The first one, is in case of Nic steering rule, and the second is - * E-Switch rule where no port_id item was found. In both cases - * the source port is set according the current port in use. ++ * The first one, is in case of NIC ingress steering rule, and the ++ * second is E-Switch rule where no port_id item was found. ++ * In both cases the source port is set according the current port ++ * in use. */ - if ((attr->ingress && !(item_flags & MLX5_FLOW_ITEM_PORT_ID)) && +- (priv->representor || priv->master)) { + if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) && - (priv->representor || priv->master)) { ++ (priv->representor || priv->master) && ++ !(attr->egress && !attr->transfer)) { if (flow_dv_translate_item_port_id(dev, match_mask, match_value, NULL)) -@@ -7250,7 +7863,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, + return -rte_errno; } ++ if (item_flags & MLX5_FLOW_LAYER_VXLAN_GPE) ++ flow_dv_translate_item_vxlan_gpe(match_mask, match_value, ++ tunnel_item, item_flags); ++ else if (item_flags & MLX5_FLOW_LAYER_GENEVE) ++ flow_dv_translate_item_geneve(match_mask, match_value, ++ tunnel_item, item_flags); ++ else if (item_flags & MLX5_FLOW_LAYER_GRE) { ++ if (tunnel_item->type == RTE_FLOW_ITEM_TYPE_GRE) ++ flow_dv_translate_item_gre(match_mask, match_value, ++ tunnel_item, item_flags); ++ else if (tunnel_item->type == RTE_FLOW_ITEM_TYPE_NVGRE) ++ flow_dv_translate_item_nvgre(match_mask, match_value, ++ tunnel_item, item_flags); ++ else ++ RTE_VERIFY(false); ++ } assert(!flow_dv_check_valid_spec(matcher.mask.buf, dev_flow->dv.value.buf)); - dev_flow->layers = item_flags; @@ -55462,7 +77536,98 @@ index 73aaea4536..a1b805c105 100644 /* Register matcher. */ matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf, matcher.mask.size); -@@ -7779,8 +8396,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, +@@ -7294,8 +7984,17 @@ __flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow, + n = dv->actions_n; + if (dev_flow->actions & MLX5_FLOW_ACTION_DROP) { + if (dev_flow->transfer) { +- dv->actions[n++] = priv->sh->esw_drop_action; ++ assert(priv->sh->dr_drop_action); ++ dv->actions[n++] = priv->sh->dr_drop_action; ++#ifdef HAVE_MLX5DV_DR ++ } else if (dev_flow->group || ++ !priv->root_verbs_drop_action) { ++ /* DR supports drop action placeholder. */ ++ assert(priv->sh->dr_drop_action); ++ dv->actions[n++] = priv->sh->dr_drop_action; ++#endif + } else { ++ /* For DV we use the explicit drop queue. */ + dv->hrxq = mlx5_hrxq_drop_new(dev); + if (!dv->hrxq) { + rte_flow_error_set +@@ -7741,6 +8440,71 @@ flow_dv_query(struct rte_eth_dev *dev, + return ret; + } + ++/** ++ * Check whether the DR drop action is supported on the root table or not. ++ * ++ * Create a simple flow with DR drop action on root table to validate ++ * if DR drop action on root table is supported or not. ++ * ++ * @param[in] dev ++ * Pointer to rte_eth_dev structure. ++ * ++ * @return ++ * 0 on success, a negative errno value otherwise and rte_errno is set. ++ */ ++int ++mlx5_flow_discover_dr_action_support(struct rte_eth_dev *dev) ++{ ++ struct mlx5_priv *priv = dev->data->dev_private; ++ struct mlx5_ibv_shared *sh = priv->sh; ++ struct mlx5_flow_dv_match_params mask = { ++ .size = sizeof(mask.buf), ++ }; ++ struct mlx5_flow_dv_match_params value = { ++ .size = sizeof(value.buf), ++ }; ++ struct mlx5dv_flow_matcher_attr dv_attr = { ++ .type = IBV_FLOW_ATTR_NORMAL, ++ .priority = 0, ++ .match_criteria_enable = 0, ++ .match_mask = (void *)&mask, ++ }; ++ struct mlx5_flow_tbl_resource *tbl = NULL; ++ void *matcher = NULL; ++ void *flow = NULL; ++ int ret = -1; ++ ++ tbl = flow_dv_tbl_resource_get(dev, 0, 0, 0, NULL); ++ if (!tbl) ++ goto err; ++ matcher = mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, ++ tbl->obj); ++ if (!matcher) ++ goto err; ++ flow = mlx5_glue->dv_create_flow(matcher, (void *)&value, 1, ++ &sh->dr_drop_action); ++err: ++ /* ++ * If DR drop action is not supported on root table, flow create will ++ * be failed with EOPNOTSUPP or EPROTONOSUPPORT. ++ */ ++ if (!flow) { ++ if (matcher && ++ (errno == EPROTONOSUPPORT || errno == EOPNOTSUPP)) ++ DRV_LOG(INFO, "DR drop action is not supported in root table."); ++ else ++ DRV_LOG(ERR, "Unexpected error in DR drop action support detection"); ++ ret = -1; ++ } else { ++ claim_zero(mlx5_glue->dv_destroy_flow(flow)); ++ } ++ if (matcher) ++ claim_zero(mlx5_glue->dv_destroy_flow_matcher(matcher)); ++ if (tbl) ++ flow_dv_tbl_resource_release(dev, tbl); ++ return ret; ++} ++ + /** + * Destroy the meter table set. + * Lock free, (mutex should be acquired by caller). +@@ -7779,8 +8543,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, claim_zero(mlx5_glue->dv_destroy_flow_matcher (mtd->egress.any_matcher)); if (mtd->egress.tbl) @@ -55474,7 +77639,7 @@ index 73aaea4536..a1b805c105 100644 if (mtd->ingress.color_matcher) claim_zero(mlx5_glue->dv_destroy_flow_matcher (mtd->ingress.color_matcher)); -@@ -7788,8 +8406,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, +@@ -7788,8 +8553,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, claim_zero(mlx5_glue->dv_destroy_flow_matcher (mtd->ingress.any_matcher)); if (mtd->ingress.tbl) @@ -55486,7 +77651,7 @@ index 73aaea4536..a1b805c105 100644 if (mtd->transfer.color_matcher) claim_zero(mlx5_glue->dv_destroy_flow_matcher (mtd->transfer.color_matcher)); -@@ -7797,8 +8416,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, +@@ -7797,8 +8563,9 @@ flow_dv_destroy_mtr_tbl(struct rte_eth_dev *dev, claim_zero(mlx5_glue->dv_destroy_flow_matcher (mtd->transfer.any_matcher)); if (mtd->transfer.tbl) @@ -55498,7 +77663,7 @@ index 73aaea4536..a1b805c105 100644 if (mtd->drop_actn) claim_zero(mlx5_glue->destroy_flow_action(mtd->drop_actn)); rte_free(mtd); -@@ -7846,31 +8466,16 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, +@@ -7846,31 +8613,16 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, .match_mask = (void *)&mask, }; void *actions[METER_ACTIONS]; @@ -55533,7 +77698,7 @@ index 73aaea4536..a1b805c105 100644 /* Create the meter table with METER level. */ dtb->tbl = flow_dv_tbl_resource_get(dev, MLX5_FLOW_TABLE_LEVEL_METER, egress, transfer, &error); -@@ -7878,6 +8483,14 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, +@@ -7878,6 +8630,14 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, DRV_LOG(ERR, "Failed to create meter policer table."); return -1; } @@ -55548,7 +77713,7 @@ index 73aaea4536..a1b805c105 100644 /* Create matchers, Any and Color. */ dv_attr.priority = 3; dv_attr.match_criteria_enable = 0; -@@ -7893,7 +8506,7 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, +@@ -7893,7 +8653,7 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, dv_attr.match_criteria_enable = 1 << MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT; flow_dv_match_meta_reg(mask.buf, value.buf, color_reg_c_idx, @@ -55557,7 +77722,7 @@ index 73aaea4536..a1b805c105 100644 dtb->color_matcher = mlx5_glue->dv_create_flow_matcher(sh->ctx, &dv_attr, dtb->tbl->obj); -@@ -8048,8 +8661,6 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev __rte_unused, +@@ -8048,8 +8808,6 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev __rte_unused, * Pointer to flow meter structure. * @param[in] mtb * Pointer to DV meter table set. @@ -55566,7 +77731,7 @@ index 73aaea4536..a1b805c105 100644 * @param[in] mtr_reg_c * Color match REG_C. * -@@ -8059,7 +8670,6 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev __rte_unused, +@@ -8059,7 +8817,6 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev __rte_unused, static int flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, struct mlx5_meter_domain_info *dtb, @@ -55574,7 +77739,7 @@ index 73aaea4536..a1b805c105 100644 uint8_t mtr_reg_c) { struct mlx5_flow_dv_match_params matcher = { -@@ -8073,12 +8683,10 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, +@@ -8073,12 +8830,10 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, int i; /* Create jump action. */ @@ -55588,7 +77753,7 @@ index 73aaea4536..a1b805c105 100644 if (!dtb->jump_actn) { DRV_LOG(ERR, "Failed to create policer jump action."); goto error; -@@ -8087,7 +8695,7 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, +@@ -8087,7 +8842,7 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, int j = 0; flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_reg_c, @@ -55597,7 +77762,7 @@ index 73aaea4536..a1b805c105 100644 if (mtb->count_actns[i]) actions[j++] = mtb->count_actns[i]; if (fm->params.action[i] == MTR_POLICER_ACTION_DROP) -@@ -8133,7 +8741,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, +@@ -8133,7 +8888,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, if (attr->egress) { ret = flow_dv_create_policer_forward_rule(fm, &mtb->egress, @@ -55605,7 +77770,7 @@ index 73aaea4536..a1b805c105 100644 priv->mtr_color_reg); if (ret) { DRV_LOG(ERR, "Failed to create egress policer."); -@@ -8142,7 +8749,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, +@@ -8142,7 +8896,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, } if (attr->ingress) { ret = flow_dv_create_policer_forward_rule(fm, &mtb->ingress, @@ -55613,7 +77778,7 @@ index 73aaea4536..a1b805c105 100644 priv->mtr_color_reg); if (ret) { DRV_LOG(ERR, "Failed to create ingress policer."); -@@ -8151,7 +8757,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, +@@ -8151,7 +8904,6 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev, } if (attr->transfer) { ret = flow_dv_create_policer_forward_rule(fm, &mtb->transfer, @@ -55622,10 +77787,23 @@ index 73aaea4536..a1b805c105 100644 if (ret) { DRV_LOG(ERR, "Failed to create transfer policer."); diff --git a/dpdk/drivers/net/mlx5/mlx5_flow_meter.c b/dpdk/drivers/net/mlx5/mlx5_flow_meter.c -index c4d28b282e..62e3a35902 100644 +index c4d28b282e..e51a85b477 100644 --- a/dpdk/drivers/net/mlx5/mlx5_flow_meter.c +++ b/dpdk/drivers/net/mlx5/mlx5_flow_meter.c -@@ -301,7 +301,7 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, +@@ -213,8 +213,10 @@ mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp) + } + /* xbs = xbs_mantissa * 2^xbs_exponent */ + _man = frexp(xbs, &_exp); +- _man = _man * pow(2, MLX5_MAN_WIDTH); +- _exp = _exp - MLX5_MAN_WIDTH; ++ if (_exp >= MLX5_MAN_WIDTH) { ++ _man = _man * pow(2, MLX5_MAN_WIDTH); ++ _exp = _exp - MLX5_MAN_WIDTH; ++ } + *man = (uint8_t)ceil(_man); + *exp = _exp; + } +@@ -301,7 +303,7 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55634,7 +77812,7 @@ index c4d28b282e..62e3a35902 100644 memset(cap, 0, sizeof(*cap)); cap->n_max = 1 << qattr->log_max_flow_meter; cap->n_shared_max = cap->n_max; -@@ -347,7 +347,7 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev, +@@ -347,7 +349,7 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55643,7 +77821,7 @@ index c4d28b282e..62e3a35902 100644 /* Check input params. */ ret = mlx5_flow_meter_profile_validate(dev, meter_profile_id, profile, error); -@@ -400,19 +400,19 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev, +@@ -400,19 +402,19 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55666,7 +77844,7 @@ index c4d28b282e..62e3a35902 100644 /* Remove from list. */ TAILQ_REMOVE(&priv->flow_meter_profiles, fmp, next); rte_free(fmp); -@@ -633,7 +633,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, +@@ -633,7 +635,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55675,7 +77853,7 @@ index c4d28b282e..62e3a35902 100644 /* Validate the parameters. */ ret = mlx5_flow_meter_validate(priv, meter_id, params, error); if (ret) -@@ -718,7 +718,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, +@@ -718,7 +720,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55684,7 +77862,7 @@ index c4d28b282e..62e3a35902 100644 /* Meter object must exist. */ fm = mlx5_flow_meter_find(priv, meter_id); if (fm == NULL) -@@ -823,7 +823,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev, +@@ -823,7 +825,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55693,7 +77871,7 @@ index c4d28b282e..62e3a35902 100644 /* Meter object must exist. */ fm = mlx5_flow_meter_find(priv, meter_id); if (fm == NULL) -@@ -864,7 +864,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev, +@@ -864,7 +866,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55702,7 +77880,7 @@ index c4d28b282e..62e3a35902 100644 /* Meter object must exist. */ fm = mlx5_flow_meter_find(priv, meter_id); if (fm == NULL) -@@ -912,7 +912,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev, +@@ -912,7 +914,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55711,7 +77889,7 @@ index c4d28b282e..62e3a35902 100644 /* Meter profile must exist. */ fmp = mlx5_flow_meter_profile_find(priv, meter_profile_id); if (fmp == NULL) -@@ -975,7 +975,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, +@@ -975,7 +977,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55720,7 +77898,7 @@ index c4d28b282e..62e3a35902 100644 /* Meter object must exist. */ fm = mlx5_flow_meter_find(priv, meter_id); if (fm == NULL) -@@ -1032,7 +1032,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, +@@ -1032,7 +1034,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, @@ -55904,9 +78082,18 @@ index c787c9838d..a670c5f3c5 100644 break; default: diff --git a/dpdk/drivers/net/mlx5/mlx5_glue.c b/dpdk/drivers/net/mlx5/mlx5_glue.c -index 0917bf28d6..65b63bd607 100644 +index 0917bf28d6..33f604364a 100644 --- a/dpdk/drivers/net/mlx5/mlx5_glue.c +++ b/dpdk/drivers/net/mlx5/mlx5_glue.c +@@ -393,7 +393,7 @@ mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl) + static void * + mlx5_glue_dr_create_flow_action_dest_port(void *domain, uint32_t port) + { +-#ifdef HAVE_MLX5DV_DR_DEVX_PORT ++#ifdef HAVE_MLX5DV_DR_CREATE_DEST_IB_PORT + return mlx5dv_dr_action_create_dest_ib_port(domain, port); + #else + #ifdef HAVE_MLX5DV_DR_ESWITCH @@ -754,7 +754,7 @@ mlx5_glue_dv_create_flow_action_tag(uint32_t tag) #ifdef HAVE_IBV_FLOW_DV_SUPPORT #ifdef HAVE_MLX5DV_DR @@ -55940,11 +78127,96 @@ index 0917bf28d6..65b63bd607 100644 return mlx5dv_devx_qp_query(qp, in, inlen, out, outlen); #else (void)qp; +@@ -1024,17 +1025,54 @@ mlx5_glue_devx_qp_query(struct ibv_qp *qp, + static int + mlx5_glue_devx_port_query(struct ibv_context *ctx, + uint32_t port_num, +- struct mlx5dv_devx_port *mlx5_devx_port) +-{ ++ struct mlx5_port_info *info) ++{ ++ int err = 0; ++ ++ info->query_flags = 0; ++#ifdef HAVE_MLX5DV_DR_DEVX_PORT_V35 ++ /* The DevX port query API is implemented (rdma-core v35 and above). */ ++ struct mlx5_ib_uapi_query_port devx_port; ++ ++ memset(&devx_port, 0, sizeof(devx_port)); ++ err = mlx5dv_query_port(ctx, port_num, &devx_port); ++ if (err) ++ return err; ++ if (devx_port.flags & MLX5DV_QUERY_PORT_VPORT_REG_C0) { ++ info->vport_meta_tag = devx_port.reg_c0.value; ++ info->vport_meta_mask = devx_port.reg_c0.mask; ++ info->query_flags |= MLX5_PORT_QUERY_REG_C0; ++ } ++ if (devx_port.flags & MLX5DV_QUERY_PORT_VPORT) { ++ info->vport_id = devx_port.vport; ++ info->query_flags |= MLX5_PORT_QUERY_VPORT; ++ } ++#else + #ifdef HAVE_MLX5DV_DR_DEVX_PORT +- return mlx5dv_query_devx_port(ctx, port_num, mlx5_devx_port); ++ /* The legacy DevX port query API is implemented (prior v35). */ ++ struct mlx5dv_devx_port devx_port = { ++ .comp_mask = MLX5DV_DEVX_PORT_VPORT | ++ MLX5DV_DEVX_PORT_MATCH_REG_C_0 ++ }; ++ ++ err = mlx5dv_query_devx_port(ctx, port_num, &devx_port); ++ if (err) ++ return err; ++ if (devx_port.comp_mask & MLX5DV_DEVX_PORT_MATCH_REG_C_0) { ++ info->vport_meta_tag = devx_port.reg_c_0.value; ++ info->vport_meta_mask = devx_port.reg_c_0.mask; ++ info->query_flags |= MLX5_PORT_QUERY_REG_C0; ++ } ++ if (devx_port.comp_mask & MLX5DV_DEVX_PORT_VPORT) { ++ info->vport_id = devx_port.vport_num; ++ info->query_flags |= MLX5_PORT_QUERY_VPORT; ++ } + #else +- (void)ctx; +- (void)port_num; +- (void)mlx5_devx_port; +- errno = ENOTSUP; +- return errno; +-#endif ++ RTE_SET_USED(ctx); ++ RTE_SET_USED(port_num); ++#endif /* HAVE_MLX5DV_DR_DEVX_PORT */ ++#endif /* HAVE_MLX5DV_DR_DEVX_PORT_V35 */ ++ return err; + } + + alignas(RTE_CACHE_LINE_SIZE) diff --git a/dpdk/drivers/net/mlx5/mlx5_glue.h b/dpdk/drivers/net/mlx5/mlx5_glue.h -index 6442f1eba8..9895e55974 100644 +index 6442f1eba8..a639ab28b0 100644 --- a/dpdk/drivers/net/mlx5/mlx5_glue.h +++ b/dpdk/drivers/net/mlx5/mlx5_glue.h -@@ -167,11 +167,11 @@ struct mlx5_glue { +@@ -81,6 +81,20 @@ struct mlx5dv_dr_domain; + struct mlx5dv_devx_port; + #endif + ++#ifndef HAVE_MLX5DV_DR_DEVX_PORT_V35 ++struct mlx5dv_port; ++#endif ++ ++#define MLX5_PORT_QUERY_VPORT (1u << 0) ++#define MLX5_PORT_QUERY_REG_C0 (1u << 1) ++ ++struct mlx5_port_info { ++ uint16_t query_flags; ++ uint16_t vport_id; /* Associated VF vport index (if any). */ ++ uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */ ++ uint32_t vport_meta_mask; /* Used for vport index field match mask. */ ++}; ++ + #ifndef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER + struct mlx5dv_dr_flow_meter_attr; + #endif +@@ -167,11 +181,11 @@ struct mlx5_glue { void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); void *(*dr_create_flow_action_dest_port)(void *domain, uint32_t port); @@ -55958,8 +78230,12 @@ index 6442f1eba8..9895e55974 100644 void *(*dr_create_flow_tbl)(void *domain, uint32_t level); int (*dr_destroy_flow_tbl)(void *tbl); void *(*dr_create_domain)(struct ibv_context *ctx, -@@ -258,6 +258,6 @@ struct mlx5_glue { - struct mlx5dv_devx_port *mlx5_devx_port); +@@ -255,9 +269,9 @@ struct mlx5_glue { + void *out, size_t outlen); + int (*devx_port_query)(struct ibv_context *ctx, + uint32_t port_num, +- struct mlx5dv_devx_port *mlx5_devx_port); ++ struct mlx5_port_info *info); }; -const struct mlx5_glue *mlx5_glue; @@ -55993,7 +78269,7 @@ index 7bdaa2a392..177871b211 100644 dev->data->port_id); RTE_ETH_FOREACH_DEV_SIBLING(port_id, dev->data->port_id) { diff --git a/dpdk/drivers/net/mlx5/mlx5_mp.c b/dpdk/drivers/net/mlx5/mlx5_mp.c -index 2a031e2610..e889247871 100644 +index 2a031e2610..6b7f5f3dcb 100644 --- a/dpdk/drivers/net/mlx5/mlx5_mp.c +++ b/dpdk/drivers/net/mlx5/mlx5_mp.c @@ -119,6 +119,8 @@ mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer) @@ -56013,7 +78289,7 @@ index 2a031e2610..e889247871 100644 switch (param->type) { case MLX5_MP_REQ_START_RXTX: DRV_LOG(INFO, "port %u starting datapath", dev->data->port_id); - rte_mb(); +- rte_mb(); dev->rx_pkt_burst = mlx5_select_rx_function(dev); dev->tx_pkt_burst = mlx5_select_tx_function(dev); + ppriv = (struct mlx5_proc_priv *)dev->process_private; @@ -56030,6 +78306,7 @@ index 2a031e2610..e889247871 100644 + return -rte_errno; + } + } ++ rte_mb(); mp_init_msg(dev, &mp_res, param->type); res->result = 0; ret = rte_mp_reply(&mp_res, peer); @@ -56053,9 +78330,22 @@ index 2a031e2610..e889247871 100644 if (ret) { if (rte_errno != ENOTSUP) diff --git a/dpdk/drivers/net/mlx5/mlx5_mr.c b/dpdk/drivers/net/mlx5/mlx5_mr.c -index 0d549b68e6..54a11bd5d1 100644 +index 0d549b68e6..71c2254c91 100644 --- a/dpdk/drivers/net/mlx5/mlx5_mr.c +++ b/dpdk/drivers/net/mlx5/mlx5_mr.c +@@ -1397,10 +1397,10 @@ mlx5_dma_unmap(struct rte_pci_device *pdev, void *addr, + } + priv = dev->data->dev_private; + sh = priv->sh; +- rte_rwlock_read_lock(&sh->mr.rwlock); ++ rte_rwlock_write_lock(&sh->mr.rwlock); + mr = mr_lookup_dev_list(sh, &entry, (uintptr_t)addr); + if (!mr) { +- rte_rwlock_read_unlock(&sh->mr.rwlock); ++ rte_rwlock_write_unlock(&sh->mr.rwlock); + DRV_LOG(WARNING, "address 0x%" PRIxPTR " wasn't registered " + "to PCI device %p", (uintptr_t)addr, + (void *)pdev); @@ -1408,7 +1408,7 @@ mlx5_dma_unmap(struct rte_pci_device *pdev, void *addr, return -1; } @@ -56065,11 +78355,53 @@ index 0d549b68e6..54a11bd5d1 100644 DEBUG("port %u remove MR(%p) from list", dev->data->port_id, (void *)mr); mr_rebuild_dev_cache(sh); +@@ -1424,7 +1424,7 @@ mlx5_dma_unmap(struct rte_pci_device *pdev, void *addr, + ++sh->mr.dev_gen; + DEBUG("broadcasting local cache flush, gen=%d", sh->mr.dev_gen); + rte_smp_wmb(); +- rte_rwlock_read_unlock(&sh->mr.rwlock); ++ rte_rwlock_write_unlock(&sh->mr.rwlock); + return 0; + } + diff --git a/dpdk/drivers/net/mlx5/mlx5_nl.c b/dpdk/drivers/net/mlx5/mlx5_nl.c -index e7ba03471d..64580b9e6a 100644 +index e7ba03471d..2564e8779b 100644 --- a/dpdk/drivers/net/mlx5/mlx5_nl.c +++ b/dpdk/drivers/net/mlx5/mlx5_nl.c -@@ -269,10 +269,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), +@@ -30,6 +30,8 @@ + #define MLX5_SEND_BUF_SIZE 32768 + /* Receive buffer size for the Netlink socket */ + #define MLX5_RECV_BUF_SIZE 32768 ++/* Maximal physical port name length. */ ++#define MLX5_PHYS_PORT_NAME_MAX 128 + + /** Parameters of VLAN devices created by driver. */ + #define MLX5_VMWA_VLAN_DEVICE_PFX "evmlx" +@@ -117,19 +119,22 @@ struct mlx5_nl_ifindex_data { + * + * @param protocol + * Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA). ++ * @param groups ++ * Groups to listen (e.g. RTMGRP_LINK), can be 0. + * + * @return + * A file descriptor on success, a negative errno value otherwise and + * rte_errno is set. + */ + int +-mlx5_nl_init(int protocol) ++mlx5_nl_init(int protocol, int groups) + { + int fd; + int sndbuf_size = MLX5_SEND_BUF_SIZE; + int rcvbuf_size = MLX5_RECV_BUF_SIZE; + struct sockaddr_nl local = { + .nl_family = AF_NETLINK, ++ .nl_groups = groups, + }; + int ret; + +@@ -269,10 +274,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), void *arg) { struct sockaddr_nl sa; @@ -56082,7 +78414,7 @@ index e7ba03471d..64580b9e6a 100644 }; struct msghdr msg = { .msg_name = &sa, -@@ -284,6 +284,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), +@@ -284,6 +289,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), int multipart = 0; int ret = 0; @@ -56093,7 +78425,7 @@ index e7ba03471d..64580b9e6a 100644 do { struct nlmsghdr *nh; int recv_bytes = 0; -@@ -292,7 +296,8 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), +@@ -292,7 +301,8 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), recv_bytes = recvmsg(nlsk_fd, &msg, 0); if (recv_bytes == -1) { rte_errno = errno; @@ -56103,7 +78435,7 @@ index e7ba03471d..64580b9e6a 100644 } nh = (struct nlmsghdr *)buf; } while (nh->nlmsg_seq != sn); -@@ -304,24 +309,30 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), +@@ -304,24 +314,30 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), if (err_data->error < 0) { rte_errno = -err_data->error; @@ -56139,8 +78471,155 @@ index e7ba03471d..64580b9e6a 100644 return ret; } +@@ -1018,6 +1034,7 @@ mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) + size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + bool switch_id_set = false; + bool num_vf_set = false; ++ int len; + + if (nh->nlmsg_type != RTM_NEWLINK) + goto error; +@@ -1033,7 +1050,24 @@ mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) + num_vf_set = true; + break; + case IFLA_PHYS_PORT_NAME: +- mlx5_translate_port_name((char *)payload, &info); ++ len = RTA_PAYLOAD(ra); ++ /* Some kernels do not pad attributes with zero. */ ++ if (len > 0 && len < MLX5_PHYS_PORT_NAME_MAX) { ++ char name[MLX5_PHYS_PORT_NAME_MAX]; ++ ++ /* ++ * We can't just patch the message with padding ++ * zero - it might corrupt the following items ++ * in the message, we have to copy the string ++ * by attribute length and pad the copied one. ++ */ ++ memcpy(name, payload, len); ++ name[len] = 0; ++ mlx5_translate_port_name(name, &info); ++ } else { ++ info.name_type = ++ MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; ++ } + break; + case IFLA_PHYS_SWITCH_ID: + info.switch_id = 0; +@@ -1369,7 +1403,7 @@ mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, + " for VLAN workaround context"); + return NULL; + } +- vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE); ++ vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE, 0); + if (vmwa->nl_socket < 0) { + DRV_LOG(WARNING, + "Can not create Netlink socket" +@@ -1400,3 +1434,103 @@ void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *vmwa) + close(vmwa->nl_socket); + rte_free(vmwa); + } ++ ++/** ++ * Try to parse a Netlink message as a link status update. ++ * ++ * @param hdr ++ * Netlink message header. ++ * @param[out] ifindex ++ * Index of the updated interface. ++ * @param[out] flags ++ * New interface flags. ++ * ++ * @return ++ * 0 on success, negative on failure. ++ */ ++int ++mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex) ++{ ++ struct ifinfomsg *info; ++ ++ switch (hdr->nlmsg_type) { ++ case RTM_NEWLINK: ++ case RTM_DELLINK: ++ case RTM_GETLINK: ++ case RTM_SETLINK: ++ info = NLMSG_DATA(hdr); ++ *ifindex = info->ifi_index; ++ return 0; ++ } ++ return -1; ++} ++ ++/** ++ * Read pending events from a Netlink socket. ++ * ++ * @param nlsk_fd ++ * Netlink socket. ++ * @param cb ++ * Callback invoked for each of the events. ++ * @param cb_arg ++ * User data for the callback. ++ * ++ * @return ++ * 0 on success, including the case when there are no events. ++ * Negative on failure and rte_errno is set. ++ */ ++int ++mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg) ++{ ++ char buf[8192]; ++ struct sockaddr_nl addr; ++ struct iovec iov = { ++ .iov_base = buf, ++ .iov_len = sizeof(buf), ++ }; ++ struct msghdr msg = { ++ .msg_name = &addr, ++ .msg_namelen = sizeof(addr), ++ .msg_iov = &iov, ++ .msg_iovlen = 1, ++ }; ++ struct nlmsghdr *hdr; ++ ssize_t size; ++ ++ while (1) { ++ size = recvmsg(nlsk_fd, &msg, MSG_DONTWAIT); ++ if (size < 0) { ++ if (errno == EAGAIN) ++ return 0; ++ if (errno == EINTR) ++ continue; ++ DRV_LOG(DEBUG, "Failed to receive netlink message: %s", ++ strerror(errno)); ++ rte_errno = errno; ++ return -rte_errno; ++ ++ } ++ hdr = (struct nlmsghdr *)buf; ++ while (size >= (ssize_t)sizeof(*hdr)) { ++ ssize_t msg_len = hdr->nlmsg_len; ++ ssize_t data_len = msg_len - sizeof(*hdr); ++ ssize_t aligned_len; ++ ++ if (data_len < 0) { ++ DRV_LOG(DEBUG, "Netlink message too short"); ++ rte_errno = EINVAL; ++ return -rte_errno; ++ } ++ aligned_len = NLMSG_ALIGN(msg_len); ++ if (aligned_len > size) { ++ DRV_LOG(DEBUG, "Netlink message too long"); ++ rte_errno = EINVAL; ++ return -rte_errno; ++ } ++ cb(hdr, cb_arg); ++ hdr = RTE_PTR_ADD(hdr, aligned_len); ++ size -= aligned_len; ++ } ++ } ++ return 0; ++} diff --git a/dpdk/drivers/net/mlx5/mlx5_prm.h b/dpdk/drivers/net/mlx5/mlx5_prm.h -index a805363757..1d13bbb009 100644 +index a805363757..35a78fdf5d 100644 --- a/dpdk/drivers/net/mlx5/mlx5_prm.h +++ b/dpdk/drivers/net/mlx5/mlx5_prm.h @@ -18,6 +18,8 @@ @@ -56161,16 +78640,20 @@ index a805363757..1d13bbb009 100644 /* * Default packet length threshold to be inlined with -@@ -251,7 +253,7 @@ +@@ -250,8 +252,11 @@ + /* The maximum log value of segments per RQ WQE. */ #define MLX5_MAX_LOG_RQ_SEGS 5u ++/* Log 2 of the default size of a WQE for Multi-Packet RQ. */ ++#define MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE 14U ++ /* The alignment needed for WQ buffer. */ -#define MLX5_WQE_BUF_ALIGNMENT 512 +#define MLX5_WQE_BUF_ALIGNMENT sysconf(_SC_PAGESIZE) /* Completion mode. */ enum mlx5_completion_mode { -@@ -513,7 +515,7 @@ typedef uint8_t u8; +@@ -513,7 +518,7 @@ typedef uint8_t u8; #define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) #define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld) @@ -56179,7 +78662,7 @@ index a805363757..1d13bbb009 100644 (&(__mlx5_nullp(typ)->fld))) #define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - \ (__mlx5_bit_off(typ, fld) & 0x1f)) -@@ -723,6 +725,9 @@ enum { +@@ -723,6 +728,9 @@ enum { MLX5_MKC_ACCESS_MODE_MTT = 0x1, }; @@ -56189,7 +78672,26 @@ index a805363757..1d13bbb009 100644 /* Flow counters. */ struct mlx5_ifc_alloc_flow_counter_out_bits { u8 status[0x8]; -@@ -1196,7 +1201,9 @@ struct mlx5_ifc_qos_cap_bits { +@@ -876,6 +884,7 @@ enum { + MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0 << 1, + MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS = 0x1 << 1, + MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP = 0xc << 1, ++ MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 = 0x20 << 1, + }; + + enum { +@@ -913,7 +922,9 @@ enum { + #define MLX5_HCA_FLEX_ICMPV6_ENABLED (1UL << 9) + + struct mlx5_ifc_cmd_hca_cap_bits { +- u8 reserved_at_0[0x30]; ++ u8 reserved_at_0[0x20]; ++ u8 hca_cap_2[0x1]; ++ u8 reserved_at_21[0xf]; + u8 vhca_id[0x10]; + u8 reserved_at_40[0x40]; + u8 log_max_srq_sz[0x8]; +@@ -1196,7 +1207,9 @@ struct mlx5_ifc_qos_cap_bits { u8 reserved_at_8[0x8]; u8 log_max_flow_meter[0x8]; u8 flow_meter_reg_id[0x8]; @@ -56200,7 +78702,46 @@ index a805363757..1d13bbb009 100644 u8 packet_pacing_max_rate[0x20]; u8 packet_pacing_min_rate[0x20]; u8 reserved_at_80[0x10]; -@@ -1816,6 +1823,9 @@ enum { +@@ -1247,8 +1260,38 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits { + u8 reserved_at_200[0x600]; + }; + ++/* ++ * HCA Capabilities 2 ++ */ ++struct mlx5_ifc_cmd_hca_cap_2_bits { ++ u8 reserved_at_0[0x80]; /* End of DW4. */ ++ u8 reserved_at_80[0x3]; ++ u8 max_num_prog_sample_field[0x5]; ++ u8 reserved_at_88[0x3]; ++ u8 log_max_num_reserved_qpn[0x5]; ++ u8 reserved_at_90[0x3]; ++ u8 log_reserved_qpn_granularity[0x5]; ++ u8 reserved_at_98[0x3]; ++ u8 log_reserved_qpn_max_alloc[0x5]; /* End of DW5. */ ++ u8 max_reformat_insert_size[0x8]; ++ u8 max_reformat_insert_offset[0x8]; ++ u8 max_reformat_remove_size[0x8]; ++ u8 max_reformat_remove_offset[0x8]; /* End of DW6. */ ++ u8 reserved_at_c0[0x3]; ++ u8 log_min_stride_wqe_sz[0x5]; ++ u8 reserved_at_c8[0x3]; ++ u8 log_conn_track_granularity[0x5]; ++ u8 reserved_at_d0[0x3]; ++ u8 log_conn_track_max_alloc[0x5]; ++ u8 reserved_at_d8[0x3]; ++ u8 log_max_conn_track_offload[0x5]; ++ u8 reserved_at_e0[0x20]; /* End of DW7. */ ++ u8 reserved_at_100[0x700]; ++}; ++ + union mlx5_ifc_hca_cap_union_bits { + struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap; ++ struct mlx5_ifc_cmd_hca_cap_2_bits cmd_hca_cap_2; + struct mlx5_ifc_per_protocol_networking_offload_caps_bits + per_protocol_networking_offload_caps; + struct mlx5_ifc_qos_cap_bits qos_cap; +@@ -1816,6 +1859,9 @@ enum { #define MLX5_SRTCM_CIR_MAX (8 * (1ULL << 30) * 0xFF) #define MLX5_SRTCM_EBS_MAX 0 @@ -56211,24 +78752,30 @@ index a805363757..1d13bbb009 100644 * Convert a user mark to flow mark. * diff --git a/dpdk/drivers/net/mlx5/mlx5_rss.c b/dpdk/drivers/net/mlx5/mlx5_rss.c -index 102826452d..170005a7af 100644 +index 102826452d..468358a589 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rss.c +++ b/dpdk/drivers/net/mlx5/mlx5_rss.c -@@ -221,9 +221,11 @@ mlx5_dev_rss_reta_update(struct rte_eth_dev *dev, +@@ -216,15 +216,11 @@ mlx5_dev_rss_reta_update(struct rte_eth_dev *dev, + for (idx = 0, i = 0; (i != reta_size); ++i) { + idx = i / RTE_RETA_GROUP_SIZE; + pos = i % RTE_RETA_GROUP_SIZE; +- if (((reta_conf[idx].mask >> i) & 0x1) == 0) ++ if (((reta_conf[idx].mask >> pos) & 0x1) == 0) + continue; assert(reta_conf[idx].reta[pos] < priv->rxqs_n); (*priv->reta_idx)[i] = reta_conf[idx].reta[pos]; } -+ -+ priv->skip_default_rss_reta = 1; -+ - if (dev->data->dev_started) { - mlx5_dev_stop(dev); +- if (dev->data->dev_started) { +- mlx5_dev_stop(dev); - priv->skip_default_rss_reta = 1; - return mlx5_dev_start(dev); - } - return 0; +- return mlx5_dev_start(dev); +- } +- return 0; ++ priv->skip_default_rss_reta = 1; ++ return mlx5_traffic_restart(dev); + } diff --git a/dpdk/drivers/net/mlx5/mlx5_rxq.c b/dpdk/drivers/net/mlx5/mlx5_rxq.c -index 986ec016df..e3f41d121d 100644 +index 986ec016df..7a0a7e6ac9 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxq.c +++ b/dpdk/drivers/net/mlx5/mlx5_rxq.c @@ -36,6 +36,7 @@ @@ -56239,6 +78786,15 @@ index 986ec016df..e3f41d121d 100644 /* Default RSS hash key also used for ConnectX-3. */ uint8_t rss_hash_default_key[] = { +@@ -88,7 +89,7 @@ mlx5_check_mprq_support(struct rte_eth_dev *dev) + inline int + mlx5_rxq_mprq_enabled(struct mlx5_rxq_data *rxq) + { +- return rxq->strd_num_n > 0; ++ return rxq->log_strd_num > 0; + } + + /** @@ -104,7 +105,7 @@ inline int mlx5_mprq_enabled(struct rte_eth_dev *dev) { @@ -56273,16 +78829,28 @@ index 986ec016df..e3f41d121d 100644 if (idx >= priv->rxqs_n) { DRV_LOG(ERR, "port %u Rx queue index out of range (%u >= %u)", dev->data->port_id, idx, priv->rxqs_n); -@@ -503,7 +504,7 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, +@@ -501,9 +502,19 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, + struct mlx5_rxq_data *rxq = (*priv->rxqs)[idx]; + struct mlx5_rxq_ctrl *rxq_ctrl = container_of(rxq, struct mlx5_rxq_ctrl, rxq); ++ uint64_t offloads = conf->offloads | ++ dev->data->dev_conf.rxmode.offloads; int res; - res = mlx5_rx_queue_pre_setup(dev, idx, desc); ++ if ((offloads & DEV_RX_OFFLOAD_TCP_LRO) && ++ !priv->config.lro.supported) { ++ DRV_LOG(ERR, ++ "Port %u queue %u LRO is configured but not supported.", ++ dev->data->port_id, idx); ++ rte_errno = EINVAL; ++ return -rte_errno; ++ } + res = mlx5_rx_queue_pre_setup(dev, idx, &desc); if (res) return res; rxq_ctrl = mlx5_rxq_new(dev, idx, desc, socket, conf, mp); -@@ -544,7 +545,7 @@ mlx5_rx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx, +@@ -544,7 +555,7 @@ mlx5_rx_hairpin_queue_setup(struct rte_eth_dev *dev, uint16_t idx, container_of(rxq, struct mlx5_rxq_ctrl, rxq); int res; @@ -56291,27 +78859,18 @@ index 986ec016df..e3f41d121d 100644 if (res) return res; if (hairpin_conf->peer_count != 1 || -@@ -722,6 +723,9 @@ mlx5_rx_intr_vec_enable(struct rte_eth_dev *dev) - unsigned int count = 0; - struct rte_intr_handle *intr_handle = dev->intr_handle; - -+ /* Representor shares dev->intr_handle with PF. */ -+ if (priv->representor) -+ return 0; - if (!dev->data->dev_conf.intr_conf.rxq) - return 0; - mlx5_rx_intr_vec_disable(dev); -@@ -799,6 +803,9 @@ mlx5_rx_intr_vec_disable(struct rte_eth_dev *dev) - unsigned int rxqs_n = priv->rxqs_n; - unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); - -+ /* Representor shares dev->intr_handle with PF. */ -+ if (priv->representor) -+ return; - if (!dev->data->dev_conf.intr_conf.rxq) - return; - if (!intr_handle->intr_vec) -@@ -1152,7 +1159,7 @@ static void +@@ -1086,8 +1097,8 @@ mlx5_ibv_wq_new(struct rte_eth_dev *dev, struct mlx5_priv *priv, + + wq_attr.mlx5.comp_mask |= MLX5DV_WQ_INIT_ATTR_MASK_STRIDING_RQ; + *mprq_attr = (struct mlx5dv_striding_rq_init_attr){ +- .single_stride_log_num_of_bytes = rxq_data->strd_sz_n, +- .single_wqe_log_num_of_strides = rxq_data->strd_num_n, ++ .single_stride_log_num_of_bytes = rxq_data->log_strd_sz, ++ .single_wqe_log_num_of_strides = rxq_data->log_strd_num, + .two_byte_shift_en = MLX5_MPRQ_TWO_BYTE_SHIFT, + }; + } +@@ -1152,7 +1163,7 @@ static void mlx5_devx_wq_attr_fill(struct mlx5_priv *priv, struct mlx5_rxq_ctrl *rxq_ctrl, struct mlx5_devx_wq_attr *wq_attr) { @@ -56320,7 +78879,21 @@ index 986ec016df..e3f41d121d 100644 MLX5_WQ_END_PAD_MODE_ALIGN : MLX5_WQ_END_PAD_MODE_NONE; wq_attr->pd = priv->sh->pdn; -@@ -1259,7 +1266,7 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) +@@ -1204,11 +1215,11 @@ mlx5_devx_rq_new(struct rte_eth_dev *dev, uint16_t idx, uint32_t cqn) + * 512*2^single_wqe_log_num_of_strides. + */ + rq_attr.wq_attr.single_wqe_log_num_of_strides = +- rxq_data->strd_num_n - ++ rxq_data->log_strd_num - + MLX5_MIN_SINGLE_WQE_LOG_NUM_STRIDES; + /* Stride size = (2^single_stride_log_num_of_bytes)*64B. */ + rq_attr.wq_attr.single_stride_log_num_of_bytes = +- rxq_data->strd_sz_n - ++ rxq_data->log_strd_sz - + MLX5_MIN_SINGLE_STRIDE_LOG_NUM_BYTES; + wqe_size = sizeof(struct mlx5_wqe_mprq); + } else { +@@ -1259,7 +1270,7 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) container_of(rxq_data, struct mlx5_rxq_ctrl, rxq); struct mlx5_devx_create_rq_attr attr = { 0 }; struct mlx5_rxq_obj *tmpl = NULL; @@ -56329,7 +78902,7 @@ index 986ec016df..e3f41d121d 100644 assert(rxq_data); assert(!rxq_ctrl->obj); -@@ -1270,24 +1277,29 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) +@@ -1270,24 +1281,29 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) "port %u Rx queue %u cannot allocate verbs resources", dev->data->port_id, rxq_data->idx); rte_errno = ENOMEM; @@ -56365,7 +78938,7 @@ index 986ec016df..e3f41d121d 100644 } DRV_LOG(DEBUG, "port %u rxq %u updated with %p", dev->data->port_id, idx, (void *)&tmpl); -@@ -1295,12 +1307,6 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) +@@ -1295,12 +1311,6 @@ mlx5_rxq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx) LIST_INSERT_HEAD(&priv->rxqsobj, tmpl, next); priv->verbs_alloc_ctx.type = MLX5_VERBS_ALLOC_TYPE_NONE; return tmpl; @@ -56378,19 +78951,216 @@ index 986ec016df..e3f41d121d 100644 } /** -@@ -1762,9 +1768,10 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, +@@ -1360,7 +1370,7 @@ mlx5_rxq_obj_new(struct rte_eth_dev *dev, uint16_t idx, + } + } + if (mlx5_rxq_mprq_enabled(rxq_data)) +- cqe_n = wqe_n * (1 << rxq_data->strd_num_n) - 1; ++ cqe_n = wqe_n * (1 << rxq_data->log_strd_num) - 1; + else + cqe_n = wqe_n - 1; + tmpl->cq = mlx5_ibv_cq_new(dev, priv, rxq_data, cqe_n, tmpl); +@@ -1604,8 +1614,8 @@ mlx5_mprq_alloc_mp(struct rte_eth_dev *dev) + unsigned int buf_len; + unsigned int obj_num; + unsigned int obj_size; +- unsigned int strd_num_n = 0; +- unsigned int strd_sz_n = 0; ++ unsigned int log_strd_num = 0; ++ unsigned int log_strd_sz = 0; + unsigned int i; + unsigned int n_ibv = 0; + +@@ -1622,16 +1632,18 @@ mlx5_mprq_alloc_mp(struct rte_eth_dev *dev) + n_ibv++; + desc += 1 << rxq->elts_n; + /* Get the max number of strides. */ +- if (strd_num_n < rxq->strd_num_n) +- strd_num_n = rxq->strd_num_n; ++ if (log_strd_num < rxq->log_strd_num) ++ log_strd_num = rxq->log_strd_num; + /* Get the max size of a stride. */ +- if (strd_sz_n < rxq->strd_sz_n) +- strd_sz_n = rxq->strd_sz_n; +- } +- assert(strd_num_n && strd_sz_n); +- buf_len = (1 << strd_num_n) * (1 << strd_sz_n); +- obj_size = sizeof(struct mlx5_mprq_buf) + buf_len + (1 << strd_num_n) * +- sizeof(struct rte_mbuf_ext_shared_info) + RTE_PKTMBUF_HEADROOM; ++ if (log_strd_sz < rxq->log_strd_sz) ++ log_strd_sz = rxq->log_strd_sz; ++ } ++ assert(log_strd_num && log_strd_sz); ++ buf_len = (1 << log_strd_num) * (1 << log_strd_sz); ++ obj_size = sizeof(struct mlx5_mprq_buf) + buf_len + ++ (1 << log_strd_num) * ++ sizeof(struct rte_mbuf_ext_shared_info) + ++ RTE_PKTMBUF_HEADROOM; + /* + * Received packets can be either memcpy'd or externally referenced. In + * case that the packet is attached to an mbuf as an external buffer, as +@@ -1677,7 +1689,7 @@ mlx5_mprq_alloc_mp(struct rte_eth_dev *dev) + snprintf(name, sizeof(name), "port-%u-mprq", dev->data->port_id); + mp = rte_mempool_create(name, obj_num, obj_size, MLX5_MPRQ_MP_CACHE_SZ, + 0, NULL, NULL, mlx5_mprq_buf_init, +- (void *)(uintptr_t)(1 << strd_num_n), ++ (void *)((uintptr_t)1 << log_strd_num), + dev->device->numa_node, 0); + if (mp == NULL) { + DRV_LOG(ERR, +@@ -1739,6 +1751,117 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint32_t max_lro_size) + priv->max_lro_msg_size = max_lro_size; + } + ++/** ++ * Prepare both size and number of stride for Multi-Packet RQ. ++ * ++ * @param dev ++ * Pointer to Ethernet device. ++ * @param idx ++ * RX queue index. ++ * @param min_mbuf_size ++ * Non scatter min mbuf size, max_rx_pktlen plus overhead. ++ * @param actual_log_stride_num ++ * Log number of strides to configure for this queue. ++ * @param actual_log_stride_size ++ * Log stride size to configure for this queue. ++ * ++ * @return ++ * 0 if Multi-Packet RQ is supported, otherwise -1. ++ */ ++static int ++mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, ++ uint32_t min_mbuf_size, uint32_t *actual_log_stride_num, ++ uint32_t *actual_log_stride_size) ++{ ++ struct mlx5_priv *priv = dev->data->dev_private; ++ struct mlx5_dev_config *config = &priv->config; ++ uint32_t log_min_stride_num = config->mprq.log_min_stride_num; ++ uint32_t log_max_stride_num = config->mprq.log_max_stride_num; ++ uint32_t log_def_stride_num = ++ RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM, ++ log_min_stride_num), ++ log_max_stride_num); ++ uint32_t log_min_stride_size = config->mprq.log_min_stride_size; ++ uint32_t log_max_stride_size = config->mprq.log_max_stride_size; ++ uint32_t log_def_stride_size = ++ RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_SIZE, ++ log_min_stride_size), ++ log_max_stride_size); ++ uint32_t log_stride_wqe_size; ++ ++ if (mlx5_check_mprq_support(dev) != 1) ++ goto unsupport; ++ /* Checks if chosen number of strides is in supported range. */ ++ if (config->mprq.log_stride_num > log_max_stride_num || ++ config->mprq.log_stride_num < log_min_stride_num) { ++ *actual_log_stride_num = log_def_stride_num; ++ DRV_LOG(WARNING, ++ "Port %u Rx queue %u number of strides for Multi-Packet RQ is out of range, setting default value (%u)", ++ dev->data->port_id, idx, 1U << log_def_stride_num); ++ } else { ++ *actual_log_stride_num = config->mprq.log_stride_num; ++ } ++ if (config->mprq.log_stride_size) { ++ /* Checks if chosen size of stride is in supported range. */ ++ if (config->mprq.log_stride_size > log_max_stride_size || ++ config->mprq.log_stride_size < log_min_stride_size) { ++ *actual_log_stride_size = log_def_stride_size; ++ DRV_LOG(WARNING, ++ "Port %u Rx queue %u size of a stride for Multi-Packet RQ is out of range, setting default value (%u)", ++ dev->data->port_id, idx, ++ 1U << log_def_stride_size); ++ } else { ++ *actual_log_stride_size = config->mprq.log_stride_size; ++ } ++ } else { ++ if (min_mbuf_size <= (1U << log_max_stride_size)) ++ *actual_log_stride_size = log2above(min_mbuf_size); ++ else ++ goto unsupport; ++ } ++ log_stride_wqe_size = *actual_log_stride_num + *actual_log_stride_size; ++ /* Check if WQE buffer size is supported by hardware. */ ++ if (log_stride_wqe_size < config->mprq.log_min_stride_wqe_size) { ++ *actual_log_stride_num = log_def_stride_num; ++ *actual_log_stride_size = log_def_stride_size; ++ DRV_LOG(WARNING, ++ "Port %u Rx queue %u size of WQE buffer for Multi-Packet RQ is too small, setting default values (stride_num_n=%u, stride_size_n=%u)", ++ dev->data->port_id, idx, 1U << log_def_stride_num, ++ 1U << log_def_stride_size); ++ log_stride_wqe_size = log_def_stride_num + log_def_stride_size; ++ } ++ assert(log_stride_wqe_size >= config->mprq.log_min_stride_wqe_size); ++ if (min_mbuf_size > (1U << log_stride_wqe_size)) { ++ DRV_LOG(WARNING, "Port %u Rx queue %u " ++ "Multi-Packet RQ is unsupported, WQE buffer size (%u) " ++ "is smaller than min mbuf size (%u)", ++ dev->data->port_id, idx, 1U << log_stride_wqe_size, ++ min_mbuf_size); ++ goto unsupport; ++ } ++ DRV_LOG(DEBUG, "Port %u Rx queue %u " ++ "Multi-Packet RQ is enabled strd_num_n = %u, strd_sz_n = %u", ++ dev->data->port_id, idx, 1U << *actual_log_stride_num, ++ 1U << *actual_log_stride_size); ++ return 0; ++unsupport: ++ if (config->mprq.enabled) ++ DRV_LOG(WARNING, ++ "Port %u MPRQ is requested but cannot be enabled\n" ++ " (requested: pkt_sz = %u," ++ " rxq_num = %u, stride_sz = %u, stride_num = %u\n" ++ " supported: min_rxqs_num = %u, min_buf_wqe_sz = %u" ++ " min_stride_sz = %u, max_stride_sz = %u).\n", ++ dev->data->port_id, min_mbuf_size, priv->rxqs_n, ++ 1U << config->mprq.log_stride_size, ++ 1U << config->mprq.log_stride_num, ++ config->mprq.min_rxqs_num, ++ 1U << config->mprq.log_min_stride_wqe_size, ++ 1U << config->mprq.log_min_stride_size, ++ 1U << config->mprq.log_max_stride_size); ++ return -1; ++} ++ + /** + * Create a DPDK Rx queue. + * +@@ -1762,19 +1885,15 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_rxq_ctrl *tmpl; unsigned int mb_len = rte_pktmbuf_data_room_size(mp); -+ unsigned int mprq_stride_nums; - unsigned int mprq_stride_size; -+ unsigned int mprq_stride_cap; +- unsigned int mprq_stride_size; struct mlx5_dev_config *config = &priv->config; - unsigned int strd_headroom_en; /* * Always allocate extra slots, even if eventually * the vector Rx will not be used. -@@ -1810,42 +1817,42 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, + */ +- uint16_t desc_n = +- desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP; ++ uint16_t desc_n = desc + config->rx_vec_en * MLX5_VPMD_DESCS_PER_LOOP; + uint64_t offloads = conf->offloads | + dev->data->dev_conf.rxmode.offloads; + unsigned int lro_on_queue = !!(offloads & DEV_RX_OFFLOAD_TCP_LRO); +- const int mprq_en = mlx5_check_mprq_support(dev) > 0; + unsigned int max_rx_pkt_len = lro_on_queue ? + dev->data->dev_conf.rxmode.max_lro_pkt_size : + dev->data->dev_conf.rxmode.max_rx_pkt_len; +@@ -1782,6 +1901,12 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, + RTE_PKTMBUF_HEADROOM; + unsigned int max_lro_size = 0; + unsigned int first_mb_free_size = mb_len - RTE_PKTMBUF_HEADROOM; ++ uint32_t mprq_log_actual_stride_num = 0; ++ uint32_t mprq_log_actual_stride_size = 0; ++ const int mprq_en = !mlx5_mprq_prepare(dev, idx, ++ non_scatter_min_mbuf_size, ++ &mprq_log_actual_stride_num, ++ &mprq_log_actual_stride_size); + + if (non_scatter_min_mbuf_size > mb_len && !(offloads & + DEV_RX_OFFLOAD_SCATTER)) { +@@ -1810,52 +1935,26 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, tmpl->socket = socket; if (dev->data->dev_conf.intr_conf.rxq) tmpl->irq = 1; @@ -56409,36 +79179,19 @@ index 986ec016df..e3f41d121d 100644 - strd_headroom_en = 1; - mprq_stride_size = non_scatter_min_mbuf_size; - } -+ mprq_stride_nums = config->mprq.stride_num_n ? -+ config->mprq.stride_num_n : MLX5_MPRQ_STRIDE_NUM_N; -+ mprq_stride_size = non_scatter_min_mbuf_size <= -+ (1U << config->mprq.max_stride_size_n) ? -+ log2above(non_scatter_min_mbuf_size) : MLX5_MPRQ_STRIDE_SIZE_N; -+ mprq_stride_cap = (config->mprq.stride_num_n ? -+ (1U << config->mprq.stride_num_n) : (1U << mprq_stride_nums)) * -+ (config->mprq.stride_size_n ? -+ (1U << config->mprq.stride_size_n) : (1U << mprq_stride_size)); - /* - * This Rx queue can be configured as a Multi-Packet RQ if all of the - * following conditions are met: - * - MPRQ is enabled. - * - The number of descs is more than the number of strides. +- /* +- * This Rx queue can be configured as a Multi-Packet RQ if all of the +- * following conditions are met: +- * - MPRQ is enabled. +- * - The number of descs is more than the number of strides. - * - max_rx_pkt_len plus overhead is less than the max size of a - * stride. -+ * - max_rx_pkt_len plus overhead is less than the max size -+ * of a stride or mprq_stride_size is specified by a user. -+ * Need to nake sure that there are enough stides to encap -+ * the maximum packet size in case mprq_stride_size is set. - * Otherwise, enable Rx scatter if necessary. - */ +- * Otherwise, enable Rx scatter if necessary. +- */ - if (mprq_en && - desc > (1U << config->mprq.stride_num_n) && - mprq_stride_size <= (1U << config->mprq.max_stride_size_n)) { -+ if (mprq_en && desc > (1U << mprq_stride_nums) && -+ (non_scatter_min_mbuf_size <= -+ (1U << config->mprq.max_stride_size_n) || -+ (config->mprq.stride_size_n && -+ non_scatter_min_mbuf_size <= mprq_stride_cap))) { ++ if (mprq_en && desc > (1U << mprq_log_actual_stride_num)) { /* TODO: Rx scatter isn't supported yet. */ tmpl->rxq.sges_n = 0; /* Trim the number of descs needed. */ @@ -56446,11 +79199,9 @@ index 986ec016df..e3f41d121d 100644 - tmpl->rxq.strd_num_n = config->mprq.stride_num_n; - tmpl->rxq.strd_sz_n = RTE_MAX(log2above(mprq_stride_size), - config->mprq.min_stride_size_n); -+ desc >>= mprq_stride_nums; -+ tmpl->rxq.strd_num_n = config->mprq.stride_num_n ? -+ config->mprq.stride_num_n : mprq_stride_nums; -+ tmpl->rxq.strd_sz_n = config->mprq.stride_size_n ? -+ config->mprq.stride_size_n : mprq_stride_size; ++ desc >>= mprq_log_actual_stride_num; ++ tmpl->rxq.log_strd_num = mprq_log_actual_stride_num; ++ tmpl->rxq.log_strd_sz = mprq_log_actual_stride_size; tmpl->rxq.strd_shift_en = MLX5_MPRQ_TWO_BYTE_SHIFT; - tmpl->rxq.strd_headroom_en = strd_headroom_en; + tmpl->rxq.strd_scatter_en = @@ -56458,39 +79209,35 @@ index 986ec016df..e3f41d121d 100644 tmpl->rxq.mprq_max_memcpy_len = RTE_MIN(first_mb_free_size, config->mprq.max_memcpy_len); max_lro_size = RTE_MIN(max_rx_pkt_len, -@@ -1889,14 +1896,24 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, +- (1u << tmpl->rxq.strd_num_n) * +- (1u << tmpl->rxq.strd_sz_n)); ++ (1u << tmpl->rxq.log_strd_num) * ++ (1u << tmpl->rxq.log_strd_sz)); + DRV_LOG(DEBUG, + "port %u Rx queue %u: Multi-Packet RQ is enabled" + " strd_num_n = %u, strd_sz_n = %u", + dev->data->port_id, idx, +- tmpl->rxq.strd_num_n, tmpl->rxq.strd_sz_n); ++ tmpl->rxq.log_strd_num, tmpl->rxq.log_strd_sz); + } else if (max_rx_pkt_len <= first_mb_free_size) { + tmpl->rxq.sges_n = 0; + max_lro_size = max_rx_pkt_len; +@@ -1889,14 +1988,6 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, tmpl->rxq.sges_n = sges_n; max_lro_size = max_rx_pkt_len; } - if (mprq_en && !mlx5_rxq_mprq_enabled(&tmpl->rxq)) -+ if (config->mprq.enabled && !mlx5_rxq_mprq_enabled(&tmpl->rxq)) - DRV_LOG(WARNING, +- DRV_LOG(WARNING, - "port %u MPRQ is requested but cannot be enabled" - " (requested: desc = %u, stride_sz = %u," - " supported: min_stride_num = %u, max_stride_sz = %u).", - dev->data->port_id, desc, mprq_stride_size, - (1 << config->mprq.stride_num_n), - (1 << config->mprq.max_stride_size_n)); -+ "port %u MPRQ is requested but cannot be enabled\n" -+ " (requested: pkt_sz = %u, desc_num = %u," -+ " rxq_num = %u, stride_sz = %u, stride_num = %u\n" -+ " supported: min_rxqs_num = %u," -+ " min_stride_sz = %u, max_stride_sz = %u).", -+ dev->data->port_id, non_scatter_min_mbuf_size, -+ desc, priv->rxqs_n, -+ config->mprq.stride_size_n ? -+ (1U << config->mprq.stride_size_n) : -+ (1U << mprq_stride_size), -+ config->mprq.stride_num_n ? -+ (1U << config->mprq.stride_num_n) : -+ (1U << mprq_stride_nums), -+ config->mprq.min_rxqs_num, -+ (1U << config->mprq.min_stride_size_n), -+ (1U << config->mprq.max_stride_size_n)); DRV_LOG(DEBUG, "port %u maximum number of segments per packet: %u", dev->data->port_id, 1 << tmpl->rxq.sges_n); if (desc % (1 << tmpl->rxq.sges_n)) { -@@ -1958,13 +1975,14 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, +@@ -1958,13 +2049,14 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, tmpl->rxq.elts = (struct rte_mbuf *(*)[1 << tmpl->rxq.elts_n])(tmpl + 1); #ifndef RTE_ARCH_64 @@ -56506,7 +79253,16 @@ index 986ec016df..e3f41d121d 100644 rte_free(tmpl); return NULL; } -@@ -2465,13 +2483,42 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, +@@ -2056,7 +2148,7 @@ mlx5_rxq_release(struct rte_eth_dev *dev, uint16_t idx) + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_rxq_ctrl *rxq_ctrl; + +- if (!(*priv->rxqs)[idx]) ++ if (priv->rxqs == NULL || (*priv->rxqs)[idx] == NULL) + return 0; + rxq_ctrl = container_of((*priv->rxqs)[idx], struct mlx5_rxq_ctrl, rxq); + assert(rxq_ctrl->priv); +@@ -2465,13 +2557,42 @@ mlx5_hrxq_new(struct rte_eth_dev *dev, memset(&tir_attr, 0, sizeof(tir_attr)); tir_attr.disp_type = MLX5_TIRC_DISP_TYPE_INDIRECT; tir_attr.rx_hash_fn = MLX5_RX_HASH_FN_TOEPLITZ; @@ -56553,7 +79309,7 @@ index 986ec016df..e3f41d121d 100644 if (dev->data->dev_conf.lpbk_mode) tir_attr.self_lb_block = diff --git a/dpdk/drivers/net/mlx5/mlx5_rxtx.c b/dpdk/drivers/net/mlx5/mlx5_rxtx.c -index acf0fd794b..ac5c1868a0 100644 +index acf0fd794b..07c994815a 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxtx.c +++ b/dpdk/drivers/net/mlx5/mlx5_rxtx.c @@ -469,13 +469,15 @@ rx_queue_count(struct mlx5_rxq_data *rxq) @@ -56562,7 +79318,7 @@ index acf0fd794b..ac5c1868a0 100644 const unsigned int cqe_n = (1 << rxq->cqe_n); + const unsigned int sges_n = (1 << rxq->sges_n); + const unsigned int elts_n = (1 << rxq->elts_n); -+ const unsigned int strd_n = (1 << rxq->strd_num_n); ++ const unsigned int strd_n = (1 << rxq->log_strd_num); const unsigned int cqe_cnt = cqe_n - 1; - unsigned int cq_ci; - unsigned int used; @@ -56648,7 +79404,90 @@ index acf0fd794b..ac5c1868a0 100644 } /** -@@ -1132,6 +1132,7 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, +@@ -769,10 +769,10 @@ mlx5_rxq_initialize(struct mlx5_rxq_data *rxq) + + scat = &((volatile struct mlx5_wqe_mprq *) + rxq->wqes)[i].dseg; +- addr = (uintptr_t)mlx5_mprq_buf_addr(buf, +- 1 << rxq->strd_num_n); +- byte_count = (1 << rxq->strd_sz_n) * +- (1 << rxq->strd_num_n); ++ addr = (uintptr_t)mlx5_mprq_buf_addr ++ (buf, (1 << rxq->log_strd_num)); ++ byte_count = (1 << rxq->log_strd_sz) * ++ (1 << rxq->log_strd_num); + } else { + struct rte_mbuf *buf = (*rxq->elts)[i]; + +@@ -931,6 +931,11 @@ mlx5_queue_state_modify(struct rte_eth_dev *dev, + return ret; + } + ++/* Must be negative. */ ++#define MLX5_ERROR_CQE_RET (-1) ++/* Must not be negative. */ ++#define MLX5_RECOVERY_ERROR_RET 0 ++ + /** + * Handle a Rx error. + * The function inserts the RQ state to reset when the first error CQE is +@@ -945,7 +950,7 @@ mlx5_queue_state_modify(struct rte_eth_dev *dev, + * 0 when called from non-vectorized Rx burst. + * + * @return +- * -1 in case of recovery error, otherwise the CQE status. ++ * MLX5_RECOVERY_ERROR_RET in case of recovery error, otherwise the CQE status. + */ + int + mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) +@@ -973,7 +978,7 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) + sm.queue_id = rxq->idx; + sm.state = IBV_WQS_RESET; + if (mlx5_queue_state_modify(ETH_DEV(rxq_ctrl->priv), &sm)) +- return -1; ++ return MLX5_RECOVERY_ERROR_RET; + if (rxq_ctrl->dump_file_n < + rxq_ctrl->priv->config.max_dump_files_num) { + MKSTR(err_str, "Unexpected CQE error syndrome " +@@ -1014,7 +1019,7 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) + sm.state = IBV_WQS_RDY; + if (mlx5_queue_state_modify(ETH_DEV(rxq_ctrl->priv), + &sm)) +- return -1; ++ return MLX5_RECOVERY_ERROR_RET; + if (vec) { + const uint16_t q_mask = wqe_n - 1; + uint16_t elt_idx; +@@ -1036,7 +1041,7 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) + rte_pktmbuf_free_seg + (*elt); + } +- return -1; ++ return MLX5_RECOVERY_ERROR_RET; + } + } + for (i = 0; i < (int)wqe_n; ++i) { +@@ -1055,7 +1060,7 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) + } + return ret; + default: +- return -1; ++ return MLX5_RECOVERY_ERROR_RET; + } + } + +@@ -1073,7 +1078,9 @@ mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) + * written. + * + * @return +- * 0 in case of empty CQE, otherwise the packet size in bytes. ++ * 0 in case of empty CQE, MLX5_ERROR_CQE_RET in case of error CQE, ++ * otherwise the packet size in regular RxQ, and striding byte ++ * count format in mprq case. + */ + static inline int + mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, +@@ -1132,6 +1139,7 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, } else { int ret; int8_t op_own; @@ -56656,7 +79495,15 @@ index acf0fd794b..ac5c1868a0 100644 ret = check_cqe(cqe, cqe_n, rxq->cq_ci); if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) { -@@ -1145,14 +1146,19 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, +@@ -1139,20 +1147,25 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, + rxq->err_state)) { + ret = mlx5_rx_err_handle(rxq, 0); + if (ret == MLX5_CQE_STATUS_HW_OWN || +- ret == -1) +- return 0; ++ ret == MLX5_RECOVERY_ERROR_RET) ++ return MLX5_ERROR_CQE_RET; + } else { return 0; } } @@ -56679,7 +79526,7 @@ index acf0fd794b..ac5c1868a0 100644 /* Fix endianness. */ zip->cqe_cnt = rte_be_to_cpu_32(cqe->byte_cnt); -@@ -1165,10 +1171,9 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, +@@ -1165,10 +1178,9 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, * 7 CQEs after the initial CQE instead of 8 * for subsequent ones. */ @@ -56691,7 +79538,7 @@ index acf0fd794b..ac5c1868a0 100644 zip->cq_ci = rxq->cq_ci + zip->cqe_cnt; /* Get packet size to return. */ len = rte_be_to_cpu_32((*mc)[0].byte_cnt); -@@ -1183,6 +1188,7 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, +@@ -1183,6 +1195,7 @@ mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, ++idx; } } else { @@ -56699,21 +79546,46 @@ index acf0fd794b..ac5c1868a0 100644 len = rte_be_to_cpu_32(cqe->byte_cnt); } } -@@ -1253,9 +1259,10 @@ rxq_cq_to_mbuf(struct mlx5_rxq_data *rxq, struct rte_mbuf *pkt, +@@ -1253,9 +1266,15 @@ rxq_cq_to_mbuf(struct mlx5_rxq_data *rxq, struct rte_mbuf *pkt, pkt->hash.fdir.hi = mlx5_flow_mark_get(mark); } } - if (rte_flow_dynf_metadata_avail() && cqe->flow_table_metadata) { - pkt->ol_flags |= PKT_RX_DYNF_METADATA; - *RTE_FLOW_DYNF_METADATA(pkt) = cqe->flow_table_metadata; -+ if (rxq->dynf_meta && cqe->flow_table_metadata) { -+ pkt->ol_flags |= rxq->flow_meta_mask; -+ *RTE_MBUF_DYNFIELD(pkt, rxq->flow_meta_offset, uint32_t *) = -+ cqe->flow_table_metadata; ++ if (rxq->dynf_meta) { ++ uint32_t meta = cqe->flow_table_metadata & ++ rxq->flow_meta_port_mask; ++ ++ if (meta) { ++ pkt->ol_flags |= rxq->flow_meta_mask; ++ *RTE_MBUF_DYNFIELD(pkt, rxq->flow_meta_offset, ++ uint32_t *) = meta; ++ } } if (rxq->csum) pkt->ol_flags |= rxq_cq_to_ol_flags(cqe); -@@ -1442,7 +1449,7 @@ mlx5_lro_update_tcp_hdr(struct rte_tcp_hdr *restrict tcp, +@@ -1330,13 +1349,18 @@ mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) + rte_mbuf_raw_free(pkt); + pkt = rep; + } ++ rq_ci >>= sges_n; ++ ++rq_ci; ++ rq_ci <<= sges_n; + break; + } + if (!pkt) { + cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_cnt]; + len = mlx5_rx_poll_len(rxq, cqe, cqe_cnt, &mcqe); +- if (!len) { ++ if (len <= 0) { + rte_mbuf_raw_free(rep); ++ if (unlikely(len == MLX5_ERROR_CQE_RET)) ++ rq_ci = rxq->rq_ci << sges_n; + break; + } + pkt = seg; +@@ -1442,7 +1466,7 @@ mlx5_lro_update_tcp_hdr(struct rte_tcp_hdr *restrict tcp, if (cqe->lro_tcppsh_abort_dupack & MLX5_CQE_LRO_PUSH_MASK) tcp->tcp_flags |= RTE_TCP_PSH_FLAG; tcp->cksum = 0; @@ -56722,7 +79594,18 @@ index acf0fd794b..ac5c1868a0 100644 csum = ((csum & 0xffff0000) >> 16) + (csum & 0xffff); csum = (~csum) & 0xffff; if (csum == 0) -@@ -1574,21 +1581,20 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1564,8 +1588,8 @@ uint16_t + mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) + { + struct mlx5_rxq_data *rxq = dpdk_rxq; +- const unsigned int strd_n = 1 << rxq->strd_num_n; +- const unsigned int strd_sz = 1 << rxq->strd_sz_n; ++ const unsigned int strd_n = 1 << rxq->log_strd_num; ++ const unsigned int strd_sz = 1 << rxq->log_strd_sz; + const unsigned int strd_shift = + MLX5_MPRQ_STRIDE_SHIFT_BYTE * rxq->strd_shift_en; + const unsigned int cq_mask = (1 << rxq->cqe_n) - 1; +@@ -1574,21 +1598,20 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) unsigned int i = 0; uint32_t rq_ci = rxq->rq_ci; uint16_t consumed_strd = rxq->consumed_strd; @@ -56746,7 +79629,22 @@ index acf0fd794b..ac5c1868a0 100644 if (consumed_strd == strd_n) { /* Replace WQE only if the buffer is still in use. */ -@@ -1634,18 +1640,6 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1616,8 +1639,13 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) + } + cqe = &(*rxq->cqes)[rxq->cq_ci & cq_mask]; + ret = mlx5_rx_poll_len(rxq, cqe, cq_mask, &mcqe); +- if (!ret) ++ if (ret == 0) ++ break; ++ if (unlikely(ret == MLX5_ERROR_CQE_RET)) { ++ rq_ci = rxq->rq_ci; ++ consumed_strd = rxq->consumed_strd; + break; ++ } + byte_cnt = ret; + strd_cnt = (byte_cnt & MLX5_MPRQ_STRIDE_NUM_MASK) >> + MLX5_MPRQ_STRIDE_NUM_SHIFT; +@@ -1634,18 +1662,6 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) } assert(strd_idx < strd_n); assert(!((rte_be_to_cpu_16(cqe->wqe_id) ^ rq_ci) & wq_mask)); @@ -56765,7 +79663,7 @@ index acf0fd794b..ac5c1868a0 100644 pkt = rte_pktmbuf_alloc(rxq->mp); if (unlikely(pkt == NULL)) { ++rxq->stats.rx_nombuf; -@@ -1657,23 +1651,57 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1657,23 +1673,57 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) len -= RTE_ETHER_CRC_LEN; offset = strd_idx * strd_sz + strd_shift; addr = RTE_PTR_ADD(mlx5_mprq_buf_addr(buf, strd_n), offset); @@ -56831,7 +79729,7 @@ index acf0fd794b..ac5c1868a0 100644 } else { rte_iova_t buf_iova; struct rte_mbuf_ext_shared_info *shinfo; -@@ -1684,7 +1712,7 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1684,7 +1734,7 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) rte_atomic16_add_return(&buf->refcnt, 1); assert((uint16_t)rte_atomic16_read(&buf->refcnt) <= strd_n + 1); @@ -56840,7 +79738,7 @@ index acf0fd794b..ac5c1868a0 100644 /* * MLX5 device doesn't use iova but it is necessary in a * case where the Rx packet is transmitted via a -@@ -1703,43 +1731,42 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1703,43 +1753,42 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) rte_pktmbuf_attach_extbuf(pkt, buf_addr, buf_iova, buf_len, shinfo); /* Set mbuf head-room. */ @@ -56905,7 +79803,7 @@ index acf0fd794b..ac5c1868a0 100644 } PKT_LEN(pkt) = len; PORT(pkt) = rxq->port_id; -@@ -1751,6 +1778,7 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) +@@ -1751,6 +1800,7 @@ mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) *(pkts++) = pkt; ++i; } @@ -56913,7 +79811,7 @@ index acf0fd794b..ac5c1868a0 100644 /* Update the consumer indexes. */ rxq->consumed_strd = consumed_strd; rte_cio_wmb(); -@@ -2034,8 +2062,6 @@ mlx5_tx_copy_elts(struct mlx5_txq_data *restrict txq, +@@ -2034,8 +2084,6 @@ mlx5_tx_copy_elts(struct mlx5_txq_data *restrict txq, * Pointer to TX queue structure. * @param valid CQE pointer * if not NULL update txq->wqe_pi and flush the buffers @@ -56922,7 +79820,7 @@ index acf0fd794b..ac5c1868a0 100644 * @param olx * Configured Tx offloads mask. It is fully defined at * compile time and may be used for optimization. -@@ -2043,25 +2069,17 @@ mlx5_tx_copy_elts(struct mlx5_txq_data *restrict txq, +@@ -2043,25 +2091,17 @@ mlx5_tx_copy_elts(struct mlx5_txq_data *restrict txq, static __rte_always_inline void mlx5_tx_comp_flush(struct mlx5_txq_data *restrict txq, volatile struct mlx5_cqe *last_cqe, @@ -56955,7 +79853,7 @@ index acf0fd794b..ac5c1868a0 100644 } } -@@ -2085,6 +2103,7 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, +@@ -2085,6 +2125,7 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, { unsigned int count = MLX5_TX_COMP_MAX_CQE; volatile struct mlx5_cqe *last_cqe = NULL; @@ -56963,7 +79861,7 @@ index acf0fd794b..ac5c1868a0 100644 int ret; static_assert(MLX5_CQE_STATUS_HW_OWN < 0, "Must be negative value"); -@@ -2109,31 +2128,49 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, +@@ -2109,31 +2150,49 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, rte_wmb(); ret = mlx5_tx_error_cqe_handle (txq, (volatile struct mlx5_err_cqe *)cqe); @@ -57031,7 +79929,7 @@ index acf0fd794b..ac5c1868a0 100644 } /** -@@ -2145,9 +2182,6 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, +@@ -2145,9 +2204,6 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, * Pointer to TX queue structure. * @param loc * Pointer to burst routine local context. @@ -57041,7 +79939,7 @@ index acf0fd794b..ac5c1868a0 100644 * @param olx * Configured Tx offloads mask. It is fully defined at * compile time and may be used for optimization. -@@ -2155,13 +2189,12 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, +@@ -2155,13 +2211,12 @@ mlx5_tx_handle_completion(struct mlx5_txq_data *restrict txq, static __rte_always_inline void mlx5_tx_request_completion(struct mlx5_txq_data *restrict txq, struct mlx5_txq_local *restrict loc, @@ -57056,7 +79954,7 @@ index acf0fd794b..ac5c1868a0 100644 0 : loc->pkts_sent - loc->pkts_copy; head += part; if ((uint16_t)(head - txq->elts_comp) >= MLX5_TX_COMP_THRESH || -@@ -2175,15 +2208,15 @@ mlx5_tx_request_completion(struct mlx5_txq_data *restrict txq, +@@ -2175,15 +2230,15 @@ mlx5_tx_request_completion(struct mlx5_txq_data *restrict txq, /* Request unconditional completion on last WQE. */ last->cseg.flags = RTE_BE32(MLX5_COMP_ALWAYS << MLX5_COMP_MODE_OFFSET); @@ -57081,7 +79979,7 @@ index acf0fd794b..ac5c1868a0 100644 } } -@@ -2818,8 +2851,14 @@ mlx5_tx_dseg_empw(struct mlx5_txq_data *restrict txq, +@@ -2818,8 +2873,14 @@ mlx5_tx_dseg_empw(struct mlx5_txq_data *restrict txq, unsigned int part; uint8_t *pdst; @@ -57098,7 +79996,7 @@ index acf0fd794b..ac5c1868a0 100644 /* * The WQEBB space availability is checked by caller. * Here we should be aware of WQE ring buffer wraparound only. -@@ -2831,7 +2870,8 @@ mlx5_tx_dseg_empw(struct mlx5_txq_data *restrict txq, +@@ -2831,7 +2892,8 @@ mlx5_tx_dseg_empw(struct mlx5_txq_data *restrict txq, len -= part; if (likely(!len)) { pdst += part; @@ -57108,7 +80006,7 @@ index acf0fd794b..ac5c1868a0 100644 /* Note: no final wraparound check here. */ return (struct mlx5_wqe_dseg *)pdst; } -@@ -2879,9 +2919,16 @@ mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq, +@@ -2879,9 +2941,16 @@ mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq, static_assert(MLX5_DSEG_MIN_INLINE_SIZE == (2 * RTE_ETHER_ADDR_LEN), "invalid Data Segment data size"); @@ -57128,7 +80026,7 @@ index acf0fd794b..ac5c1868a0 100644 memcpy(pdst, buf, MLX5_DSEG_MIN_INLINE_SIZE); buf += MLX5_DSEG_MIN_INLINE_SIZE; pdst += MLX5_DSEG_MIN_INLINE_SIZE; -@@ -2904,7 +2951,8 @@ mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq, +@@ -2904,7 +2973,8 @@ mlx5_tx_dseg_vlan(struct mlx5_txq_data *restrict txq, len -= part; if (likely(!len)) { pdst += part; @@ -57138,7 +80036,7 @@ index acf0fd794b..ac5c1868a0 100644 /* Note: no final wraparound check here. */ return (struct mlx5_wqe_dseg *)pdst; } -@@ -3120,8 +3168,6 @@ mlx5_tx_packet_multi_tso(struct mlx5_txq_data *restrict txq, +@@ -3120,8 +3190,6 @@ mlx5_tx_packet_multi_tso(struct mlx5_txq_data *restrict txq, wqe->cseg.sq_ds = rte_cpu_to_be_32(txq->qp_num_8s | ds); txq->wqe_ci += (ds + 3) / 4; loc->wqe_free -= (ds + 3) / 4; @@ -57147,7 +80045,7 @@ index acf0fd794b..ac5c1868a0 100644 return MLX5_TXCMP_CODE_MULTI; } -@@ -3230,8 +3276,6 @@ mlx5_tx_packet_multi_send(struct mlx5_txq_data *restrict txq, +@@ -3230,8 +3298,6 @@ mlx5_tx_packet_multi_send(struct mlx5_txq_data *restrict txq, } while (true); txq->wqe_ci += (ds + 3) / 4; loc->wqe_free -= (ds + 3) / 4; @@ -57156,7 +80054,16 @@ index acf0fd794b..ac5c1868a0 100644 return MLX5_TXCMP_CODE_MULTI; } -@@ -3388,8 +3432,6 @@ mlx5_tx_packet_multi_inline(struct mlx5_txq_data *restrict txq, +@@ -3375,7 +3441,7 @@ mlx5_tx_packet_multi_inline(struct mlx5_txq_data *restrict txq, + if (unlikely(loc->wqe_free < ((ds + 3) / 4))) + return MLX5_TXCMP_CODE_EXIT; + /* Check for maximal WQE size. */ +- if (unlikely((MLX5_WQE_SIZE_MAX / MLX5_WSEG_SIZE) < ((ds + 3) / 4))) ++ if (unlikely((MLX5_WQE_SIZE_MAX / MLX5_WSEG_SIZE) < ds)) + return MLX5_TXCMP_CODE_ERROR; + #ifdef MLX5_PMD_SOFT_COUNTERS + /* Update sent data bytes/packets counters. */ +@@ -3388,8 +3454,6 @@ mlx5_tx_packet_multi_inline(struct mlx5_txq_data *restrict txq, wqe->cseg.sq_ds = rte_cpu_to_be_32(txq->qp_num_8s | ds); txq->wqe_ci += (ds + 3) / 4; loc->wqe_free -= (ds + 3) / 4; @@ -57165,7 +80072,7 @@ index acf0fd794b..ac5c1868a0 100644 return MLX5_TXCMP_CODE_MULTI; } -@@ -3599,8 +3641,6 @@ mlx5_tx_burst_tso(struct mlx5_txq_data *restrict txq, +@@ -3599,8 +3663,6 @@ mlx5_tx_burst_tso(struct mlx5_txq_data *restrict txq, --loc->elts_free; ++loc->pkts_sent; --pkts_n; @@ -57174,7 +80081,7 @@ index acf0fd794b..ac5c1868a0 100644 if (unlikely(!pkts_n || !loc->elts_free || !loc->wqe_free)) return MLX5_TXCMP_CODE_EXIT; loc->mbuf = *pkts++; -@@ -3750,7 +3790,7 @@ mlx5_tx_sdone_empw(struct mlx5_txq_data *restrict txq, +@@ -3750,7 +3812,7 @@ mlx5_tx_sdone_empw(struct mlx5_txq_data *restrict txq, struct mlx5_txq_local *restrict loc, unsigned int ds, unsigned int slen, @@ -57183,7 +80090,7 @@ index acf0fd794b..ac5c1868a0 100644 { assert(!MLX5_TXOFF_CONFIG(INLINE)); #ifdef MLX5_PMD_SOFT_COUNTERS -@@ -3765,8 +3805,6 @@ mlx5_tx_sdone_empw(struct mlx5_txq_data *restrict txq, +@@ -3765,8 +3827,6 @@ mlx5_tx_sdone_empw(struct mlx5_txq_data *restrict txq, loc->wqe_last->cseg.sq_ds = rte_cpu_to_be_32(txq->qp_num_8s | ds); txq->wqe_ci += (ds + 3) / 4; loc->wqe_free -= (ds + 3) / 4; @@ -57192,7 +80099,7 @@ index acf0fd794b..ac5c1868a0 100644 } /* -@@ -3797,20 +3835,36 @@ mlx5_tx_idone_empw(struct mlx5_txq_data *restrict txq, +@@ -3797,20 +3857,36 @@ mlx5_tx_idone_empw(struct mlx5_txq_data *restrict txq, unsigned int slen, unsigned int olx __rte_unused) { @@ -57233,7 +80140,7 @@ index acf0fd794b..ac5c1868a0 100644 } /** -@@ -4011,8 +4065,6 @@ mlx5_tx_burst_empw_simple(struct mlx5_txq_data *restrict txq, +@@ -4011,8 +4087,6 @@ mlx5_tx_burst_empw_simple(struct mlx5_txq_data *restrict txq, txq->wqe_ci += (2 + part + 3) / 4; loc->wqe_free -= (2 + part + 3) / 4; pkts_n -= part; @@ -57242,7 +80149,7 @@ index acf0fd794b..ac5c1868a0 100644 if (unlikely(!pkts_n || !loc->elts_free || !loc->wqe_free)) return MLX5_TXCMP_CODE_EXIT; loc->mbuf = *pkts++; -@@ -4088,6 +4140,15 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, +@@ -4088,6 +4162,15 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, loc->wqe_free) * MLX5_WQE_SIZE - MLX5_WQE_CSEG_SIZE - MLX5_WQE_ESEG_SIZE; @@ -57258,7 +80165,7 @@ index acf0fd794b..ac5c1868a0 100644 /* Build WQE till we have space, packets and resources. */ part = room; for (;;) { -@@ -4117,8 +4178,28 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, +@@ -4117,8 +4200,28 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, /* Inline or not inline - that's the Question. */ if (dlen > txq->inlen_empw) goto pointer_empw; @@ -57288,7 +80195,7 @@ index acf0fd794b..ac5c1868a0 100644 if (MLX5_TXOFF_CONFIG(VLAN) && loc->mbuf->ol_flags & PKT_TX_VLAN_PKT) { /* -@@ -4143,7 +4224,8 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, +@@ -4143,7 +4246,8 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, dseg = mlx5_tx_dseg_empw(txq, loc, dseg, dptr, dlen, olx); } @@ -57298,7 +80205,7 @@ index acf0fd794b..ac5c1868a0 100644 assert(room >= tlen); room -= tlen; /* -@@ -4153,6 +4235,14 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, +@@ -4153,6 +4257,14 @@ mlx5_tx_burst_empw_inline(struct mlx5_txq_data *restrict txq, rte_pktmbuf_free_seg(loc->mbuf); goto next_mbuf; pointer_empw: @@ -57313,7 +80220,7 @@ index acf0fd794b..ac5c1868a0 100644 /* * Not inlinable VLAN packets are * proceeded outside of this routine. -@@ -4496,8 +4586,6 @@ mlx5_tx_burst_single_send(struct mlx5_txq_data *restrict txq, +@@ -4496,8 +4608,6 @@ mlx5_tx_burst_single_send(struct mlx5_txq_data *restrict txq, } ++loc->pkts_sent; --pkts_n; @@ -57322,7 +80229,7 @@ index acf0fd794b..ac5c1868a0 100644 if (unlikely(!pkts_n || !loc->elts_free || !loc->wqe_free)) return MLX5_TXCMP_CODE_EXIT; loc->mbuf = *pkts++; -@@ -4596,7 +4684,7 @@ mlx5_tx_burst_tmpl(struct mlx5_txq_data *restrict txq, +@@ -4596,7 +4706,7 @@ mlx5_tx_burst_tmpl(struct mlx5_txq_data *restrict txq, /* * Calculate the number of available resources - elts and WQEs. * There are two possible different scenarios: @@ -57331,7 +80238,7 @@ index acf0fd794b..ac5c1868a0 100644 * four packets, in this case elts become scarce resource * - data inlining into WQEs, one packet may require multiple * WQEBBs, the WQEs become the limiting factor. -@@ -4776,6 +4864,8 @@ mlx5_tx_burst_tmpl(struct mlx5_txq_data *restrict txq, +@@ -4776,6 +4886,8 @@ mlx5_tx_burst_tmpl(struct mlx5_txq_data *restrict txq, /* Take a shortcut if nothing is sent. */ if (unlikely(loc.pkts_sent == loc.pkts_loop)) goto burst_exit; @@ -57340,7 +80247,7 @@ index acf0fd794b..ac5c1868a0 100644 /* * Ring QP doorbell immediately after WQE building completion * to improve latencies. The pure software related data treatment -@@ -4977,7 +5067,7 @@ MLX5_TXOFF_DECL(iv, +@@ -4977,7 +5089,7 @@ MLX5_TXOFF_DECL(iv, /* * Generate routines with Legacy Multi-Packet Write support. @@ -57349,7 +80256,7 @@ index acf0fd794b..ac5c1868a0 100644 * offload limitations, not supported: * - ACL/Flows (metadata are becoming meaningless) * - WQE Inline headers -@@ -4995,6 +5085,10 @@ MLX5_TXOFF_DECL(mci_mpw, +@@ -4995,6 +5107,10 @@ MLX5_TXOFF_DECL(mci_mpw, MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW | MLX5_TXOFF_CONFIG_MPW) @@ -57360,7 +80267,7 @@ index acf0fd794b..ac5c1868a0 100644 MLX5_TXOFF_DECL(i_mpw, MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW | MLX5_TXOFF_CONFIG_MPW) -@@ -5151,6 +5245,10 @@ MLX5_TXOFF_INFO(mci_mpw, +@@ -5151,6 +5267,10 @@ MLX5_TXOFF_INFO(mci_mpw, MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW | MLX5_TXOFF_CONFIG_MPW) @@ -57371,7 +80278,7 @@ index acf0fd794b..ac5c1868a0 100644 MLX5_TXOFF_INFO(i_mpw, MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW | MLX5_TXOFF_CONFIG_MPW) -@@ -5277,6 +5375,9 @@ mlx5_select_tx_function(struct rte_eth_dev *dev) +@@ -5277,6 +5397,9 @@ mlx5_select_tx_function(struct rte_eth_dev *dev) /* Does not meet requested offloads at all. */ continue; } @@ -57382,11 +80289,17 @@ index acf0fd794b..ac5c1868a0 100644 /* Do not enable eMPW if not configured. */ continue; diff --git a/dpdk/drivers/net/mlx5/mlx5_rxtx.h b/dpdk/drivers/net/mlx5/mlx5_rxtx.h -index e927343f7d..daa67e2f5c 100644 +index e927343f7d..4648a62998 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxtx.h +++ b/dpdk/drivers/net/mlx5/mlx5_rxtx.h -@@ -114,9 +114,9 @@ struct mlx5_rxq_data { - unsigned int strd_sz_n:4; /* Log 2 of stride size. */ +@@ -110,13 +110,13 @@ 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 strd_num_n:5; /* Log 2 of the number of stride. */ +- unsigned int strd_sz_n:4; /* Log 2 of stride size. */ ++ unsigned int log_strd_num:5; /* Log 2 of the number of stride. */ ++ unsigned int log_strd_sz:4; /* Log 2 of stride size. */ unsigned int strd_shift_en:1; /* Enable 2bytes shift on a stride. */ unsigned int err_state:2; /* enum mlx5_rxq_err_state. */ - unsigned int strd_headroom_en:1; /* Enable mbuf headroom in MPRQ. */ @@ -57397,15 +80310,24 @@ index e927343f7d..daa67e2f5c 100644 volatile uint32_t *rq_db; volatile uint32_t *cq_db; uint16_t port_id; -@@ -154,6 +154,8 @@ struct mlx5_rxq_data { +@@ -154,6 +154,9 @@ struct mlx5_rxq_data { /* CQ (UAR) access lock required for 32bit implementations */ #endif uint32_t tunnel; /* Tunnel information. */ + uint64_t flow_meta_mask; + int32_t flow_meta_offset; ++ uint32_t flow_meta_port_mask; } __rte_cache_aligned; enum mlx5_rxq_obj_type { +@@ -195,7 +198,6 @@ struct mlx5_rxq_ctrl { + unsigned int socket; /* CPU socket ID for allocations. */ + unsigned int irq:1; /* Whether IRQ is enabled. */ + unsigned int dbr_umem_id_valid:1; /* dbr_umem_id holds a valid value. */ +- uint32_t flow_mark_n; /* Number of Mark/Flag flows using this Queue. */ + uint32_t flow_tunnels_n[MLX5_FLOW_TUNNEL]; /* Tunnels counters. */ + uint32_t wqn; /* WQ number. */ + uint16_t dump_file_n; /* Number of dump files. */ @@ -273,9 +275,7 @@ struct mlx5_txq_data { uint16_t wqe_thres; /* WQE threshold to request completion in CQ. */ /* WQ related fields. */ @@ -57495,7 +80417,7 @@ index d85f90874d..0c705d1f7f 100644 if (!priv->config.rx_vec_en) return -ENOTSUP; diff --git a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h -index 8e79883dfe..c167672f52 100644 +index 8e79883dfe..576bc627b7 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h +++ b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h @@ -11,7 +11,7 @@ @@ -57550,7 +80472,7 @@ index 8e79883dfe..c167672f52 100644 { const uint16_t q_n = 1 << rxq->cqe_n; const uint16_t q_mask = q_n - 1; -@@ -644,8 +665,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -644,14 +665,16 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, /* Not to cross queue end. */ pkts_n = RTE_MIN(pkts_n, q_n - elts_idx); pkts_n = RTE_MIN(pkts_n, q_n - cq_idx); @@ -57562,20 +80484,75 @@ index 8e79883dfe..c167672f52 100644 /* At this point, there shouldn't be any remaining packets. */ assert(rxq->decompressed == 0); -@@ -1010,9 +1033,9 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + /* + * A. load first Qword (8bytes) in one loop. +- * B. copy 4 mbuf pointers from elts ring to returing pkts. ++ * B. copy 4 mbuf pointers from elts ring to returning pkts. + * C. load remaining CQE data and extract necessary fields. + * Final 16bytes cqes[] extracted from original 64bytes CQE has the + * following structure: +@@ -785,10 +808,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + (vector unsigned short)cqe_tmp1, cqe_sel_mask1); + cqe_tmp2 = (vector unsigned char)(vector unsigned long){ + *(__attribute__((__aligned__(8))) unsigned long *) +- &cq[pos + p3].rsvd3[9], 0LL}; ++ &cq[pos + p3].rsvd4[2], 0LL}; + cqe_tmp1 = (vector unsigned char)(vector unsigned long){ + *(__attribute__((__aligned__(8))) unsigned long *) +- &cq[pos + p2].rsvd3[9], 0LL}; ++ &cq[pos + p2].rsvd4[2], 0LL}; + cqes[3] = (vector unsigned char) + vec_sel((vector unsigned short)cqes[3], + (vector unsigned short)cqe_tmp2, +@@ -848,10 +871,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + (vector unsigned short)cqe_tmp1, cqe_sel_mask1); + cqe_tmp2 = (vector unsigned char)(vector unsigned long){ + *(__attribute__((__aligned__(8))) unsigned long *) +- &cq[pos + p1].rsvd3[9], 0LL}; ++ &cq[pos + p1].rsvd4[2], 0LL}; + cqe_tmp1 = (vector unsigned char)(vector unsigned long){ + *(__attribute__((__aligned__(8))) unsigned long *) +- &cq[pos].rsvd3[9], 0LL}; ++ &cq[pos].rsvd4[2], 0LL}; + cqes[1] = (vector unsigned char) + vec_sel((vector unsigned short)cqes[1], + (vector unsigned short)cqe_tmp2, cqe_sel_mask2); +@@ -1010,25 +1033,26 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, pkts[pos + 3]->timestamp = rte_be_to_cpu_64(cq[pos + p3].timestamp); } - if (rte_flow_dynf_metadata_avail()) { - uint64_t flag = rte_flow_dynf_metadata_mask; - int offs = rte_flow_dynf_metadata_offs; +- uint32_t metadata; + if (rxq->dynf_meta) { + uint64_t flag = rxq->flow_meta_mask; + int32_t offs = rxq->flow_meta_offset; - uint32_t metadata; ++ uint32_t metadata, mask; ++ mask = rxq->flow_meta_port_mask; /* This code is subject for futher optimization. */ -@@ -1060,8 +1083,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +- metadata = cq[pos].flow_table_metadata; ++ metadata = cq[pos].flow_table_metadata & mask; + *RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) = + metadata; + pkts[pos]->ol_flags |= metadata ? flag : 0ULL; +- metadata = cq[pos + 1].flow_table_metadata; ++ metadata = cq[pos + 1].flow_table_metadata & mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) = + metadata; + pkts[pos + 1]->ol_flags |= metadata ? flag : 0ULL; +- metadata = cq[pos + 2].flow_table_metadata; ++ metadata = cq[pos + 2].flow_table_metadata & mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) = + metadata; + pkts[pos + 2]->ol_flags |= metadata ? flag : 0ULL; +- metadata = cq[pos + 3].flow_table_metadata; ++ metadata = cq[pos + 3].flow_table_metadata & mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) = + metadata; + pkts[pos + 3]->ol_flags |= metadata ? flag : 0ULL; +@@ -1060,8 +1084,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, break; } /* If no new CQE seen, return without updating cq_db. */ @@ -57587,7 +80564,7 @@ index 8e79883dfe..c167672f52 100644 /* Update the consumer indexes for non-compressed CQEs. */ assert(nocmp_n <= pkts_n); rxq->cq_ci += nocmp_n; -@@ -1089,6 +1114,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -1089,6 +1115,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, } rte_compiler_barrier(); *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); @@ -57596,7 +80573,7 @@ index 8e79883dfe..c167672f52 100644 } diff --git a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_neon.h b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_neon.h -index 86785c7496..607659a629 100644 +index 86785c7496..51ad62dd7f 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_neon.h +++ b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_neon.h @@ -205,6 +205,25 @@ rxq_cq_decompress_v(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cq, @@ -57654,7 +80631,38 @@ index 86785c7496..607659a629 100644 /* At this point, there shouldn't be any remained packets. */ assert(rxq->decompressed == 0); /* -@@ -687,28 +710,30 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -474,7 +497,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + * there's no instruction to count trailing zeros. __builtin_clzl() is + * used instead. + * +- * A. copy 4 mbuf pointers from elts ring to returing pkts. ++ * A. copy 4 mbuf pointers from elts ring to returning pkts. + * B. load 64B CQE and extract necessary fields + * Final 16bytes cqes[] extracted from original 64bytes CQE has the + * following structure: +@@ -648,16 +671,15 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + comp_idx = __builtin_clzl(vget_lane_u64(vreinterpret_u64_u16( + comp_mask), 0)) / + (sizeof(uint16_t) * 8); +- /* D.6 mask out entries after the compressed CQE. */ +- mask = vcreate_u16(comp_idx < MLX5_VPMD_DESCS_PER_LOOP ? +- -1UL >> (comp_idx * sizeof(uint16_t) * 8) : +- 0); +- invalid_mask = vorr_u16(invalid_mask, mask); ++ invalid_mask = vorr_u16(invalid_mask, comp_mask); + /* D.7 count non-compressed valid CQEs. */ + n = __builtin_clzl(vget_lane_u64(vreinterpret_u64_u16( + invalid_mask), 0)) / (sizeof(uint16_t) * 8); + nocmp_n += n; +- /* D.2 get the final invalid mask. */ ++ /* ++ * D.2 mask out entries after the compressed CQE. ++ * get the final invalid mask. ++ */ + mask = vcreate_u16(n < MLX5_VPMD_DESCS_PER_LOOP ? + -1UL >> (n * sizeof(uint16_t) * 8) : 0); + invalid_mask = vorr_u16(invalid_mask, mask); +@@ -687,28 +709,35 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, container_of(p3, struct mlx5_cqe, pkt_info)->timestamp); } @@ -57663,22 +80671,29 @@ index 86785c7496..607659a629 100644 /* This code is subject for futher optimization. */ - *RTE_FLOW_DYNF_METADATA(elts[pos]) = + int32_t offs = rxq->flow_meta_offset; ++ uint32_t mask = rxq->flow_meta_port_mask; + + *RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) = container_of(p0, struct mlx5_cqe, - pkt_info)->flow_table_metadata; +- pkt_info)->flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(elts[pos + 1]) = ++ pkt_info)->flow_table_metadata & ++ mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) = container_of(p1, struct mlx5_cqe, - pkt_info)->flow_table_metadata; +- pkt_info)->flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(elts[pos + 2]) = ++ pkt_info)->flow_table_metadata & ++ mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) = container_of(p2, struct mlx5_cqe, - pkt_info)->flow_table_metadata; +- pkt_info)->flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(elts[pos + 3]) = ++ pkt_info)->flow_table_metadata & ++ mask; + *RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) = container_of(p3, struct mlx5_cqe, - pkt_info)->flow_table_metadata; +- pkt_info)->flow_table_metadata; - if (*RTE_FLOW_DYNF_METADATA(elts[pos])) - elts[pos]->ol_flags |= PKT_RX_DYNF_METADATA; - if (*RTE_FLOW_DYNF_METADATA(elts[pos + 1])) @@ -57687,6 +80702,8 @@ index 86785c7496..607659a629 100644 - elts[pos + 2]->ol_flags |= PKT_RX_DYNF_METADATA; - if (*RTE_FLOW_DYNF_METADATA(elts[pos + 3])) - elts[pos + 3]->ol_flags |= PKT_RX_DYNF_METADATA; ++ pkt_info)->flow_table_metadata & ++ mask; + if (*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *)) + elts[pos]->ol_flags |= rxq->flow_meta_mask; + if (*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *)) @@ -57698,7 +80715,7 @@ index 86785c7496..607659a629 100644 } #ifdef MLX5_PMD_SOFT_COUNTERS /* Add up received bytes count. */ -@@ -723,8 +748,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -723,8 +752,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, break; } /* If no new CQE seen, return without updating cq_db. */ @@ -57710,7 +80727,7 @@ index 86785c7496..607659a629 100644 /* Update the consumer indexes for non-compressed CQEs. */ assert(nocmp_n <= pkts_n); rxq->cq_ci += nocmp_n; -@@ -752,6 +779,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -752,6 +783,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, } rte_cio_wmb(); *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); @@ -57719,7 +80736,7 @@ index 86785c7496..607659a629 100644 } diff --git a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_sse.h b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_sse.h -index 35b7761007..9935299d59 100644 +index 35b7761007..2a983c12a1 100644 --- a/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_sse.h +++ b/dpdk/drivers/net/mlx5/mlx5_rxtx_vec_sse.h @@ -118,7 +118,6 @@ rxq_cq_decompress_v(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cq, @@ -57773,7 +80790,7 @@ index 35b7761007..9935299d59 100644 { const uint16_t q_n = 1 << rxq->cqe_n; const uint16_t q_mask = q_n - 1; -@@ -453,8 +473,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -453,13 +473,15 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, /* Not to cross queue end. */ pkts_n = RTE_MIN(pkts_n, q_n - elts_idx); pkts_n = RTE_MIN(pkts_n, q_n - cq_idx); @@ -57785,7 +80802,13 @@ index 35b7761007..9935299d59 100644 /* At this point, there shouldn't be any remained packets. */ assert(rxq->decompressed == 0); /* -@@ -640,24 +662,26 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, + * A. load first Qword (8bytes) in one loop. +- * B. copy 4 mbuf pointers from elts ring to returing pkts. ++ * B. copy 4 mbuf pointers from elts ring to returning pkts. + * C. load remained CQE data and extract necessary fields. + * Final 16bytes cqes[] extracted from original 64bytes CQE has the + * following structure: +@@ -640,24 +662,27 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, pkts[pos + 3]->timestamp = rte_be_to_cpu_64(cq[pos + p3].timestamp); } @@ -57793,19 +80816,13 @@ index 35b7761007..9935299d59 100644 + if (rxq->dynf_meta) { /* This code is subject for futher optimization. */ - *RTE_FLOW_DYNF_METADATA(pkts[pos]) = -+ int32_t offs = rxq->flow_meta_offset; -+ -+ *RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) = - cq[pos].flow_table_metadata; +- cq[pos].flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(pkts[pos + 1]) = -+ *RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) = - cq[pos + p1].flow_table_metadata; +- cq[pos + p1].flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(pkts[pos + 2]) = -+ *RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) = - cq[pos + p2].flow_table_metadata; +- cq[pos + p2].flow_table_metadata; - *RTE_FLOW_DYNF_METADATA(pkts[pos + 3]) = -+ *RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) = - cq[pos + p3].flow_table_metadata; +- cq[pos + p3].flow_table_metadata; - if (*RTE_FLOW_DYNF_METADATA(pkts[pos])) - pkts[pos]->ol_flags |= PKT_RX_DYNF_METADATA; - if (*RTE_FLOW_DYNF_METADATA(pkts[pos + 1])) @@ -57814,6 +80831,17 @@ index 35b7761007..9935299d59 100644 - pkts[pos + 2]->ol_flags |= PKT_RX_DYNF_METADATA; - if (*RTE_FLOW_DYNF_METADATA(pkts[pos + 3])) - pkts[pos + 3]->ol_flags |= PKT_RX_DYNF_METADATA; ++ int32_t offs = rxq->flow_meta_offset; ++ uint32_t mask = rxq->flow_meta_port_mask; ++ ++ *RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *) = ++ cq[pos].flow_table_metadata & mask; ++ *RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *) = ++ cq[pos + p1].flow_table_metadata & mask; ++ *RTE_MBUF_DYNFIELD(pkts[pos + 2], offs, uint32_t *) = ++ cq[pos + p2].flow_table_metadata & mask; ++ *RTE_MBUF_DYNFIELD(pkts[pos + 3], offs, uint32_t *) = ++ cq[pos + p3].flow_table_metadata & mask; + if (*RTE_MBUF_DYNFIELD(pkts[pos], offs, uint32_t *)) + pkts[pos]->ol_flags |= rxq->flow_meta_mask; + if (*RTE_MBUF_DYNFIELD(pkts[pos + 1], offs, uint32_t *)) @@ -57825,7 +80853,7 @@ index 35b7761007..9935299d59 100644 } #ifdef MLX5_PMD_SOFT_COUNTERS /* Add up received bytes count. */ -@@ -674,8 +698,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -674,8 +699,10 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, break; } /* If no new CQE seen, return without updating cq_db. */ @@ -57837,7 +80865,7 @@ index 35b7761007..9935299d59 100644 /* Update the consumer indexes for non-compressed CQEs. */ assert(nocmp_n <= pkts_n); rxq->cq_ci += nocmp_n; -@@ -703,6 +729,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, +@@ -703,6 +730,7 @@ rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, uint16_t pkts_n, } rte_compiler_barrier(); *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); @@ -58057,7 +81085,7 @@ index 205e4fec78..ccdcdcfff6 100644 } diff --git a/dpdk/drivers/net/mlx5/mlx5_trigger.c b/dpdk/drivers/net/mlx5/mlx5_trigger.c -index cafab25c67..04b06e11d7 100644 +index cafab25c67..e91970ddae 100644 --- a/dpdk/drivers/net/mlx5/mlx5_trigger.c +++ b/dpdk/drivers/net/mlx5/mlx5_trigger.c @@ -106,9 +106,12 @@ mlx5_rxq_start(struct rte_eth_dev *dev) @@ -58102,7 +81130,7 @@ index cafab25c67..04b06e11d7 100644 ret = mlx5_flow_start(dev, &priv->flows); if (ret) { DRV_LOG(DEBUG, "port %u failed to set flows", -@@ -320,7 +327,18 @@ mlx5_dev_start(struct rte_eth_dev *dev) +@@ -320,7 +327,25 @@ mlx5_dev_start(struct rte_eth_dev *dev) dev->rx_pkt_burst = mlx5_select_rx_function(dev); /* Enable datapath on secondary process. */ mlx5_mp_req_start_rxtx(dev); @@ -58111,28 +81139,36 @@ index cafab25c67..04b06e11d7 100644 + priv->sh->port[priv->ibv_port - 1].ih_port_id = + (uint32_t)dev->data->port_id; + } else { -+ DRV_LOG(INFO, "port %u starts without LSC and RMV interrupts.", ++ DRV_LOG(INFO, "port %u starts without RMV interrupts.", + dev->data->port_id); -+ dev->data->dev_conf.intr_conf.lsc = 0; + dev->data->dev_conf.intr_conf.rmv = 0; + } ++ if (priv->sh->intr_handle_nl.fd >= 0) { ++ priv->sh->port[priv->ibv_port - 1].nl_ih_port_id = ++ (uint32_t)dev->data->port_id; ++ } else { ++ DRV_LOG(INFO, "port %u starts without LSC interrupts.", ++ dev->data->port_id); ++ dev->data->dev_conf.intr_conf.lsc = 0; ++ } + if (priv->sh->intr_handle_devx.fd >= 0) + priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = + (uint32_t)dev->data->port_id; return 0; error: ret = rte_errno; /* Save rte_errno before cleanup. */ -@@ -359,7 +377,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev) +@@ -359,7 +384,9 @@ mlx5_dev_stop(struct rte_eth_dev *dev) mlx5_flow_stop(dev, &priv->flows); mlx5_traffic_disable(dev); mlx5_rx_intr_vec_disable(dev); - mlx5_dev_interrupt_handler_uninstall(dev); + priv->sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS; + priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS; ++ priv->sh->port[priv->ibv_port - 1].nl_ih_port_id = RTE_MAX_ETHPORTS; mlx5_txq_stop(dev); mlx5_rxq_stop(dev); } -@@ -420,9 +439,14 @@ mlx5_traffic_enable(struct rte_eth_dev *dev) +@@ -420,9 +447,14 @@ mlx5_traffic_enable(struct rte_eth_dev *dev) } mlx5_txq_release(dev, i); } @@ -58151,7 +81187,7 @@ index cafab25c67..04b06e11d7 100644 return 0; if (dev->data->promiscuous) { diff --git a/dpdk/drivers/net/mlx5/mlx5_txq.c b/dpdk/drivers/net/mlx5/mlx5_txq.c -index bac4f71c24..9c929a57ea 100644 +index bac4f71c24..a63b362048 100644 --- a/dpdk/drivers/net/mlx5/mlx5_txq.c +++ b/dpdk/drivers/net/mlx5/mlx5_txq.c @@ -62,7 +62,7 @@ txq_alloc_elts(struct mlx5_txq_ctrl *txq_ctrl) @@ -58429,6 +81465,15 @@ index bac4f71c24..9c929a57ea 100644 rte_free(tmpl); return NULL; } +@@ -1375,7 +1410,7 @@ mlx5_txq_release(struct rte_eth_dev *dev, uint16_t idx) + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_txq_ctrl *txq; + +- if (!(*priv->txqs)[idx]) ++ if (priv->txqs == NULL || (*priv->txqs)[idx] == NULL) + return 0; + txq = container_of((*priv->txqs)[idx], struct mlx5_txq_ctrl, txq); + if (txq->obj && !mlx5_txq_obj_release(txq->obj)) diff --git a/dpdk/drivers/net/mlx5/mlx5_utils.c b/dpdk/drivers/net/mlx5/mlx5_utils.c index 5d86615ea0..c1c238941d 100644 --- a/dpdk/drivers/net/mlx5/mlx5_utils.c @@ -58506,10 +81551,20 @@ index b4ed8c6dad..b23eec622d 100644 /** * Return logarithm of the nearest power of two above input value. diff --git a/dpdk/drivers/net/mvneta/mvneta_ethdev.c b/dpdk/drivers/net/mvneta/mvneta_ethdev.c -index 865ad61aed..4aea876488 100644 +index 865ad61aed..202c477cc0 100644 --- a/dpdk/drivers/net/mvneta/mvneta_ethdev.c +++ b/dpdk/drivers/net/mvneta/mvneta_ethdev.c -@@ -751,7 +751,7 @@ mvneta_stats_reset(struct rte_eth_dev *dev) +@@ -437,6 +437,9 @@ mvneta_dev_close(struct rte_eth_dev *dev) + struct mvneta_priv *priv = dev->data->dev_private; + int i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + if (priv->ppio) + mvneta_dev_stop(dev); + +@@ -751,7 +754,7 @@ mvneta_stats_reset(struct rte_eth_dev *dev) ret = mvneta_stats_get(dev, &priv->prev_stats); if (unlikely(ret)) @@ -58541,10 +81596,32 @@ index 10b6f57584..dfa7ecc090 100644 do { num = MRVL_NETA_RXD_MAX; diff --git a/dpdk/drivers/net/mvpp2/mrvl_ethdev.c b/dpdk/drivers/net/mvpp2/mrvl_ethdev.c -index b98b1fd667..fe4cadda04 100644 +index b98b1fd667..3e12b4b119 100644 --- a/dpdk/drivers/net/mvpp2/mrvl_ethdev.c +++ b/dpdk/drivers/net/mvpp2/mrvl_ethdev.c -@@ -443,8 +443,8 @@ mrvl_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +@@ -400,12 +400,18 @@ mrvl_dev_configure(struct rte_eth_dev *dev) + dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) { + MRVL_LOG(WARNING, "Disabling hash for 1 rx queue"); + priv->ppio_params.inqs_params.hash_type = PP2_PPIO_HASH_T_NONE; +- ++ priv->configured = 1; + return 0; + } + +- return mrvl_configure_rss(priv, +- &dev->data->dev_conf.rx_adv_conf.rss_conf); ++ ret = mrvl_configure_rss(priv, ++ &dev->data->dev_conf.rx_adv_conf.rss_conf); ++ if (ret < 0) ++ return ret; ++ ++ priv->configured = 1; ++ ++ return 0; + } + + /** +@@ -443,8 +449,8 @@ mrvl_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) * when this feature has not been enabled/supported so far * (TODO check scattered_rx flag here once scattered RX is supported). */ @@ -58555,7 +81632,7 @@ index b98b1fd667..fe4cadda04 100644 mtu = MRVL_PP2_MRU_TO_MTU(mru); MRVL_LOG(WARNING, "MTU too big, max MTU possible limitted " "by current mbuf size: %u. Set MTU to %u, MRU to %u", -@@ -673,18 +673,6 @@ mrvl_dev_start(struct rte_eth_dev *dev) +@@ -673,18 +679,6 @@ mrvl_dev_start(struct rte_eth_dev *dev) priv->uc_mc_flushed = 1; } @@ -58574,7 +81651,7 @@ index b98b1fd667..fe4cadda04 100644 ret = mrvl_mtu_set(dev, dev->data->mtu); if (ret) MRVL_LOG(ERR, "Failed to set MTU to %d", dev->data->mtu); -@@ -816,7 +804,7 @@ mrvl_flush_bpool(struct rte_eth_dev *dev) +@@ -816,7 +810,7 @@ mrvl_flush_bpool(struct rte_eth_dev *dev) unsigned int core_id = rte_lcore_id(); if (core_id == LCORE_ID_ANY) @@ -58583,7 +81660,45 @@ index b98b1fd667..fe4cadda04 100644 hif = mrvl_get_hif(priv, core_id); -@@ -1611,8 +1599,8 @@ mrvl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) +@@ -863,6 +857,9 @@ mrvl_dev_close(struct rte_eth_dev *dev) + struct mrvl_priv *priv = dev->data->dev_private; + size_t i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + mrvl_flush_rx_queues(dev); + mrvl_flush_tx_shadow_queues(dev); + mrvl_flow_deinit(dev); +@@ -1379,13 +1376,14 @@ mrvl_xstats_get(struct rte_eth_dev *dev, + { + struct mrvl_priv *priv = dev->data->dev_private; + struct pp2_ppio_statistics ppio_stats; +- unsigned int i; ++ unsigned int i, count; + +- if (!stats) +- return 0; ++ count = RTE_DIM(mrvl_xstats_tbl); ++ if (n < count) ++ return count; + + pp2_ppio_get_statistics(priv->ppio, &ppio_stats, 0); +- for (i = 0; i < n && i < RTE_DIM(mrvl_xstats_tbl); i++) { ++ for (i = 0; i < count; i++) { + uint64_t val; + + if (mrvl_xstats_tbl[i].size == sizeof(uint32_t)) +@@ -1401,7 +1399,7 @@ mrvl_xstats_get(struct rte_eth_dev *dev, + stats[i].value = val; + } + +- return n; ++ return count; + } + + /** +@@ -1611,8 +1609,8 @@ mrvl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) static int mrvl_fill_bpool(struct mrvl_rxq *rxq, int num) { @@ -58594,7 +81709,7 @@ index b98b1fd667..fe4cadda04 100644 int i, ret; unsigned int core_id; struct pp2_hif *hif; -@@ -1620,7 +1608,7 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num) +@@ -1620,7 +1618,7 @@ mrvl_fill_bpool(struct mrvl_rxq *rxq, int num) core_id = rte_lcore_id(); if (core_id == LCORE_ID_ANY) @@ -58603,7 +81718,7 @@ index b98b1fd667..fe4cadda04 100644 hif = mrvl_get_hif(rxq->priv, core_id); if (!hif) -@@ -1708,7 +1696,8 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, +@@ -1708,7 +1706,8 @@ mrvl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, return -EFAULT; } @@ -58613,7 +81728,7 @@ index b98b1fd667..fe4cadda04 100644 if (frame_size < max_rx_pkt_len) { MRVL_LOG(WARNING, "Mbuf size must be increased to %u bytes to hold up " -@@ -1770,7 +1759,7 @@ mrvl_rx_queue_release(void *rxq) +@@ -1770,7 +1769,7 @@ mrvl_rx_queue_release(void *rxq) unsigned int core_id = rte_lcore_id(); if (core_id == LCORE_ID_ANY) @@ -58622,7 +81737,7 @@ index b98b1fd667..fe4cadda04 100644 if (!q) return; -@@ -2168,7 +2157,6 @@ mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc, +@@ -2168,7 +2167,6 @@ mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc, *l4_offset = *l3_offset + MRVL_ARP_LENGTH; break; default: @@ -58630,7 +81745,7 @@ index b98b1fd667..fe4cadda04 100644 break; } -@@ -2180,7 +2168,6 @@ mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc, +@@ -2180,7 +2178,6 @@ mrvl_desc_to_packet_type_and_offset(struct pp2_ppio_desc *desc, packet_type |= RTE_PTYPE_L4_UDP; break; default: @@ -58638,7 +81753,7 @@ index b98b1fd667..fe4cadda04 100644 break; } -@@ -2250,10 +2237,9 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -2250,10 +2247,9 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) ret = pp2_ppio_recv(q->priv->ppio, q->priv->rxq_map[q->queue_id].tc, q->priv->rxq_map[q->queue_id].inq, descs, &nb_pkts); @@ -58651,7 +81766,7 @@ index b98b1fd667..fe4cadda04 100644 mrvl_port_bpool_size[bpool->pp2_id][bpool->id][core_id] -= nb_pkts; for (i = 0; i < nb_pkts; i++) { -@@ -2316,21 +2302,13 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -2316,21 +2312,13 @@ mrvl_rx_pkt_burst(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) if (unlikely(num <= q->priv->bpool_min_size || (!rx_done && num < q->priv->bpool_init_size))) { @@ -58674,7 +81789,7 @@ index b98b1fd667..fe4cadda04 100644 for (i = 0; i < pkt_to_remove; i++) { ret = pp2_bpool_get_buff(hif, bpool, &buff); if (ret) -@@ -2523,12 +2501,8 @@ mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -2523,12 +2511,8 @@ mrvl_tx_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) sq, q->queue_id, 0); sq_free_size = MRVL_PP2_TX_SHADOWQ_SIZE - sq->size - 1; @@ -58688,7 +81803,7 @@ index b98b1fd667..fe4cadda04 100644 for (i = 0; i < nb_pkts; i++) { struct rte_mbuf *mbuf = tx_pkts[i]; -@@ -2645,10 +2619,6 @@ mrvl_tx_sg_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, +@@ -2645,10 +2629,6 @@ mrvl_tx_sg_pkt_burst(void *txq, struct rte_mbuf **tx_pkts, */ if (unlikely(total_descs > sq_free_size)) { total_descs -= nb_segs; @@ -58700,7 +81815,7 @@ index b98b1fd667..fe4cadda04 100644 } diff --git a/dpdk/drivers/net/mvpp2/mrvl_ethdev.h b/dpdk/drivers/net/mvpp2/mrvl_ethdev.h -index db6632f5b6..eee5182ce8 100644 +index db6632f5b6..8566873199 100644 --- a/dpdk/drivers/net/mvpp2/mrvl_ethdev.h +++ b/dpdk/drivers/net/mvpp2/mrvl_ethdev.h @@ -186,7 +186,6 @@ struct mrvl_priv { @@ -58711,6 +81826,15 @@ index db6632f5b6..eee5182ce8 100644 uint8_t isolated; uint8_t multiseg; +@@ -209,6 +208,8 @@ struct mrvl_priv { + LIST_HEAD(shaper_profiles, mrvl_tm_shaper_profile) shaper_profiles; + LIST_HEAD(nodes, mrvl_tm_node) nodes; + uint64_t rate_max; ++ ++ uint8_t configured; /** indicates if device has been configured */ + }; + + /** Flow operations forward declaration. */ diff --git a/dpdk/drivers/net/mvpp2/mrvl_flow.c b/dpdk/drivers/net/mvpp2/mrvl_flow.c index 381b54e291..ea43255284 100644 --- a/dpdk/drivers/net/mvpp2/mrvl_flow.c @@ -58762,8 +81886,177 @@ index 39272acea4..2fa5cb43ad 100644 mtr->shared = shared; mtr->mtr_id = mtr_id; mtr->plcr_bit = MRVL_PLCR_BIT_INVALID; +diff --git a/dpdk/drivers/net/mvpp2/mrvl_tm.c b/dpdk/drivers/net/mvpp2/mrvl_tm.c +index 3de8997030..3e3b0c1f9b 100644 +--- a/dpdk/drivers/net/mvpp2/mrvl_tm.c ++++ b/dpdk/drivers/net/mvpp2/mrvl_tm.c +@@ -57,7 +57,7 @@ mrvl_get_max_rate(struct rte_eth_dev *dev, uint64_t *rate) + + close(fd); + +- *rate = ethtool_cmd_speed(&edata) * 1000 * 1000 / 8; ++ *rate = (uint64_t)ethtool_cmd_speed(&edata) * 1000 * 1000 / 8; + + return 0; + } +@@ -146,6 +146,11 @@ mrvl_node_type_get(struct rte_eth_dev *dev, uint32_t node_id, int *is_leaf, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_node *node; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!is_leaf) + return -rte_tm_error_set(error, EINVAL, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -177,6 +182,11 @@ mrvl_capabilities_get(struct rte_eth_dev *dev, + { + struct mrvl_priv *priv = dev->data->dev_private; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!cap) + return -rte_tm_error_set(error, EINVAL, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -224,6 +234,11 @@ mrvl_level_capabilities_get(struct rte_eth_dev *dev, + { + struct mrvl_priv *priv = dev->data->dev_private; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!cap) + return -rte_tm_error_set(error, EINVAL, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -284,6 +299,11 @@ mrvl_node_capabilities_get(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_node *node; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!cap) + return -rte_tm_error_set(error, EINVAL, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -352,6 +372,11 @@ mrvl_shaper_profile_add(struct rte_eth_dev *dev, uint32_t shaper_profile_id, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_shaper_profile *profile; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!params) + return -rte_tm_error_set(error, EINVAL, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -420,6 +445,11 @@ mrvl_shaper_profile_delete(struct rte_eth_dev *dev, uint32_t shaper_profile_id, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_shaper_profile *profile; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + profile = mrvl_shaper_profile_from_id(priv, shaper_profile_id); + if (!profile) + return -rte_tm_error_set(error, ENODEV, +@@ -566,6 +596,11 @@ mrvl_node_add(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_tm_node *node, *parent = NULL; + int ret; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (priv->ppio) + return -rte_tm_error_set(error, EPERM, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -651,6 +686,11 @@ mrvl_node_delete(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_node *node; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (priv->ppio) { + return -rte_tm_error_set(error, EPERM, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -715,6 +755,11 @@ mrvl_node_suspend(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_tm_node *node, *tmp; + int ret; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + node = mrvl_node_from_id(priv, node_id); + if (!node) + return -rte_tm_error_set(error, ENODEV, +@@ -756,6 +801,11 @@ mrvl_node_resume(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_tm_node *node; + int ret; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + node = mrvl_node_from_id(priv, node_id); + if (!node) + return -rte_tm_error_set(error, ENODEV, +@@ -792,6 +842,11 @@ mrvl_hierarchy_commit(struct rte_eth_dev *dev, int clear_on_fail, + struct mrvl_tm_node *node; + int ret; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (priv->ppio) { + ret = -rte_tm_error_set(error, EPERM, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -898,6 +953,11 @@ mrvl_node_stats_read(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_tm_node *node; + int ret; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + if (!priv->ppio) { + return -rte_tm_error_set(error, EPERM, + RTE_TM_ERROR_TYPE_UNSPECIFIED, +@@ -967,6 +1027,11 @@ mrvl_node_stats_update(struct rte_eth_dev *dev, uint32_t node_id, + struct mrvl_priv *priv = dev->data->dev_private; + struct mrvl_tm_node *node; + ++ if (!priv->configured) ++ return -rte_tm_error_set(error, ENODEV, ++ RTE_TM_ERROR_TYPE_UNSPECIFIED, ++ NULL, "Port didn't configured\n"); ++ + node = mrvl_node_from_id(priv, node_id); + if (!node) + return -rte_tm_error_set(error, ENODEV, diff --git a/dpdk/drivers/net/netvsc/hn_ethdev.c b/dpdk/drivers/net/netvsc/hn_ethdev.c -index 164e9ad174..988f3cf1cb 100644 +index 164e9ad174..22f58fa62b 100644 --- a/dpdk/drivers/net/netvsc/hn_ethdev.c +++ b/dpdk/drivers/net/netvsc/hn_ethdev.c @@ -42,7 +42,8 @@ @@ -58917,7 +82210,16 @@ index 164e9ad174..988f3cf1cb 100644 return error; } -@@ -921,8 +943,14 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) +@@ -825,6 +847,8 @@ static void + hn_dev_close(struct rte_eth_dev *dev) + { + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + hn_vf_close(dev); + hn_dev_free_queues(dev); +@@ -921,16 +945,22 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; @@ -58933,8 +82235,10 @@ index 164e9ad174..988f3cf1cb 100644 + } hv->vmbus = vmbus; - hv->rxbuf_res = &vmbus->resource[HV_RECV_BUF_MAP]; -@@ -930,7 +958,7 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) +- hv->rxbuf_res = &vmbus->resource[HV_RECV_BUF_MAP]; +- hv->chim_res = &vmbus->resource[HV_SEND_BUF_MAP]; ++ hv->rxbuf_res = vmbus->resource[HV_RECV_BUF_MAP]; ++ hv->chim_res = vmbus->resource[HV_SEND_BUF_MAP]; hv->port_id = eth_dev->data->port_id; hv->latency = HN_CHAN_LATENCY_NS; hv->max_queues = 1; @@ -58943,7 +82247,7 @@ index 164e9ad174..988f3cf1cb 100644 hv->vf_port = HN_INVALID_PORT; err = hn_parse_args(eth_dev); -@@ -962,11 +990,11 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) +@@ -962,11 +992,11 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) if (err) goto failed; @@ -58957,7 +82261,7 @@ index 164e9ad174..988f3cf1cb 100644 if (err) goto failed; -@@ -998,7 +1026,7 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) +@@ -998,7 +1028,7 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) failed: PMD_INIT_LOG(NOTICE, "device init failed"); @@ -58966,7 +82270,7 @@ index 164e9ad174..988f3cf1cb 100644 hn_detach(hv); return err; } -@@ -1022,7 +1050,7 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev) +@@ -1022,7 +1052,7 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev) eth_dev->rx_pkt_burst = NULL; hn_detach(hv); @@ -58976,7 +82280,7 @@ index 164e9ad174..988f3cf1cb 100644 rte_free(hv->primary); ret = rte_eth_dev_owner_delete(hv->owner.id); diff --git a/dpdk/drivers/net/netvsc/hn_nvs.c b/dpdk/drivers/net/netvsc/hn_nvs.c -index 6b518685ab..03b6cc1551 100644 +index 6b518685ab..09f363cb9d 100644 --- a/dpdk/drivers/net/netvsc/hn_nvs.c +++ b/dpdk/drivers/net/netvsc/hn_nvs.c @@ -54,7 +54,7 @@ static int hn_nvs_req_send(struct hn_data *hv, @@ -59060,6 +82364,21 @@ index 6b518685ab..03b6cc1551 100644 static int hn_nvs_doinit(struct hn_data *hv, uint32_t nvs_ver) { +@@ -152,11 +193,11 @@ hn_nvs_conn_rxbuf(struct hn_data *hv) + * Connect RXBUF to NVS. + */ + conn.type = NVS_TYPE_RXBUF_CONN; +- conn.gpadl = hv->rxbuf_res->phys_addr; ++ conn.gpadl = hv->rxbuf_res.phys_addr; + conn.sig = NVS_RXBUF_SIG; + PMD_DRV_LOG(DEBUG, "connect rxbuff va=%p gpad=%#" PRIx64, +- hv->rxbuf_res->addr, +- hv->rxbuf_res->phys_addr); ++ hv->rxbuf_res.addr, ++ hv->rxbuf_res.phys_addr); + + error = hn_nvs_execute(hv, &conn, sizeof(conn), + &resp, sizeof(resp), @@ -187,9 +228,15 @@ hn_nvs_conn_rxbuf(struct hn_data *hv) resp.nvs_sect[0].slotcnt); hv->rxbuf_section_cnt = resp.nvs_sect[0].slotcnt; @@ -59087,6 +82406,28 @@ index 6b518685ab..03b6cc1551 100644 /* * Linger long enough for NVS to disconnect RXBUF. */ +@@ -262,17 +308,17 @@ hn_nvs_conn_chim(struct hn_data *hv) + struct hn_nvs_chim_conn chim; + struct hn_nvs_chim_connresp resp; + uint32_t sectsz; +- unsigned long len = hv->chim_res->len; ++ unsigned long len = hv->chim_res.len; + int error; + + /* Connect chimney sending buffer to NVS */ + memset(&chim, 0, sizeof(chim)); + chim.type = NVS_TYPE_CHIM_CONN; +- chim.gpadl = hv->chim_res->phys_addr; ++ chim.gpadl = hv->chim_res.phys_addr; + chim.sig = NVS_CHIM_SIG; + PMD_DRV_LOG(DEBUG, "connect send buf va=%p gpad=%#" PRIx64, +- hv->chim_res->addr, +- hv->chim_res->phys_addr); ++ hv->chim_res.addr, ++ hv->chim_res.phys_addr); + + error = hn_nvs_execute(hv, &chim, sizeof(chim), + &resp, sizeof(resp), diff --git a/dpdk/drivers/net/netvsc/hn_nvs.h b/dpdk/drivers/net/netvsc/hn_nvs.h index 2563fd8d86..015839e364 100644 --- a/dpdk/drivers/net/netvsc/hn_nvs.h @@ -59181,7 +82522,7 @@ index 2b4714042e..6a976ce5e8 100644 memcpy(comp, hv->rndis_resp, comp_len); } diff --git a/dpdk/drivers/net/netvsc/hn_rxtx.c b/dpdk/drivers/net/netvsc/hn_rxtx.c -index 7212780c15..af702dafe6 100644 +index 7212780c15..8adf1525fd 100644 --- a/dpdk/drivers/net/netvsc/hn_rxtx.c +++ b/dpdk/drivers/net/netvsc/hn_rxtx.c @@ -18,6 +18,7 @@ @@ -59567,7 +82908,12 @@ index 7212780c15..af702dafe6 100644 struct rte_mbuf_ext_shared_info *shinfo; const void *rxbuf; rte_iova_t iova; -@@ -484,8 +557,9 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb, +@@ -480,12 +553,13 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb, + * Use refcount to handle multiple packets in same + * receive buffer section. + */ +- rxbuf = hv->rxbuf_res->addr; ++ rxbuf = hv->rxbuf_res.addr; iova = rte_mem_virt2iova(rxbuf) + RTE_PTR_DIFF(data, rxbuf); shinfo = &rxb->shinfo; @@ -59599,6 +82945,17 @@ index 7212780c15..af702dafe6 100644 goto error; if (unlikely(data_len < RTE_ETHER_HDR_LEN)) +@@ -654,8 +730,8 @@ hn_nvs_handle_rxbuf(struct rte_eth_dev *dev, + { + const struct vmbus_chanpkt_rxbuf *pkt; + const struct hn_nvs_hdr *nvs_hdr = buf; +- uint32_t rxbuf_sz = hv->rxbuf_res->len; +- char *rxbuf = hv->rxbuf_res->addr; ++ uint32_t rxbuf_sz = hv->rxbuf_res.len; ++ char *rxbuf = hv->rxbuf_res.addr; + unsigned int i, hlen, count; + struct hn_rx_bufinfo *rxb; + @@ -725,7 +801,8 @@ hn_nvs_handle_rxbuf(struct rte_eth_dev *dev, } @@ -59739,7 +83096,7 @@ index 7212780c15..af702dafe6 100644 + if (txd->chim_index == NVS_CHIM_IDX_INVALID) + return NULL; + -+ chim = (uint8_t *)hv->chim_res->addr ++ chim = (uint8_t *)hv->chim_res.addr + + txd->chim_index * hv->chim_szmax; + + txq->agg_txd = txd; @@ -59748,7 +83105,35 @@ index 7212780c15..af702dafe6 100644 txq->agg_prevpkt = chim; return chim; -@@ -1282,11 +1361,8 @@ static int hn_xmit_sg(struct hn_tx_queue *txq, +@@ -1183,8 +1262,11 @@ static void hn_encap(struct rndis_packet_msg *pkt, + *pi_data = NDIS_LSO2_INFO_MAKEIPV4(hlen, + m->tso_segsz); + } +- } else if (m->ol_flags & +- (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM)) { ++ } else if ((m->ol_flags & PKT_TX_L4_MASK) == ++ PKT_TX_TCP_CKSUM || ++ (m->ol_flags & PKT_TX_L4_MASK) == ++ PKT_TX_UDP_CKSUM || ++ (m->ol_flags & PKT_TX_IP_CKSUM)) { + pi_data = hn_rndis_pktinfo_append(pkt, NDIS_TXCSUM_INFO_SIZE, + NDIS_PKTINFO_TYPE_CSUM); + *pi_data = 0; +@@ -1198,9 +1280,11 @@ static void hn_encap(struct rndis_packet_msg *pkt, + *pi_data |= NDIS_TXCSUM_INFO_IPCS; + } + +- if (m->ol_flags & PKT_TX_TCP_CKSUM) ++ if ((m->ol_flags & PKT_TX_L4_MASK) == ++ PKT_TX_TCP_CKSUM) + *pi_data |= NDIS_TXCSUM_INFO_MKTCPCS(hlen); +- else if (m->ol_flags & PKT_TX_UDP_CKSUM) ++ else if ((m->ol_flags & PKT_TX_L4_MASK) == ++ PKT_TX_UDP_CKSUM) + *pi_data |= NDIS_TXCSUM_INFO_MKUDPCS(hlen); + } + +@@ -1282,11 +1366,8 @@ static int hn_xmit_sg(struct hn_tx_queue *txq, hn_rndis_dump(txd->rndis_pkt); /* pass IOVA of rndis header in first segment */ @@ -59762,7 +83147,7 @@ index 7212780c15..af702dafe6 100644 sg[0].page = addr / PAGE_SIZE; sg[0].ofs = addr & PAGE_MASK; -@@ -1314,28 +1390,38 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1314,28 +1395,38 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) struct hn_data *hv = txq->hv; struct rte_eth_dev *vf_dev; bool need_sig = false; @@ -59804,7 +83189,7 @@ index 7212780c15..af702dafe6 100644 /* For small packets aggregate them in chimney buffer */ if (m->pkt_len < HN_TXCOPY_THRESHOLD && pkt_size <= txq->agg_szmax) { -@@ -1346,7 +1432,8 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1346,7 +1437,8 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) goto fail; } @@ -59814,7 +83199,7 @@ index 7212780c15..af702dafe6 100644 if (unlikely(!pkt)) break; -@@ -1360,21 +1447,13 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1360,21 +1452,13 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) hn_flush_txagg(txq, &need_sig)) goto fail; } else { @@ -59840,7 +83225,7 @@ index 7212780c15..af702dafe6 100644 ++txd->packets; hn_encap(pkt, queue_id, m); -@@ -1383,7 +1462,7 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +@@ -1383,7 +1467,7 @@ hn_xmit_pkts(void *ptxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) if (unlikely(ret != 0)) { PMD_TX_LOG(NOTICE, "sg send failed: %d", ret); ++txq->stats.errors; @@ -59849,7 +83234,7 @@ index 7212780c15..af702dafe6 100644 goto fail; } } -@@ -1442,10 +1521,12 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -1442,10 +1526,12 @@ hn_recv_pkts(void *prxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) (void **)rx_pkts, nb_pkts, NULL); /* If VF is available, check that as well */ @@ -59863,7 +83248,7 @@ index 7212780c15..af702dafe6 100644 } diff --git a/dpdk/drivers/net/netvsc/hn_var.h b/dpdk/drivers/net/netvsc/hn_var.h -index 05bc492511..9814113a0c 100644 +index 05bc492511..66cb084a51 100644 --- a/dpdk/drivers/net/netvsc/hn_var.h +++ b/dpdk/drivers/net/netvsc/hn_var.h @@ -52,6 +52,10 @@ struct hn_tx_queue { @@ -59903,20 +83288,23 @@ index 05bc492511..9814113a0c 100644 uint16_t port_id; uint16_t vf_port; -@@ -108,15 +114,15 @@ struct hn_data { +@@ -107,16 +113,16 @@ struct hn_data { + uint32_t link_status; uint32_t link_speed; - struct rte_mem_resource *rxbuf_res; /* UIO resource for Rx */ +- struct rte_mem_resource *rxbuf_res; /* UIO resource for Rx */ - struct hn_rx_bufinfo *rxbuf_info; ++ struct rte_mem_resource rxbuf_res; /* UIO resource for Rx */ uint32_t rxbuf_section_cnt; /* # of Rx sections */ - volatile uint32_t rxbuf_outstanding; uint16_t max_queues; /* Max available queues */ uint16_t num_queues; uint64_t rss_offloads; -+ rte_spinlock_t chim_lock; - struct rte_mem_resource *chim_res; /* UIO resource for Tx */ +- struct rte_mem_resource *chim_res; /* UIO resource for Tx */ - struct rte_mempool *tx_pool; /* Tx descriptors */ ++ rte_spinlock_t chim_lock; ++ struct rte_mem_resource chim_res; /* UIO resource for Tx */ + struct rte_bitmap *chim_bmap; /* Send buffer map */ + void *chim_bmem; uint32_t chim_szmax; /* Max size per buffer */ @@ -60467,14 +83855,164 @@ index d53e8eca7d..995c44c61c 100644 reason = 'missing dependency, "libnfb"' build = dep.found() ext_deps += dep +diff --git a/dpdk/drivers/net/nfb/nfb.h b/dpdk/drivers/net/nfb/nfb.h +index 59d3ab4986..96c44c3a45 100644 +--- a/dpdk/drivers/net/nfb/nfb.h ++++ b/dpdk/drivers/net/nfb/nfb.h +@@ -48,10 +48,6 @@ struct pmd_internals { + + char nfb_dev[PATH_MAX]; + struct nfb_device *nfb; +- /* Place to remember if filter was promiscuous or filtering by table, +- * when disabling allmulticast +- */ +- enum nc_rxmac_mac_filter rx_filter_original; + }; + + #endif /* _NFB_H_ */ +diff --git a/dpdk/drivers/net/nfb/nfb_ethdev.c b/dpdk/drivers/net/nfb/nfb_ethdev.c +index b039ab6fc2..f4958067c0 100644 +--- a/dpdk/drivers/net/nfb/nfb_ethdev.c ++++ b/dpdk/drivers/net/nfb/nfb_ethdev.c +@@ -77,9 +77,10 @@ static void + nfb_nc_rxmac_deinit(struct nc_rxmac *rxmac[RTE_MAX_NC_RXMAC], + uint16_t max_rxmac) + { +- for (; max_rxmac > 0; --max_rxmac) { +- nc_rxmac_close(rxmac[max_rxmac]); +- rxmac[max_rxmac] = NULL; ++ uint16_t i; ++ for (i = 0; i < max_rxmac; i++) { ++ nc_rxmac_close(rxmac[i]); ++ rxmac[i] = NULL; + } + } + +@@ -95,9 +96,10 @@ static void + nfb_nc_txmac_deinit(struct nc_txmac *txmac[RTE_MAX_NC_TXMAC], + uint16_t max_txmac) + { +- for (; max_txmac > 0; --max_txmac) { +- nc_txmac_close(txmac[max_txmac]); +- txmac[max_txmac] = NULL; ++ uint16_t i; ++ for (i = 0; i < max_txmac; i++) { ++ nc_txmac_close(txmac[i]); ++ txmac[i] = NULL; + } + } + +@@ -217,6 +219,9 @@ nfb_eth_dev_close(struct rte_eth_dev *dev) + uint16_t nb_rx = dev->data->nb_rx_queues; + uint16_t nb_tx = dev->data->nb_tx_queues; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + nfb_eth_dev_stop(dev); + + nfb_nc_rxmac_deinit(internals->rxmac, internals->max_rxmac); +@@ -510,7 +515,6 @@ nfb_eth_dev_init(struct rte_eth_dev *dev) + + data->promiscuous = nfb_eth_promiscuous_get(dev); + data->all_multicast = nfb_eth_allmulticast_get(dev); +- internals->rx_filter_original = data->promiscuous; + + RTE_LOG(INFO, PMD, "NFB device (" + PCI_PRI_FMT ") successfully initialized\n", +diff --git a/dpdk/drivers/net/nfb/nfb_rxmode.c b/dpdk/drivers/net/nfb/nfb_rxmode.c +index 3327c8272b..53894accc1 100644 +--- a/dpdk/drivers/net/nfb/nfb_rxmode.c ++++ b/dpdk/drivers/net/nfb/nfb_rxmode.c +@@ -14,8 +14,6 @@ nfb_eth_promiscuous_enable(struct rte_eth_dev *dev) + dev->data->dev_private; + uint16_t i; + +- internals->rx_filter_original = RXMAC_MAC_FILTER_PROMISCUOUS; +- + for (i = 0; i < internals->max_rxmac; ++i) { + nc_rxmac_mac_filter_enable(internals->rxmac[i], + RXMAC_MAC_FILTER_PROMISCUOUS); +@@ -30,16 +28,13 @@ nfb_eth_promiscuous_disable(struct rte_eth_dev *dev) + struct pmd_internals *internals = (struct pmd_internals *) + dev->data->dev_private; + uint16_t i; ++ enum nc_rxmac_mac_filter filter = RXMAC_MAC_FILTER_TABLE_BCAST; + +- internals->rx_filter_original = RXMAC_MAC_FILTER_TABLE; +- +- /* if promisc is not enabled, do nothing */ +- if (!nfb_eth_promiscuous_get(dev)) +- return 0; ++ if (dev->data->all_multicast) ++ filter = RXMAC_MAC_FILTER_TABLE_BCAST_MCAST; + + for (i = 0; i < internals->max_rxmac; ++i) { +- nc_rxmac_mac_filter_enable(internals->rxmac[i], +- RXMAC_MAC_FILTER_TABLE); ++ nc_rxmac_mac_filter_enable(internals->rxmac[i], filter); + } + + return 0; +@@ -66,6 +61,8 @@ nfb_eth_allmulticast_enable(struct rte_eth_dev *dev) + dev->data->dev_private; + + uint16_t i; ++ if (dev->data->promiscuous) ++ return 0; + for (i = 0; i < internals->max_rxmac; ++i) { + nc_rxmac_mac_filter_enable(internals->rxmac[i], + RXMAC_MAC_FILTER_TABLE_BCAST_MCAST); +@@ -82,13 +79,12 @@ nfb_eth_allmulticast_disable(struct rte_eth_dev *dev) + + uint16_t i; + +- /* if multicast is not enabled do nothing */ +- if (!nfb_eth_allmulticast_get(dev)) ++ if (dev->data->promiscuous) + return 0; + + for (i = 0; i < internals->max_rxmac; ++i) { + nc_rxmac_mac_filter_enable(internals->rxmac[i], +- internals->rx_filter_original); ++ RXMAC_MAC_FILTER_TABLE_BCAST); + } + + return 0; diff --git a/dpdk/drivers/net/nfp/nfp_net.c b/dpdk/drivers/net/nfp/nfp_net.c -index 3aafa7f80f..2aa3b2a103 100644 +index 3aafa7f80f..f427fad487 100644 --- a/dpdk/drivers/net/nfp/nfp_net.c +++ b/dpdk/drivers/net/nfp/nfp_net.c -@@ -1250,6 +1250,20 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) +@@ -871,6 +871,9 @@ nfp_net_close(struct rte_eth_dev *dev) + struct rte_pci_device *pci_dev; + int i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + PMD_INIT_LOG(DEBUG, "Close"); + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); +@@ -1213,9 +1216,6 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM; + +- dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME | +- DEV_RX_OFFLOAD_RSS_HASH; +- + if (hw->cap & NFP_NET_CFG_CTRL_TXVLAN) + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT; + +@@ -1250,15 +1250,36 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) .tx_rs_thresh = DEFAULT_TX_RSBIT_THRESH, }; +- dev_info->flow_type_rss_offloads = ETH_RSS_IPV4 | +- ETH_RSS_NONFRAG_IPV4_TCP | +- ETH_RSS_NONFRAG_IPV4_UDP | +- ETH_RSS_IPV6 | +- ETH_RSS_NONFRAG_IPV6_TCP | +- ETH_RSS_NONFRAG_IPV6_UDP; + dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = NFP_NET_MAX_RX_DESC, + .nb_min = NFP_NET_MIN_RX_DESC, @@ -60489,10 +84027,28 @@ index 3aafa7f80f..2aa3b2a103 100644 + .nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG, + }; + - dev_info->flow_type_rss_offloads = ETH_RSS_IPV4 | - ETH_RSS_NONFRAG_IPV4_TCP | - ETH_RSS_NONFRAG_IPV4_UDP | -@@ -1487,7 +1501,7 @@ nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) ++ /* All NFP devices support jumbo frames */ ++ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_JUMBO_FRAME; ++ ++ if (hw->cap & NFP_NET_CFG_CTRL_RSS) { ++ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_RSS_HASH; + +- dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ; +- dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ; ++ dev_info->flow_type_rss_offloads = ETH_RSS_IPV4 | ++ ETH_RSS_NONFRAG_IPV4_TCP | ++ ETH_RSS_NONFRAG_IPV4_UDP | ++ ETH_RSS_IPV6 | ++ ETH_RSS_NONFRAG_IPV6_TCP | ++ ETH_RSS_NONFRAG_IPV6_UDP; ++ ++ dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ; ++ dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ; ++ } + + dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G | + ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G | +@@ -1487,7 +1508,7 @@ nfp_net_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) } /* switch to jumbo mode if needed */ @@ -60501,7 +84057,7 @@ index 3aafa7f80f..2aa3b2a103 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; -@@ -1513,15 +1527,17 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev, +@@ -1513,15 +1534,17 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev, const struct rte_memzone *tz; struct nfp_net_rxq *rxq; struct nfp_net_hw *hw; @@ -60522,7 +84078,7 @@ index 3aafa7f80f..2aa3b2a103 100644 PMD_DRV_LOG(ERR, "Wrong nb_desc value"); return -EINVAL; } -@@ -1660,15 +1676,17 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, +@@ -1660,15 +1683,17 @@ nfp_net_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, struct nfp_net_txq *txq; uint16_t tx_free_thresh; struct nfp_net_hw *hw; @@ -60543,19 +84099,49 @@ index 3aafa7f80f..2aa3b2a103 100644 PMD_DRV_LOG(ERR, "Wrong nb_desc value"); return -EINVAL; } -@@ -2353,11 +2371,6 @@ nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask) - hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); - new_ctrl = 0; +@@ -2348,27 +2373,25 @@ nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask) + { + uint32_t new_ctrl, update; + struct nfp_net_hw *hw; ++ struct rte_eth_conf *dev_conf; + int ret; + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- new_ctrl = 0; +- - if ((mask & ETH_VLAN_FILTER_OFFLOAD) || - (mask & ETH_VLAN_EXTEND_OFFLOAD)) - PMD_DRV_LOG(INFO, "No support for ETH_VLAN_FILTER_OFFLOAD or" - " ETH_VLAN_EXTEND_OFFLOAD"); - - /* Enable vlan strip if it is not configured yet */ - if ((mask & ETH_VLAN_STRIP_OFFLOAD) && - !(hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) -@@ -2626,6 +2639,9 @@ nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, +- /* Enable vlan strip if it is not configured yet */ +- if ((mask & ETH_VLAN_STRIP_OFFLOAD) && +- !(hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) +- new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_RXVLAN; ++ dev_conf = &dev->data->dev_conf; ++ new_ctrl = hw->ctrl; + +- /* Disable vlan strip just if it is configured */ +- if (!(mask & ETH_VLAN_STRIP_OFFLOAD) && +- (hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) +- new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_RXVLAN; ++ /* ++ * Vlan stripping setting ++ * Enable or disable VLAN stripping ++ */ ++ if (mask & ETH_VLAN_STRIP_MASK) { ++ if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) ++ new_ctrl |= NFP_NET_CFG_CTRL_RXVLAN; ++ else ++ new_ctrl &= ~NFP_NET_CFG_CTRL_RXVLAN; ++ } + +- if (new_ctrl == 0) ++ if (new_ctrl == hw->ctrl) + return 0; + + update = NFP_NET_CFG_UPDATE_GEN; +@@ -2626,6 +2649,9 @@ nfp_net_rss_hash_conf_get(struct rte_eth_dev *dev, if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP; @@ -60565,8 +84151,20 @@ index 3aafa7f80f..2aa3b2a103 100644 /* Reading the key size */ rss_conf->rss_key_len = nn_cfg_readl(hw, NFP_NET_CFG_RSS_KEY_SZ); -@@ -3014,7 +3030,7 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) - size_t count, curlen, totlen = 0; +@@ -2896,6 +2922,7 @@ nfp_net_init(struct rte_eth_dev *eth_dev) + hw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP); + hw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU); + hw->mtu = RTE_ETHER_MTU; ++ hw->flbufsz = RTE_ETHER_MTU; + + /* VLAN insertion is incompatible with LSOv2 */ + if (hw->cap & NFP_NET_CFG_CTRL_LSO2) +@@ -3011,10 +3038,10 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) + off_t offset, nfp_offset; + uint32_t cpp_id, pos, len; + uint32_t tmpbuf[16]; +- size_t count, curlen, totlen = 0; ++ size_t count, curlen; int err = 0; - PMD_CPP_LOG(DEBUG, "%s: offset size %lu, count_size: %lu\n", __func__, @@ -60574,7 +84172,7 @@ index 3aafa7f80f..2aa3b2a103 100644 sizeof(off_t), sizeof(size_t)); /* Reading the count param */ -@@ -3033,9 +3049,9 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) +@@ -3033,9 +3060,9 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) cpp_id = (offset >> 40) << 8; nfp_offset = offset & ((1ull << 40) - 1); @@ -60586,7 +84184,7 @@ index 3aafa7f80f..2aa3b2a103 100644 cpp_id, nfp_offset); /* Adjust length if not aligned */ -@@ -3067,12 +3083,12 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) +@@ -3067,12 +3094,12 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) if (len > sizeof(tmpbuf)) len = sizeof(tmpbuf); @@ -60601,8 +84199,20 @@ index 3aafa7f80f..2aa3b2a103 100644 __func__, err, count); nfp_cpp_area_release(area); nfp_cpp_area_free(area); -@@ -3116,7 +3132,7 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) - size_t count, curlen, totlen = 0; +@@ -3088,7 +3115,6 @@ nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) + } + + nfp_offset += pos; +- totlen += pos; + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + +@@ -3113,10 +3139,10 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) + off_t offset, nfp_offset; + uint32_t cpp_id, pos, len; + uint32_t tmpbuf[16]; +- size_t count, curlen, totlen = 0; ++ size_t count, curlen; int err = 0; - PMD_CPP_LOG(DEBUG, "%s: offset size %lu, count_size: %lu\n", __func__, @@ -60610,7 +84220,7 @@ index 3aafa7f80f..2aa3b2a103 100644 sizeof(off_t), sizeof(size_t)); /* Reading the count param */ -@@ -3135,9 +3151,9 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) +@@ -3135,9 +3161,9 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) cpp_id = (offset >> 40) << 8; nfp_offset = offset & ((1ull << 40) - 1); @@ -60622,7 +84232,7 @@ index 3aafa7f80f..2aa3b2a103 100644 cpp_id, nfp_offset); /* Adjust length if not aligned */ -@@ -3174,13 +3190,13 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) +@@ -3174,13 +3200,13 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) nfp_cpp_area_free(area); return -EIO; } @@ -60638,7 +84248,15 @@ index 3aafa7f80f..2aa3b2a103 100644 __func__, err, count); nfp_cpp_area_release(area); nfp_cpp_area_free(area); -@@ -3451,9 +3467,10 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports, +@@ -3189,7 +3215,6 @@ nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) + } + + nfp_offset += pos; +- totlen += pos; + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + +@@ -3451,9 +3476,10 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports, probe_failed: rte_free(port_name); /* free ports private data if primary process */ @@ -60652,22 +84270,28 @@ index 3aafa7f80f..2aa3b2a103 100644 return retval; diff --git a/dpdk/drivers/net/nfp/nfp_net_pmd.h b/dpdk/drivers/net/nfp/nfp_net_pmd.h -index cc1055c49a..466a11aca2 100644 +index cc1055c49a..42ab369cff 100644 --- a/dpdk/drivers/net/nfp/nfp_net_pmd.h +++ b/dpdk/drivers/net/nfp/nfp_net_pmd.h -@@ -33,6 +33,12 @@ struct nfp_net_adapter; - #define NFP_NET_MAX_RX_DESC (32 * 1024) - #define NFP_NET_MIN_RX_DESC 64 +@@ -28,10 +28,16 @@ struct nfp_net_adapter; + * DPDK uses uint16_t variables for these values + */ + #define NFP_NET_MAX_TX_DESC (32 * 1024) +-#define NFP_NET_MIN_TX_DESC 64 ++#define NFP_NET_MIN_TX_DESC 256 + #define NFP_NET_MAX_RX_DESC (32 * 1024) +-#define NFP_NET_MIN_RX_DESC 64 ++#define NFP_NET_MIN_RX_DESC 256 ++ +/* Descriptor alignment */ +#define NFP_ALIGN_RING_DESC 128 + +#define NFP_TX_MAX_SEG UINT8_MAX +#define NFP_TX_MAX_MTU_SEG 8 -+ + /* Bar allocation */ #define NFP_NET_CRTL_BAR 0 - #define NFP_NET_TX_BAR 2 diff --git a/dpdk/drivers/net/nfp/nfpcore/nfp_cpp.h b/dpdk/drivers/net/nfp/nfpcore/nfp_cpp.h index 1427954c17..08d656da14 100644 --- a/dpdk/drivers/net/nfp/nfpcore/nfp_cpp.h @@ -60681,6 +84305,20 @@ index 1427954c17..08d656da14 100644 /* * NFP CPP core interface for CPP clients. +diff --git a/dpdk/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c b/dpdk/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c +index 0b9db974e1..0fb3e7864b 100644 +--- a/dpdk/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c ++++ b/dpdk/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c +@@ -16,9 +16,6 @@ + + #include + #include +-#if defined(RTE_BACKTRACE) +-#include +-#endif + #include + #include + #include diff --git a/dpdk/drivers/net/nfp/nfpcore/nfp_cppcore.c b/dpdk/drivers/net/nfp/nfpcore/nfp_cppcore.c index dec4a8b6d1..6d629430d4 100644 --- a/dpdk/drivers/net/nfp/nfpcore/nfp_cppcore.c @@ -60770,6 +84408,103 @@ index dec4a8b6d1..6d629430d4 100644 } /* +diff --git a/dpdk/drivers/net/nfp/nfpcore/nfp_target.h b/dpdk/drivers/net/nfp/nfpcore/nfp_target.h +index 2884a0034f..e8dcc9ad1e 100644 +--- a/dpdk/drivers/net/nfp/nfpcore/nfp_target.h ++++ b/dpdk/drivers/net/nfp/nfpcore/nfp_target.h +@@ -37,7 +37,7 @@ pushpull_width(int pp) + static inline int + target_rw(uint32_t cpp_id, int pp, int start, int len) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + + if (island && (island < start || island > (start + len))) + return NFP_ERRNO(EINVAL); +@@ -117,7 +117,7 @@ nfp6000_nbi_ppc(uint32_t cpp_id) + static inline int + nfp6000_nbi(uint32_t cpp_id, uint64_t address) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + uint64_t rel_addr = address & 0x3fFFFF; + + if (island && (island < 8 || island > 9)) +@@ -281,7 +281,7 @@ static inline int + nfp6000_mu(uint32_t cpp_id, uint64_t address) + { + int pp; +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + + if (island == 0) { + if (address < 0x2000000000ULL) +@@ -316,7 +316,7 @@ nfp6000_mu(uint32_t cpp_id, uint64_t address) + static inline int + nfp6000_ila(uint32_t cpp_id) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + + if (island && (island < 48 || island > 51)) + return NFP_ERRNO(EINVAL); +@@ -336,7 +336,7 @@ nfp6000_ila(uint32_t cpp_id) + static inline int + nfp6000_pci(uint32_t cpp_id) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + + if (island && (island < 4 || island > 7)) + return NFP_ERRNO(EINVAL); +@@ -354,7 +354,7 @@ nfp6000_pci(uint32_t cpp_id) + static inline int + nfp6000_crypto(uint32_t cpp_id) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + + if (island && (island < 12 || island > 15)) + return NFP_ERRNO(EINVAL); +@@ -370,9 +370,9 @@ nfp6000_crypto(uint32_t cpp_id) + static inline int + nfp6000_cap_xpb(uint32_t cpp_id) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + +- if (island && (island < 1 || island > 63)) ++ if (island > 63) + return NFP_ERRNO(EINVAL); + + switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) { +@@ -410,9 +410,9 @@ nfp6000_cap_xpb(uint32_t cpp_id) + static inline int + nfp6000_cls(uint32_t cpp_id) + { +- int island = NFP_CPP_ID_ISLAND_of(cpp_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_id); + +- if (island && (island < 1 || island > 63)) ++ if (island > 63) + return NFP_ERRNO(EINVAL); + + switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) { +@@ -540,11 +540,11 @@ nfp_target_cpp(uint32_t cpp_island_id, uint64_t cpp_island_address, + const uint32_t *imb_table) + { + int err; +- int island = NFP_CPP_ID_ISLAND_of(cpp_island_id); +- int target = NFP_CPP_ID_TARGET_of(cpp_island_id); ++ uint8_t island = NFP_CPP_ID_ISLAND_of(cpp_island_id); ++ uint8_t target = NFP_CPP_ID_TARGET_of(cpp_island_id); + uint32_t imb; + +- if (target < 0 || target >= 16) ++ if (target >= 16) + return NFP_ERRNO(EINVAL); + + if (island == 0) { diff --git a/dpdk/drivers/net/null/rte_eth_null.c b/dpdk/drivers/net/null/rte_eth_null.c index 025b73acb3..beedd5f4b2 100644 --- a/dpdk/drivers/net/null/rte_eth_null.c @@ -60827,7 +84562,7 @@ index 025b73acb3..beedd5f4b2 100644 PMD_LOG(INFO, "Configure pmd_null: packet size is %d, " diff --git a/dpdk/drivers/net/octeontx/base/meson.build b/dpdk/drivers/net/octeontx/base/meson.build -index a06a2c89c9..e1060fc4ec 100644 +index a06a2c89c9..a3c3475994 100644 --- a/dpdk/drivers/net/octeontx/base/meson.build +++ b/dpdk/drivers/net/octeontx/base/meson.build @@ -10,7 +10,10 @@ sources = [ @@ -60842,6 +84577,12 @@ index a06a2c89c9..e1060fc4ec 100644 endforeach c_args = cflags +@@ -22,4 +25,4 @@ base_lib = static_library('octeontx_base', sources, + dependencies: static_objs, + ) + +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/octeontx/base/octeontx_io.h b/dpdk/drivers/net/octeontx/base/octeontx_io.h index 04b9ce1910..d0b9cfbc67 100644 --- a/dpdk/drivers/net/octeontx/base/octeontx_io.h @@ -60882,11 +84623,51 @@ index 04b9ce1910..d0b9cfbc67 100644 #else static inline uint64_t +diff --git a/dpdk/drivers/net/octeontx/base/octeontx_pkivf.h b/dpdk/drivers/net/octeontx/base/octeontx_pkivf.h +index d541dc3bd9..ae5ffadf49 100644 +--- a/dpdk/drivers/net/octeontx/base/octeontx_pkivf.h ++++ b/dpdk/drivers/net/octeontx/base/octeontx_pkivf.h +@@ -346,7 +346,6 @@ int octeontx_pki_port_open(int port); + int octeontx_pki_port_hash_config(int port, pki_hash_cfg_t *hash_cfg); + int octeontx_pki_port_pktbuf_config(int port, pki_pktbuf_cfg_t *buf_cfg); + int octeontx_pki_port_create_qos(int port, pki_qos_cfg_t *qos_cfg); +-int octeontx_pki_port_close(int port); + int octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg); + + #endif /* __OCTEONTX_PKI_H__ */ diff --git a/dpdk/drivers/net/octeontx/octeontx_ethdev.c b/dpdk/drivers/net/octeontx/octeontx_ethdev.c -index 679803dd4c..e85acdde0a 100644 +index 679803dd4c..3fc405908d 100644 --- a/dpdk/drivers/net/octeontx/octeontx_ethdev.c +++ b/dpdk/drivers/net/octeontx/octeontx_ethdev.c -@@ -351,6 +351,10 @@ octeontx_dev_close(struct rte_eth_dev *dev) +@@ -24,6 +24,11 @@ + #include "octeontx_rxtx.h" + #include "octeontx_logs.h" + ++/* Useful in stopping/closing event device if no of ++ * eth ports are using it. ++ */ ++uint16_t evdev_refcnt; ++ + struct octeontx_vdev_init_params { + uint8_t nr_port; + }; +@@ -333,8 +338,14 @@ octeontx_dev_close(struct rte_eth_dev *dev) + int ret; + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + +- rte_event_dev_close(nic->evdev); ++ /* Stopping/closing event device once all eth ports are closed. */ ++ if (__atomic_sub_fetch(&evdev_refcnt, 1, __ATOMIC_ACQUIRE) == 0) { ++ rte_event_dev_stop(nic->evdev); ++ rte_event_dev_close(nic->evdev); ++ } + + ret = octeontx_pko_channel_close(nic->base_ochan); + if (ret < 0) { +@@ -351,6 +362,10 @@ octeontx_dev_close(struct rte_eth_dev *dev) rte_free(txq); } @@ -60897,7 +84678,24 @@ index 679803dd4c..e85acdde0a 100644 dev->tx_pkt_burst = NULL; dev->rx_pkt_burst = NULL; } -@@ -1099,7 +1103,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, +@@ -423,8 +438,6 @@ octeontx_dev_stop(struct rte_eth_dev *dev) + + PMD_INIT_FUNC_TRACE(); + +- rte_event_dev_stop(nic->evdev); +- + ret = octeontx_port_stop(nic); + if (ret < 0) { + octeontx_log_err("failed to req stop port %d res=%d", +@@ -1053,6 +1066,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, + nic->pko_vfid = pko_vfid; + nic->port_id = port; + nic->evdev = evdev; ++ __atomic_add_fetch(&evdev_refcnt, 1, __ATOMIC_ACQUIRE); + + res = octeontx_port_open(nic); + if (res < 0) +@@ -1099,7 +1113,7 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)", data->port_id, nic->port_id); res = -EINVAL; @@ -60906,7 +84704,7 @@ index 679803dd4c..e85acdde0a 100644 } /* Update port_id mac to eth_dev */ -@@ -1118,6 +1122,9 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, +@@ -1118,6 +1132,9 @@ octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, rte_eth_dev_probing_finish(eth_dev); return data->port_id; @@ -60916,8 +84714,16 @@ index 679803dd4c..e85acdde0a 100644 err: if (nic) octeontx_port_close(nic); +@@ -1278,6 +1295,7 @@ octeontx_probe(struct rte_vdev_device *dev) + } + } + ++ __atomic_store_n(&evdev_refcnt, 0, __ATOMIC_RELEASE); + /* + * Do 1:1 links for ports & queues. All queues would be mapped to + * one port. If there are more ports than queues, then some ports diff --git a/dpdk/drivers/net/octeontx2/otx2_ethdev.c b/dpdk/drivers/net/octeontx2/otx2_ethdev.c -index ed329273dc..c952373be4 100644 +index ed329273dc..edd46eae48 100644 --- a/dpdk/drivers/net/octeontx2/otx2_ethdev.c +++ b/dpdk/drivers/net/octeontx2/otx2_ethdev.c @@ -18,7 +18,8 @@ nix_get_rx_offload_capa(struct otx2_eth_dev *dev) @@ -60995,7 +84801,15 @@ index ed329273dc..c952373be4 100644 static int nix_sq_init(struct otx2_eth_txq *txq) { -@@ -1114,10 +1142,12 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) +@@ -1070,6 +1098,7 @@ otx2_nix_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t sq, + txq->qconf.nb_desc = nb_desc; + memcpy(&txq->qconf.conf.tx, tx_conf, sizeof(struct rte_eth_txconf)); + ++ txq->lso_tun_fmt = dev->lso_tun_fmt; + otx2_nix_form_default_desc(txq); + + otx2_nix_dbg("sq=%d fc=%p offload=0x%" PRIx64 " sqb=0x%" PRIx64 "" +@@ -1114,10 +1143,12 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) txq = (struct otx2_eth_txq **)eth_dev->data->tx_queues; for (i = 0; i < nb_txq; i++) { if (txq[i] == NULL) { @@ -61010,7 +84824,7 @@ index ed329273dc..c952373be4 100644 otx2_nix_tx_queue_release(txq[i]); eth_dev->data->tx_queues[i] = NULL; } -@@ -1125,10 +1155,12 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) +@@ -1125,10 +1156,12 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) rxq = (struct otx2_eth_rxq **)eth_dev->data->rx_queues; for (i = 0; i < nb_rxq; i++) { if (rxq[i] == NULL) { @@ -61025,7 +84839,7 @@ index ed329273dc..c952373be4 100644 otx2_nix_rx_queue_release(rxq[i]); eth_dev->data->rx_queues[i] = NULL; } -@@ -1138,10 +1170,8 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) +@@ -1138,10 +1171,8 @@ nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev) return 0; fail: @@ -61038,7 +84852,7 @@ index ed329273dc..c952373be4 100644 return -ENOMEM; } -@@ -1183,6 +1213,8 @@ nix_restore_queue_cfg(struct rte_eth_dev *eth_dev) +@@ -1183,6 +1214,8 @@ nix_restore_queue_cfg(struct rte_eth_dev *eth_dev) * queues are already setup in port_configure(). */ for (i = 0; i < nb_txq; i++) { @@ -61047,7 +84861,7 @@ index ed329273dc..c952373be4 100644 rc = otx2_nix_tx_queue_setup(eth_dev, i, tx_qconf[i].nb_desc, tx_qconf[i].socket_id, &tx_qconf[i].conf.tx); -@@ -1198,6 +1230,8 @@ nix_restore_queue_cfg(struct rte_eth_dev *eth_dev) +@@ -1198,6 +1231,8 @@ nix_restore_queue_cfg(struct rte_eth_dev *eth_dev) free(tx_qconf); tx_qconf = NULL; for (i = 0; i < nb_rxq; i++) { @@ -61056,7 +84870,157 @@ index ed329273dc..c952373be4 100644 rc = otx2_nix_rx_queue_setup(eth_dev, i, rx_qconf[i].nb_desc, rx_qconf[i].socket_id, &rx_qconf[i].conf.rx, -@@ -1641,6 +1675,15 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) +@@ -1414,7 +1449,7 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + struct otx2_mbox *mbox = dev->mbox; + struct nix_lso_format_cfg_rsp *rsp; + struct nix_lso_format_cfg *req; +- uint8_t base; ++ uint8_t *fmt; + int rc; + + /* Skip if TSO was not requested */ +@@ -1429,11 +1464,9 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- base = rsp->lso_format_idx; +- if (base != NIX_LSO_FORMAT_IDX_TSOV4) ++ if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV4) + return -EFAULT; +- dev->lso_base_idx = base; +- otx2_nix_dbg("tcpv4 lso fmt=%u", base); ++ otx2_nix_dbg("tcpv4 lso fmt=%u", rsp->lso_format_idx); + + + /* +@@ -1445,9 +1478,9 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 1) ++ if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV6) + return -EFAULT; +- otx2_nix_dbg("tcpv6 lso fmt=%u\n", base + 1); ++ otx2_nix_dbg("tcpv6 lso fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv4/UDP/TUN HDR/IPv4/TCP LSO +@@ -1458,9 +1491,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 2) +- return -EFAULT; +- otx2_nix_dbg("udp tun v4v4 fmt=%u\n", base + 2); ++ dev->lso_udp_tun_idx[NIX_LSO_TUN_V4V4] = rsp->lso_format_idx; ++ otx2_nix_dbg("udp tun v4v4 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv4/UDP/TUN HDR/IPv6/TCP LSO +@@ -1471,9 +1503,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 3) +- return -EFAULT; +- otx2_nix_dbg("udp tun v4v6 fmt=%u\n", base + 3); ++ dev->lso_udp_tun_idx[NIX_LSO_TUN_V4V6] = rsp->lso_format_idx; ++ otx2_nix_dbg("udp tun v4v6 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv6/UDP/TUN HDR/IPv4/TCP LSO +@@ -1484,9 +1515,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 4) +- return -EFAULT; +- otx2_nix_dbg("udp tun v6v4 fmt=%u\n", base + 4); ++ dev->lso_udp_tun_idx[NIX_LSO_TUN_V6V4] = rsp->lso_format_idx; ++ otx2_nix_dbg("udp tun v6v4 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv6/UDP/TUN HDR/IPv6/TCP LSO +@@ -1496,9 +1526,9 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + rc = otx2_mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; +- if (rsp->lso_format_idx != base + 5) +- return -EFAULT; +- otx2_nix_dbg("udp tun v6v6 fmt=%u\n", base + 5); ++ ++ dev->lso_udp_tun_idx[NIX_LSO_TUN_V6V6] = rsp->lso_format_idx; ++ otx2_nix_dbg("udp tun v6v6 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv4/TUN HDR/IPv4/TCP LSO +@@ -1509,9 +1539,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 6) +- return -EFAULT; +- otx2_nix_dbg("tun v4v4 fmt=%u\n", base + 6); ++ dev->lso_tun_idx[NIX_LSO_TUN_V4V4] = rsp->lso_format_idx; ++ otx2_nix_dbg("tun v4v4 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv4/TUN HDR/IPv6/TCP LSO +@@ -1522,9 +1551,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 7) +- return -EFAULT; +- otx2_nix_dbg("tun v4v6 fmt=%u\n", base + 7); ++ dev->lso_tun_idx[NIX_LSO_TUN_V4V6] = rsp->lso_format_idx; ++ otx2_nix_dbg("tun v4v6 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv6/TUN HDR/IPv4/TCP LSO +@@ -1535,9 +1563,8 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + if (rc) + return rc; + +- if (rsp->lso_format_idx != base + 8) +- return -EFAULT; +- otx2_nix_dbg("tun v6v4 fmt=%u\n", base + 8); ++ dev->lso_tun_idx[NIX_LSO_TUN_V6V4] = rsp->lso_format_idx; ++ otx2_nix_dbg("tun v6v4 fmt=%u\n", rsp->lso_format_idx); + + /* + * IPv6/TUN HDR/IPv6/TCP LSO +@@ -1547,9 +1574,26 @@ nix_setup_lso_formats(struct otx2_eth_dev *dev) + rc = otx2_mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; +- if (rsp->lso_format_idx != base + 9) +- return -EFAULT; +- otx2_nix_dbg("tun v6v6 fmt=%u\n", base + 9); ++ ++ dev->lso_tun_idx[NIX_LSO_TUN_V6V6] = rsp->lso_format_idx; ++ otx2_nix_dbg("tun v6v6 fmt=%u\n", rsp->lso_format_idx); ++ ++ /* Save all tun formats into u64 for fast path. ++ * Lower 32bit has non-udp tunnel formats. ++ * Upper 32bit has udp tunnel formats. ++ */ ++ fmt = dev->lso_tun_idx; ++ dev->lso_tun_fmt = ((uint64_t)fmt[NIX_LSO_TUN_V4V4] | ++ (uint64_t)fmt[NIX_LSO_TUN_V4V6] << 8 | ++ (uint64_t)fmt[NIX_LSO_TUN_V6V4] << 16 | ++ (uint64_t)fmt[NIX_LSO_TUN_V6V6] << 24); ++ ++ fmt = dev->lso_udp_tun_idx; ++ dev->lso_tun_fmt |= ((uint64_t)fmt[NIX_LSO_TUN_V4V4] << 32 | ++ (uint64_t)fmt[NIX_LSO_TUN_V4V6] << 40 | ++ (uint64_t)fmt[NIX_LSO_TUN_V6V4] << 48 | ++ (uint64_t)fmt[NIX_LSO_TUN_V6V6] << 56); ++ + return 0; + } + +@@ -1641,6 +1685,15 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) goto fail_offloads; } @@ -61072,7 +85036,7 @@ index ed329273dc..c952373be4 100644 rc = nix_lf_switch_header_type_enable(dev); if (rc) { otx2_err("Failed to enable switch type nix_lf rc=%d", rc); -@@ -1714,6 +1757,12 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) +@@ -1714,6 +1767,12 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) goto cq_fini; } @@ -61086,7 +85050,7 @@ index ed329273dc..c952373be4 100644 if (rc < 0) { otx2_err("Failed to install mc address list rc=%d", rc); diff --git a/dpdk/drivers/net/octeontx2/otx2_ethdev.h b/dpdk/drivers/net/octeontx2/otx2_ethdev.h -index 987e7607c4..6855200fb2 100644 +index 987e7607c4..848a1dff85 100644 --- a/dpdk/drivers/net/octeontx2/otx2_ethdev.h +++ b/dpdk/drivers/net/octeontx2/otx2_ethdev.h @@ -50,6 +50,8 @@ @@ -61098,7 +85062,22 @@ index 987e7607c4..6855200fb2 100644 /* HW config of frame size doesn't include FCS */ #define NIX_MAX_HW_FRS 9212 -@@ -192,6 +194,7 @@ struct otx2_eth_qconf { +@@ -169,6 +171,14 @@ enum nix_q_size_e { + nix_q_size_max + }; + ++enum nix_lso_tun_type { ++ NIX_LSO_TUN_V4V4, ++ NIX_LSO_TUN_V4V6, ++ NIX_LSO_TUN_V6V4, ++ NIX_LSO_TUN_V6V6, ++ NIX_LSO_TUN_MAX, ++}; ++ + struct otx2_qint { + struct rte_eth_dev *eth_dev; + uint8_t qintx; +@@ -192,6 +202,7 @@ struct otx2_eth_qconf { void *mempool; uint32_t socket_id; uint16_t nb_desc; @@ -61106,7 +85085,14 @@ index 987e7607c4..6855200fb2 100644 }; struct otx2_fc_info { -@@ -266,6 +269,7 @@ struct otx2_eth_dev { +@@ -262,10 +273,13 @@ struct otx2_eth_dev { + uint8_t tx_chan_cnt; + uint8_t lso_tsov4_idx; + uint8_t lso_tsov6_idx; +- uint8_t lso_base_idx; ++ uint8_t lso_udp_tun_idx[NIX_LSO_TUN_MAX]; ++ uint8_t lso_tun_idx[NIX_LSO_TUN_MAX]; ++ uint64_t lso_tun_fmt; uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; uint8_t mkex_pfl_name[MKEX_NAME_LEN]; uint8_t max_mac_entries; @@ -61114,7 +85100,15 @@ index 987e7607c4..6855200fb2 100644 uint8_t lf_tx_stats; uint8_t lf_rx_stats; uint16_t flags; -@@ -422,6 +426,8 @@ int otx2_nix_set_mc_addr_list(struct rte_eth_dev *eth_dev, +@@ -335,6 +349,7 @@ struct otx2_eth_txq { + rte_iova_t fc_iova; + uint16_t sqes_per_sqb_log2; + int16_t nb_sqb_bufs_adj; ++ uint64_t lso_tun_fmt; + MARKER slow_path_start; + uint16_t nb_sqb_bufs; + uint16_t sq; +@@ -422,6 +437,8 @@ int otx2_nix_set_mc_addr_list(struct rte_eth_dev *eth_dev, /* MTU */ int otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu); int otx2_nix_recalc_mtu(struct rte_eth_dev *eth_dev); @@ -61123,7 +85117,7 @@ index 987e7607c4..6855200fb2 100644 /* Link */ void otx2_nix_toggle_flag_link_cfg(struct otx2_eth_dev *dev, bool set); -@@ -438,6 +444,8 @@ int oxt2_nix_register_cq_irqs(struct rte_eth_dev *eth_dev); +@@ -438,6 +455,8 @@ int oxt2_nix_register_cq_irqs(struct rte_eth_dev *eth_dev); void otx2_nix_unregister_irqs(struct rte_eth_dev *eth_dev); void oxt2_nix_unregister_queue_irqs(struct rte_eth_dev *eth_dev); void oxt2_nix_unregister_cq_irqs(struct rte_eth_dev *eth_dev); @@ -61132,7 +85126,7 @@ index 987e7607c4..6855200fb2 100644 int otx2_nix_rx_queue_intr_enable(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id); -@@ -504,6 +512,8 @@ int otx2_cgx_mac_addr_set(struct rte_eth_dev *eth_dev, +@@ -504,6 +523,8 @@ int otx2_cgx_mac_addr_set(struct rte_eth_dev *eth_dev, struct rte_ether_addr *addr); /* Flow Control */ @@ -61141,6 +85135,19 @@ index 987e7607c4..6855200fb2 100644 int otx2_nix_flow_ctrl_get(struct rte_eth_dev *eth_dev, struct rte_eth_fc_conf *fc_conf); +diff --git a/dpdk/drivers/net/octeontx2/otx2_ethdev_devargs.c b/dpdk/drivers/net/octeontx2/otx2_ethdev_devargs.c +index 04da1abbdb..d29d1eb97b 100644 +--- a/dpdk/drivers/net/octeontx2/otx2_ethdev_devargs.c ++++ b/dpdk/drivers/net/octeontx2/otx2_ethdev_devargs.c +@@ -115,7 +115,7 @@ otx2_ethdev_parse_devargs(struct rte_devargs *devargs, struct otx2_eth_dev *dev) + { + uint16_t rss_size = NIX_RSS_RETA_SIZE; + uint16_t sqb_count = NIX_MAX_SQB; +- uint16_t flow_prealloc_size = 8; ++ uint16_t flow_prealloc_size = 1; + uint16_t switch_header_type = 0; + uint16_t flow_max_priority = 3; + uint16_t scalar_enable = 0; diff --git a/dpdk/drivers/net/octeontx2/otx2_ethdev_irq.c b/dpdk/drivers/net/octeontx2/otx2_ethdev_irq.c index 2256e40b6f..b121488faf 100644 --- a/dpdk/drivers/net/octeontx2/otx2_ethdev_irq.c @@ -61222,10 +85229,20 @@ index 2256e40b6f..b121488faf 100644 + otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1C); +} diff --git a/dpdk/drivers/net/octeontx2/otx2_ethdev_ops.c b/dpdk/drivers/net/octeontx2/otx2_ethdev_ops.c -index 8f1635dbab..beb4f58148 100644 +index 8f1635dbab..0854026706 100644 --- a/dpdk/drivers/net/octeontx2/otx2_ethdev_ops.c +++ b/dpdk/drivers/net/octeontx2/otx2_ethdev_ops.c -@@ -58,7 +58,7 @@ otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) +@@ -17,7 +17,8 @@ otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) + struct nix_frs_cfg *req; + int rc; + +- frame_size += NIX_TIMESYNC_RX_OFFSET * otx2_ethdev_is_ptp_en(dev); ++ if (dev->configured && otx2_ethdev_is_ptp_en(dev)) ++ frame_size += NIX_TIMESYNC_RX_OFFSET; + + /* Check if MTU is within the allowed range */ + if (frame_size < NIX_MIN_FRS || frame_size > NIX_MAX_FRS) +@@ -58,7 +59,7 @@ otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) if (rc) return rc; @@ -61234,7 +85251,7 @@ index 8f1635dbab..beb4f58148 100644 dev->rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else dev->rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; -@@ -72,22 +72,15 @@ otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) +@@ -72,22 +73,15 @@ otx2_nix_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) int otx2_nix_recalc_mtu(struct rte_eth_dev *eth_dev) { @@ -61258,7 +85275,7 @@ index 8f1635dbab..beb4f58148 100644 /* Setup MTU based on max_rx_pkt_len */ mtu = data->dev_conf.rxmode.max_rx_pkt_len - NIX_L2_OVERHEAD; -@@ -148,8 +141,10 @@ otx2_nix_promisc_enable(struct rte_eth_dev *eth_dev) +@@ -148,8 +142,10 @@ otx2_nix_promisc_enable(struct rte_eth_dev *eth_dev) int otx2_nix_promisc_disable(struct rte_eth_dev *eth_dev) { @@ -61270,8 +85287,30 @@ index 8f1635dbab..beb4f58148 100644 return 0; } +@@ -538,8 +534,7 @@ otx2_nix_get_module_eeprom(struct rte_eth_dev *eth_dev, + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct cgx_fw_data *rsp; + +- if (!info->data || !info->length || +- (info->offset + info->length > SFP_EEPROM_SIZE)) ++ if (info->offset + info->length > SFP_EEPROM_SIZE) + return -EINVAL; + + rsp = nix_get_fwdata(dev); +@@ -566,6 +561,11 @@ otx2_nix_info_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *devinfo) + devinfo->max_vfs = pci_dev->max_vfs; + devinfo->max_mtu = devinfo->max_rx_pktlen - NIX_L2_OVERHEAD; + devinfo->min_mtu = devinfo->min_rx_bufsize - NIX_L2_OVERHEAD; ++ if (dev->configured && otx2_ethdev_is_ptp_en(dev)) { ++ devinfo->max_mtu -= NIX_TIMESYNC_RX_OFFSET; ++ devinfo->min_mtu -= NIX_TIMESYNC_RX_OFFSET; ++ devinfo->max_rx_pktlen -= NIX_TIMESYNC_RX_OFFSET; ++ } + + devinfo->rx_offload_capa = dev->rx_offload_capa; + devinfo->tx_offload_capa = dev->tx_offload_capa; diff --git a/dpdk/drivers/net/octeontx2/otx2_flow.c b/dpdk/drivers/net/octeontx2/otx2_flow.c -index f1fb9f9884..c9886c9705 100644 +index f1fb9f9884..0930244da4 100644 --- a/dpdk/drivers/net/octeontx2/otx2_flow.c +++ b/dpdk/drivers/net/octeontx2/otx2_flow.c @@ -269,6 +269,8 @@ flow_program_rss_action(struct rte_eth_dev *eth_dev, @@ -61283,6 +85322,53 @@ index f1fb9f9884..c9886c9705 100644 flow->npc_action |= ((uint64_t)(alg_idx & NIX_RSS_ACT_ALG_MASK) << NIX_RSS_ACT_ALG_OFFSET) | +@@ -808,12 +810,23 @@ flow_fetch_kex_cfg(struct otx2_eth_dev *dev) + return rc; + } + ++#define OTX2_MCAM_TOT_ENTRIES_96XX (4096) ++#define OTX2_MCAM_TOT_ENTRIES_98XX (16384) ++ ++static int otx2_mcam_tot_entries(struct otx2_eth_dev *dev) ++{ ++ if (otx2_dev_is_98xx(dev)) ++ return OTX2_MCAM_TOT_ENTRIES_98XX; ++ else ++ return OTX2_MCAM_TOT_ENTRIES_96XX; ++} ++ + int + otx2_flow_init(struct otx2_eth_dev *hw) + { + uint8_t *mem = NULL, *nix_mem = NULL, *npc_mem = NULL; + struct otx2_npc_flow_info *npc = &hw->npc_flow; +- uint32_t bmap_sz; ++ uint32_t bmap_sz, tot_mcam_entries = 0; + int rc = 0, idx; + + rc = flow_fetch_kex_cfg(hw); +@@ -824,7 +837,8 @@ otx2_flow_init(struct otx2_eth_dev *hw) + + rte_atomic32_init(&npc->mark_actions); + +- npc->mcam_entries = NPC_MCAM_TOT_ENTRIES >> npc->keyw[NPC_MCAM_RX]; ++ tot_mcam_entries = otx2_mcam_tot_entries(hw); ++ npc->mcam_entries = tot_mcam_entries >> npc->keyw[NPC_MCAM_RX]; + /* Free, free_rev, live and live_rev entries */ + bmap_sz = rte_bitmap_get_memory_footprint(npc->mcam_entries); + mem = rte_zmalloc(NULL, 4 * bmap_sz * npc->flow_max_priority, +diff --git a/dpdk/drivers/net/octeontx2/otx2_flow.h b/dpdk/drivers/net/octeontx2/otx2_flow.h +index df78f41d3b..e618664ca7 100644 +--- a/dpdk/drivers/net/octeontx2/otx2_flow.h ++++ b/dpdk/drivers/net/octeontx2/otx2_flow.h +@@ -34,7 +34,6 @@ enum { + /* 32 bytes from LDATA_CFG & 32 bytes from FLAGS_CFG */ + #define NPC_MAX_EXTRACT_DATA_LEN (64) + #define NPC_LDATA_LFLAG_LEN (16) +-#define NPC_MCAM_TOT_ENTRIES (4096) + #define NPC_MAX_KEY_NIBBLES (31) + /* Nibble offsets */ + #define NPC_LAYER_KEYX_SZ (3) diff --git a/dpdk/drivers/net/octeontx2/otx2_flow_ctrl.c b/dpdk/drivers/net/octeontx2/otx2_flow_ctrl.c index c6d7b1971a..76bf481001 100644 --- a/dpdk/drivers/net/octeontx2/otx2_flow_ctrl.c @@ -61557,10 +85643,115 @@ index 351ad0fcb4..1863bfde72 100644 } #define CKSUM_F NIX_RX_OFFLOAD_CHECKSUM_F +diff --git a/dpdk/drivers/net/octeontx2/otx2_tx.c b/dpdk/drivers/net/octeontx2/otx2_tx.c +index fa533000ed..f498a90d16 100644 +--- a/dpdk/drivers/net/octeontx2/otx2_tx.c ++++ b/dpdk/drivers/net/octeontx2/otx2_tx.c +@@ -27,6 +27,7 @@ nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + struct otx2_eth_txq *txq = tx_queue; uint16_t i; + const rte_iova_t io_addr = txq->io_addr; + void *lmt_addr = txq->lmt_addr; ++ uint64_t lso_tun_fmt; + + NIX_XMIT_FC_OR_RETURN(txq, pkts); + +@@ -34,6 +35,7 @@ nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + + /* Perform header writes before barrier for TSO */ + if (flags & NIX_TX_OFFLOAD_TSO_F) { ++ lso_tun_fmt = txq->lso_tun_fmt; + for (i = 0; i < pkts; i++) + otx2_nix_xmit_prepare_tso(tx_pkts[i], flags); + } +@@ -42,7 +44,7 @@ nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + rte_cio_wmb(); + + for (i = 0; i < pkts; i++) { +- otx2_nix_xmit_prepare(tx_pkts[i], cmd, flags); ++ otx2_nix_xmit_prepare(tx_pkts[i], cmd, flags, lso_tun_fmt); + /* Passing no of segdw as 4: HDR + EXT + SG + SMEM */ + otx2_nix_xmit_prepare_tstamp(cmd, &txq->cmd[0], + tx_pkts[i]->ol_flags, 4, flags); +@@ -62,6 +64,7 @@ nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts, + struct otx2_eth_txq *txq = tx_queue; uint64_t i; + const rte_iova_t io_addr = txq->io_addr; + void *lmt_addr = txq->lmt_addr; ++ uint64_t lso_tun_fmt; + uint16_t segdw; + + NIX_XMIT_FC_OR_RETURN(txq, pkts); +@@ -70,6 +73,7 @@ nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts, + + /* Perform header writes before barrier for TSO */ + if (flags & NIX_TX_OFFLOAD_TSO_F) { ++ lso_tun_fmt = txq->lso_tun_fmt; + for (i = 0; i < pkts; i++) + otx2_nix_xmit_prepare_tso(tx_pkts[i], flags); + } +@@ -78,7 +82,7 @@ nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts, + rte_cio_wmb(); + + for (i = 0; i < pkts; i++) { +- otx2_nix_xmit_prepare(tx_pkts[i], cmd, flags); ++ otx2_nix_xmit_prepare(tx_pkts[i], cmd, flags, lso_tun_fmt); + segdw = otx2_nix_prepare_mseg(tx_pkts[i], cmd, flags); + otx2_nix_xmit_prepare_tstamp(cmd, &txq->cmd[0], + tx_pkts[i]->ol_flags, segdw, +diff --git a/dpdk/drivers/net/octeontx2/otx2_tx.h b/dpdk/drivers/net/octeontx2/otx2_tx.h +index 04e859bacd..c13c4c2c2f 100644 +--- a/dpdk/drivers/net/octeontx2/otx2_tx.h ++++ b/dpdk/drivers/net/octeontx2/otx2_tx.h +@@ -196,7 +196,8 @@ otx2_nix_xmit_prepare_tso(struct rte_mbuf *m, const uint64_t flags) + } + + static __rte_always_inline void +-otx2_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags) ++otx2_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags, ++ const uint64_t lso_tun_fmt) + { + struct nix_send_ext_s *send_hdr_ext; + struct nix_send_hdr_s *send_hdr; +@@ -338,14 +339,15 @@ otx2_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags) + (ol_flags & PKT_TX_TUNNEL_MASK)) { + const uint8_t is_udp_tun = (NIX_UDP_TUN_BITMASK >> + ((ol_flags & PKT_TX_TUNNEL_MASK) >> 45)) & 0x1; ++ uint8_t shift = is_udp_tun ? 32 : 0; ++ ++ shift += (!!(ol_flags & PKT_TX_OUTER_IPV6) << 4); ++ shift += (!!(ol_flags & PKT_TX_IPV6) << 3); + + w1.il4type = NIX_SENDL4TYPE_TCP_CKSUM; + w1.ol4type = is_udp_tun ? NIX_SENDL4TYPE_UDP_CKSUM : 0; + /* Update format for UDP tunneled packet */ +- send_hdr_ext->w0.lso_format += is_udp_tun ? 2 : 6; +- +- send_hdr_ext->w0.lso_format += +- !!(ol_flags & PKT_TX_OUTER_IPV6) << 1; ++ send_hdr_ext->w0.lso_format = (lso_tun_fmt >> shift); + } + } + diff --git a/dpdk/drivers/net/octeontx2/otx2_vlan.c b/dpdk/drivers/net/octeontx2/otx2_vlan.c -index 322a565b3e..7357b06695 100644 +index 322a565b3e..f5161e17a1 100644 --- a/dpdk/drivers/net/octeontx2/otx2_vlan.c +++ b/dpdk/drivers/net/octeontx2/otx2_vlan.c +@@ -306,12 +306,12 @@ nix_vlan_mcam_config(struct rte_eth_dev *eth_dev, + (0xF & ~(NPC_LT_LB_CTAG ^ NPC_LT_LB_STAG_QINQ)) + << mkex->lb_lt_offset; + +- mcam_data = ((uint32_t)vlan_id << 16); +- mcam_mask = (BIT_ULL(16) - 1) << 16; ++ mcam_data = (uint16_t)vlan_id; ++ mcam_mask = (BIT_ULL(16) - 1); + otx2_mbox_memcpy(key_data + mkex->lb_xtract.key_off, +- &mcam_data, mkex->lb_xtract.len + 1); ++ &mcam_data, mkex->lb_xtract.len); + otx2_mbox_memcpy(key_mask + mkex->lb_xtract.key_off, +- &mcam_mask, mkex->lb_xtract.len + 1); ++ &mcam_mask, mkex->lb_xtract.len); + } + + /* Adds LB STAG flag to MCAM KW */ @@ -717,11 +717,6 @@ otx2_nix_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) rxmode = ð_dev->data->dev_conf.rxmode; @@ -61574,7 +85765,7 @@ index 322a565b3e..7357b06695 100644 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) { offloads |= DEV_RX_OFFLOAD_VLAN_STRIP; diff --git a/dpdk/drivers/net/pcap/rte_eth_pcap.c b/dpdk/drivers/net/pcap/rte_eth_pcap.c -index aa7ef6fdbc..f4afe67116 100644 +index aa7ef6fdbc..619868c510 100644 --- a/dpdk/drivers/net/pcap/rte_eth_pcap.c +++ b/dpdk/drivers/net/pcap/rte_eth_pcap.c @@ -377,7 +377,7 @@ eth_tx_drop(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) @@ -61625,6 +85816,15 @@ index aa7ef6fdbc..f4afe67116 100644 } } +@@ -789,7 +802,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, + + pcap_pkt_count = count_packets_in_pcap(pcap, pcap_q); + +- snprintf(ring_name, sizeof(ring_name), "PCAP_RING%" PRIu16, ++ snprintf(ring_name, sizeof(ring_name), "PCAP_RING%" PRIu32, + ring_number); + + pcap_q->pkts = rte_ring_create(ring_name, @@ -803,21 +816,25 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, while (eth_pcap_rx(pcap_q, bufs, 1)) { /* Check for multiseg mbufs. */ @@ -61672,7 +85872,41 @@ index aa7ef6fdbc..f4afe67116 100644 internals->phy_mac = 1; } } -@@ -1398,7 +1414,8 @@ pmd_pcap_probe(struct rte_vdev_device *dev) +@@ -1320,6 +1336,33 @@ eth_from_pcaps(struct rte_vdev_device *vdev, + return 0; + } + ++static void ++eth_release_pcaps(struct pmd_devargs *pcaps, ++ struct pmd_devargs *dumpers, ++ int single_iface) ++{ ++ unsigned int i; ++ ++ if (single_iface) { ++ if (pcaps->queue[0].pcap) ++ pcap_close(pcaps->queue[0].pcap); ++ return; ++ } ++ ++ for (i = 0; i < dumpers->num_of_queue; i++) { ++ if (dumpers->queue[i].dumper) ++ pcap_dump_close(dumpers->queue[i].dumper); ++ ++ if (dumpers->queue[i].pcap) ++ pcap_close(dumpers->queue[i].pcap); ++ } ++ ++ for (i = 0; i < pcaps->num_of_queue; i++) { ++ if (pcaps->queue[i].pcap) ++ pcap_close(pcaps->queue[i].pcap); ++ } ++} ++ + static int + pmd_pcap_probe(struct rte_vdev_device *dev) + { +@@ -1398,7 +1441,8 @@ pmd_pcap_probe(struct rte_vdev_device *dev) devargs_all.is_rx_pcap = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0; devargs_all.is_rx_iface = @@ -61682,8 +85916,18 @@ index aa7ef6fdbc..f4afe67116 100644 pcaps.num_of_queue = 0; devargs_all.is_tx_pcap = +@@ -1532,6 +1576,9 @@ pmd_pcap_probe(struct rte_vdev_device *dev) + free_kvlist: + rte_kvargs_free(kvlist); + ++ if (ret < 0) ++ eth_release_pcaps(&pcaps, &dumpers, devargs_all.single_iface); ++ + return ret; + } + diff --git a/dpdk/drivers/net/pfe/pfe_ethdev.c b/dpdk/drivers/net/pfe/pfe_ethdev.c -index 9403478198..5a231918a1 100644 +index 9403478198..4e2ba0565f 100644 --- a/dpdk/drivers/net/pfe/pfe_ethdev.c +++ b/dpdk/drivers/net/pfe/pfe_ethdev.c @@ -13,7 +13,7 @@ @@ -61695,7 +85939,14 @@ index 9403478198..5a231918a1 100644 #define PFE_VDEV_GEM_ID_ARG "intf" struct pfe_vdev_init_params { -@@ -396,7 +396,6 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) +@@ -392,11 +392,13 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) + { + PMD_INIT_FUNC_TRACE(); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + pfe_eth_stop(dev); /* Close the device file for link status */ pfe_eth_close_cdev(dev->data->dev_private); @@ -61703,7 +85954,7 @@ index 9403478198..5a231918a1 100644 rte_eth_dev_release_port(dev); pfe->nb_devs--; } -@@ -430,9 +429,6 @@ static int +@@ -430,9 +432,6 @@ static int pfe_eth_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { @@ -61713,7 +85964,19 @@ index 9403478198..5a231918a1 100644 dev_info->max_mac_addrs = PFE_MAX_MACS; dev_info->max_rx_queues = dev->data->nb_rx_queues; dev_info->max_tx_queues = dev->data->nb_tx_queues; -@@ -990,7 +986,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) +@@ -584,11 +583,6 @@ pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused) + struct rte_eth_link link, old; + unsigned int lstatus = 1; + +- if (dev == NULL) { +- PFE_PMD_ERR("Invalid device in link_update.\n"); +- return 0; +- } +- + memset(&old, 0, sizeof(old)); + memset(&link, 0, sizeof(struct rte_eth_link)); + +@@ -990,7 +984,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) if (rc < 0) return -EINVAL; @@ -61722,7 +85985,7 @@ index 9403478198..5a231918a1 100644 name, init_params.gem_id); if (g_pfe) { -@@ -1118,7 +1114,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) +@@ -1118,7 +1112,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) else gem_id = init_params.gem_id; @@ -61732,10 +85995,18 @@ index 9403478198..5a231918a1 100644 rc = pfe_eth_init(vdev, g_pfe, gem_id); diff --git a/dpdk/drivers/net/qede/base/bcm_osal.h b/dpdk/drivers/net/qede/base/bcm_osal.h -index 0f09557cf0..d9f507f233 100644 +index 0f09557cf0..1e4fe2db02 100644 --- a/dpdk/drivers/net/qede/base/bcm_osal.h +++ b/dpdk/drivers/net/qede/base/bcm_osal.h -@@ -81,9 +81,8 @@ typedef int bool; +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -81,9 +80,8 @@ typedef int bool; #define DELAY(x) rte_delay_us(x) #define usec_delay(x) DELAY(x) @@ -61746,6 +86017,15 @@ index 0f09557cf0..d9f507f233 100644 /* Memory allocations and deallocations */ +@@ -99,7 +97,7 @@ typedef int bool; + } while (0) + #define OSAL_VFREE(dev, memory) OSAL_FREE(dev, memory) + #define OSAL_MEM_ZERO(mem, size) bzero(mem, size) +-#define OSAL_MEMCPY(dst, src, size) rte_memcpy(dst, src, size) ++#define OSAL_MEMCPY(dst, src, size) memcpy(dst, src, size) + #define OSAL_MEMCMP(s1, s2, size) memcmp(s1, s2, size) + #define OSAL_MEMSET(dst, val, length) \ + memset(dst, val, length) diff --git a/dpdk/drivers/net/qede/base/ecore_dev.c b/dpdk/drivers/net/qede/base/ecore_dev.c index 9d1db14590..86ecfb2690 100644 --- a/dpdk/drivers/net/qede/base/ecore_dev.c @@ -61841,6 +86121,19 @@ index 4d5cc1a0fa..5ea8427a07 100644 }; /** +diff --git a/dpdk/drivers/net/qede/base/ecore_int.c b/dpdk/drivers/net/qede/base/ecore_int.c +index 4207b1853e..2c4aac9418 100644 +--- a/dpdk/drivers/net/qede/base/ecore_int.c ++++ b/dpdk/drivers/net/qede/base/ecore_int.c +@@ -928,7 +928,7 @@ static void ecore_int_attn_print(struct ecore_hwfn *p_hwfn, + bool b_clear) + { + /* @DPDK */ +- DP_NOTICE(p_hwfn->p_dev, false, "[block_id %d type %d]\n", id, type); ++ DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "[block_id %d type %d]\n", id, type); + } + + /** diff --git a/dpdk/drivers/net/qede/base/ecore_iov_api.h b/dpdk/drivers/net/qede/base/ecore_iov_api.h index c998dbf8d5..5450018121 100644 --- a/dpdk/drivers/net/qede/base/ecore_iov_api.h @@ -61907,10 +86200,29 @@ index deee04ac4b..6633d6b42e 100644 return rc; } diff --git a/dpdk/drivers/net/qede/base/ecore_vf.c b/dpdk/drivers/net/qede/base/ecore_vf.c -index 24846cfb51..0e5b7d5eb3 100644 +index 24846cfb51..6d4a1d9708 100644 --- a/dpdk/drivers/net/qede/base/ecore_vf.c +++ b/dpdk/drivers/net/qede/base/ecore_vf.c -@@ -226,7 +226,6 @@ enum _ecore_status_t ecore_vf_pf_release(struct ecore_hwfn *p_hwfn) +@@ -73,7 +73,7 @@ static void ecore_vf_pf_req_end(struct ecore_hwfn *p_hwfn, + #endif + static enum _ecore_status_t + ecore_send_msg2pf(struct ecore_hwfn *p_hwfn, +- u8 *done, u32 resp_size) ++ u8 *done, __rte_unused u32 resp_size) + { + union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request; + struct ustorm_trigger_vf_zone trigger; +@@ -86,9 +86,6 @@ ecore_send_msg2pf(struct ecore_hwfn *p_hwfn, + /* output tlvs list */ + ecore_dp_tlv_list(p_hwfn, p_req); + +- /* need to add the END TLV to the message size */ +- resp_size += sizeof(struct channel_list_end_tlv); +- + /* Send TLVs over HW channel */ + OSAL_MEMSET(&trigger, 0, sizeof(struct ustorm_trigger_vf_zone)); + trigger.vf_pf_msg_valid = 1; +@@ -226,7 +223,6 @@ enum _ecore_status_t ecore_vf_pf_release(struct ecore_hwfn *p_hwfn) return _ecore_vf_pf_release(p_hwfn, true); } @@ -61918,7 +86230,7 @@ index 24846cfb51..0e5b7d5eb3 100644 static void ecore_vf_pf_acquire_reduce_resc(struct ecore_hwfn *p_hwfn, struct vf_pf_resc_request *p_req, struct pf_vf_resc *p_resp) -@@ -251,13 +250,47 @@ static void ecore_vf_pf_acquire_reduce_resc(struct ecore_hwfn *p_hwfn, +@@ -251,13 +247,47 @@ static void ecore_vf_pf_acquire_reduce_resc(struct ecore_hwfn *p_hwfn, p_req->num_cids = p_resp->num_cids; } @@ -61967,7 +86279,7 @@ index 24846cfb51..0e5b7d5eb3 100644 struct vf_pf_resc_request *p_resc; bool resources_acquired = false; struct vfpf_acquire_tlv *req; -@@ -318,6 +351,14 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) +@@ -318,6 +348,14 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) /* send acquire request */ rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); @@ -61982,7 +86294,7 @@ index 24846cfb51..0e5b7d5eb3 100644 if (rc != ECORE_SUCCESS) goto exit; -@@ -343,7 +384,7 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) +@@ -343,7 +381,7 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) resources_acquired = true; } /* PF refuses to allocate our resources */ else if (resp->hdr.status == PFVF_STATUS_NO_RESOURCE && @@ -61991,7 +86303,7 @@ index 24846cfb51..0e5b7d5eb3 100644 ecore_vf_pf_acquire_reduce_resc(p_hwfn, p_resc, &resp->resc); -@@ -391,6 +432,9 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) +@@ -391,6 +429,9 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn) "PF rejected acquisition by VF\n"); rc = ECORE_INVAL; goto exit; @@ -62001,7 +86313,7 @@ index 24846cfb51..0e5b7d5eb3 100644 } else { DP_ERR(p_hwfn, "PF returned err %d to VF acquisition request\n", -@@ -477,7 +521,9 @@ u32 ecore_vf_hw_bar_size(struct ecore_hwfn *p_hwfn, +@@ -477,7 +518,9 @@ u32 ecore_vf_hw_bar_size(struct ecore_hwfn *p_hwfn, return 0; } @@ -62012,7 +86324,7 @@ index 24846cfb51..0e5b7d5eb3 100644 { struct ecore_hwfn *p_lead = ECORE_LEADING_HWFN(p_hwfn->p_dev); struct ecore_vf_iov *p_iov; -@@ -583,6 +629,7 @@ enum _ecore_status_t ecore_vf_hw_prepare(struct ecore_hwfn *p_hwfn) +@@ -583,6 +626,7 @@ enum _ecore_status_t ecore_vf_hw_prepare(struct ecore_hwfn *p_hwfn) #endif OSAL_MUTEX_INIT(&p_iov->mutex); @@ -62166,10 +86478,29 @@ index 98b9723dd4..6667c2d7ab 100644 #define FW_MSG_CODE_ERR_RESOURCE_TEMPORARY_UNAVAILABLE 0x008b0000 #define FW_MSG_CODE_ERR_RESOURCE_ALREADY_ALLOCATED 0x008c0000 #define FW_MSG_CODE_ERR_RESOURCE_NOT_ALLOCATED 0x008d0000 +diff --git a/dpdk/drivers/net/qede/base/meson.build b/dpdk/drivers/net/qede/base/meson.build +index 71b89737df..83446ee637 100644 +--- a/dpdk/drivers/net/qede/base/meson.build ++++ b/dpdk/drivers/net/qede/base/meson.build +@@ -57,4 +57,4 @@ endforeach + base_lib = static_library('qede_base', sources, + dependencies: static_rte_net, + c_args: c_args) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/qede/qede_ethdev.c b/dpdk/drivers/net/qede/qede_ethdev.c -index 19d2e96191..6f2f0051f6 100644 +index 19d2e96191..0c50c61d97 100644 --- a/dpdk/drivers/net/qede/qede_ethdev.c +++ b/dpdk/drivers/net/qede/qede_ethdev.c +@@ -270,7 +270,7 @@ qede_interrupt_handler(void *param) + static void + qede_alloc_etherdev(struct qede_dev *qdev, struct qed_dev_eth_info *info) + { +- rte_memcpy(&qdev->dev_info, info, sizeof(*info)); ++ qdev->dev_info = *info; + qdev->ops = qed_ops; + } + @@ -551,17 +551,16 @@ qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev, ECORE_ACCEPT_BCAST; @@ -62318,7 +86649,20 @@ index 19d2e96191..6f2f0051f6 100644 ecore_status = qed_configure_filter_rx_mode(eth_dev, type); return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN; -@@ -2275,7 +2282,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) +@@ -2042,8 +2049,10 @@ int qede_rss_hash_update(struct rte_eth_dev *eth_dev, + /* RSS hash key */ + if (key) { + if (len > (ECORE_RSS_KEY_SIZE * sizeof(uint32_t))) { +- DP_ERR(edev, "RSS key length exceeds limit\n"); +- return -EINVAL; ++ len = ECORE_RSS_KEY_SIZE * sizeof(uint32_t); ++ DP_NOTICE(edev, false, ++ "RSS key length too big, trimmed to %d\n", ++ len); + } + DP_INFO(edev, "Applying user supplied hash key\n"); + rss_params.update_rss_key = 1; +@@ -2275,7 +2284,7 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) fp->rxq->rx_buf_size = rc; } } @@ -62327,7 +86671,7 @@ index 19d2e96191..6f2f0051f6 100644 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; else dev->data->dev_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; -@@ -2604,9 +2611,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) +@@ -2604,9 +2613,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) eth_dev->dev_ops = (is_vf) ? &qede_eth_vf_dev_ops : &qede_eth_dev_ops; @@ -62337,8 +86681,42 @@ index 19d2e96191..6f2f0051f6 100644 adapter->num_tx_queues = 0; adapter->num_rx_queues = 0; SLIST_INIT(&adapter->arfs_info.arfs_list_head); +diff --git a/dpdk/drivers/net/qede/qede_filter.c b/dpdk/drivers/net/qede/qede_filter.c +index b7ad59ad6d..0d50d38d52 100644 +--- a/dpdk/drivers/net/qede/qede_filter.c ++++ b/dpdk/drivers/net/qede/qede_filter.c +@@ -519,10 +519,8 @@ qede_arfs_construct_pkt(struct rte_eth_dev *eth_dev, + ip6->vtc_flow = + rte_cpu_to_be_32(QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW); + +- rte_memcpy(&ip6->src_addr, arfs->tuple.src_ipv6, +- IPV6_ADDR_LEN); +- rte_memcpy(&ip6->dst_addr, arfs->tuple.dst_ipv6, +- IPV6_ADDR_LEN); ++ memcpy(&ip6->src_addr, arfs->tuple.src_ipv6, IPV6_ADDR_LEN); ++ memcpy(&ip6->dst_addr, arfs->tuple.dst_ipv6, IPV6_ADDR_LEN); + len += sizeof(struct rte_ipv6_hdr); + params->ipv6 = true; + +@@ -1285,12 +1283,10 @@ qede_flow_parse_pattern(__attribute__((unused))struct rte_eth_dev *dev, + const struct rte_flow_item_ipv6 *spec; + + spec = pattern->spec; +- rte_memcpy(flow->entry.tuple.src_ipv6, +- spec->hdr.src_addr, +- IPV6_ADDR_LEN); +- rte_memcpy(flow->entry.tuple.dst_ipv6, +- spec->hdr.dst_addr, +- IPV6_ADDR_LEN); ++ memcpy(flow->entry.tuple.src_ipv6, ++ spec->hdr.src_addr, IPV6_ADDR_LEN); ++ memcpy(flow->entry.tuple.dst_ipv6, ++ spec->hdr.dst_addr, IPV6_ADDR_LEN); + flow->entry.tuple.eth_proto = + RTE_ETHER_TYPE_IPV6; + } diff --git a/dpdk/drivers/net/qede/qede_main.c b/dpdk/drivers/net/qede/qede_main.c -index 4eb79d0fbb..67392d6aa4 100644 +index 4eb79d0fbb..08677c8546 100644 --- a/dpdk/drivers/net/qede/qede_main.c +++ b/dpdk/drivers/net/qede/qede_main.c @@ -56,6 +56,10 @@ qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev, @@ -62352,7 +86730,48 @@ index 4eb79d0fbb..67392d6aa4 100644 hw_prepare_params.personality = ECORE_PCI_ETH; hw_prepare_params.drv_resc_alloc = false; hw_prepare_params.chk_reg_fifo = false; -@@ -571,13 +575,12 @@ qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link) +@@ -368,7 +372,7 @@ qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info) + dev_info->mtu = ECORE_LEADING_HWFN(edev)->hw_info.mtu; + dev_info->dev_type = edev->type; + +- rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr, ++ memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr, + RTE_ETHER_ADDR_LEN); + + dev_info->fw_major = FW_MAJOR_VERSION; +@@ -433,7 +437,7 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info) + info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) - + max_vf_vlan_filters; + +- rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, ++ memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, + RTE_ETHER_ADDR_LEN); + } else { + ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev), +@@ -464,7 +468,7 @@ static void qed_set_name(struct ecore_dev *edev, char name[NAME_SIZE]) + { + int i; + +- rte_memcpy(edev->name, name, NAME_SIZE); ++ memcpy(edev->name, name, NAME_SIZE); + for_each_hwfn(edev, i) { + snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i); + } +@@ -506,10 +510,9 @@ static void qed_fill_link(struct ecore_hwfn *hwfn, + + /* Prepare source inputs */ + if (IS_PF(hwfn->p_dev)) { +- rte_memcpy(¶ms, ecore_mcp_get_link_params(hwfn), +- sizeof(params)); +- rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link)); +- rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn), ++ memcpy(¶ms, ecore_mcp_get_link_params(hwfn), sizeof(params)); ++ memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link)); ++ memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn), + sizeof(link_caps)); + } else { + ecore_vf_read_bulletin(hwfn, &change); +@@ -571,13 +574,12 @@ qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link) hwfn = &edev->hwfns[0]; if (IS_PF(edev)) { ptt = ecore_ptt_acquire(hwfn); @@ -62371,7 +86790,7 @@ index 4eb79d0fbb..67392d6aa4 100644 qed_fill_link(hwfn, NULL, if_link); } diff --git a/dpdk/drivers/net/qede/qede_rxtx.c b/dpdk/drivers/net/qede/qede_rxtx.c -index a28dd0a07f..64e6de4743 100644 +index a28dd0a07f..d45675af89 100644 --- a/dpdk/drivers/net/qede/qede_rxtx.c +++ b/dpdk/drivers/net/qede/qede_rxtx.c @@ -593,12 +593,14 @@ qede_alloc_mem_sb(struct qede_dev *qdev, struct ecore_sb_info *sb_info, @@ -62413,6 +86832,18 @@ index a28dd0a07f..64e6de4743 100644 OSAL_DMA_FREE_COHERENT(edev, fp->sb_info->sb_virt, fp->sb_info->sb_phys, sizeof(struct status_block)); +@@ -719,9 +717,10 @@ qede_update_rx_prod(__rte_unused struct qede_dev *edev, + { + uint16_t bd_prod = ecore_chain_get_prod_idx(&rxq->rx_bd_ring); + uint16_t cqe_prod = ecore_chain_get_prod_idx(&rxq->rx_comp_ring); +- struct eth_rx_prod_data rx_prods = { 0 }; ++ struct eth_rx_prod_data rx_prods; + + /* Update producers */ ++ memset(&rx_prods, 0, sizeof(rx_prods)); + rx_prods.bd_prod = rte_cpu_to_le_16(bd_prod); + rx_prods.cqe_prod = rte_cpu_to_le_16(cqe_prod); + diff --git a/dpdk/drivers/net/qede/qede_rxtx.h b/dpdk/drivers/net/qede/qede_rxtx.h index 75cc930fd5..8dc669963b 100644 --- a/dpdk/drivers/net/qede/qede_rxtx.h @@ -63681,6 +88112,20 @@ index 85d984f651..9755f4dfd2 100644 efx_rc_t (*efo_delete)(efx_nic_t *, efx_filter_spec_t *); efx_rc_t (*efo_supported_filters)(efx_nic_t *, uint32_t *, size_t, size_t *); +diff --git a/dpdk/drivers/net/sfc/base/efx_mcdi.c b/dpdk/drivers/net/sfc/base/efx_mcdi.c +index 477b128686..db143294d9 100644 +--- a/dpdk/drivers/net/sfc/base/efx_mcdi.c ++++ b/dpdk/drivers/net/sfc/base/efx_mcdi.c +@@ -495,6 +495,9 @@ efx_mcdi_finish_response( + bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length); + efx_mcdi_read_response(enp, emrp->emr_out_buf, resp_off, bytes); + ++ /* Report bytes copied to caller (response message may be larger) */ ++ emrp->emr_out_length_used = bytes; ++ + #if EFSYS_OPT_MCDI_LOGGING + if (emtp->emt_logger != NULL) { + emtp->emt_logger(emtp->emt_context, diff --git a/dpdk/drivers/net/sfc/base/efx_proxy.c b/dpdk/drivers/net/sfc/base/efx_proxy.c index 791105a5a0..ecf703b03d 100644 --- a/dpdk/drivers/net/sfc/base/efx_proxy.c @@ -63733,6 +88178,19 @@ index edb6be028f..c92c02cfa2 100644 /* * Although the caller should be able to handle MC reboot, +diff --git a/dpdk/drivers/net/sfc/base/meson.build b/dpdk/drivers/net/sfc/base/meson.build +index 074112f169..4e6b15e5e5 100644 +--- a/dpdk/drivers/net/sfc/base/meson.build ++++ b/dpdk/drivers/net/sfc/base/meson.build +@@ -78,7 +78,7 @@ if build + dependencies: static_rte_eal, + c_args: c_args) + +- base_objs = base_lib.extract_all_objects() ++ base_objs = base_lib.extract_all_objects(recursive: true) + else + base_objs = [] + endif diff --git a/dpdk/drivers/net/sfc/sfc.c b/dpdk/drivers/net/sfc/sfc.c index 141c767f09..da67acaa87 100644 --- a/dpdk/drivers/net/sfc/sfc.c @@ -63765,10 +88223,27 @@ index 141c767f09..da67acaa87 100644 return 0; diff --git a/dpdk/drivers/net/sfc/sfc.h b/dpdk/drivers/net/sfc/sfc.h -index cc52228771..bce6beefaa 100644 +index cc52228771..4c0320c6a8 100644 --- a/dpdk/drivers/net/sfc/sfc.h +++ b/dpdk/drivers/net/sfc/sfc.h -@@ -172,6 +172,8 @@ struct sfc_rss { +@@ -141,7 +141,6 @@ struct sfc_port { + unsigned int nb_mcast_addrs; + uint8_t *mcast_addrs; + +- rte_spinlock_t mac_stats_lock; + uint64_t *mac_stats_buf; + unsigned int mac_stats_nb_supported; + efsys_mem_t mac_stats_dma_mem; +@@ -153,6 +152,8 @@ struct sfc_port { + + uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; + ++ unsigned int mac_stats_by_id[EFX_MAC_NSTATS]; ++ + uint64_t ipackets; + }; + +@@ -172,6 +173,8 @@ struct sfc_rss { efx_rx_hash_type_t hash_types; unsigned int tbl[EFX_RSS_TBL_SIZE]; uint8_t key[EFX_RSS_KEY_SIZE]; @@ -63777,6 +88252,15 @@ index cc52228771..bce6beefaa 100644 }; /* Adapter private data shared by primary and secondary processes */ +@@ -402,7 +405,7 @@ int sfc_port_start(struct sfc_adapter *sa); + void sfc_port_stop(struct sfc_adapter *sa); + void sfc_port_link_mode_to_info(efx_link_mode_t link_mode, + struct rte_eth_link *link_info); +-int sfc_port_update_mac_stats(struct sfc_adapter *sa); ++int sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t manual_update); + int sfc_port_reset_mac_stats(struct sfc_adapter *sa); + int sfc_set_rx_mode(struct sfc_adapter *sa); + diff --git a/dpdk/drivers/net/sfc/sfc_ef10_tx.c b/dpdk/drivers/net/sfc/sfc_ef10_tx.c index 43e3447805..b57c9afb71 100644 --- a/dpdk/drivers/net/sfc/sfc_ef10_tx.c @@ -63808,10 +88292,60 @@ index 43e3447805..b57c9afb71 100644 * Tx prepare has debug-only checks that offload flags are correctly * filled in in TSO mbuf. Use zero IPID if there is no IPv4 flag. diff --git a/dpdk/drivers/net/sfc/sfc_ethdev.c b/dpdk/drivers/net/sfc/sfc_ethdev.c -index 454b8956a2..cc7eefb322 100644 +index 454b8956a2..8206fa78e5 100644 --- a/dpdk/drivers/net/sfc/sfc_ethdev.c +++ b/dpdk/drivers/net/sfc/sfc_ethdev.c -@@ -405,25 +405,37 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode, +@@ -93,7 +93,6 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + struct sfc_adapter_shared *sas = sfc_adapter_shared_by_eth_dev(dev); + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_rss *rss = &sas->rss; +- uint64_t txq_offloads_def = 0; + + sfc_log_init(sa, "entry"); + +@@ -143,11 +142,6 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + dev_info->tx_offload_capa = sfc_tx_get_dev_offload_caps(sa) | + dev_info->tx_queue_offload_capa; + +- if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) +- txq_offloads_def |= DEV_TX_OFFLOAD_MBUF_FAST_FREE; +- +- dev_info->default_txconf.offloads |= txq_offloads_def; +- + if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { + uint64_t rte_hf = 0; + unsigned int i; +@@ -318,6 +312,17 @@ sfc_dev_set_link_down(struct rte_eth_dev *dev) + return 0; + } + ++static void ++sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev) ++{ ++ free(dev->process_private); ++ dev->process_private = NULL; ++ dev->dev_ops = NULL; ++ dev->tx_pkt_prepare = NULL; ++ dev->tx_pkt_burst = NULL; ++ dev->rx_pkt_burst = NULL; ++} ++ + static void + sfc_dev_close(struct rte_eth_dev *dev) + { +@@ -325,6 +330,11 @@ sfc_dev_close(struct rte_eth_dev *dev) + + sfc_log_init(sa, "entry"); + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { ++ sfc_eth_dev_secondary_clear_ops(dev); ++ return; ++ } ++ + sfc_adapter_lock(sa); + switch (sa->state) { + case SFC_ADAPTER_STARTED: +@@ -405,25 +415,37 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode, static int sfc_dev_promisc_enable(struct rte_eth_dev *dev) { @@ -63853,7 +88387,19 @@ index 454b8956a2..cc7eefb322 100644 } static int -@@ -596,10 +608,19 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +@@ -568,9 +590,9 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) + uint64_t *mac_stats; + int ret; + +- rte_spinlock_lock(&port->mac_stats_lock); ++ sfc_adapter_lock(sa); + +- ret = sfc_port_update_mac_stats(sa); ++ ret = sfc_port_update_mac_stats(sa, B_FALSE); + if (ret != 0) + goto unlock; + +@@ -596,10 +618,19 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]; stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS]; stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS]; @@ -63873,7 +88419,172 @@ index 454b8956a2..cc7eefb322 100644 /* * Take into account stats which are whenever supported * on EF10. If some stat is not supported by current -@@ -972,7 +993,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) +@@ -632,7 +663,7 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) + } + + unlock: +- rte_spinlock_unlock(&port->mac_stats_lock); ++ sfc_adapter_unlock(sa); + SFC_ASSERT(ret >= 0); + return -ret; + } +@@ -644,12 +675,15 @@ sfc_stats_reset(struct rte_eth_dev *dev) + struct sfc_port *port = &sa->port; + int rc; + ++ sfc_adapter_lock(sa); ++ + if (sa->state != SFC_ADAPTER_STARTED) { + /* + * The operation cannot be done if port is not started; it + * will be scheduled to be done during the next port start + */ + port->mac_stats_reset_pending = B_TRUE; ++ sfc_adapter_unlock(sa); + return 0; + } + +@@ -657,6 +691,8 @@ sfc_stats_reset(struct rte_eth_dev *dev) + if (rc != 0) + sfc_err(sa, "failed to reset statistics (rc = %d)", rc); + ++ sfc_adapter_unlock(sa); ++ + SFC_ASSERT(rc >= 0); + return -rc; + } +@@ -672,9 +708,9 @@ sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + unsigned int i; + int nstats = 0; + +- rte_spinlock_lock(&port->mac_stats_lock); ++ sfc_adapter_lock(sa); + +- rc = sfc_port_update_mac_stats(sa); ++ rc = sfc_port_update_mac_stats(sa, B_FALSE); + if (rc != 0) { + SFC_ASSERT(rc > 0); + nstats = -rc; +@@ -694,7 +730,7 @@ sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + } + + unlock: +- rte_spinlock_unlock(&port->mac_stats_lock); ++ sfc_adapter_unlock(sa); + + return nstats; + } +@@ -729,19 +765,16 @@ sfc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_port *port = &sa->port; + uint64_t *mac_stats; +- unsigned int nb_supported = 0; +- unsigned int nb_written = 0; + unsigned int i; + int ret; + int rc; + +- if (unlikely(values == NULL) || +- unlikely((ids == NULL) && (n < port->mac_stats_nb_supported))) +- return port->mac_stats_nb_supported; ++ if (unlikely(ids == NULL || values == NULL)) ++ return -EINVAL; + +- rte_spinlock_lock(&port->mac_stats_lock); ++ sfc_adapter_lock(sa); + +- rc = sfc_port_update_mac_stats(sa); ++ rc = sfc_port_update_mac_stats(sa, B_FALSE); + if (rc != 0) { + SFC_ASSERT(rc > 0); + ret = -rc; +@@ -750,20 +783,22 @@ sfc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, + + mac_stats = port->mac_stats_buf; + +- for (i = 0; (i < EFX_MAC_NSTATS) && (nb_written < n); ++i) { +- if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) +- continue; +- +- if ((ids == NULL) || (ids[nb_written] == nb_supported)) +- values[nb_written++] = mac_stats[i]; ++ SFC_ASSERT(port->mac_stats_nb_supported <= ++ RTE_DIM(port->mac_stats_by_id)); + +- ++nb_supported; ++ for (i = 0; i < n; i++) { ++ if (ids[i] < port->mac_stats_nb_supported) { ++ values[i] = mac_stats[port->mac_stats_by_id[ids[i]]]; ++ } else { ++ ret = i; ++ goto unlock; ++ } + } + +- ret = nb_written; ++ ret = n; + + unlock: +- rte_spinlock_unlock(&port->mac_stats_lock); ++ sfc_adapter_unlock(sa); + + return ret; + } +@@ -775,29 +810,39 @@ sfc_xstats_get_names_by_id(struct rte_eth_dev *dev, + { + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_port *port = &sa->port; +- unsigned int nb_supported = 0; +- unsigned int nb_written = 0; ++ unsigned int nb_supported; + unsigned int i; + +- if (unlikely(xstats_names == NULL) || +- unlikely((ids == NULL) && (size < port->mac_stats_nb_supported))) +- return port->mac_stats_nb_supported; ++ if (unlikely(xstats_names == NULL && ids != NULL) || ++ unlikely(xstats_names != NULL && ids == NULL)) ++ return -EINVAL; + +- for (i = 0; (i < EFX_MAC_NSTATS) && (nb_written < size); ++i) { +- if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) +- continue; ++ sfc_adapter_lock(sa); + +- if ((ids == NULL) || (ids[nb_written] == nb_supported)) { +- char *name = xstats_names[nb_written++].name; ++ if (unlikely(xstats_names == NULL && ids == NULL)) { ++ nb_supported = port->mac_stats_nb_supported; ++ sfc_adapter_unlock(sa); ++ return nb_supported; ++ } + +- strlcpy(name, efx_mac_stat_name(sa->nic, i), ++ SFC_ASSERT(port->mac_stats_nb_supported <= ++ RTE_DIM(port->mac_stats_by_id)); ++ ++ for (i = 0; i < size; i++) { ++ if (ids[i] < port->mac_stats_nb_supported) { ++ strlcpy(xstats_names[i].name, ++ efx_mac_stat_name(sa->nic, ++ port->mac_stats_by_id[ids[i]]), + sizeof(xstats_names[0].name)); ++ } else { ++ sfc_adapter_unlock(sa); ++ return i; + } +- +- ++nb_supported; + } + +- return nb_written; ++ sfc_adapter_unlock(sa); ++ ++ return size; + } + + static int +@@ -972,7 +1017,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) * The driver does not use it, but other PMDs update jumbo frame * flag and max_rx_pkt_len when MTU is set. */ @@ -63882,7 +88593,7 @@ index 454b8956a2..cc7eefb322 100644 struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; rxmode->offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; } -@@ -1503,8 +1524,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -1503,8 +1548,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); struct sfc_rss *rss = &sfc_sa2shared(sa)->rss; unsigned int efx_hash_types; @@ -63898,7 +88609,7 @@ index 454b8956a2..cc7eefb322 100644 if (sfc_sa2shared(sa)->isolated) return -ENOTSUP; -@@ -1520,7 +1548,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -1520,7 +1572,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if ((rss_conf->rss_key != NULL) && (rss_conf->rss_key_len != sizeof(rss->key))) { @@ -63907,7 +88618,7 @@ index 454b8956a2..cc7eefb322 100644 sizeof(rss->key)); return -EINVAL; } -@@ -1531,19 +1559,24 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -1531,19 +1583,24 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if (rc != 0) goto fail_rx_hf_rte_to_efx; @@ -63942,7 +88653,7 @@ index 454b8956a2..cc7eefb322 100644 } rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key)); -@@ -1556,12 +1589,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, +@@ -1556,12 +1613,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, return 0; fail_scale_key_set: @@ -63967,8 +88678,38 @@ index 454b8956a2..cc7eefb322 100644 fail_rx_hf_rte_to_efx: sfc_adapter_unlock(sa); return -rc; +@@ -2076,17 +2141,6 @@ sfc_eth_dev_secondary_init(struct rte_eth_dev *dev, uint32_t logtype_main) + return rc; + } + +-static void +-sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev) +-{ +- free(dev->process_private); +- dev->process_private = NULL; +- dev->dev_ops = NULL; +- dev->tx_pkt_prepare = NULL; +- dev->tx_pkt_burst = NULL; +- dev->rx_pkt_burst = NULL; +-} +- + static void + sfc_register_dp(void) + { +@@ -2222,11 +2276,6 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) + static int + sfc_eth_dev_uninit(struct rte_eth_dev *dev) + { +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) { +- sfc_eth_dev_secondary_clear_ops(dev); +- return 0; +- } +- + sfc_dev_close(dev); + + return 0; diff --git a/dpdk/drivers/net/sfc/sfc_flow.c b/dpdk/drivers/net/sfc/sfc_flow.c -index 8d636f6923..91aa2a687a 100644 +index 8d636f6923..c8ff0ff2a6 100644 --- a/dpdk/drivers/net/sfc/sfc_flow.c +++ b/dpdk/drivers/net/sfc/sfc_flow.c @@ -1132,6 +1132,7 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr, @@ -63998,7 +88739,17 @@ index 8d636f6923..91aa2a687a 100644 return 0; } -@@ -1404,13 +1410,34 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1288,6 +1294,9 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, + rxq_hw_index_max = rxq->hw_index; + } + ++ if (rxq_hw_index_max - rxq_hw_index_min + 1 > EFX_MAXRSS) ++ return -EINVAL; ++ + switch (action_rss->func) { + case RTE_ETH_HASH_FUNCTION_DEFAULT: + case RTE_ETH_HASH_FUNCTION_TOEPLITZ: +@@ -1404,13 +1413,33 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, struct sfc_rss *rss = &sas->rss; struct sfc_flow_rss *flow_rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; @@ -64019,9 +88770,8 @@ index 8d636f6923..91aa2a687a 100644 + uint8_t *rss_key; + + if (flow->rss) { -+ rss_spread = MIN(flow_rss->rxq_hw_index_max - -+ flow_rss->rxq_hw_index_min + 1, -+ EFX_MAXRSS); ++ rss_spread = flow_rss->rxq_hw_index_max - ++ flow_rss->rxq_hw_index_min + 1; + rss_hash_types = flow_rss->rss_hash_types; + rss_key = flow_rss->rss_key; + } else { @@ -64037,7 +88787,7 @@ index 8d636f6923..91aa2a687a 100644 rc = efx_rx_scale_context_alloc(sa->nic, EFX_RX_SCALE_EXCLUSIVE, -@@ -1421,16 +1448,19 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1421,16 +1450,19 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, rss->hash_alg, @@ -64060,7 +88810,7 @@ index 8d636f6923..91aa2a687a 100644 /* * At this point, fully elaborated filter specifications * have been produced from the template. To make sure that -@@ -1441,8 +1471,9 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1441,8 +1473,9 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, efx_filter_spec_t *spec = &flow->spec.filters[i]; spec->efs_rss_context = efs_rss_context; @@ -64071,7 +88821,7 @@ index 8d636f6923..91aa2a687a 100644 } } -@@ -1450,7 +1481,12 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1450,7 +1483,12 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, if (rc != 0) goto fail_filter_insert; @@ -64085,7 +88835,7 @@ index 8d636f6923..91aa2a687a 100644 /* * Scale table is set after filter insertion because * the table entries are relative to the base RxQ ID -@@ -1460,10 +1496,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1460,10 +1498,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, * the table entries, and the operation will succeed */ rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, @@ -64101,7 +88851,7 @@ index 8d636f6923..91aa2a687a 100644 } return 0; -@@ -1474,7 +1513,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, +@@ -1474,7 +1515,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, fail_filter_insert: fail_scale_key_set: fail_scale_mode_set: @@ -64110,7 +88860,7 @@ index 8d636f6923..91aa2a687a 100644 efx_rx_scale_context_free(sa->nic, efs_rss_context); fail_scale_context_alloc: -@@ -2473,12 +2512,19 @@ sfc_flow_fini(struct sfc_adapter *sa) +@@ -2473,12 +2514,19 @@ sfc_flow_fini(struct sfc_adapter *sa) void sfc_flow_stop(struct sfc_adapter *sa) { @@ -64143,6 +88893,135 @@ index 71ec18cb95..f59db0a468 100644 }; /* PMD-specific definition of the opaque type from rte_flow.h */ +diff --git a/dpdk/drivers/net/sfc/sfc_port.c b/dpdk/drivers/net/sfc/sfc_port.c +index 23313e125f..7fd1f777ac 100644 +--- a/dpdk/drivers/net/sfc/sfc_port.c ++++ b/dpdk/drivers/net/sfc/sfc_port.c +@@ -25,7 +25,8 @@ + /** + * Update MAC statistics in the buffer. + * +- * @param sa Adapter ++ * @param sa Adapter ++ * @param force_upload Flag to upload MAC stats in any case + * + * @return Status code + * @retval 0 Success +@@ -33,7 +34,7 @@ + * @retval ENOMEM Memory allocation failure + */ + int +-sfc_port_update_mac_stats(struct sfc_adapter *sa) ++sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t force_upload) + { + struct sfc_port *port = &sa->port; + efsys_mem_t *esmp = &port->mac_stats_dma_mem; +@@ -42,17 +43,17 @@ sfc_port_update_mac_stats(struct sfc_adapter *sa) + unsigned int nb_attempts = 0; + int rc; + +- SFC_ASSERT(rte_spinlock_is_locked(&port->mac_stats_lock)); ++ SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (sa->state != SFC_ADAPTER_STARTED) +- return EINVAL; ++ return 0; + + /* + * If periodic statistics DMA'ing is off or if not supported, + * make a manual request and keep an eye on timer if need be + */ + if (!port->mac_stats_periodic_dma_supported || +- (port->mac_stats_update_period_ms == 0)) { ++ (port->mac_stats_update_period_ms == 0) || force_upload) { + if (port->mac_stats_update_period_ms != 0) { + uint64_t timestamp = sfc_get_system_msecs(); + +@@ -102,14 +103,13 @@ sfc_port_reset_sw_stats(struct sfc_adapter *sa) + int + sfc_port_reset_mac_stats(struct sfc_adapter *sa) + { +- struct sfc_port *port = &sa->port; + int rc; + +- rte_spinlock_lock(&port->mac_stats_lock); ++ SFC_ASSERT(sfc_adapter_is_locked(sa)); ++ + rc = efx_mac_stats_clear(sa->nic); + if (rc == 0) + sfc_port_reset_sw_stats(sa); +- rte_spinlock_unlock(&port->mac_stats_lock); + + return rc; + } +@@ -157,6 +157,27 @@ sfc_port_phy_caps_to_max_link_speed(uint32_t phy_caps) + + #endif + ++static void ++sfc_port_fill_mac_stats_info(struct sfc_adapter *sa) ++{ ++ unsigned int mac_stats_nb_supported = 0; ++ struct sfc_port *port = &sa->port; ++ unsigned int stat_idx; ++ ++ efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask, ++ sizeof(port->mac_stats_mask)); ++ ++ for (stat_idx = 0; stat_idx < EFX_MAC_NSTATS; ++stat_idx) { ++ if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, stat_idx)) ++ continue; ++ ++ port->mac_stats_by_id[mac_stats_nb_supported] = stat_idx; ++ mac_stats_nb_supported++; ++ } ++ ++ port->mac_stats_nb_supported = mac_stats_nb_supported; ++} ++ + int + sfc_port_start(struct sfc_adapter *sa) + { +@@ -165,7 +186,6 @@ sfc_port_start(struct sfc_adapter *sa) + uint32_t phy_adv_cap; + const uint32_t phy_pause_caps = + ((1u << EFX_PHY_CAP_PAUSE) | (1u << EFX_PHY_CAP_ASYM)); +- unsigned int i; + + sfc_log_init(sa, "entry"); + +@@ -259,12 +279,7 @@ sfc_port_start(struct sfc_adapter *sa) + port->mac_stats_reset_pending = B_FALSE; + } + +- efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask, +- sizeof(port->mac_stats_mask)); +- +- for (i = 0, port->mac_stats_nb_supported = 0; i < EFX_MAC_NSTATS; ++i) +- if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) +- port->mac_stats_nb_supported++; ++ sfc_port_fill_mac_stats_info(sa); + + port->mac_stats_update_generation = 0; + +@@ -352,6 +367,8 @@ sfc_port_stop(struct sfc_adapter *sa) + (void)efx_mac_stats_periodic(sa->nic, &sa->port.mac_stats_dma_mem, + 0, B_FALSE); + ++ sfc_port_update_mac_stats(sa, B_TRUE); ++ + efx_port_fini(sa->nic); + efx_filter_fini(sa->nic); + +@@ -415,8 +432,6 @@ sfc_port_attach(struct sfc_adapter *sa) + goto fail_mcast_addr_list_buf_alloc; + } + +- rte_spinlock_init(&port->mac_stats_lock); +- + rc = ENOMEM; + port->mac_stats_buf = rte_calloc_socket("mac_stats_buf", EFX_MAC_NSTATS, + sizeof(uint64_t), 0, diff --git a/dpdk/drivers/net/sfc/sfc_rx.c b/dpdk/drivers/net/sfc/sfc_rx.c index 74218296cd..9a1c368328 100644 --- a/dpdk/drivers/net/sfc/sfc_rx.c @@ -64294,6 +89173,44 @@ index ef257519ac..3d1c3e46c3 100644 unsigned int sfc_tso_prepare_header(uint8_t *tsoh, size_t header_len, struct rte_mbuf **in_seg, size_t *in_off); +diff --git a/dpdk/drivers/net/sfc/sfc_tx.c b/dpdk/drivers/net/sfc/sfc_tx.c +index 7d0e18a6bd..9738ed9660 100644 +--- a/dpdk/drivers/net/sfc/sfc_tx.c ++++ b/dpdk/drivers/net/sfc/sfc_tx.c +@@ -258,6 +258,7 @@ sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) + static int + sfc_tx_check_mode(struct sfc_adapter *sa, const struct rte_eth_txmode *txmode) + { ++ uint64_t dev_tx_offload_cap = sfc_tx_get_dev_offload_caps(sa); + int rc = 0; + + switch (txmode->mq_mode) { +@@ -269,6 +270,13 @@ sfc_tx_check_mode(struct sfc_adapter *sa, const struct rte_eth_txmode *txmode) + rc = EINVAL; + } + ++ if ((dev_tx_offload_cap & DEV_TX_OFFLOAD_MBUF_FAST_FREE) != 0 && ++ (txmode->offloads & DEV_TX_OFFLOAD_MBUF_FAST_FREE) == 0) { ++ sfc_err(sa, "There is no FAST_FREE flag in the attempted Tx mode configuration"); ++ sfc_err(sa, "FAST_FREE is always active as per the current Tx datapath variant"); ++ rc = EINVAL; ++ } ++ + /* + * These features are claimed to be i40e-specific, + * but it does make sense to double-check their absence +diff --git a/dpdk/drivers/net/softnic/conn.c b/dpdk/drivers/net/softnic/conn.c +index 8b66580887..5b031358d5 100644 +--- a/dpdk/drivers/net/softnic/conn.c ++++ b/dpdk/drivers/net/softnic/conn.c +@@ -144,6 +144,7 @@ softnic_conn_free(struct softnic_conn *conn) + + free(conn->msg_out); + free(conn->msg_in); ++ free(conn->buf); + free(conn->prompt); + free(conn->welcome); + free(conn); diff --git a/dpdk/drivers/net/softnic/parser.c b/dpdk/drivers/net/softnic/parser.c index dc15ec8aa2..ebcb10268a 100644 --- a/dpdk/drivers/net/softnic/parser.c @@ -64521,6 +89438,139 @@ index dc15ec8aa2..ebcb10268a 100644 return -EINVAL; return 0; +diff --git a/dpdk/drivers/net/softnic/rte_eth_softnic_action.c b/dpdk/drivers/net/softnic/rte_eth_softnic_action.c +index 92c744dc9a..33be9552a6 100644 +--- a/dpdk/drivers/net/softnic/rte_eth_softnic_action.c ++++ b/dpdk/drivers/net/softnic/rte_eth_softnic_action.c +@@ -183,6 +183,7 @@ softnic_table_action_profile_free(struct pmd_internals *p) + break; + + TAILQ_REMOVE(&p->table_action_profile_list, profile, node); ++ rte_table_action_profile_free(profile->ap); + free(profile); + } + } +diff --git a/dpdk/drivers/net/softnic/rte_eth_softnic_cli.c b/dpdk/drivers/net/softnic/rte_eth_softnic_cli.c +index bc95f16439..aa9971579e 100644 +--- a/dpdk/drivers/net/softnic/rte_eth_softnic_cli.c ++++ b/dpdk/drivers/net/softnic/rte_eth_softnic_cli.c +@@ -631,7 +631,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[0], + .shared_shaper_id = &shared_shaper_id[0], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[0]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -641,7 +641,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[1], + .shared_shaper_id = &shared_shaper_id[1], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[1]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -651,7 +651,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[2], + .shared_shaper_id = &shared_shaper_id[2], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[2]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -661,7 +661,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[3], + .shared_shaper_id = &shared_shaper_id[3], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[3]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -671,7 +671,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[4], + .shared_shaper_id = &shared_shaper_id[4], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[4]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[4]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -681,7 +681,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[5], + .shared_shaper_id = &shared_shaper_id[5], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[5]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[5]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -691,7 +691,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[6], + .shared_shaper_id = &shared_shaper_id[6], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[6]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[6]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -701,7 +701,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[7], + .shared_shaper_id = &shared_shaper_id[7], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[7]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[7]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -711,7 +711,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[8], + .shared_shaper_id = &shared_shaper_id[8], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[8]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[8]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -721,7 +721,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[9], + .shared_shaper_id = &shared_shaper_id[9], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[9]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[9]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -731,7 +731,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[10], + .shared_shaper_id = &shared_shaper_id[10], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[10]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[10]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -741,7 +741,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[11], + .shared_shaper_id = &shared_shaper_id[11], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[11]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[11]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, +@@ -751,7 +751,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, + .shaper_profile_id = params->shaper_profile_id.tc[12], + .shared_shaper_id = &shared_shaper_id[12], + .n_shared_shapers = +- (¶ms->shared_shaper_id.tc_valid[12]) ? 1 : 0, ++ (params->shared_shaper_id.tc_valid[12]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, diff --git a/dpdk/drivers/net/softnic/rte_eth_softnic_thread.c b/dpdk/drivers/net/softnic/rte_eth_softnic_thread.c index d610b1617e..dcfb5eb82c 100644 --- a/dpdk/drivers/net/softnic/rte_eth_softnic_thread.c @@ -64702,8 +89752,22 @@ index b53fcbc591..77a5b0ed80 100644 build = dep.found() reason = 'missing dependency, "libsze2"' ext_deps += dep +diff --git a/dpdk/drivers/net/szedata2/rte_eth_szedata2.c b/dpdk/drivers/net/szedata2/rte_eth_szedata2.c +index 821bb346c3..6f798d044c 100644 +--- a/dpdk/drivers/net/szedata2/rte_eth_szedata2.c ++++ b/dpdk/drivers/net/szedata2/rte_eth_szedata2.c +@@ -1166,6 +1166,9 @@ eth_dev_close(struct rte_eth_dev *dev) + uint16_t nb_rx = dev->data->nb_rx_queues; + uint16_t nb_tx = dev->data->nb_tx_queues; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + eth_dev_stop(dev); + + free(internals->sze_dev_path); diff --git a/dpdk/drivers/net/tap/rte_eth_tap.c b/dpdk/drivers/net/tap/rte_eth_tap.c -index a13d8d50d7..cfbd579cd6 100644 +index a13d8d50d7..653f9db64e 100644 --- a/dpdk/drivers/net/tap/rte_eth_tap.c +++ b/dpdk/drivers/net/tap/rte_eth_tap.c @@ -18,8 +18,8 @@ @@ -64896,8 +89960,16 @@ index a13d8d50d7..cfbd579cd6 100644 } if (process_private->txq_fds[i] != -1) { close(process_private->txq_fds[i]); -@@ -1035,6 +1070,9 @@ tap_dev_close(struct rte_eth_dev *dev) +@@ -1031,10 +1066,16 @@ tap_dev_close(struct rte_eth_dev *dev) + + if (internals->remote_if_index) { + /* Restore initial remote state */ +- ioctl(internals->ioctl_sock, SIOCSIFFLAGS, ++ int ret = ioctl(internals->ioctl_sock, SIOCSIFFLAGS, &internals->remote_initial_flags); ++ if (ret) ++ TAP_LOG(ERR, "restore remote state failed: %d", ret); ++ } + rte_mempool_free(internals->gso_ctx_mp); @@ -64906,7 +89978,7 @@ index a13d8d50d7..cfbd579cd6 100644 if (internals->ka_fd != -1) { close(internals->ka_fd); internals->ka_fd = -1; -@@ -1054,10 +1092,10 @@ tap_rx_queue_release(void *queue) +@@ -1054,10 +1095,10 @@ tap_rx_queue_release(void *queue) if (!rxq) return; process_private = rte_eth_devices[rxq->in_port].process_private; @@ -64919,7 +89991,7 @@ index a13d8d50d7..cfbd579cd6 100644 rte_free(rxq->iovecs); rxq->pool = NULL; rxq->iovecs = NULL; -@@ -1074,7 +1112,7 @@ tap_tx_queue_release(void *queue) +@@ -1074,7 +1115,7 @@ tap_tx_queue_release(void *queue) return; process_private = rte_eth_devices[txq->out_port].process_private; @@ -64928,7 +90000,7 @@ index a13d8d50d7..cfbd579cd6 100644 close(process_private->txq_fds[txq->queue_id]); process_private->txq_fds[txq->queue_id] = -1; } -@@ -1282,33 +1320,40 @@ tap_gso_ctx_setup(struct rte_gso_ctx *gso_ctx, struct rte_eth_dev *dev) +@@ -1282,33 +1323,40 @@ tap_gso_ctx_setup(struct rte_gso_ctx *gso_ctx, struct rte_eth_dev *dev) { uint32_t gso_types; char pool_name[64]; @@ -64986,7 +90058,7 @@ index a13d8d50d7..cfbd579cd6 100644 gso_ctx->gso_types = gso_types; gso_ctx->gso_size = 0; /* gso_size is set in tx_burst() per packet */ gso_ctx->flag = 0; -@@ -1465,7 +1510,7 @@ tap_rx_queue_setup(struct rte_eth_dev *dev, +@@ -1465,7 +1513,7 @@ tap_rx_queue_setup(struct rte_eth_dev *dev, return 0; error: @@ -64995,7 +90067,7 @@ index a13d8d50d7..cfbd579cd6 100644 rxq->pool = NULL; rte_free(rxq->iovecs); rxq->iovecs = NULL; -@@ -1563,13 +1608,12 @@ static int +@@ -1563,13 +1611,12 @@ static int tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set) { struct pmd_internals *pmd = dev->data->dev_private; @@ -65011,7 +90083,7 @@ index a13d8d50d7..cfbd579cd6 100644 } return 0; } -@@ -1580,9 +1624,26 @@ tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set) +@@ -1580,9 +1627,26 @@ tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set) return rte_intr_callback_register( &pmd->intr_handle, tap_dev_intr_handler, dev); } @@ -65040,7 +90112,7 @@ index a13d8d50d7..cfbd579cd6 100644 } static int -@@ -1591,8 +1652,11 @@ tap_intr_handle_set(struct rte_eth_dev *dev, int set) +@@ -1591,8 +1655,11 @@ tap_intr_handle_set(struct rte_eth_dev *dev, int set) int err; err = tap_lsc_intr_handle_set(dev, set); @@ -65053,7 +90125,7 @@ index a13d8d50d7..cfbd579cd6 100644 err = tap_rx_intr_vec_set(dev, set); if (err && set) tap_lsc_intr_handle_set(dev, 0); -@@ -1784,6 +1848,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, +@@ -1784,6 +1851,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, pmd->dev = dev; strlcpy(pmd->name, tap_name, sizeof(pmd->name)); pmd->type = type; @@ -65063,7 +90135,7 @@ index a13d8d50d7..cfbd579cd6 100644 pmd->ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0); if (pmd->ioctl_sock == -1) { -@@ -1814,7 +1881,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, +@@ -1814,7 +1884,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, dev->intr_handle = &pmd->intr_handle; /* Presetup the fds to -1 as being not valid */ @@ -65071,7 +90143,7 @@ index a13d8d50d7..cfbd579cd6 100644 for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { process_private->rxq_fds[i] = -1; process_private->txq_fds[i] = -1; -@@ -1954,7 +2020,11 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, +@@ -1954,7 +2023,11 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, tap_flow_implicit_flush(pmd, NULL); error_exit: @@ -65084,7 +90156,7 @@ index a13d8d50d7..cfbd579cd6 100644 close(pmd->ioctl_sock); /* mac_addrs must not be freed alone because part of dev_private */ dev->data->mac_addrs = NULL; -@@ -2386,8 +2456,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) +@@ -2386,8 +2459,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) { struct rte_eth_dev *eth_dev = NULL; struct pmd_internals *internals; @@ -65093,7 +90165,7 @@ index a13d8d50d7..cfbd579cd6 100644 /* find the ethdev entry */ eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev)); -@@ -2400,28 +2468,12 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) +@@ -2400,28 +2471,12 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return rte_eth_dev_release_port(eth_dev); @@ -65124,7 +90196,7 @@ index a13d8d50d7..cfbd579cd6 100644 close(internals->ioctl_sock); rte_free(eth_dev->process_private); if (tap_devices_count == 1) -@@ -2429,10 +2481,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) +@@ -2429,10 +2484,6 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) tap_devices_count--; rte_eth_dev_release_port(eth_dev); @@ -65148,10 +90220,28 @@ index 8d6d53dc0a..ba45de8409 100644 struct pmd_process_private { diff --git a/dpdk/drivers/net/tap/tap_flow.c b/dpdk/drivers/net/tap/tap_flow.c -index 9d90361d99..1538349e9c 100644 +index 9d90361d99..2e471832b5 100644 --- a/dpdk/drivers/net/tap/tap_flow.c +++ b/dpdk/drivers/net/tap/tap_flow.c -@@ -1380,7 +1380,7 @@ tap_flow_create(struct rte_eth_dev *dev, +@@ -1300,10 +1300,16 @@ tap_flow_validate(struct rte_eth_dev *dev, + static void + tap_flow_set_handle(struct rte_flow *flow) + { ++ union { ++ struct rte_flow *flow; ++ const void *key; ++ } tmp; + uint32_t handle = 0; + ++ tmp.flow = flow; ++ + if (sizeof(flow) > 4) +- handle = rte_jhash(&flow, sizeof(flow), 1); ++ handle = rte_jhash(tmp.key, sizeof(flow), 1); + else + handle = (uintptr_t)flow; + /* must be at least 1 to avoid letting the kernel choose one for us */ +@@ -1380,7 +1386,7 @@ tap_flow_create(struct rte_eth_dev *dev, NULL, "priority value too big"); goto fail; } @@ -65160,7 +90250,7 @@ index 9d90361d99..1538349e9c 100644 if (!flow) { rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "cannot allocate memory for rte_flow"); -@@ -1416,7 +1416,7 @@ tap_flow_create(struct rte_eth_dev *dev, +@@ -1416,7 +1422,7 @@ tap_flow_create(struct rte_eth_dev *dev, * to the local pmd->if_index. */ if (pmd->remote_if_index) { @@ -65169,7 +90259,7 @@ index 9d90361d99..1538349e9c 100644 if (!remote_flow) { rte_flow_error_set( error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, -@@ -1693,7 +1693,7 @@ int tap_flow_implicit_create(struct pmd_internals *pmd, +@@ -1693,7 +1699,7 @@ int tap_flow_implicit_create(struct pmd_internals *pmd, } }; @@ -65178,7 +90268,7 @@ index 9d90361d99..1538349e9c 100644 if (!remote_flow) { TAP_LOG(ERR, "Cannot allocate memory for rte_flow"); goto fail; -@@ -1896,7 +1896,7 @@ static int rss_enable(struct pmd_internals *pmd, +@@ -1896,7 +1902,7 @@ static int rss_enable(struct pmd_internals *pmd, return -ENOTSUP; } @@ -65188,7 +90278,7 @@ index 9d90361d99..1538349e9c 100644 TAP_LOG(ERR, "Cannot allocate memory for rte_flow"); diff --git a/dpdk/drivers/net/tap/tap_intr.c b/dpdk/drivers/net/tap/tap_intr.c -index 7af0010e37..5cf4f173a0 100644 +index 7af0010e37..1cacc15d9f 100644 --- a/dpdk/drivers/net/tap/tap_intr.c +++ b/dpdk/drivers/net/tap/tap_intr.c @@ -7,7 +7,6 @@ @@ -65199,6 +90289,15 @@ index 7af0010e37..5cf4f173a0 100644 #include #include #include +@@ -60,7 +59,7 @@ tap_rx_intr_vec_install(struct rte_eth_dev *dev) + + if (!dev->data->dev_conf.intr_conf.rxq) + return 0; +- intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n])); ++ intr_handle->intr_vec = malloc(sizeof(int) * rxqs_n); + if (intr_handle->intr_vec == NULL) { + rte_errno = ENOMEM; + TAP_LOG(ERR, @@ -72,7 +71,7 @@ tap_rx_intr_vec_install(struct rte_eth_dev *dev) struct rx_queue *rxq = pmd->dev->data->rx_queues[i]; @@ -65208,6 +90307,16 @@ index 7af0010e37..5cf4f173a0 100644 /* Use invalid intr_vec[] index to disable entry. */ intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + +diff --git a/dpdk/drivers/net/thunderx/base/meson.build b/dpdk/drivers/net/thunderx/base/meson.build +index bf4e8608ad..1034531371 100644 +--- a/dpdk/drivers/net/thunderx/base/meson.build ++++ b/dpdk/drivers/net/thunderx/base/meson.build +@@ -16,4 +16,4 @@ base_lib = static_library('nicvf_base', sources, + dependencies: static_rte_ethdev + ) + +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) diff --git a/dpdk/drivers/net/thunderx/base/nicvf_hw_defs.h b/dpdk/drivers/net/thunderx/base/nicvf_hw_defs.h index b12c8ec50a..adc8ec943d 100644 --- a/dpdk/drivers/net/thunderx/base/nicvf_hw_defs.h @@ -65221,7 +90330,7 @@ index b12c8ec50a..adc8ec943d 100644 /* Descriptor alignments */ #define NICVF_RBDR_BASE_ALIGN_BYTES (128) /* 7 bits */ diff --git a/dpdk/drivers/net/thunderx/nicvf_ethdev.c b/dpdk/drivers/net/thunderx/nicvf_ethdev.c -index 2cf0ffe13b..0fba26ac45 100644 +index 2cf0ffe13b..1a25bde358 100644 --- a/dpdk/drivers/net/thunderx/nicvf_ethdev.c +++ b/dpdk/drivers/net/thunderx/nicvf_ethdev.c @@ -191,7 +191,7 @@ nicvf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) @@ -65279,6 +90388,27 @@ index 2cf0ffe13b..0fba26ac45 100644 return -ENOMEM; } +@@ -1873,6 +1875,8 @@ nicvf_dev_close(struct rte_eth_dev *dev) + struct nicvf *nic = nicvf_pmd_priv(dev); + + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + nicvf_dev_stop_cleanup(dev, true); + nicvf_periodic_alarm_stop(nicvf_interrupt, dev); +@@ -2099,10 +2103,7 @@ static int + nicvf_eth_dev_uninit(struct rte_eth_dev *dev) + { + PMD_INIT_FUNC_TRACE(); +- +- if (rte_eal_process_type() == RTE_PROC_PRIMARY) +- nicvf_dev_close(dev); +- ++ nicvf_dev_close(dev); + return 0; + } + static int diff --git a/dpdk/drivers/net/vdev_netvsc/vdev_netvsc.c b/dpdk/drivers/net/vdev_netvsc/vdev_netvsc.c index be8f19c0c6..48081b9146 100644 --- a/dpdk/drivers/net/vdev_netvsc/vdev_netvsc.c @@ -65340,7 +90470,7 @@ index be8f19c0c6..48081b9146 100644 } diff --git a/dpdk/drivers/net/vhost/rte_eth_vhost.c b/dpdk/drivers/net/vhost/rte_eth_vhost.c -index 46f01a7f46..323efb3c07 100644 +index 46f01a7f46..bb714a5c90 100644 --- a/dpdk/drivers/net/vhost/rte_eth_vhost.c +++ b/dpdk/drivers/net/vhost/rte_eth_vhost.c @@ -68,6 +68,9 @@ enum vhost_xstats_pkts { @@ -65546,7 +90676,82 @@ index 46f01a7f46..323efb3c07 100644 static inline struct internal_list * find_internal_resource(char *ifname) { -@@ -877,6 +868,74 @@ static struct vhost_device_ops vhost_ops = { +@@ -661,10 +652,11 @@ eth_vhost_install_intr(struct rte_eth_dev *dev) + } + + static void +-update_queuing_status(struct rte_eth_dev *dev) ++update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing) + { + struct pmd_internal *internal = dev->data->dev_private; + struct vhost_queue *vq; ++ struct rte_vhost_vring_state *state; + unsigned int i; + int allow_queuing = 1; + +@@ -675,13 +667,18 @@ update_queuing_status(struct rte_eth_dev *dev) + rte_atomic32_read(&internal->dev_attached) == 0) + allow_queuing = 0; + ++ state = vring_states[dev->data->port_id]; ++ + /* Wait until rx/tx_pkt_burst stops accessing vhost device */ + for (i = 0; i < dev->data->nb_rx_queues; i++) { + vq = dev->data->rx_queues[i]; + if (vq == NULL) + continue; +- rte_atomic32_set(&vq->allow_queuing, allow_queuing); +- while (rte_atomic32_read(&vq->while_queuing)) ++ if (allow_queuing && state->cur[vq->virtqueue_id]) ++ rte_atomic32_set(&vq->allow_queuing, 1); ++ else ++ rte_atomic32_set(&vq->allow_queuing, 0); ++ while (wait_queuing && rte_atomic32_read(&vq->while_queuing)) + rte_pause(); + } + +@@ -689,8 +686,11 @@ update_queuing_status(struct rte_eth_dev *dev) + vq = dev->data->tx_queues[i]; + if (vq == NULL) + continue; +- rte_atomic32_set(&vq->allow_queuing, allow_queuing); +- while (rte_atomic32_read(&vq->while_queuing)) ++ if (allow_queuing && state->cur[vq->virtqueue_id]) ++ rte_atomic32_set(&vq->allow_queuing, 1); ++ else ++ rte_atomic32_set(&vq->allow_queuing, 0); ++ while (wait_queuing && rte_atomic32_read(&vq->while_queuing)) + rte_pause(); + } + } +@@ -772,7 +772,7 @@ new_device(int vid) + eth_dev->data->dev_link.link_status = ETH_LINK_UP; + + rte_atomic32_set(&internal->dev_attached, 1); +- update_queuing_status(eth_dev); ++ update_queuing_status(eth_dev, false); + + VHOST_LOG(INFO, "Vhost device %d created\n", vid); + +@@ -802,7 +802,7 @@ destroy_device(int vid) + internal = eth_dev->data->dev_private; + + rte_atomic32_set(&internal->dev_attached, 0); +- update_queuing_status(eth_dev); ++ update_queuing_status(eth_dev, true); + + eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; + +@@ -863,6 +863,8 @@ vring_state_changed(int vid, uint16_t vring, int enable) + state->max_vring = RTE_MAX(vring, state->max_vring); + rte_spinlock_unlock(&state->lock); + ++ update_queuing_status(eth_dev, false); ++ + VHOST_LOG(INFO, "vring%u is %s\n", + vring, enable ? "enabled" : "disabled"); + +@@ -877,6 +879,74 @@ static struct vhost_device_ops vhost_ops = { .vring_state_changed = vring_state_changed, }; @@ -65621,7 +90826,7 @@ index 46f01a7f46..323efb3c07 100644 int rte_eth_vhost_get_queue_event(uint16_t port_id, struct rte_eth_vhost_queue_event *event) -@@ -943,6 +1002,24 @@ rte_eth_vhost_get_vid_from_port_id(uint16_t port_id) +@@ -943,6 +1013,24 @@ rte_eth_vhost_get_vid_from_port_id(uint16_t port_id) return vid; } @@ -65646,7 +90851,34 @@ index 46f01a7f46..323efb3c07 100644 static int eth_dev_start(struct rte_eth_dev *eth_dev) { -@@ -989,16 +1066,14 @@ eth_dev_close(struct rte_eth_dev *dev) +@@ -962,7 +1050,7 @@ eth_dev_start(struct rte_eth_dev *eth_dev) + } + + rte_atomic32_set(&internal->started, 1); +- update_queuing_status(eth_dev); ++ update_queuing_status(eth_dev, false); + + return 0; + } +@@ -973,7 +1061,7 @@ eth_dev_stop(struct rte_eth_dev *dev) + struct pmd_internal *internal = dev->data->dev_private; + + rte_atomic32_set(&internal->started, 0); +- update_queuing_status(dev); ++ update_queuing_status(dev, true); + } + + static void +@@ -983,22 +1071,23 @@ eth_dev_close(struct rte_eth_dev *dev) + struct internal_list *list; + unsigned int i; + ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ + internal = dev->data->dev_private; + if (!internal) + return; eth_dev_stop(dev); @@ -65670,7 +90902,7 @@ index 46f01a7f46..323efb3c07 100644 if (dev->data->rx_queues) for (i = 0; i < dev->data->nb_rx_queues; i++) -@@ -1009,7 +1084,7 @@ eth_dev_close(struct rte_eth_dev *dev) +@@ -1009,7 +1098,7 @@ eth_dev_close(struct rte_eth_dev *dev) rte_free(dev->data->tx_queues[i]); free(internal->dev_name); @@ -65679,7 +90911,7 @@ index 46f01a7f46..323efb3c07 100644 rte_free(internal); dev->data->dev_private = NULL; -@@ -1219,16 +1294,10 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, +@@ -1219,16 +1308,10 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, struct pmd_internal *internal = NULL; struct rte_eth_dev *eth_dev = NULL; struct rte_ether_addr *eth_addr = NULL; @@ -65696,7 +90928,7 @@ index 46f01a7f46..323efb3c07 100644 /* reserve an ethdev entry */ eth_dev = rte_eth_vdev_allocate(dev, sizeof(*internal)); if (eth_dev == NULL) -@@ -1242,11 +1311,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, +@@ -1242,11 +1325,6 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, *eth_addr = base_eth_addr; eth_addr->addr_bytes[5] = eth_dev->data->port_id; @@ -65708,7 +90940,7 @@ index 46f01a7f46..323efb3c07 100644 /* now put it all together * - store queue data in internal, * - point eth_dev_data to internals -@@ -1256,22 +1320,18 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, +@@ -1256,22 +1334,18 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, internal->dev_name = strdup(name); if (internal->dev_name == NULL) goto error; @@ -65736,7 +90968,7 @@ index 46f01a7f46..323efb3c07 100644 data->dev_link = pmd_link; data->dev_flags = RTE_ETH_DEV_INTR_LSC | RTE_ETH_DEV_CLOSE_REMOVE; -@@ -1281,37 +1341,15 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, +@@ -1281,37 +1355,15 @@ eth_dev_vhost_create(struct rte_vdev_device *dev, char *iface_name, eth_dev->rx_pkt_burst = eth_vhost_rx; eth_dev->tx_pkt_burst = eth_vhost_tx; @@ -65776,7 +91008,7 @@ index 46f01a7f46..323efb3c07 100644 return -1; } -@@ -1369,8 +1407,11 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev) +@@ -1369,8 +1421,11 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev) VHOST_LOG(ERR, "Failed to probe %s\n", name); return -1; } @@ -65789,7 +91021,21 @@ index 46f01a7f46..323efb3c07 100644 eth_dev->device = &dev->device; rte_eth_dev_probing_finish(eth_dev); return 0; -@@ -1455,8 +1496,10 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev) +@@ -1445,18 +1500,20 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev) + &open_int, &tso); + if (ret < 0) + goto out_free; ++ } + +- if (tso == 0) { +- disable_flags |= (1ULL << VIRTIO_NET_F_HOST_TSO4); +- disable_flags |= (1ULL << VIRTIO_NET_F_HOST_TSO6); +- } ++ if (tso == 0) { ++ disable_flags |= (1ULL << VIRTIO_NET_F_HOST_TSO4); ++ disable_flags |= (1ULL << VIRTIO_NET_F_HOST_TSO6); + } + if (dev->device.numa_node == SOCKET_ID_ANY) dev->device.numa_node = rte_socket_id(); @@ -65802,8 +91048,33 @@ index 46f01a7f46..323efb3c07 100644 out_free: rte_kvargs_free(kvlist); +@@ -1477,11 +1534,7 @@ rte_pmd_vhost_remove(struct rte_vdev_device *dev) + if (eth_dev == NULL) + return 0; + +- if (rte_eal_process_type() != RTE_PROC_PRIMARY) +- return rte_eth_dev_release_port(eth_dev); +- + eth_dev_close(eth_dev); +- + rte_eth_dev_release_port(eth_dev); + + return 0; +diff --git a/dpdk/drivers/net/virtio/meson.build b/dpdk/drivers/net/virtio/meson.build +index 04c7fdf25d..a99365807f 100644 +--- a/dpdk/drivers/net/virtio/meson.build ++++ b/dpdk/drivers/net/virtio/meson.build +@@ -13,7 +13,7 @@ if arch_subdir == 'x86' + sources += files('virtio_rxtx_simple_sse.c') + elif arch_subdir == 'ppc_64' + sources += files('virtio_rxtx_simple_altivec.c') +-elif arch_subdir == 'arm' and host_machine.cpu_family().startswith('aarch64') ++elif arch_subdir == 'arm' and dpdk_conf.get('RTE_ARCH_64') + sources += files('virtio_rxtx_simple_neon.c') + endif + diff --git a/dpdk/drivers/net/virtio/virtio_ethdev.c b/dpdk/drivers/net/virtio/virtio_ethdev.c -index 044eb10a70..8a107ebf9e 100644 +index 044eb10a70..4e615d2b4b 100644 --- a/dpdk/drivers/net/virtio/virtio_ethdev.c +++ b/dpdk/drivers/net/virtio/virtio_ethdev.c @@ -466,7 +466,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx) @@ -65855,7 +91126,39 @@ index 044eb10a70..8a107ebf9e 100644 } } } -@@ -1913,6 +1922,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev) +@@ -712,6 +721,8 @@ virtio_dev_close(struct rte_eth_dev *dev) + struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf; + + PMD_INIT_LOG(DEBUG, "virtio_dev_close"); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + if (!hw->opened) + return; +@@ -1632,13 +1643,15 @@ virtio_configure_intr(struct rte_eth_dev *dev) + } + } + +- /* Re-register callback to update max_intr */ +- rte_intr_callback_unregister(dev->intr_handle, +- virtio_interrupt_handler, +- dev); +- rte_intr_callback_register(dev->intr_handle, +- virtio_interrupt_handler, +- dev); ++ if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) { ++ /* Re-register callback to update max_intr */ ++ rte_intr_callback_unregister(dev->intr_handle, ++ virtio_interrupt_handler, ++ dev); ++ rte_intr_callback_register(dev->intr_handle, ++ virtio_interrupt_handler, ++ dev); ++ } + + /* DO NOT try to remove this! This function will enable msix, or QEMU + * will encounter SIGSEGV when DRIVER_OK is sent. +@@ -1913,6 +1926,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev) goto err_vtpci_init; } @@ -65864,7 +91167,7 @@ index 044eb10a70..8a107ebf9e 100644 /* reset device and negotiate default features */ ret = virtio_init_device(eth_dev, VIRTIO_PMD_DEFAULT_GUEST_FEATURES); if (ret < 0) -@@ -2155,8 +2166,6 @@ virtio_dev_configure(struct rte_eth_dev *dev) +@@ -2155,8 +2170,6 @@ virtio_dev_configure(struct rte_eth_dev *dev) return -EBUSY; } @@ -65873,11 +91176,139 @@ index 044eb10a70..8a107ebf9e 100644 hw->use_simple_rx = 1; if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER)) { +@@ -2436,6 +2449,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + dev_info->min_rx_bufsize = VIRTIO_MIN_RX_BUFSIZE; + dev_info->max_rx_pktlen = VIRTIO_MAX_RX_PKTLEN; + dev_info->max_mac_addrs = VIRTIO_MAX_MAC_ADDRS; ++ dev_info->max_mtu = hw->max_mtu; + + host_features = VTPCI_OPS(hw)->get_features(hw); + dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP; diff --git a/dpdk/drivers/net/virtio/virtio_rxtx.c b/dpdk/drivers/net/virtio/virtio_rxtx.c -index 752faa0f6e..5211736d29 100644 +index 752faa0f6e..6706366e9f 100644 --- a/dpdk/drivers/net/virtio/virtio_rxtx.c +++ b/dpdk/drivers/net/virtio/virtio_rxtx.c -@@ -1085,7 +1085,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev, +@@ -474,13 +474,35 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf **cookie, + return 0; + } + ++static inline void ++virtqueue_refill_single_packed(struct virtqueue *vq, ++ struct vring_packed_desc *dp, ++ struct rte_mbuf *cookie) ++{ ++ uint16_t flags = vq->vq_packed.cached_flags; ++ struct virtio_hw *hw = vq->hw; ++ ++ dp->addr = VIRTIO_MBUF_ADDR(cookie, vq) + ++ RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size; ++ dp->len = cookie->buf_len - ++ RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size; ++ ++ virtqueue_store_flags_packed(dp, flags, ++ hw->weak_barriers); ++ ++ if (++vq->vq_avail_idx >= vq->vq_nentries) { ++ vq->vq_avail_idx -= vq->vq_nentries; ++ vq->vq_packed.cached_flags ^= ++ VRING_PACKED_DESC_F_AVAIL_USED; ++ flags = vq->vq_packed.cached_flags; ++ } ++} ++ + static inline int +-virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, ++virtqueue_enqueue_recv_refill_packed_init(struct virtqueue *vq, + struct rte_mbuf **cookie, uint16_t num) + { + struct vring_packed_desc *start_dp = vq->vq_packed.ring.desc; +- uint16_t flags = vq->vq_packed.cached_flags; +- struct virtio_hw *hw = vq->hw; + struct vq_desc_extra *dxp; + uint16_t idx; + int i; +@@ -496,24 +518,34 @@ virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, + dxp->cookie = (void *)cookie[i]; + dxp->ndescs = 1; + +- start_dp[idx].addr = VIRTIO_MBUF_ADDR(cookie[i], vq) + +- RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size; +- start_dp[idx].len = cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM +- + hw->vtnet_hdr_size; ++ virtqueue_refill_single_packed(vq, &start_dp[idx], cookie[i]); ++ } ++ vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num); ++ return 0; ++} + +- vq->vq_desc_head_idx = dxp->next; +- if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END) +- vq->vq_desc_tail_idx = vq->vq_desc_head_idx; ++static inline int ++virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq, ++ struct rte_mbuf **cookie, uint16_t num) ++{ ++ struct vring_packed_desc *start_dp = vq->vq_packed.ring.desc; ++ struct vq_desc_extra *dxp; ++ uint16_t idx, did; ++ int i; ++ ++ if (unlikely(vq->vq_free_cnt == 0)) ++ return -ENOSPC; ++ if (unlikely(vq->vq_free_cnt < num)) ++ return -EMSGSIZE; + +- virtqueue_store_flags_packed(&start_dp[idx], flags, +- hw->weak_barriers); ++ for (i = 0; i < num; i++) { ++ idx = vq->vq_avail_idx; ++ did = start_dp[idx].id; ++ dxp = &vq->vq_descx[did]; ++ dxp->cookie = (void *)cookie[i]; ++ dxp->ndescs = 1; + +- if (++vq->vq_avail_idx >= vq->vq_nentries) { +- vq->vq_avail_idx -= vq->vq_nentries; +- vq->vq_packed.cached_flags ^= +- VRING_PACKED_DESC_F_AVAIL_USED; +- flags = vq->vq_packed.cached_flags; +- } ++ virtqueue_refill_single_packed(vq, &start_dp[idx], cookie[i]); + } + vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num); + return 0; +@@ -1008,10 +1040,11 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx) + if (unlikely(error)) { + for (i = 0; i < free_cnt; i++) + rte_pktmbuf_free(pkts[i]); ++ } else { ++ nbufs += free_cnt; + } + } + +- nbufs += free_cnt; + vq_update_avail_idx(vq); + } + } else { +@@ -1022,7 +1055,7 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx) + + /* Enqueue allocated buffers */ + if (vtpci_packed_queue(vq->hw)) +- error = virtqueue_enqueue_recv_refill_packed(vq, ++ error = virtqueue_enqueue_recv_refill_packed_init(vq, + &m, 1); + else + error = virtqueue_enqueue_recv_refill(vq, +@@ -1059,7 +1092,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev, + unsigned int socket_id __rte_unused, + const struct rte_eth_txconf *tx_conf) + { +- uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX; ++ uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX; + struct virtio_hw *hw = dev->data->dev_private; + struct virtqueue *vq = hw->vqs[vtpci_queue_idx]; + struct virtnet_tx *txvq; +@@ -1085,7 +1118,7 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev, RTE_MIN(vq->vq_nentries / 4, DEFAULT_TX_FREE_THRESH); if (tx_free_thresh >= (vq->vq_nentries - 3)) { @@ -65886,7 +91317,16 @@ index 752faa0f6e..5211736d29 100644 "number of TX entries minus 3 (%u)." " (tx_free_thresh=%u port=%u queue=%u)\n", vq->vq_nentries - 3, -@@ -1133,7 +1133,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m) +@@ -1103,7 +1136,7 @@ int + virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev, + uint16_t queue_idx) + { +- uint8_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX; ++ uint16_t vtpci_queue_idx = 2 * queue_idx + VTNET_SQ_TQ_QUEUE_IDX; + struct virtio_hw *hw = dev->data->dev_private; + struct virtqueue *vq = hw->vqs[vtpci_queue_idx]; + +@@ -1133,7 +1166,7 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m) error = virtqueue_enqueue_recv_refill(vq, &m, 1); if (unlikely(error)) { @@ -65895,7 +91335,7 @@ index 752faa0f6e..5211736d29 100644 rte_pktmbuf_free(m); } } -@@ -1145,7 +1145,7 @@ virtio_discard_rxbuf_inorder(struct virtqueue *vq, struct rte_mbuf *m) +@@ -1145,7 +1178,7 @@ virtio_discard_rxbuf_inorder(struct virtqueue *vq, struct rte_mbuf *m) error = virtqueue_enqueue_refill_inorder(vq, &m, 1); if (unlikely(error)) { @@ -65904,7 +91344,7 @@ index 752faa0f6e..5211736d29 100644 rte_pktmbuf_free(m); } } -@@ -1184,9 +1184,10 @@ virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr) +@@ -1184,9 +1217,10 @@ virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr) */ uint16_t csum = 0, off; @@ -65918,7 +91358,7 @@ index 752faa0f6e..5211736d29 100644 csum = ~csum; off = hdr->csum_offset + hdr->csum_start; diff --git a/dpdk/drivers/net/virtio/virtio_rxtx_simple_altivec.c b/dpdk/drivers/net/virtio/virtio_rxtx_simple_altivec.c -index 47225f4121..003b6ec3f6 100644 +index 47225f4121..19dc37e774 100644 --- a/dpdk/drivers/net/virtio/virtio_rxtx_simple_altivec.c +++ b/dpdk/drivers/net/virtio/virtio_rxtx_simple_altivec.c @@ -9,8 +9,7 @@ @@ -65931,6 +91371,92 @@ index 47225f4121..003b6ec3f6 100644 #include #include #include +@@ -86,6 +85,12 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP)) + return 0; + ++ if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { ++ virtio_rxq_rearm_vec(rxvq); ++ if (unlikely(virtqueue_kick_prepare(vq))) ++ virtqueue_notify(vq); ++ } ++ + nb_used = VIRTQUEUE_NUSED(vq); + + rte_compiler_barrier(); +@@ -103,12 +108,6 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + + rte_prefetch0(rused); + +- if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { +- virtio_rxq_rearm_vec(rxvq); +- if (unlikely(virtqueue_kick_prepare(vq))) +- virtqueue_notify(vq); +- } +- + nb_total = nb_used; + ref_rx_pkts = rx_pkts; + for (nb_pkts_received = 0; +diff --git a/dpdk/drivers/net/virtio/virtio_rxtx_simple_neon.c b/dpdk/drivers/net/virtio/virtio_rxtx_simple_neon.c +index 992e71f010..588a3af2a1 100644 +--- a/dpdk/drivers/net/virtio/virtio_rxtx_simple_neon.c ++++ b/dpdk/drivers/net/virtio/virtio_rxtx_simple_neon.c +@@ -83,6 +83,12 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP)) + return 0; + ++ if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { ++ virtio_rxq_rearm_vec(rxvq); ++ if (unlikely(virtqueue_kick_prepare(vq))) ++ virtqueue_notify(vq); ++ } ++ + nb_used = VIRTQUEUE_NUSED(vq); + + rte_rmb(); +@@ -100,12 +106,6 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + + rte_prefetch_non_temporal(rused); + +- if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { +- virtio_rxq_rearm_vec(rxvq); +- if (unlikely(virtqueue_kick_prepare(vq))) +- virtqueue_notify(vq); +- } +- + nb_total = nb_used; + ref_rx_pkts = rx_pkts; + for (nb_pkts_received = 0; +diff --git a/dpdk/drivers/net/virtio/virtio_rxtx_simple_sse.c b/dpdk/drivers/net/virtio/virtio_rxtx_simple_sse.c +index f9ec4ae699..9a45886820 100644 +--- a/dpdk/drivers/net/virtio/virtio_rxtx_simple_sse.c ++++ b/dpdk/drivers/net/virtio/virtio_rxtx_simple_sse.c +@@ -85,6 +85,12 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP)) + return 0; + ++ if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { ++ virtio_rxq_rearm_vec(rxvq); ++ if (unlikely(virtqueue_kick_prepare(vq))) ++ virtqueue_notify(vq); ++ } ++ + nb_used = VIRTQUEUE_NUSED(vq); + + rte_compiler_barrier(); +@@ -102,12 +108,6 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, + + rte_prefetch0(rused); + +- if (vq->vq_free_cnt >= RTE_VIRTIO_VPMD_RX_REARM_THRESH) { +- virtio_rxq_rearm_vec(rxvq); +- if (unlikely(virtqueue_kick_prepare(vq))) +- virtqueue_notify(vq); +- } +- + nb_total = nb_used; + ref_rx_pkts = rx_pkts; + for (nb_pkts_received = 0; diff --git a/dpdk/drivers/net/virtio/virtio_user/vhost_kernel.c b/dpdk/drivers/net/virtio/virtio_user/vhost_kernel.c index 5c81e8dd9f..2c805077af 100644 --- a/dpdk/drivers/net/virtio/virtio_user/vhost_kernel.c @@ -66108,10 +91634,23 @@ index e0e95b4f59..5c4447b296 100644 + +#endif diff --git a/dpdk/drivers/net/virtio/virtio_user/vhost_user.c b/dpdk/drivers/net/virtio/virtio_user/vhost_user.c -index a4b5c25cd3..d8e083ba8b 100644 +index a4b5c25cd3..b4e8ec4b4b 100644 --- a/dpdk/drivers/net/virtio/virtio_user/vhost_user.c +++ b/dpdk/drivers/net/virtio/virtio_user/vhost_user.c -@@ -456,6 +456,9 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev, +@@ -422,8 +422,10 @@ vhost_user_setup(struct virtio_user_dev *dev) + } + + flag = fcntl(fd, F_GETFD); +- if (fcntl(fd, F_SETFD, flag | FD_CLOEXEC) < 0) +- PMD_DRV_LOG(WARNING, "fcntl failed, %s", strerror(errno)); ++ if (flag == -1) ++ PMD_DRV_LOG(WARNING, "fcntl get fd failed, %s", strerror(errno)); ++ else if (fcntl(fd, F_SETFD, flag | FD_CLOEXEC) < 0) ++ PMD_DRV_LOG(WARNING, "fcntl set fd failed, %s", strerror(errno)); + + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; +@@ -456,6 +458,9 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev, { int i; @@ -66121,7 +91660,7 @@ index a4b5c25cd3..d8e083ba8b 100644 for (i = 0; i < 2; ++i) { struct vhost_vring_state state = { .index = pair_idx * 2 + i, -@@ -466,6 +469,7 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev, +@@ -466,6 +471,7 @@ vhost_user_enable_queue_pair(struct virtio_user_dev *dev, return -1; } @@ -66130,7 +91669,7 @@ index a4b5c25cd3..d8e083ba8b 100644 } diff --git a/dpdk/drivers/net/virtio/virtio_user/virtio_user_dev.c b/dpdk/drivers/net/virtio/virtio_user/virtio_user_dev.c -index ea016e85d8..ad5d2f3bf8 100644 +index ea016e85d8..72b3dbd265 100644 --- a/dpdk/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/dpdk/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -263,6 +263,7 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev) @@ -66150,6 +91689,15 @@ index ea016e85d8..ad5d2f3bf8 100644 close(dev->callfds[j]); close(dev->kickfds[j]); } +@@ -298,7 +299,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev) + } + + for (i = 0; i < dev->max_queue_pairs; ++i) +- eth_dev->intr_handle->efds[i] = dev->callfds[i]; ++ eth_dev->intr_handle->efds[i] = dev->callfds[2 * i]; + eth_dev->intr_handle->nb_efd = dev->max_queue_pairs; + eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1; + eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; @@ -537,7 +538,8 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev) close(dev->kickfds[i]); } @@ -66194,7 +91742,7 @@ index ad86837717..8937124d92 100644 struct virtio_user_backend_ops *ops; pthread_mutex_t mutex; diff --git a/dpdk/drivers/net/virtio/virtio_user_ethdev.c b/dpdk/drivers/net/virtio/virtio_user_ethdev.c -index 3fc1725736..4a35fa1c95 100644 +index 3fc1725736..1c07caeb5c 100644 --- a/dpdk/drivers/net/virtio/virtio_user_ethdev.c +++ b/dpdk/drivers/net/virtio/virtio_user_ethdev.c @@ -13,6 +13,7 @@ @@ -66205,7 +91753,7 @@ index 3fc1725736..4a35fa1c95 100644 #include "virtio_ethdev.h" #include "virtio_logs.h" -@@ -25,12 +26,48 @@ +@@ -25,12 +26,74 @@ #define virtio_user_get_dev(hw) \ ((struct virtio_user_dev *)(hw)->virtio_user_dev) @@ -66243,6 +91791,32 @@ index 3fc1725736..4a35fa1c95 100644 + rte_spinlock_unlock(&hw->state_lock); +} + ++static void ++virtio_user_delayed_intr_reconfig_handler(void *param) ++{ ++ struct virtio_hw *hw = (struct virtio_hw *)param; ++ struct rte_eth_dev *eth_dev = &rte_eth_devices[hw->port_id]; ++ struct virtio_user_dev *dev = virtio_user_get_dev(hw); ++ ++ PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d", ++ eth_dev->intr_handle->fd); ++ ++ if (rte_intr_callback_unregister(eth_dev->intr_handle, ++ virtio_interrupt_handler, ++ eth_dev) != 1) ++ PMD_DRV_LOG(ERR, "interrupt unregister failed"); ++ ++ eth_dev->intr_handle->fd = dev->vhostfd; ++ ++ PMD_DRV_LOG(DEBUG, "Registering intr fd: %d", eth_dev->intr_handle->fd); ++ ++ if (rte_intr_callback_register(eth_dev->intr_handle, ++ virtio_interrupt_handler, eth_dev)) ++ PMD_DRV_LOG(ERR, "interrupt register failed"); ++ ++ if (rte_intr_enable(eth_dev->intr_handle) < 0) ++ PMD_DRV_LOG(ERR, "interrupt enable failed"); ++} + static int virtio_user_server_reconnect(struct virtio_user_dev *dev) @@ -66254,7 +91828,7 @@ index 3fc1725736..4a35fa1c95 100644 connectfd = accept(dev->listenfd, NULL, NULL); if (connectfd < 0) -@@ -51,6 +88,14 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) +@@ -51,6 +114,14 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) dev->features &= dev->device_features; @@ -66269,27 +91843,112 @@ index 3fc1725736..4a35fa1c95 100644 ret = virtio_user_start_device(dev); if (ret < 0) return -1; -@@ -140,7 +185,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, - } - r = recv(dev->vhostfd, buf, 128, MSG_PEEK); +@@ -67,24 +138,21 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) + PMD_DRV_LOG(ERR, "interrupt disable failed"); + return -1; + } +- rte_intr_callback_unregister(eth_dev->intr_handle, +- virtio_interrupt_handler, +- eth_dev); +- eth_dev->intr_handle->fd = connectfd; +- rte_intr_callback_register(eth_dev->intr_handle, +- virtio_interrupt_handler, eth_dev); +- +- if (rte_intr_enable(eth_dev->intr_handle) < 0) { +- PMD_DRV_LOG(ERR, "interrupt enable failed"); +- return -1; +- } ++ /* ++ * This function can be called from the interrupt handler, so ++ * we can't unregister interrupt handler here. Setting ++ * alarm to do that later. ++ */ ++ rte_eal_alarm_set(1, ++ virtio_user_delayed_intr_reconfig_handler, ++ (void *)hw); + } + PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!"); + return 0; + } + + static void +-virtio_user_delayed_handler(void *param) ++virtio_user_delayed_disconnect_handler(void *param) + { + struct virtio_hw *hw = (struct virtio_hw *)param; + struct rte_eth_dev *eth_dev = &rte_eth_devices[hw->port_id]; +@@ -94,16 +162,29 @@ virtio_user_delayed_handler(void *param) + PMD_DRV_LOG(ERR, "interrupt disable failed"); + return; + } +- rte_intr_callback_unregister(eth_dev->intr_handle, +- virtio_interrupt_handler, eth_dev); ++ ++ PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d", ++ eth_dev->intr_handle->fd); ++ if (rte_intr_callback_unregister(eth_dev->intr_handle, ++ virtio_interrupt_handler, ++ eth_dev) != 1) ++ PMD_DRV_LOG(ERR, "interrupt unregister failed"); ++ + if (dev->is_server) { + if (dev->vhostfd >= 0) { + close(dev->vhostfd); + dev->vhostfd = -1; + } + eth_dev->intr_handle->fd = dev->listenfd; +- rte_intr_callback_register(eth_dev->intr_handle, +- virtio_interrupt_handler, eth_dev); ++ ++ PMD_DRV_LOG(DEBUG, "Registering intr fd: %d", ++ eth_dev->intr_handle->fd); ++ ++ if (rte_intr_callback_register(eth_dev->intr_handle, ++ virtio_interrupt_handler, ++ eth_dev)) ++ PMD_DRV_LOG(ERR, "interrupt register failed"); ++ + if (rte_intr_enable(eth_dev->intr_handle) < 0) { + PMD_DRV_LOG(ERR, "interrupt enable failed"); + return; +@@ -130,17 +211,11 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, + + if (dev->vhostfd >= 0) { + int r; +- int flags; + +- flags = fcntl(dev->vhostfd, F_GETFL); +- if (fcntl(dev->vhostfd, F_SETFL, +- flags | O_NONBLOCK) == -1) { +- PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag"); +- return; +- } +- r = recv(dev->vhostfd, buf, 128, MSG_PEEK); ++ r = recv(dev->vhostfd, buf, 128, ++ MSG_PEEK | MSG_DONTWAIT); if (r == 0 || (r < 0 && errno != EAGAIN)) { - dev->status &= (~VIRTIO_NET_S_LINK_UP); + dev->net_status &= (~VIRTIO_NET_S_LINK_UP); PMD_DRV_LOG(ERR, "virtio-user port %u is down", hw->port_id); -@@ -152,7 +197,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, - virtio_user_delayed_handler, - (void *)hw); +@@ -149,23 +224,18 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, + * unregistered here, set an alarm to do it. + */ + rte_eal_alarm_set(1, +- virtio_user_delayed_handler, +- (void *)hw); ++ virtio_user_delayed_disconnect_handler, ++ (void *)hw); } else { - dev->status |= VIRTIO_NET_S_LINK_UP; +- } +- if (fcntl(dev->vhostfd, F_SETFL, +- flags & ~O_NONBLOCK) == -1) { +- PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag"); +- return; + dev->net_status |= VIRTIO_NET_S_LINK_UP; } - if (fcntl(dev->vhostfd, F_SETFL, - flags & ~O_NONBLOCK) == -1) { -@@ -160,12 +205,12 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, - return; - } } else if (dev->is_server) { - dev->status &= (~VIRTIO_NET_S_LINK_UP); + dev->net_status &= (~VIRTIO_NET_S_LINK_UP); @@ -66303,7 +91962,7 @@ index 3fc1725736..4a35fa1c95 100644 } if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs)) -@@ -433,12 +478,17 @@ static int +@@ -433,12 +503,17 @@ static int get_integer_arg(const char *key __rte_unused, const char *value, void *extra_args) { @@ -66325,7 +91984,7 @@ index 3fc1725736..4a35fa1c95 100644 } static struct rte_eth_dev * -@@ -517,7 +567,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) +@@ -517,7 +592,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) const char *name = rte_vdev_device_name(dev); eth_dev = rte_eth_dev_attach_secondary(name); if (!eth_dev) { @@ -66334,7 +91993,7 @@ index 3fc1725736..4a35fa1c95 100644 return -1; } -@@ -669,7 +719,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) +@@ -669,7 +744,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) goto end; } @@ -66344,10 +92003,10 @@ index 3fc1725736..4a35fa1c95 100644 PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails"); virtio_user_eth_dev_free(eth_dev); diff --git a/dpdk/drivers/net/virtio/virtqueue.c b/dpdk/drivers/net/virtio/virtqueue.c -index 5ff1e3587e..02c8b9fc54 100644 +index 5ff1e3587e..8195aaa8c8 100644 --- a/dpdk/drivers/net/virtio/virtqueue.c +++ b/dpdk/drivers/net/virtio/virtqueue.c -@@ -141,3 +141,76 @@ virtqueue_rxvq_flush(struct virtqueue *vq) +@@ -141,3 +141,90 @@ virtqueue_rxvq_flush(struct virtqueue *vq) else virtqueue_rxvq_flush_split(vq); } @@ -66395,6 +92054,8 @@ index 5ff1e3587e..02c8b9fc54 100644 + struct vq_desc_extra *dxp; + struct virtnet_tx *txvq; + uint16_t desc_idx; ++ struct virtio_tx_region *txr; ++ struct vring_packed_desc *start_dp; + + vq->vq_used_cons_idx = 0; + vq->vq_desc_head_idx = 0; @@ -66407,6 +92068,7 @@ index 5ff1e3587e..02c8b9fc54 100644 + vq->vq_packed.event_flags_shadow = 0; + + txvq = &vq->txq; ++ txr = txvq->virtio_net_hdr_mz->addr; + memset(txvq->mz->addr, 0, txvq->mz->len); + memset(txvq->virtio_net_hdr_mz->addr, 0, + txvq->virtio_net_hdr_mz->len); @@ -66417,6 +92079,17 @@ index 5ff1e3587e..02c8b9fc54 100644 + rte_pktmbuf_free(dxp->cookie); + dxp->cookie = NULL; + } ++ ++ if (vtpci_with_feature(vq->hw, VIRTIO_RING_F_INDIRECT_DESC)) { ++ /* first indirect descriptor is always the tx header */ ++ start_dp = txr[desc_idx].tx_packed_indir; ++ vring_desc_init_indirect_packed(start_dp, ++ RTE_DIM(txr[desc_idx].tx_packed_indir)); ++ start_dp->addr = txvq->virtio_net_hdr_mem ++ + desc_idx * sizeof(*txr) ++ + offsetof(struct virtio_tx_region, tx_hdr); ++ start_dp->len = vq->hw->vtnet_hdr_size; ++ } + } + + vring_desc_init_packed(vq, size); @@ -66471,7 +92144,7 @@ index 8d7f197b13..e901249601 100644 virtqueue_full(const struct virtqueue *vq) { diff --git a/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c b/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c -index 6e6efa9603..705e9760f4 100644 +index 6e6efa9603..10fb7e5cfd 100644 --- a/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c +++ b/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c @@ -771,7 +771,8 @@ vmxnet3_dev_start(struct rte_eth_dev *dev) @@ -66484,6 +92157,15 @@ index 6e6efa9603..705e9760f4 100644 /* Check for additional RSS */ ret = vmxnet3_v4_rss_configure(dev); if (ret != VMXNET3_SUCCESS) { +@@ -892,6 +893,8 @@ static void + vmxnet3_dev_close(struct rte_eth_dev *dev) + { + PMD_INIT_FUNC_TRACE(); ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; + + vmxnet3_dev_stop(dev); + vmxnet3_free_queues(dev); diff --git a/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.h b/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.h index 8c2b6f8771..dd685b02b7 100644 --- a/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.h @@ -66500,10 +92182,20 @@ index 8c2b6f8771..dd685b02b7 100644 typedef struct VMXNET3_RSSConf { uint16_t hashType; diff --git a/dpdk/drivers/net/vmxnet3/vmxnet3_rxtx.c b/dpdk/drivers/net/vmxnet3/vmxnet3_rxtx.c -index 7794d74214..73e270f30f 100644 +index 7794d74214..76b8e54772 100644 --- a/dpdk/drivers/net/vmxnet3/vmxnet3_rxtx.c +++ b/dpdk/drivers/net/vmxnet3/vmxnet3_rxtx.c -@@ -950,13 +950,17 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +@@ -341,6 +341,9 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq) + } + + PMD_TX_LOG(DEBUG, "Processed %d tx comps & command descs.", completed); ++ ++ /* To avoid compiler warnings when not in DEBUG mode. */ ++ RTE_SET_USED(completed); + } + + uint16_t +@@ -950,13 +953,17 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) RTE_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY); @@ -66522,7 +92214,7 @@ index 7794d74214..73e270f30f 100644 rte_pktmbuf_free_seg(rxm); } } -@@ -1311,6 +1315,14 @@ vmxnet3_v4_rss_configure(struct rte_eth_dev *dev) +@@ -1311,6 +1318,14 @@ vmxnet3_v4_rss_configure(struct rte_eth_dev *dev) cmdInfo->setRSSFields = 0; port_rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf; @@ -66553,6 +92245,95 @@ index c905954004..b31d7aacb3 100644 } /* Reset HW queues */ +diff --git a/dpdk/drivers/raw/ifpga/base/README b/dpdk/drivers/raw/ifpga/base/README +index 6b2b171b01..55d92d590a 100644 +--- a/dpdk/drivers/raw/ifpga/base/README ++++ b/dpdk/drivers/raw/ifpga/base/README +@@ -42,5 +42,5 @@ Some features added in this version: + 3. Add altera SPI master driver and Intel MAX10 device driver. + 4. Add Altera I2C master driver and AT24 eeprom driver. + 5. Add Device Tree support to get the configuration from card. +-6. Instruding and exposing APIs to DPDK PMD driver to access networking ++6. Instruding and exposing APIs to DPDK PMD to access networking + functionality. +diff --git a/dpdk/drivers/raw/ifpga/base/ifpga_api.c b/dpdk/drivers/raw/ifpga/base/ifpga_api.c +index 6dbd7159e8..1ff57fa188 100644 +--- a/dpdk/drivers/raw/ifpga/base/ifpga_api.c ++++ b/dpdk/drivers/raw/ifpga/base/ifpga_api.c +@@ -330,8 +330,20 @@ static int ifpga_adapter_enumerate(struct opae_adapter *adapter) + return -ENOMEM; + } + ++static void ifpga_adapter_destroy(struct opae_adapter *adapter) ++{ ++ struct ifpga_fme_hw *fme; ++ ++ if (adapter && adapter->mgr && adapter->mgr->data) { ++ fme = (struct ifpga_fme_hw *)adapter->mgr->data; ++ if (fme->parent) ++ ifpga_bus_uinit(fme->parent); ++ } ++} ++ + struct opae_adapter_ops ifpga_adapter_ops = { + .enumerate = ifpga_adapter_enumerate, ++ .destroy = ifpga_adapter_destroy, + }; + + /** +diff --git a/dpdk/drivers/raw/ifpga/base/ifpga_defines.h b/dpdk/drivers/raw/ifpga/base/ifpga_defines.h +index 9f0147d1ed..7853d2976a 100644 +--- a/dpdk/drivers/raw/ifpga/base/ifpga_defines.h ++++ b/dpdk/drivers/raw/ifpga/base/ifpga_defines.h +@@ -93,9 +93,9 @@ enum fpga_id_type { + + #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER + #define PORT_FEATURE_ID_ERROR 0x10 +-#define PORT_FEATURE_ID_UMSG 0x12 +-#define PORT_FEATURE_ID_UINT 0x13 +-#define PORT_FEATURE_ID_STP 0x14 ++#define PORT_FEATURE_ID_UMSG 0x11 ++#define PORT_FEATURE_ID_UINT 0x12 ++#define PORT_FEATURE_ID_STP 0x13 + #define PORT_FEATURE_ID_UAFU FEATURE_ID_AFU + + /* +diff --git a/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.c b/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.c +index b8846e3731..48b8af4587 100644 +--- a/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.c ++++ b/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.c +@@ -722,3 +722,19 @@ int ifpga_bus_init(struct ifpga_hw *hw) + + return 0; + } ++ ++int ifpga_bus_uinit(struct ifpga_hw *hw) ++{ ++ int i; ++ struct ifpga_port_hw *port; ++ ++ if (hw) { ++ fme_hw_uinit(&hw->fme); ++ for (i = 0; i < MAX_FPGA_PORT_NUM; i++) { ++ port = &hw->port[i]; ++ port_hw_uinit(port); ++ } ++ } ++ ++ return 0; ++} +diff --git a/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.h b/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.h +index 14131e3206..95ed594cdc 100644 +--- a/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.h ++++ b/dpdk/drivers/raw/ifpga/base/ifpga_enumerate.h +@@ -6,6 +6,7 @@ + #define _IFPGA_ENUMERATE_H_ + + int ifpga_bus_init(struct ifpga_hw *hw); ++int ifpga_bus_uinit(struct ifpga_hw *hw); + int ifpga_bus_enumerate(struct ifpga_hw *hw); + + #endif /* _IFPGA_ENUMERATE_H_ */ diff --git a/dpdk/drivers/raw/ifpga/base/ifpga_fme.c b/dpdk/drivers/raw/ifpga/base/ifpga_fme.c index c31a94cf80..9057087b55 100644 --- a/dpdk/drivers/raw/ifpga/base/ifpga_fme.c @@ -66621,11 +92402,55 @@ index c31a94cf80..9057087b55 100644 return 0; } +diff --git a/dpdk/drivers/raw/ifpga/base/meson.build b/dpdk/drivers/raw/ifpga/base/meson.build +index b13e13e894..55a9c29d2f 100644 +--- a/dpdk/drivers/raw/ifpga/base/meson.build ++++ b/dpdk/drivers/raw/ifpga/base/meson.build +@@ -26,4 +26,4 @@ sources = [ + base_lib = static_library('ifpga_rawdev_base', sources, + dependencies: static_rte_eal, + c_args: cflags) +-base_objs = base_lib.extract_all_objects() ++base_objs = base_lib.extract_all_objects(recursive: true) +diff --git a/dpdk/drivers/raw/ifpga/base/opae_spi.c b/dpdk/drivers/raw/ifpga/base/opae_spi.c +index bfdc83e6cd..d2c955e6b3 100644 +--- a/dpdk/drivers/raw/ifpga/base/opae_spi.c ++++ b/dpdk/drivers/raw/ifpga/base/opae_spi.c +@@ -239,6 +239,18 @@ int spi_command(struct altera_spi_device *dev, unsigned int chip_select, + return 0; + } + ++int spi_write(struct altera_spi_device *dev, unsigned int chip_select, ++ unsigned int wlen, void *wdata) ++{ ++ return spi_command(dev, chip_select, wlen, wdata, 0, NULL); ++} ++ ++int spi_read(struct altera_spi_device *dev, unsigned int chip_select, ++ unsigned int rlen, void *rdata) ++{ ++ return spi_command(dev, chip_select, 0, NULL, rlen, rdata); ++} ++ + struct altera_spi_device *altera_spi_alloc(void *base, int type) + { + struct altera_spi_device *spi_dev = diff --git a/dpdk/drivers/raw/ifpga/base/opae_spi.h b/dpdk/drivers/raw/ifpga/base/opae_spi.h -index d20a4c3edd..73a2276739 100644 +index d20a4c3edd..e0f87a9088 100644 --- a/dpdk/drivers/raw/ifpga/base/opae_spi.h +++ b/dpdk/drivers/raw/ifpga/base/opae_spi.h -@@ -153,6 +153,7 @@ int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val); +@@ -112,6 +112,10 @@ struct spi_tran_header { + u32 addr; + }; + ++int spi_read(struct altera_spi_device *dev, unsigned int chip_select, ++ unsigned int rlen, void *rdata); ++int spi_write(struct altera_spi_device *dev, unsigned int chip_select, ++ unsigned int wlen, void *wdata); + int spi_command(struct altera_spi_device *dev, unsigned int chip_select, + unsigned int wlen, void *wdata, unsigned int rlen, void *rdata); + void spi_cs_deactivate(struct altera_spi_device *dev); +@@ -153,6 +157,7 @@ int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val); #define NIOS_INIT 0x1000 #define REQ_FEC_MODE GENMASK(23, 8) @@ -66634,10 +92459,185 @@ index d20a4c3edd..73a2276739 100644 #define FEC_MODE_KR 0x5555 #define FEC_MODE_RS 0xaaaa diff --git a/dpdk/drivers/raw/ifpga/base/opae_spi_transaction.c b/dpdk/drivers/raw/ifpga/base/opae_spi_transaction.c -index 013efee3e6..d13d2fbc83 100644 +index 013efee3e6..99131a1f76 100644 --- a/dpdk/drivers/raw/ifpga/base/opae_spi_transaction.c +++ b/dpdk/drivers/raw/ifpga/base/opae_spi_transaction.c -@@ -166,7 +166,7 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, +@@ -40,7 +40,7 @@ static void print_buffer(const char *string, void *buffer, int len) + printf("%s print buffer, len=%d\n", string, len); + + for (i = 0; i < len; i++) +- printf("%x ", *(p+i)); ++ printf("%02x ", *(p+i)); + printf("\n"); + } + #else +@@ -72,43 +72,6 @@ static void reorder_phy_data(u8 bits_per_word, + } + } + +-enum { +- SPI_FOUND_SOP, +- SPI_FOUND_EOP, +- SPI_NOT_FOUND, +-}; +- +-static int resp_find_sop_eop(unsigned char *resp, unsigned int len, +- int flags) +-{ +- int ret = SPI_NOT_FOUND; +- +- unsigned char *b = resp; +- +- /* find SOP */ +- if (flags != SPI_FOUND_SOP) { +- while (b < resp + len && *b != SPI_PACKET_SOP) +- b++; +- +- if (*b != SPI_PACKET_SOP) +- goto done; +- +- ret = SPI_FOUND_SOP; +- } +- +- /* find EOP */ +- while (b < resp + len && *b != SPI_PACKET_EOP) +- b++; +- +- if (*b != SPI_PACKET_EOP) +- goto done; +- +- ret = SPI_FOUND_EOP; +- +-done: +- return ret; +-} +- + static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len, + unsigned int *aligned_len) + { +@@ -137,6 +100,104 @@ static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len, + *p++ = SPI_BYTE_IDLE; + } + ++#define RX_ALL_IDLE_DATA (SPI_BYTE_IDLE << 24 | SPI_BYTE_IDLE << 16 | \ ++ SPI_BYTE_IDLE << 8 | SPI_BYTE_IDLE) ++ ++static bool all_idle_data(u8 *rxbuf) ++{ ++ return *(u32 *)rxbuf == RX_ALL_IDLE_DATA; ++} ++ ++static unsigned char *find_eop(u8 *rxbuf, u32 BPW) ++{ ++ return memchr(rxbuf, SPI_PACKET_EOP, BPW); ++} ++ ++static int do_spi_txrx(struct spi_transaction_dev *dev, ++ unsigned char *tx_buffer, ++ unsigned int tx_len, unsigned char *rx_buffer, ++ unsigned int rx_len, ++ unsigned int *actual_rx) ++{ ++ unsigned int rx_cnt = 0; ++ int ret = 0; ++ unsigned int BPW = 4; ++ bool eop_found = false; ++ unsigned char *eop; ++ unsigned char *ptr; ++ unsigned char *rxbuf = rx_buffer; ++ int add_byte = 0; ++ unsigned long ticks; ++ unsigned long timeout; ++ ++ /* send command */ ++ ret = spi_write(dev->dev, dev->chipselect, tx_len, tx_buffer); ++ if (ret) ++ return -EBUSY; ++ ++ timeout = rte_get_timer_cycles() + ++ msecs_to_timer_cycles(2000); ++ ++ /* read out data */ ++ while (rx_cnt < rx_len) { ++ ret = spi_read(dev->dev, dev->chipselect, BPW, rxbuf); ++ if (ret) ++ return -EBUSY; ++ ++ /* skip all of invalid data */ ++ if (!eop_found && all_idle_data(rxbuf)) { ++ ticks = rte_get_timer_cycles(); ++ if (!time_after(ticks, timeout)) { ++ continue; ++ } else { ++ dev_err(dev, "read spi data timeout\n"); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ rx_cnt += BPW; ++ if (!eop_found) { ++ /* EOP is found, we read 2 more bytes and exit. */ ++ eop = find_eop(rxbuf, BPW); ++ if (eop) { ++ if ((BPW + rxbuf - eop) > 2) { ++ /* ++ * check if the last 2 bytes are already ++ * received in current word. ++ */ ++ break; ++ } else if ((BPW + rxbuf - eop) == 2) { ++ /* ++ * skip if last byte is not SPI_BYTE_ESC ++ * or SPI_PACKET_ESC. this is the valid ++ * end of a response too. ++ */ ++ ptr = eop + 1; ++ ++ if (*ptr != SPI_BYTE_ESC && ++ *ptr != SPI_PACKET_ESC) ++ break; ++ ++ add_byte = 1; ++ } else { ++ add_byte = 2; ++ } ++ ++ rx_len = min(rx_len, ++ IFPGA_ALIGN(rx_cnt + ++ add_byte, BPW)); ++ eop_found = true; ++ } ++ } ++ rxbuf += BPW; ++ } ++ ++ *actual_rx = rx_cnt; ++ print_buffer("found valid data:", rx_buffer, rx_cnt); ++ ++ return ret; ++} ++ + static int byte_to_core_convert(struct spi_transaction_dev *dev, + unsigned int send_len, unsigned char *send_data, + unsigned int resp_len, unsigned char *resp_data, +@@ -148,15 +209,9 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, + unsigned char *resp_packet = dev->buffer->bytes_resp; + unsigned char *p; + unsigned char current_byte; +- unsigned char *tx_buffer; + unsigned int tx_len = 0; +- unsigned char *rx_buffer; +- unsigned int rx_len = 0; +- int retry = 0; +- int spi_flags; +- unsigned long timeout = msecs_to_timer_cycles(1000); +- unsigned long ticks; + unsigned int resp_max_len = 2 * resp_len; ++ unsigned int actual_rx; + + print_buffer("before bytes:", send_data, send_len); + +@@ -166,7 +221,7 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, current_byte = send_data[i]; switch (current_byte) { case SPI_BYTE_IDLE: @@ -66646,11 +92646,194 @@ index 013efee3e6..d13d2fbc83 100644 *p++ = xor_20(current_byte); break; case SPI_BYTE_ESC: +@@ -190,48 +245,15 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, + + print_buffer("after order to spi:", send_packet, tx_len); + +- /* call spi */ +- tx_buffer = send_packet; +- rx_buffer = resp_packet; +- rx_len = resp_max_len; +- spi_flags = SPI_NOT_FOUND; +- +-read_again: +- ret = spi_command(dev->dev, dev->chipselect, tx_len, tx_buffer, +- rx_len, rx_buffer); ++ ret = do_spi_txrx(dev, send_packet, tx_len, resp_packet, ++ resp_max_len, &actual_rx); + if (ret) +- return -EBUSY; +- +- print_buffer("read from spi:", rx_buffer, rx_len); +- +- /* look for SOP firstly*/ +- ret = resp_find_sop_eop(rx_buffer, rx_len - 1, spi_flags); +- if (ret != SPI_FOUND_EOP) { +- tx_buffer = NULL; +- tx_len = 0; +- ticks = rte_get_timer_cycles(); +- if (time_after(ticks, timeout) && +- retry++ > SPI_MAX_RETRY) { +- dev_err(NULL, "Have retry %d, found invalid packet data\n", +- retry); +- return -EBUSY; +- } +- +- if (ret == SPI_FOUND_SOP) { +- rx_buffer += rx_len; +- resp_max_len += rx_len; +- } +- +- spi_flags = ret; +- goto read_again; +- } +- +- print_buffer("found valid data:", resp_packet, resp_max_len); ++ return ret; + + /* analyze response packet */ + i = 0; + p = resp_data; +- while (i < resp_max_len) { ++ while (i < actual_rx) { + current_byte = resp_packet[i]; + switch (current_byte) { + case SPI_BYTE_IDLE: +@@ -337,9 +359,13 @@ static int packet_to_byte_conver(struct spi_transaction_dev *dev, + current_byte = resp_packet[i]; + + switch (current_byte) { +- case SPI_PACKET_ESC: +- case SPI_PACKET_CHANNEL: + case SPI_PACKET_SOP: ++ dev_err(dev, "error on get SOP after SOP\n"); ++ return -EINVAL; ++ case SPI_PACKET_CHANNEL: ++ i += 2; ++ break; ++ case SPI_PACKET_ESC: + i++; + current_byte = resp_packet[i]; + *p++ = xor_20(current_byte); +@@ -348,23 +374,30 @@ static int packet_to_byte_conver(struct spi_transaction_dev *dev, + case SPI_PACKET_EOP: + i++; + current_byte = resp_packet[i]; +- if (current_byte == SPI_PACKET_ESC || +- current_byte == SPI_PACKET_CHANNEL || +- current_byte == SPI_PACKET_SOP) { ++ switch (current_byte) { ++ case SPI_PACKET_ESC: + i++; + current_byte = resp_packet[i]; + *p++ = xor_20(current_byte); +- } else ++ break; ++ case SPI_PACKET_CHANNEL: ++ case SPI_PACKET_SOP: ++ case SPI_PACKET_EOP: ++ dev_err(dev, "error get SOP/EOP after EOP\n"); ++ return -EINVAL; ++ default: + *p++ = current_byte; +- i = valid_resp_len; +- break; ++ break; ++ } ++ goto done; ++ + default: + *p++ = current_byte; + i++; + } +- + } + ++done: + *valid = p - resp_buf; + + print_buffer("after packet:", resp_buf, *valid); diff --git a/dpdk/drivers/raw/ifpga/ifpga_rawdev.c b/dpdk/drivers/raw/ifpga/ifpga_rawdev.c -index b8701e155b..0c5392d082 100644 +index b8701e155b..0d6119c915 100644 --- a/dpdk/drivers/raw/ifpga/ifpga_rawdev.c +++ b/dpdk/drivers/raw/ifpga/ifpga_rawdev.c -@@ -237,8 +237,9 @@ static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev, +@@ -76,13 +76,9 @@ static const struct rte_pci_id pci_ifpga_map[] = { + + static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM]; + +-static int ifpga_monitor_start; ++static int ifpga_monitor_refcnt; + static pthread_t ifpga_monitor_start_thread; + +-#define IFPGA_MAX_IRQ 12 +-/* 0 for FME interrupt, others are reserved for AFU irq */ +-static struct rte_intr_handle ifpga_irq_handle[IFPGA_MAX_IRQ]; +- + static struct ifpga_rawdev * + ifpga_rawdev_allocate(struct rte_rawdev *rawdev); + static int set_surprise_link_check_aer( +@@ -90,6 +86,7 @@ static int set_surprise_link_check_aer( + static int ifpga_pci_find_next_ext_capability(unsigned int fd, + int start, int cap); + static int ifpga_pci_find_ext_capability(unsigned int fd, int cap); ++static void fme_interrupt_handler(void *param); + + struct ifpga_rawdev * + ifpga_rawdev_get(const struct rte_rawdev *rawdev) +@@ -126,6 +123,7 @@ ifpga_rawdev_allocate(struct rte_rawdev *rawdev) + { + struct ifpga_rawdev *dev; + uint16_t dev_id; ++ int i = 0; + + dev = ifpga_rawdev_get(rawdev); + if (dev != NULL) { +@@ -142,6 +140,11 @@ ifpga_rawdev_allocate(struct rte_rawdev *rawdev) + dev = &ifpga_rawdevices[dev_id]; + dev->rawdev = rawdev; + dev->dev_id = dev_id; ++ for (i = 0; i < IFPGA_MAX_IRQ; i++) ++ dev->intr_handle[i] = NULL; ++ dev->poll_enabled = 0; ++ for (i = 0; i < IFPGA_MAX_VDEV; i++) ++ dev->vdev_name[i] = NULL; + + return dev; + } +@@ -215,15 +218,15 @@ static int ifpga_get_dev_vendor_id(const char *bdf, + + return 0; + } +-static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev, +- const char *bdf) ++static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev) + { +- char path[1024] = "/sys/bus/pci/devices/0000:"; ++ struct opae_adapter *adapter = NULL; ++ char path[1024] = "/sys/bus/pci/devices/"; + char link[1024], link1[1024]; + char dir[1024] = "/sys/devices/"; + char *c; + int ret; +- char sub_brg_bdf[4][16]; ++ char sub_brg_bdf[4][16] = {{0}}; + int point; + DIR *dp = NULL; + struct dirent *entry; +@@ -231,14 +234,20 @@ static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev, + + unsigned int dom, bus, dev; + int func; +- uint32_t dev_id, vendor_id; ++ uint32_t dev_id = 0; ++ uint32_t vendor_id = 0; + +- strlcat(path, bdf, sizeof(path)); ++ adapter = ifpga_dev ? ifpga_rawdev_get_priv(ifpga_dev->rawdev) : NULL; ++ if (!adapter) ++ return -ENODEV; ++ ++ strlcat(path, adapter->name, sizeof(path)); memset(link, 0, sizeof(link)); memset(link1, 0, sizeof(link1)); ret = readlink(path, link, (sizeof(link)-1)); @@ -66661,7 +92844,142 @@ index b8701e155b..0c5392d082 100644 strlcpy(link1, link, sizeof(link1)); memset(ifpga_dev->parent_bdf, 0, 16); point = strlen(link); -@@ -779,7 +780,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, +@@ -382,7 +391,7 @@ ifpga_monitor_sensor(struct rte_rawdev *raw_dev, + /* monitor temperature sensors */ + if (!strcmp(sensor->name, "Board Temperature") || + !strcmp(sensor->name, "FPGA Die Temperature")) { +- IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n", ++ IFPGA_RAWDEV_PMD_DEBUG("read sensor %s %d %d %d\n", + sensor->name, value, sensor->high_warn, + sensor->high_fatal); + +@@ -424,7 +433,7 @@ static int set_surprise_link_check_aer( + bool enable = 0; + uint32_t aer_new0, aer_new1; + +- if (!ifpga_rdev) { ++ if (!ifpga_rdev || !ifpga_rdev->rawdev) { + printf("\n device does not exist\n"); + return -EFAULT; + } +@@ -503,11 +512,11 @@ ifpga_rawdev_gsd_handle(__rte_unused void *param) + int gsd_enable, ret; + #define MS 1000 + +- while (1) { ++ while (ifpga_monitor_refcnt) { + gsd_enable = 0; + for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { + ifpga_rdev = &ifpga_rawdevices[i]; +- if (ifpga_rdev->rawdev) { ++ if (ifpga_rdev->poll_enabled) { + ret = set_surprise_link_check_aer(ifpga_rdev, + gsd_enable); + if (ret == 1 && !gsd_enable) { +@@ -527,30 +536,45 @@ ifpga_rawdev_gsd_handle(__rte_unused void *param) + } + + static int +-ifpga_monitor_start_func(void) ++ifpga_monitor_start_func(struct ifpga_rawdev *dev) + { + int ret; + +- if (ifpga_monitor_start == 0) { +- ret = pthread_create(&ifpga_monitor_start_thread, +- NULL, ++ if (!dev) ++ return -ENODEV; ++ ++ ret = ifpga_rawdev_fill_info(dev); ++ if (ret) ++ return ret; ++ ++ dev->poll_enabled = 1; ++ ++ if (ifpga_monitor_refcnt++ == 0) { ++ ret = rte_ctrl_thread_create(&ifpga_monitor_start_thread, ++ "ifpga-monitor", NULL, + ifpga_rawdev_gsd_handle, NULL); + if (ret) { ++ ifpga_monitor_start_thread = 0; + IFPGA_RAWDEV_PMD_ERR( +- "Fail to create ifpga nonitor thread"); ++ "Fail to create ifpga monitor thread"); + return -1; + } +- ifpga_monitor_start = 1; + } + + return 0; + } + static int +-ifpga_monitor_stop_func(void) ++ifpga_monitor_stop_func(struct ifpga_rawdev *dev) + { + int ret; + +- if (ifpga_monitor_start == 1) { ++ if (!dev || !dev->poll_enabled) ++ return 0; ++ ++ dev->poll_enabled = 0; ++ ++ if ((--ifpga_monitor_refcnt == 0) && ++ ifpga_monitor_start_thread) { + ret = pthread_cancel(ifpga_monitor_start_thread); + if (ret) + IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread"); +@@ -559,8 +583,6 @@ ifpga_monitor_stop_func(void) + if (ret) + IFPGA_RAWDEV_PMD_ERR("Can't join the thread"); + +- ifpga_monitor_start = 0; +- + return ret; + } + +@@ -719,7 +741,38 @@ ifpga_rawdev_stop(struct rte_rawdev *dev) + static int + ifpga_rawdev_close(struct rte_rawdev *dev) + { +- return dev ? 0:1; ++ struct ifpga_rawdev *ifpga_rdev = NULL; ++ struct opae_adapter *adapter; ++ struct opae_manager *mgr; ++ char *vdev_name = NULL; ++ int i, ret = 0; ++ ++ if (dev) { ++ ifpga_rdev = ifpga_rawdev_get(dev); ++ if (ifpga_rdev) { ++ for (i = 0; i < IFPGA_MAX_VDEV; i++) { ++ vdev_name = ifpga_rdev->vdev_name[i]; ++ if (vdev_name) ++ rte_vdev_uninit(vdev_name); ++ } ++ ifpga_monitor_stop_func(ifpga_rdev); ++ ifpga_rdev->rawdev = NULL; ++ } ++ adapter = ifpga_rawdev_get_priv(dev); ++ if (adapter) { ++ mgr = opae_adapter_get_mgr(adapter); ++ if (ifpga_rdev && mgr) { ++ if (ifpga_unregister_msix_irq(ifpga_rdev, ++ IFPGA_FME_IRQ, 0, ++ fme_interrupt_handler, mgr) < 0) ++ ret = -EINVAL; ++ } ++ opae_adapter_destroy(adapter); ++ opae_adapter_data_free(adapter->data); ++ } ++ } ++ ++ return ret; + } + + static int +@@ -779,7 +832,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, int file_fd; int ret = 0; ssize_t buffer_size; @@ -66670,7 +92988,7 @@ index b8701e155b..0c5392d082 100644 u64 pr_error; if (!file_name) -@@ -811,6 +812,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, +@@ -811,6 +864,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, ret = -ENOMEM; goto close_fd; } @@ -66678,7 +92996,7 @@ index b8701e155b..0c5392d082 100644 /*read the raw data*/ if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) { -@@ -828,8 +830,8 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, +@@ -828,8 +882,8 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, } free_buffer: @@ -66689,105 +93007,452 @@ index b8701e155b..0c5392d082 100644 close_fd: close(file_fd); file_fd = 0; -@@ -1336,17 +1338,18 @@ int - ifpga_unregister_msix_irq(enum ifpga_irq_type type, +@@ -1333,35 +1387,63 @@ fme_interrupt_handler(void *param) + } + + int +-ifpga_unregister_msix_irq(enum ifpga_irq_type type, ++ifpga_unregister_msix_irq(struct ifpga_rawdev *dev, enum ifpga_irq_type type, int vec_start, rte_intr_callback_fn handler, void *arg) { - struct rte_intr_handle intr_handle; -+ struct rte_intr_handle *intr_handle; ++ struct rte_intr_handle **intr_handle; ++ int rc = 0; ++ int i = vec_start + 1; ++ ++ if (!dev) ++ return -ENODEV; if (type == IFPGA_FME_IRQ) - intr_handle = ifpga_irq_handle[0]; -+ intr_handle = &ifpga_irq_handle[0]; ++ intr_handle = (struct rte_intr_handle **)&dev->intr_handle[0]; else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; -+ intr_handle = &ifpga_irq_handle[vec_start + 1]; ++ intr_handle = (struct rte_intr_handle **)&dev->intr_handle[i]; + else -+ return 0; ++ return -EINVAL; ++ ++ if ((*intr_handle) == NULL) { ++ IFPGA_RAWDEV_PMD_ERR("%s interrupt %d not registered\n", ++ type == IFPGA_FME_IRQ ? "FME" : "AFU", ++ type == IFPGA_FME_IRQ ? 0 : vec_start); ++ return -ENOENT; ++ } - rte_intr_efd_disable(&intr_handle); -+ rte_intr_efd_disable(intr_handle); ++ rte_intr_efd_disable(*intr_handle); - return rte_intr_callback_unregister(&intr_handle, - handler, arg); -+ return rte_intr_callback_unregister(intr_handle, handler, arg); ++ ++ rc = rte_intr_callback_unregister(*intr_handle, handler, arg); ++ if (rc < 0) { ++ IFPGA_RAWDEV_PMD_ERR("Failed to unregister %s interrupt %d\n", ++ type == IFPGA_FME_IRQ ? "FME" : "AFU", ++ type == IFPGA_FME_IRQ ? 0 : vec_start); ++ } else { ++ rte_free(*intr_handle); ++ *intr_handle = NULL; ++ } ++ ++ return rc; } int -@@ -1356,7 +1359,7 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, +-ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, ++ifpga_register_msix_irq(struct ifpga_rawdev *dev, int port_id, + enum ifpga_irq_type type, int vec_start, int count, + rte_intr_callback_fn handler, const char *name, void *arg) { int ret; - struct rte_intr_handle intr_handle; -+ struct rte_intr_handle *intr_handle; ++ struct rte_intr_handle **intr_handle; struct opae_adapter *adapter; struct opae_manager *mgr; struct opae_accelerator *acc; -@@ -1370,26 +1373,29 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, ++ int i; + +- adapter = ifpga_rawdev_get_priv(dev); ++ if (!dev || !dev->rawdev) ++ return -ENODEV; ++ ++ adapter = ifpga_rawdev_get_priv(dev->rawdev); + if (!adapter) + return -ENODEV; + +@@ -1370,26 +1452,37 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, return -ENODEV; if (type == IFPGA_FME_IRQ) { - intr_handle = ifpga_irq_handle[0]; -+ intr_handle = &ifpga_irq_handle[0]; ++ intr_handle = (struct rte_intr_handle **)&dev->intr_handle[0]; count = 1; - } else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + } else if (type == IFPGA_AFU_IRQ) { -+ intr_handle = &ifpga_irq_handle[vec_start + 1]; ++ i = vec_start + 1; ++ intr_handle = (struct rte_intr_handle **)&dev->intr_handle[i]; + } else { + return -EINVAL; + } - intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; -+ intr_handle->type = RTE_INTR_HANDLE_VFIO_MSIX; ++ if (*intr_handle) ++ return -EBUSY; - ret = rte_intr_efd_enable(&intr_handle, count); -+ ret = rte_intr_efd_enable(intr_handle, count); ++ *intr_handle = rte_zmalloc(NULL, sizeof(struct rte_intr_handle), 0); ++ if (!(*intr_handle)) ++ return -ENOMEM; ++ ++ (*intr_handle)->type = RTE_INTR_HANDLE_VFIO_MSIX; ++ ++ ret = rte_intr_efd_enable(*intr_handle, count); if (ret) return -ENODEV; - intr_handle.fd = intr_handle.efds[0]; -+ intr_handle->fd = intr_handle->efds[0]; ++ (*intr_handle)->fd = (*intr_handle)->efds[0]; IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", - name, intr_handle.vfio_dev_fd, - intr_handle.fd); -+ name, intr_handle->vfio_dev_fd, -+ intr_handle->fd); ++ name, (*intr_handle)->vfio_dev_fd, ++ (*intr_handle)->fd); if (type == IFPGA_FME_IRQ) { struct fpga_fme_err_irq_set err_irq_set; - err_irq_set.evtfd = intr_handle.efds[0]; -+ err_irq_set.evtfd = intr_handle->efds[0]; ++ err_irq_set.evtfd = (*intr_handle)->efds[0]; ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); if (ret) -@@ -1399,13 +1405,14 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, +@@ -1399,13 +1492,14 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, if (!acc) return -EINVAL; - ret = opae_acc_set_irq(acc, vec_start, count, intr_handle.efds); + ret = opae_acc_set_irq(acc, vec_start, count, -+ intr_handle->efds); ++ (*intr_handle)->efds); if (ret) return -EINVAL; } /* register interrupt handler using DPDK API */ - ret = rte_intr_callback_register(&intr_handle, -+ ret = rte_intr_callback_register(intr_handle, ++ ret = rte_intr_callback_register(*intr_handle, handler, (void *)arg); if (ret) return -EINVAL; -@@ -1558,7 +1565,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) - return -ENODEV; +@@ -1504,11 +1598,15 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev, + IFPGA_RAWDEV_PMD_INFO("this is a PF function"); + } - if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, -- fme_interrupt_handler, mgr)) -+ fme_interrupt_handler, mgr) < 0) +- ret = ifpga_register_msix_irq(rawdev, 0, IFPGA_FME_IRQ, 0, 0, ++ ret = ifpga_register_msix_irq(dev, 0, IFPGA_FME_IRQ, 0, 0, + fme_interrupt_handler, "fme_irq", mgr); + if (ret) + goto free_adapter_data; + ++ ret = ifpga_monitor_start_func(dev); ++ if (ret) ++ goto free_adapter_data; ++ + return ret; + + free_adapter_data: +@@ -1527,8 +1625,6 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) + int ret; + struct rte_rawdev *rawdev; + char name[RTE_RAWDEV_NAME_MAX_LEN]; +- struct opae_adapter *adapter; +- struct opae_manager *mgr; + + if (!pci_dev) { + IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); +@@ -1549,21 +1645,6 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) return -EINVAL; + } + +- adapter = ifpga_rawdev_get_priv(rawdev); +- if (!adapter) +- return -ENODEV; +- +- mgr = opae_adapter_get_mgr(adapter); +- if (!mgr) +- return -ENODEV; +- +- if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, +- fme_interrupt_handler, mgr)) +- return -EINVAL; +- +- opae_adapter_data_free(adapter->data); +- opae_adapter_free(adapter); +- + /* rte_rawdev_close is called by pmd_release */ + ret = rte_rawdev_pmd_release(rawdev); + if (ret) +@@ -1583,7 +1664,7 @@ ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + static int + ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev) + { +- ifpga_monitor_stop_func(); ++ IFPGA_RAWDEV_PMD_INFO("remove pci_dev %s", pci_dev->device.name); + return ifpga_rawdev_destroy(pci_dev); + } + +@@ -1631,80 +1712,117 @@ static int ifpga_rawdev_get_string_arg(const char *key __rte_unused, + + return 0; + } ++ + static int +-ifpga_cfg_probe(struct rte_vdev_device *dev) ++ifpga_vdev_parse_devargs(struct rte_devargs *devargs, ++ struct ifpga_vdev_args *args) + { +- struct rte_devargs *devargs; +- struct rte_kvargs *kvlist = NULL; +- struct rte_rawdev *rawdev = NULL; +- struct ifpga_rawdev *ifpga_dev; +- int port; ++ struct rte_kvargs *kvlist; + char *name = NULL; +- const char *bdf; +- char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; +- int ret = -1; ++ int port = 0; ++ int ret = -EINVAL; + +- devargs = dev->device.devargs; ++ if (!devargs || !args) ++ return ret; + + kvlist = rte_kvargs_parse(devargs->args, valid_args); + if (!kvlist) { +- IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param"); +- goto end; ++ IFPGA_RAWDEV_PMD_ERR("error when parsing devargs"); ++ return ret; + } + + if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) { + if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME, +- &ifpga_rawdev_get_string_arg, +- &name) < 0) { ++ &ifpga_rawdev_get_string_arg, &name) < 0) { + IFPGA_RAWDEV_PMD_ERR("error to parse %s", +- IFPGA_ARG_NAME); ++ IFPGA_ARG_NAME); + goto end; ++ } else { ++ strlcpy(args->bdf, name, sizeof(args->bdf)); ++ rte_free(name); + } + } else { + IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", +- IFPGA_ARG_NAME); ++ IFPGA_ARG_NAME); + goto end; + } + + if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) { +- if (rte_kvargs_process(kvlist, +- IFPGA_ARG_PORT, +- &rte_ifpga_get_integer32_arg, +- &port) < 0) { ++ if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT, ++ &rte_ifpga_get_integer32_arg, &port) < 0) { + IFPGA_RAWDEV_PMD_ERR("error to parse %s", + IFPGA_ARG_PORT); + goto end; ++ } else { ++ args->port = port; + } + } else { + IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", +- IFPGA_ARG_PORT); ++ IFPGA_ARG_PORT); + goto end; + } + ++ ret = 0; ++ ++end: ++ rte_kvargs_free(kvlist); ++ ++ return ret; ++} ++ ++static int ++ifpga_cfg_probe(struct rte_vdev_device *vdev) ++{ ++ struct rte_rawdev *rawdev = NULL; ++ struct ifpga_rawdev *ifpga_dev; ++ struct ifpga_vdev_args args; ++ char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; ++ const char *vdev_name = NULL; ++ int i, n, ret = 0; ++ ++ vdev_name = rte_vdev_device_name(vdev); ++ if (!vdev_name) ++ return -EINVAL; ++ ++ IFPGA_RAWDEV_PMD_INFO("probe ifpga virtual device %s", vdev_name); ++ ++ ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args); ++ if (ret) ++ return ret; ++ + memset(dev_name, 0, sizeof(dev_name)); +- snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name); ++ snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf); + rawdev = rte_rawdev_pmd_get_named_dev(dev_name); + if (!rawdev) +- goto end; ++ return -ENODEV; + ifpga_dev = ifpga_rawdev_get(rawdev); + if (!ifpga_dev) +- goto end; +- bdf = name; +- ifpga_rawdev_fill_info(ifpga_dev, bdf); ++ return -ENODEV; ++ ++ for (i = 0; i < IFPGA_MAX_VDEV; i++) { ++ if (ifpga_dev->vdev_name[i] == NULL) { ++ n = strlen(vdev_name) + 1; ++ ifpga_dev->vdev_name[i] = rte_malloc(NULL, n, 0); ++ if (ifpga_dev->vdev_name[i] == NULL) ++ return -ENOMEM; ++ strlcpy(ifpga_dev->vdev_name[i], vdev_name, n); ++ break; ++ } ++ } + +- ifpga_monitor_start_func(); ++ if (i >= IFPGA_MAX_VDEV) { ++ IFPGA_RAWDEV_PMD_ERR("Can't create more virtual device!"); ++ return -ENOENT; ++ } + +- memset(dev_name, 0, sizeof(dev_name)); + snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", +- port, name); +- ++ args.port, args.bdf); + ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME), +- dev_name, devargs->args); +-end: +- if (kvlist) +- rte_kvargs_free(kvlist); +- if (name) +- free(name); ++ dev_name, vdev->device.devargs->args); ++ if (ret) { ++ rte_free(ifpga_dev->vdev_name[i]); ++ ifpga_dev->vdev_name[i] = NULL; ++ } + + return ret; + } +@@ -1712,10 +1830,47 @@ ifpga_cfg_probe(struct rte_vdev_device *dev) + static int + ifpga_cfg_remove(struct rte_vdev_device *vdev) + { +- IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p", +- vdev); ++ struct rte_rawdev *rawdev = NULL; ++ struct ifpga_rawdev *ifpga_dev; ++ struct ifpga_vdev_args args; ++ char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; ++ const char *vdev_name = NULL; ++ char *tmp_vdev = NULL; ++ int i, ret = 0; + +- return 0; ++ vdev_name = rte_vdev_device_name(vdev); ++ if (!vdev_name) ++ return -EINVAL; ++ ++ IFPGA_RAWDEV_PMD_INFO("remove ifpga virtual device %s", vdev_name); ++ ++ ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args); ++ if (ret) ++ return ret; ++ ++ memset(dev_name, 0, sizeof(dev_name)); ++ snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf); ++ rawdev = rte_rawdev_pmd_get_named_dev(dev_name); ++ if (!rawdev) ++ return -ENODEV; ++ ifpga_dev = ifpga_rawdev_get(rawdev); ++ if (!ifpga_dev) ++ return -ENODEV; ++ ++ snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", ++ args.port, args.bdf); ++ ret = rte_eal_hotplug_remove(RTE_STR(IFPGA_BUS_NAME), dev_name); ++ ++ for (i = 0; i < IFPGA_MAX_VDEV; i++) { ++ tmp_vdev = ifpga_dev->vdev_name[i]; ++ if (tmp_vdev && !strcmp(tmp_vdev, vdev_name)) { ++ free(tmp_vdev); ++ ifpga_dev->vdev_name[i] = NULL; ++ break; ++ } ++ } ++ ++ return ret; + } + + static struct rte_vdev_driver ifpga_cfg_driver = { +diff --git a/dpdk/drivers/raw/ifpga/ifpga_rawdev.h b/dpdk/drivers/raw/ifpga/ifpga_rawdev.h +index 7754beb02b..8929bd7407 100644 +--- a/dpdk/drivers/raw/ifpga/ifpga_rawdev.h ++++ b/dpdk/drivers/raw/ifpga/ifpga_rawdev.h +@@ -48,6 +48,8 @@ ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev) + + #define IFPGA_RAWDEV_MSIX_IRQ_NUM 7 + #define IFPGA_RAWDEV_NUM 32 ++#define IFPGA_MAX_VDEV 4 ++#define IFPGA_MAX_IRQ 12 + + struct ifpga_rawdev { + int dev_id; +@@ -57,6 +59,17 @@ struct ifpga_rawdev { + uint32_t aer_old[2]; + char fvl_bdf[8][16]; + char parent_bdf[16]; ++ /* 0 for FME interrupt, others are reserved for AFU irq */ ++ void *intr_handle[IFPGA_MAX_IRQ]; ++ /* enable monitor thread poll device's sensors or not */ ++ int poll_enabled; ++ /* name of virtual devices created on raw device */ ++ char *vdev_name[IFPGA_MAX_VDEV]; ++}; ++ ++struct ifpga_vdev_args { ++ char bdf[PCI_PRI_STR_SIZE]; ++ int port; + }; + + struct ifpga_rawdev * +@@ -68,12 +81,12 @@ enum ifpga_irq_type { + }; + + int +-ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, ++ifpga_register_msix_irq(struct ifpga_rawdev *dev, int port_id, + enum ifpga_irq_type type, int vec_start, int count, + rte_intr_callback_fn handler, const char *name, + void *arg); + int +-ifpga_unregister_msix_irq(enum ifpga_irq_type type, ++ifpga_unregister_msix_irq(struct ifpga_rawdev *dev, enum ifpga_irq_type type, + int vec_start, rte_intr_callback_fn handler, void *arg); - opae_adapter_data_free(adapter->data); + #endif /* _IFPGA_RAWDEV_H_ */ diff --git a/dpdk/drivers/raw/ifpga/meson.build b/dpdk/drivers/raw/ifpga/meson.build index 206136ff48..c267373e5e 100644 --- a/dpdk/drivers/raw/ifpga/meson.build @@ -66841,7 +93506,7 @@ index af8414b34c..a9b762330a 100644 .xstats_get = ioat_xstats_get, .xstats_get_names = ioat_xstats_get_names, diff --git a/dpdk/drivers/raw/ntb/ntb.c b/dpdk/drivers/raw/ntb/ntb.c -index ad7f6abfd3..dd0b72f8c5 100644 +index ad7f6abfd3..c25608ee8a 100644 --- a/dpdk/drivers/raw/ntb/ntb.c +++ b/dpdk/drivers/raw/ntb/ntb.c @@ -683,8 +683,8 @@ ntb_enqueue_bufs(struct rte_rawdev *dev, @@ -66864,6 +93529,67 @@ index ad7f6abfd3..dd0b72f8c5 100644 /* update queue stats */ off = NTB_XSTATS_NUM * ((size_t)context + 1); +@@ -894,6 +894,11 @@ ntb_dev_start(struct rte_rawdev *dev) + + hw->peer_mw_base = rte_zmalloc("ntb_peer_mw_base", hw->mw_cnt * + sizeof(uint64_t), 0); ++ if (hw->peer_mw_base == NULL) { ++ NTB_LOG(ERR, "Cannot allocate memory for peer mw base."); ++ ret = -ENOMEM; ++ goto err_q_init; ++ } + + if (hw->ntb_ops->spad_read == NULL) { + ret = -ENOTSUP; +@@ -1051,6 +1056,10 @@ ntb_attr_set(struct rte_rawdev *dev, const char *attr_name, + if (hw->ntb_ops->spad_write == NULL) + return -ENOTSUP; + index = atoi(&attr_name[NTB_SPAD_USER_LEN]); ++ if (index < 0 || index >= NTB_SPAD_USER_MAX_NUM) { ++ NTB_LOG(ERR, "Invalid attribute (%s)", attr_name); ++ return -EINVAL; ++ } + (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index], + 1, attr_value); + NTB_LOG(DEBUG, "Set attribute (%s) Value (%" PRIu64 ")", +@@ -1145,6 +1154,10 @@ ntb_attr_get(struct rte_rawdev *dev, const char *attr_name, + if (hw->ntb_ops->spad_read == NULL) + return -ENOTSUP; + index = atoi(&attr_name[NTB_SPAD_USER_LEN]); ++ if (index < 0 || index >= NTB_SPAD_USER_MAX_NUM) { ++ NTB_LOG(ERR, "Attribute (%s) out of range", attr_name); ++ return -EINVAL; ++ } + *attr_value = (*hw->ntb_ops->spad_read)(dev, + hw->spad_user_list[index], 0); + NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")", +@@ -1358,6 +1371,10 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev) + + /* Init doorbell. */ + hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t); ++ /* Clear all valid doorbell bits before registering intr handler */ ++ if (hw->ntb_ops->db_clear == NULL) ++ return -ENOTSUP; ++ (*hw->ntb_ops->db_clear)(dev, hw->db_valid_mask); + + intr_handle = &pci_dev->intr_handle; + /* Register callback func to eal lib */ +diff --git a/dpdk/drivers/raw/ntb/ntb_hw_intel.c b/dpdk/drivers/raw/ntb/ntb_hw_intel.c +index e7f8667cd7..88fe6a3794 100644 +--- a/dpdk/drivers/raw/ntb/ntb_hw_intel.c ++++ b/dpdk/drivers/raw/ntb/ntb_hw_intel.c +@@ -79,6 +79,11 @@ intel_ntb_dev_init(const struct rte_rawdev *dev) + + hw->mw_size = rte_zmalloc("ntb_mw_size", + hw->mw_cnt * sizeof(uint64_t), 0); ++ if (hw->mw_size == NULL) { ++ NTB_LOG(ERR, "Cannot allocate memory for mw size."); ++ return -ENOMEM; ++ } ++ + for (i = 0; i < hw->mw_cnt; i++) { + bar = intel_ntb_bar[i]; + hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len; diff --git a/dpdk/drivers/raw/skeleton/skeleton_rawdev.c b/dpdk/drivers/raw/skeleton/skeleton_rawdev.c index 586183a5b8..1daf0fecd2 100644 --- a/dpdk/drivers/raw/skeleton/skeleton_rawdev.c @@ -66882,7 +93608,7 @@ index 586183a5b8..1daf0fecd2 100644 break; } diff --git a/dpdk/drivers/raw/skeleton/skeleton_rawdev_test.c b/dpdk/drivers/raw/skeleton/skeleton_rawdev_test.c -index 9ecfdee818..1190e28bb7 100644 +index 9ecfdee818..fa7f4fab5e 100644 --- a/dpdk/drivers/raw/skeleton/skeleton_rawdev_test.c +++ b/dpdk/drivers/raw/skeleton/skeleton_rawdev_test.c @@ -42,6 +42,12 @@ static int @@ -66898,23 +93624,27 @@ index 9ecfdee818..1190e28bb7 100644 count = rte_rawdev_count(); if (!count) { SKELDEV_TEST_INFO("\tNo existing rawdev; " -diff --git a/dpdk/examples/bbdev_app/Makefile b/dpdk/examples/bbdev_app/Makefile -index ead3f016b8..3c8eb75a4e 100644 ---- a/dpdk/examples/bbdev_app/Makefile -+++ b/dpdk/examples/bbdev_app/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API - +@@ -285,6 +291,7 @@ test_rawdev_attr_set_get(void) + dummy_value = &set_value; + *dummy_value = 200; + ret = rte_rawdev_set_attr(test_dev_id, "Test2", (uintptr_t)dummy_value); ++ RTE_TEST_ASSERT(!ret, "Unable to set an attribute (Test2)"); + + /* Check if attributes have been set */ + ret = rte_rawdev_get_attr(test_dev_id, "Test1", &ret_value); diff --git a/dpdk/examples/bbdev_app/main.c b/dpdk/examples/bbdev_app/main.c -index fb38dc3a72..68a46050c0 100644 +index fb38dc3a72..a5e69d5852 100644 --- a/dpdk/examples/bbdev_app/main.c +++ b/dpdk/examples/bbdev_app/main.c +@@ -8,7 +8,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include @@ -659,6 +659,8 @@ print_stats(struct stats_lcore_params *stats_lcore) print_lcore_stats(stats_lcore->lconf[l_id].lcore_stats, l_id); } @@ -66924,45 +93654,163 @@ index fb38dc3a72..68a46050c0 100644 free(xstats); free(xstats_names); } -diff --git a/dpdk/examples/bond/Makefile b/dpdk/examples/bond/Makefile -index 2030ca410a..4e4289e151 100644 ---- a/dpdk/examples/bond/Makefile -+++ b/dpdk/examples/bond/Makefile -@@ -24,7 +24,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API - -diff --git a/dpdk/examples/cmdline/Makefile b/dpdk/examples/cmdline/Makefile -index 0b6b54540a..9418b50b87 100644 ---- a/dpdk/examples/cmdline/Makefile -+++ b/dpdk/examples/cmdline/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1169,5 +1171,8 @@ main(int argc, char **argv) + ret |= rte_eal_wait_lcore(lcore_id); + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/distributor/Makefile b/dpdk/examples/distributor/Makefile -index 4192d8a4ae..5253780793a 100644 ---- a/dpdk/examples/distributor/Makefile -+++ b/dpdk/examples/distributor/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return ret; + } +diff --git a/dpdk/examples/bond/main.c b/dpdk/examples/bond/main.c +index ee8fa2d271..9243a85501 100644 +--- a/dpdk/examples/bond/main.c ++++ b/dpdk/examples/bond/main.c +@@ -379,7 +379,7 @@ static int lcore_main(__attribute__((unused)) void *arg1) + bond_ip = BOND_IP_1 | (BOND_IP_2 << 8) | + (BOND_IP_3 << 16) | (BOND_IP_4 << 24); + +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + + while (global_flag_stru_p->LcoreMainIsRunning) { + rte_spinlock_unlock(&global_flag_stru_p->lock); +@@ -460,7 +460,7 @@ static int lcore_main(__attribute__((unused)) void *arg1) + if (is_free == 0) + rte_pktmbuf_free(pkts[i]); + } +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + } + rte_spinlock_unlock(&global_flag_stru_p->lock); + printf("BYE lcore_main\n"); +@@ -575,7 +575,7 @@ static void cmd_start_parsed(__attribute__((unused)) void *parsed_result, + { + int slave_core_id = rte_lcore_id(); + +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + if (global_flag_stru_p->LcoreMainIsRunning == 0) { + if (rte_eal_get_lcore_state(global_flag_stru_p->LcoreMainCore) + != WAIT) { +@@ -595,7 +595,7 @@ static void cmd_start_parsed(__attribute__((unused)) void *parsed_result, + if ((slave_core_id >= RTE_MAX_LCORE) || (slave_core_id == 0)) + return; - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + global_flag_stru_p->LcoreMainIsRunning = 1; + rte_spinlock_unlock(&global_flag_stru_p->lock); + cmdline_printf(cl, +@@ -663,7 +663,7 @@ static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) + { +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + if (global_flag_stru_p->LcoreMainIsRunning == 0) { + cmdline_printf(cl, + "lcore_main not running on core:%d\n", +@@ -704,7 +704,7 @@ static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) + { +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + if (global_flag_stru_p->LcoreMainIsRunning == 0) { + cmdline_printf(cl, + "lcore_main not running on core:%d\n", +@@ -766,7 +766,7 @@ static void cmd_show_parsed(__attribute__((unused)) void *parsed_result, + printf("\n"); + } + +- rte_spinlock_trylock(&global_flag_stru_p->lock); ++ rte_spinlock_lock(&global_flag_stru_p->lock); + cmdline_printf(cl, + "Active_slaves:%d " + "packets received:Tot:%d Arp:%d IPv4:%d\n", +@@ -879,5 +879,9 @@ main(int argc, char *argv[]) + prompt(NULL); + + rte_delay_ms(100); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/cmdline/main.c b/dpdk/examples/cmdline/main.c +index f2f2e5a2f4..dd3bfab9d1 100644 +--- a/dpdk/examples/cmdline/main.c ++++ b/dpdk/examples/cmdline/main.c +@@ -37,5 +37,8 @@ int main(int argc, char **argv) + cmdline_interact(cl); + cmdline_stdin_exit(cl); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/distributor/main.c b/dpdk/examples/distributor/main.c +index 567c5e9891..4d5e137b99 100644 +--- a/dpdk/examples/distributor/main.c ++++ b/dpdk/examples/distributor/main.c +@@ -109,7 +109,7 @@ static inline int + port_init(uint16_t port, struct rte_mempool *mbuf_pool) + { + struct rte_eth_conf port_conf = port_conf_default; +- const uint16_t rxRings = 1, txRings = rte_lcore_count() - 1; ++ const uint16_t rxRings = 1, txRings = 1; + int retval; + uint16_t q; + uint16_t nb_rxd = RX_RING_SIZE; +@@ -265,8 +265,8 @@ lcore_rx(struct lcore_params *p) + * packets are then send straight to the tx core. + */ + #if 0 +- rte_distributor_process(d, bufs, nb_rx); +- const uint16_t nb_ret = rte_distributor_returned_pktsd, ++ rte_distributor_process(p->d, bufs, nb_rx); ++ const uint16_t nb_ret = rte_distributor_returned_pkts(p->d, + bufs, BURST_SIZE*2); + + app_stats.rx.returned_pkts += nb_ret; +@@ -935,5 +935,8 @@ main(int argc, char *argv[]) + rte_free(pd); + rte_free(pr); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/ethtool/ethtool-app/ethapp.c b/dpdk/examples/ethtool/ethtool-app/ethapp.c +index b6b967118e..62e400bba9 100644 +--- a/dpdk/examples/ethtool/ethtool-app/ethapp.c ++++ b/dpdk/examples/ethtool/ethtool-app/ethapp.c +@@ -527,7 +527,6 @@ pcmd_mtu_callback(void *ptr_params, + printf("Error: Invalid port number %i\n", params->port); + return; + } +- new_mtu = atoi(params->opt); + new_mtu = strtoul(params->opt, &ptr_parse_end, 10); + if (*ptr_parse_end != '\0' || + new_mtu < RTE_ETHER_MIN_MTU || +diff --git a/dpdk/examples/ethtool/ethtool-app/main.c b/dpdk/examples/ethtool/ethtool-app/main.c +index 29891012ac..608327170f 100644 +--- a/dpdk/examples/ethtool/ethtool-app/main.c ++++ b/dpdk/examples/ethtool/ethtool-app/main.c +@@ -298,5 +298,8 @@ int main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/ethtool/lib/rte_ethtool.c b/dpdk/examples/ethtool/lib/rte_ethtool.c index 667d7eaf27..db8150efd5 100644 --- a/dpdk/examples/ethtool/lib/rte_ethtool.c @@ -66978,19 +93826,6 @@ index 667d7eaf27..db8150efd5 100644 return 0; } -diff --git a/dpdk/examples/eventdev_pipeline/Makefile b/dpdk/examples/eventdev_pipeline/Makefile -index 96cd244378..95a8d0884a 100644 ---- a/dpdk/examples/eventdev_pipeline/Makefile -+++ b/dpdk/examples/eventdev_pipeline/Makefile -@@ -24,7 +24,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/eventdev_pipeline/main.c b/dpdk/examples/eventdev_pipeline/main.c index d3ff1bbe4f..a3eeb50a75 100644 --- a/dpdk/examples/eventdev_pipeline/main.c @@ -67197,22 +94032,20 @@ index 8e30393d09..6a4287602e 100644 static __rte_always_inline void exchange_mac(struct rte_mbuf *m) diff --git a/dpdk/examples/fips_validation/Makefile b/dpdk/examples/fips_validation/Makefile -index 1385e8cc8c..5bcf1872c4 100644 +index 1385e8cc8c..e5ae22b521 100644 --- a/dpdk/examples/fips_validation/Makefile +++ b/dpdk/examples/fips_validation/Makefile -@@ -31,7 +31,9 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) +@@ -33,6 +33,8 @@ CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) -+ -+CFLAGS += -DALLOW_EXPERIMENTAL_API + LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) ++CFLAGS += -DALLOW_EXPERIMENTAL_API ++ build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + diff --git a/dpdk/examples/fips_validation/fips_validation.c b/dpdk/examples/fips_validation/fips_validation.c -index 07ffa62e9e..701d87dc4d 100644 +index 07ffa62e9e..0bed91a821 100644 --- a/dpdk/examples/fips_validation/fips_validation.c +++ b/dpdk/examples/fips_validation/fips_validation.c @@ -92,6 +92,15 @@ fips_test_fetch_one_block(void) @@ -67356,6 +94189,15 @@ index 07ffa62e9e..701d87dc4d 100644 fprintf(info.fp_wr, "%s\n", info.vec[i]); } +@@ -460,7 +516,7 @@ parse_uint8_hex_str(const char *key, char *src, struct fips_val *val) + val->val = NULL; + } + +- val->val = rte_zmalloc(NULL, len, 0); ++ val->val = rte_zmalloc(NULL, len + 1, 0); + if (!val->val) + return -ENOMEM; + @@ -607,9 +663,16 @@ update_info_vec(uint32_t count) cb = &info.writeback_callbacks[0]; @@ -67472,10 +94314,31 @@ index 5b6737643a..f4c738c789 100644 return 0; diff --git a/dpdk/examples/fips_validation/main.c b/dpdk/examples/fips_validation/main.c -index 9a2c8da619..eadfdb4bac 100644 +index 9a2c8da619..739c93656f 100644 --- a/dpdk/examples/fips_validation/main.c +++ b/dpdk/examples/fips_validation/main.c -@@ -1030,6 +1030,11 @@ fips_mct_tdes_test(void) +@@ -118,6 +118,10 @@ cryptodev_fips_validate_app_int(void) + if (ret < 0) + goto error_exit; + ++ ret = rte_cryptodev_start(env.dev_id); ++ if (ret < 0) ++ goto error_exit; ++ + return 0; + + error_exit: +@@ -433,6 +437,9 @@ main(int argc, char *argv[]) + fips_test_clear(); + cryptodev_fips_validate_app_uninit(); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return ret; + + } +@@ -1030,6 +1037,11 @@ fips_mct_tdes_test(void) int test_mode = info.interim_info.tdes_data.test_mode; for (i = 0; i < TDES_EXTERN_ITER; i++) { @@ -67487,60 +94350,74 @@ index 9a2c8da619..eadfdb4bac 100644 if (i != 0) update_info_vec(i); -diff --git a/dpdk/examples/flow_classify/Makefile b/dpdk/examples/flow_classify/Makefile -index 6864941b3e..161d576b60 100644 ---- a/dpdk/examples/flow_classify/Makefile -+++ b/dpdk/examples/flow_classify/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API - -diff --git a/dpdk/examples/flow_filtering/Makefile b/dpdk/examples/flow_filtering/Makefile -index 6c51c0b7a0..0ce20d3485 100644 ---- a/dpdk/examples/flow_filtering/Makefile -+++ b/dpdk/examples/flow_filtering/Makefile -@@ -20,7 +20,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1365,7 +1377,6 @@ fips_mct_sha_test(void) + int ret; + uint32_t i, j; + +- val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0); + for (i = 0; i < SHA_MD_BLOCK; i++) + md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0); + +diff --git a/dpdk/examples/flow_classify/flow_classify.c b/dpdk/examples/flow_classify/flow_classify.c +index 1c12bbb2fd..7f0379e471 100644 +--- a/dpdk/examples/flow_classify/flow_classify.c ++++ b/dpdk/examples/flow_classify/flow_classify.c +@@ -284,7 +284,7 @@ lcore_main(struct flow_classifier *cls_app) + * for best performance. + */ + RTE_ETH_FOREACH_DEV(port) +- if (rte_eth_dev_socket_id(port) > 0 && ++ if (rte_eth_dev_socket_id(port) >= 0 && + rte_eth_dev_socket_id(port) != (int)rte_socket_id()) { + printf("\n\n"); + printf("WARNING: port %u is on remote NUMA node\n", +@@ -424,7 +424,7 @@ parse_ipv4_5tuple_rule(char *str, struct rte_eth_ntuple_filter *ntuple_filter) + &ntuple_filter->dst_ip, + &ntuple_filter->dst_ip_mask); + if (ret != 0) { +- flow_classify_log("failed to read source address/mask: %s\n", ++ flow_classify_log("failed to read destination address/mask: %s\n", + in[CB_FLD_DST_ADDR]); + return ret; + } +@@ -853,5 +853,8 @@ main(int argc, char *argv[]) + /* Call lcore_main on the master core only. */ + lcore_main(cls_app); - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/helloworld/Makefile b/dpdk/examples/helloworld/Makefile -index 16d82b02f0..9a07f89efc 100644 ---- a/dpdk/examples/helloworld/Makefile -+++ b/dpdk/examples/helloworld/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/flow_filtering/main.c b/dpdk/examples/flow_filtering/main.c +index cc9e7e7808..6188f9c6bb 100644 +--- a/dpdk/examples/flow_filtering/main.c ++++ b/dpdk/examples/flow_filtering/main.c +@@ -256,5 +256,8 @@ main(int argc, char **argv) - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/ioat/Makefile b/dpdk/examples/ioat/Makefile -index ef63f5d689..dd4930136e 100644 ---- a/dpdk/examples/ioat/Makefile -+++ b/dpdk/examples/ioat/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) + main_loop(); - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/helloworld/main.c b/dpdk/examples/helloworld/main.c +index c922cfbad7..d2f262b86b 100644 +--- a/dpdk/examples/helloworld/main.c ++++ b/dpdk/examples/helloworld/main.c +@@ -43,5 +43,9 @@ main(int argc, char **argv) + lcore_hello(NULL); + + rte_eal_mp_wait_lcore(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/ioat/ioatfwd.c b/dpdk/examples/ioat/ioatfwd.c -index e9117718fe..7971442b5d 100644 +index e9117718fe..087bdcf66a 100644 --- a/dpdk/examples/ioat/ioatfwd.c +++ b/dpdk/examples/ioat/ioatfwd.c @@ -168,7 +168,7 @@ print_stats(char *prgname) @@ -67640,21 +94517,18 @@ index e9117718fe..7971442b5d 100644 local_port_conf.rx_adv_conf.rss_conf.rss_hf &= dev_info.flow_type_rss_offloads; if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) -diff --git a/dpdk/examples/ip_fragmentation/Makefile b/dpdk/examples/ip_fragmentation/Makefile -index ede0c4f02b..d200cc627d 100644 ---- a/dpdk/examples/ip_fragmentation/Makefile -+++ b/dpdk/examples/ip_fragmentation/Makefile -@@ -23,7 +23,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1002,6 +1013,9 @@ main(int argc, char **argv) + rte_ring_free(cfg.ports[i].rx_to_tx_ring); + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + printf("Bye...\n"); + return 0; + } diff --git a/dpdk/examples/ip_fragmentation/main.c b/dpdk/examples/ip_fragmentation/main.c -index 104612339c..90e4d1ea4a 100644 +index 104612339c..435b6eca61 100644 --- a/dpdk/examples/ip_fragmentation/main.c +++ b/dpdk/examples/ip_fragmentation/main.c @@ -617,7 +617,7 @@ check_all_ports_link_status(uint32_t port_mask) @@ -67675,22 +94549,40 @@ index 104612339c..90e4d1ea4a 100644 static int check_ptype(int portid) { +@@ -1078,5 +1078,8 @@ main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/ip_pipeline/Makefile b/dpdk/examples/ip_pipeline/Makefile -index 3a0193818f..b8e086267b 100644 +index 3a0193818f..1e404ff5d0 100644 --- a/dpdk/examples/ip_pipeline/Makefile +++ b/dpdk/examples/ip_pipeline/Makefile -@@ -35,9 +35,9 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) +@@ -37,7 +37,7 @@ CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) + LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -CFLAGS += -I. +CFLAGS += -I. -DALLOW_EXPERIMENTAL_API -D_GNU_SOURCE OBJS := $(patsubst %.c,build/%.o,$(SRCS-y)) +diff --git a/dpdk/examples/ip_pipeline/main.c b/dpdk/examples/ip_pipeline/main.c +index 97d1e91c2b..95051fca49 100644 +--- a/dpdk/examples/ip_pipeline/main.c ++++ b/dpdk/examples/ip_pipeline/main.c +@@ -266,4 +266,7 @@ main(int argc, char **argv) + + kni_handle_request(); + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + } diff --git a/dpdk/examples/ip_pipeline/parser.c b/dpdk/examples/ip_pipeline/parser.c index 3fffeb5867..f043d6bf4f 100644 --- a/dpdk/examples/ip_pipeline/parser.c @@ -68101,21 +94993,8 @@ index 272fbbeed1..adb83167cd 100644 /* Read response */ status = rsp->status; -diff --git a/dpdk/examples/ip_reassembly/Makefile b/dpdk/examples/ip_reassembly/Makefile -index 3f2888b338..c7424da2b7 100644 ---- a/dpdk/examples/ip_reassembly/Makefile -+++ b/dpdk/examples/ip_reassembly/Makefile -@@ -23,7 +23,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/ip_reassembly/main.c b/dpdk/examples/ip_reassembly/main.c -index d59e6d02ff..29b34d0710 100644 +index d59e6d02ff..89ff1a06b6 100644 --- a/dpdk/examples/ip_reassembly/main.c +++ b/dpdk/examples/ip_reassembly/main.c @@ -736,7 +736,7 @@ check_all_ports_link_status(uint32_t port_mask) @@ -68127,23 +95006,28 @@ index d59e6d02ff..29b34d0710 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/ipsec-secgw/Makefile b/dpdk/examples/ipsec-secgw/Makefile -index a4977f61f8..38c456daa2 100644 ---- a/dpdk/examples/ipsec-secgw/Makefile -+++ b/dpdk/examples/ipsec-secgw/Makefile -@@ -33,7 +33,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API +@@ -1207,5 +1207,8 @@ main(int argc, char **argv) + return -1; + } ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/ipsec-secgw/ipsec-secgw.c b/dpdk/examples/ipsec-secgw/ipsec-secgw.c -index 3b5aaf6832..1493be9025 100644 +index 3b5aaf6832..ce57787a14 100644 --- a/dpdk/examples/ipsec-secgw/ipsec-secgw.c +++ b/dpdk/examples/ipsec-secgw/ipsec-secgw.c +@@ -170,7 +170,7 @@ static const struct option lgopts[] = { + static uint32_t enabled_port_mask; + static uint64_t enabled_cryptodev_mask = UINT64_MAX; + static uint32_t unprotected_port_mask; +-static int32_t promiscuous_on = 1; ++static int32_t promiscuous_on; + static int32_t numa_on = 1; /**< NUMA is enabled by default. */ + static uint32_t nb_lcores; + static uint32_t single_sa; @@ -1668,7 +1668,7 @@ check_all_ports_link_status(uint32_t port_mask) "Port%d Link Up - speed %u Mbps -%s\n", portid, link.link_speed, @@ -68153,6 +95037,14 @@ index 3b5aaf6832..1493be9025 100644 else printf("Port %d Link Down\n", portid); continue; +@@ -2543,5 +2543,7 @@ main(int32_t argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + return 0; + } diff --git a/dpdk/examples/ipsec-secgw/ipsec_process.c b/dpdk/examples/ipsec-secgw/ipsec_process.c index 2eb5c8b345..37f406d46c 100644 --- a/dpdk/examples/ipsec-secgw/ipsec_process.c @@ -68456,21 +95348,8 @@ index 7f046e3ed7..fcc6695388 100644 } return 0; -diff --git a/dpdk/examples/ipv4_multicast/Makefile b/dpdk/examples/ipv4_multicast/Makefile -index 92d3db0f4d..5e34bbba00 100644 ---- a/dpdk/examples/ipv4_multicast/Makefile -+++ b/dpdk/examples/ipv4_multicast/Makefile -@@ -23,7 +23,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/ipv4_multicast/main.c b/dpdk/examples/ipv4_multicast/main.c -index 63333b5b69..09d9270aff 100644 +index 63333b5b69..83bdeb7403 100644 --- a/dpdk/examples/ipv4_multicast/main.c +++ b/dpdk/examples/ipv4_multicast/main.c @@ -600,7 +600,7 @@ check_all_ports_link_status(uint32_t port_mask) @@ -68482,23 +95361,30 @@ index 63333b5b69..09d9270aff 100644 else printf("Port %d Link Down\n", portid); continue; +@@ -811,5 +811,8 @@ main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/kni/Makefile b/dpdk/examples/kni/Makefile -index c7ca96d8a0..10b42891da 100644 +index c7ca96d8a0..f687765510 100644 --- a/dpdk/examples/kni/Makefile +++ b/dpdk/examples/kni/Makefile -@@ -23,7 +23,9 @@ PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - CFLAGS += -DALLOW_EXPERIMENTAL_API +@@ -25,6 +25,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) -+ -+LDFLAGS += -pthread + LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) ++LDFLAGS += -pthread ++ build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + diff --git a/dpdk/examples/kni/main.c b/dpdk/examples/kni/main.c -index 5f713e6b22..7edc73ab91 100644 +index 5f713e6b22..a696a83578 100644 --- a/dpdk/examples/kni/main.c +++ b/dpdk/examples/kni/main.c @@ -158,6 +158,8 @@ print_stats(void) @@ -68584,43 +95470,73 @@ index 5f713e6b22..7edc73ab91 100644 /* Callback for request of configuring network interface up/down */ static int kni_config_network_interface(uint16_t port_id, uint8_t if_up) -diff --git a/dpdk/examples/l2fwd-cat/Makefile b/dpdk/examples/l2fwd-cat/Makefile -index b0e53c37e8..e8fdc46d74 100644 ---- a/dpdk/examples/l2fwd-cat/Makefile -+++ b/dpdk/examples/l2fwd-cat/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - LDFLAGS += -lpqos +@@ -1094,5 +1120,8 @@ main(int argc, char** argv) + kni_port_params_array[i] = NULL; + } ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/l2fwd-cat/l2fwd-cat.c b/dpdk/examples/l2fwd-cat/l2fwd-cat.c +index 6838f288c6..a583e13eca 100644 +--- a/dpdk/examples/l2fwd-cat/l2fwd-cat.c ++++ b/dpdk/examples/l2fwd-cat/l2fwd-cat.c +@@ -107,7 +107,7 @@ lcore_main(void) + * for best performance. + */ + RTE_ETH_FOREACH_DEV(port) +- if (rte_eth_dev_socket_id(port) > 0 && ++ if (rte_eth_dev_socket_id(port) >= 0 && + rte_eth_dev_socket_id(port) != + (int)rte_socket_id()) + printf("WARNING, port %u is on remote NUMA node to " +@@ -201,5 +201,8 @@ main(int argc, char *argv[]) + /* Call lcore_main on the master core only. */ + lcore_main(); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/l2fwd-crypto/Makefile b/dpdk/examples/l2fwd-crypto/Makefile -index 2f1405a72b..cafe778fc6 100644 +index 2f1405a72b..7c170cfb53 100644 --- a/dpdk/examples/l2fwd-crypto/Makefile +++ b/dpdk/examples/l2fwd-crypto/Makefile -@@ -22,7 +22,13 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) +@@ -24,6 +24,12 @@ CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) -+ + LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) + +CFLAGS += -DALLOW_EXPERIMENTAL_API +CONFIG_DEFINES = $(shell $(CC) $(CFLAGS) -dM -E - < /dev/null) +ifneq ($(findstring RTE_CRYPTO_SCHEDULER,$(CONFIG_DEFINES)),) +LDFLAGS_SHARED += -lrte_crypto_scheduler +endif - ++ build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + diff --git a/dpdk/examples/l2fwd-crypto/main.c b/dpdk/examples/l2fwd-crypto/main.c -index 61d78295d4..827da9b3e3 100644 +index 61d78295d4..d7692464e4 100644 --- a/dpdk/examples/l2fwd-crypto/main.c +++ b/dpdk/examples/l2fwd-crypto/main.c -@@ -334,6 +334,8 @@ print_stats(void) +@@ -252,11 +252,9 @@ struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; + struct l2fwd_crypto_statistics crypto_statistics[RTE_CRYPTO_MAX_DEVS]; + + /* A tsc-based timer responsible for triggering statistics printout */ +-#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ ++#define TIMER_MILLISECOND (rte_get_tsc_hz() / 1000) + #define MAX_TIMER_PERIOD 86400UL /* 1 day max */ +- +-/* default period is 10 seconds */ +-static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; ++#define DEFAULT_TIMER_PERIOD 10UL + + /* Print out statistics on packets dropped */ + static void +@@ -334,6 +332,8 @@ print_stats(void) total_packets_dropped, total_packets_errors); printf("\n====================================================\n"); @@ -68629,7 +95545,66 @@ index 61d78295d4..827da9b3e3 100644 } static int -@@ -1756,7 +1758,7 @@ check_all_ports_link_status(uint32_t port_mask) +@@ -614,12 +614,26 @@ l2fwd_simple_forward(struct rte_mbuf *m, uint16_t portid, + struct l2fwd_crypto_options *options) + { + uint16_t dst_port; ++ uint32_t pad_len; ++ struct rte_ipv4_hdr *ip_hdr; ++ uint32_t ipdata_offset = sizeof(struct rte_ether_hdr); + ++ ip_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(m, char *) + ++ ipdata_offset); + dst_port = l2fwd_dst_ports[portid]; + + if (options->mac_updating) + l2fwd_mac_updating(m, dst_port); + ++ if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) ++ rte_pktmbuf_trim(m, options->auth_xform.auth.digest_length); ++ ++ if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { ++ pad_len = m->pkt_len - rte_be_to_cpu_16(ip_hdr->total_length) - ++ ipdata_offset; ++ rte_pktmbuf_trim(m, pad_len); ++ } ++ + l2fwd_send_packet(m, dst_port); + } + +@@ -863,18 +877,17 @@ l2fwd_main_loop(struct l2fwd_crypto_options *options) + } + + /* if timer is enabled */ +- if (timer_period > 0) { ++ if (options->refresh_period > 0) { + + /* advance the timer */ + timer_tsc += diff_tsc; + + /* if timer has reached its timeout */ + if (unlikely(timer_tsc >= +- (uint64_t)timer_period)) { ++ options->refresh_period)) { + + /* do this only on master core */ +- if (lcore_id == rte_get_master_lcore() +- && options->refresh_period) { ++ if (lcore_id == rte_get_master_lcore()) { + print_stats(); + timer_tsc = 0; + } +@@ -1435,7 +1448,8 @@ l2fwd_crypto_default_options(struct l2fwd_crypto_options *options) + { + options->portmask = 0xffffffff; + options->nb_ports_per_lcore = 1; +- options->refresh_period = 10000; ++ options->refresh_period = DEFAULT_TIMER_PERIOD * ++ TIMER_MILLISECOND * 1000; + options->single_lcore = 0; + options->sessionless = 0; + +@@ -1756,7 +1770,7 @@ check_all_ports_link_status(uint32_t port_mask) "Port%d Link Up. Speed %u Mbps - %s\n", portid, link.link_speed, (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? @@ -68638,6 +95613,37 @@ index 61d78295d4..827da9b3e3 100644 else printf("Port %d Link Down\n", portid); continue; +@@ -2252,6 +2266,12 @@ initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports, + if (enabled_cdevs[cdev_id] == 0) + continue; + ++ if (check_cryptodev_mask(options, cdev_id) < 0) ++ continue; ++ ++ if (check_capabilities(options, cdev_id) < 0) ++ continue; ++ + retval = rte_cryptodev_socket_id(cdev_id); + + if (retval < 0) { +@@ -2617,7 +2637,7 @@ initialize_ports(struct l2fwd_crypto_options *options) + last_portid = portid; + } + +- l2fwd_enabled_port_mask |= (1 << portid); ++ l2fwd_enabled_port_mask |= (1ULL << portid); + enabled_portcount++; + } + +@@ -2806,5 +2826,8 @@ main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/l2fwd-crypto/meson.build b/dpdk/examples/l2fwd-crypto/meson.build index 6c852ad199..c08d8469b4 100644 --- a/dpdk/examples/l2fwd-crypto/meson.build @@ -68652,19 +95658,6 @@ index 6c852ad199..c08d8469b4 100644 allow_experimental_apis = true sources = files( 'main.c' -diff --git a/dpdk/examples/l2fwd-event/Makefile b/dpdk/examples/l2fwd-event/Makefile -index 4cdae36f17..bf0ee890d5 100644 ---- a/dpdk/examples/l2fwd-event/Makefile -+++ b/dpdk/examples/l2fwd-event/Makefile -@@ -28,7 +28,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/l2fwd-event/l2fwd_common.c b/dpdk/examples/l2fwd-event/l2fwd_common.c index 181301fe6b..ab341e55b2 100644 --- a/dpdk/examples/l2fwd-event/l2fwd_common.c @@ -68823,7 +95816,7 @@ index a3a3835582..2033c65e54 100644 rsrc->rx_queue_per_lcore) { rx_lcore_id++; diff --git a/dpdk/examples/l2fwd-event/main.c b/dpdk/examples/l2fwd-event/main.c -index 89a6bb9a44..7969a1c313 100644 +index 89a6bb9a44..5bfdcf42ef 100644 --- a/dpdk/examples/l2fwd-event/main.c +++ b/dpdk/examples/l2fwd-event/main.c @@ -263,7 +263,7 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc, @@ -68844,21 +95837,18 @@ index 89a6bb9a44..7969a1c313 100644 } static void -diff --git a/dpdk/examples/l2fwd-jobstats/Makefile b/dpdk/examples/l2fwd-jobstats/Makefile -index 73c91faa8d..c26803909f 100644 ---- a/dpdk/examples/l2fwd-jobstats/Makefile -+++ b/dpdk/examples/l2fwd-jobstats/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -581,6 +583,9 @@ main(int argc, char **argv) + printf(" Done\n"); + } + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + printf("Bye...\n"); - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + return 0; diff --git a/dpdk/examples/l2fwd-jobstats/main.c b/dpdk/examples/l2fwd-jobstats/main.c -index f975aa12d0..c2180c2d1c 100644 +index f975aa12d0..b50ba604eb 100644 --- a/dpdk/examples/l2fwd-jobstats/main.c +++ b/dpdk/examples/l2fwd-jobstats/main.c @@ -329,6 +329,9 @@ show_stats_cb(__rte_unused void *param) @@ -68880,21 +95870,17 @@ index f975aa12d0..c2180c2d1c 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/l2fwd-keepalive/Makefile b/dpdk/examples/l2fwd-keepalive/Makefile -index 94d1e58bb5..ea3a9cbbf3 100644 ---- a/dpdk/examples/l2fwd-keepalive/Makefile -+++ b/dpdk/examples/l2fwd-keepalive/Makefile -@@ -24,7 +24,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1025,5 +1028,8 @@ main(int argc, char **argv) + return -1; + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/l2fwd-keepalive/main.c b/dpdk/examples/l2fwd-keepalive/main.c -index b36834974e..ba2745c915 100644 +index b36834974e..935987bf8f 100644 --- a/dpdk/examples/l2fwd-keepalive/main.c +++ b/dpdk/examples/l2fwd-keepalive/main.c @@ -44,7 +44,7 @@ @@ -68958,6 +95944,16 @@ index b36834974e..ba2745c915 100644 /* reset l2fwd_dst_ports */ for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) l2fwd_dst_ports[portid] = 0; +@@ -817,5 +823,9 @@ main(int argc, char **argv) + + if (ka_shm != NULL) + rte_keepalive_shm_cleanup(ka_shm); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/l2fwd-keepalive/meson.build b/dpdk/examples/l2fwd-keepalive/meson.build index 6f7b007e1e..aecc8d9fc9 100644 --- a/dpdk/examples/l2fwd-keepalive/meson.build @@ -68977,21 +95973,8 @@ index 6f7b007e1e..aecc8d9fc9 100644 deps += 'timer' sources = files( 'main.c', 'shm.c' -diff --git a/dpdk/examples/l2fwd/Makefile b/dpdk/examples/l2fwd/Makefile -index 8b7b26cb90..15105ac57e 100644 ---- a/dpdk/examples/l2fwd/Makefile -+++ b/dpdk/examples/l2fwd/Makefile -@@ -24,7 +24,7 @@ CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - # Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API - CFLAGS += -DALLOW_EXPERIMENTAL_API - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/l2fwd/main.c b/dpdk/examples/l2fwd/main.c -index 09257aab1c..e3767a3159 100644 +index 09257aab1c..1d850fcfc1 100644 --- a/dpdk/examples/l2fwd/main.c +++ b/dpdk/examples/l2fwd/main.c @@ -146,6 +146,8 @@ print_stats(void) @@ -69012,21 +95995,18 @@ index 09257aab1c..e3767a3159 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/l3fwd-acl/Makefile b/dpdk/examples/l3fwd-acl/Makefile -index d9909584b1..156dc19606 100644 ---- a/dpdk/examples/l3fwd-acl/Makefile -+++ b/dpdk/examples/l3fwd-acl/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -770,6 +772,9 @@ main(int argc, char **argv) + rte_eth_dev_close(portid); + printf(" Done\n"); + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + printf("Bye...\n"); - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + return ret; diff --git a/dpdk/examples/l3fwd-acl/main.c b/dpdk/examples/l3fwd-acl/main.c -index fa92a28297..cfbeee962b 100644 +index fa92a28297..430d42d103 100644 --- a/dpdk/examples/l3fwd-acl/main.c +++ b/dpdk/examples/l3fwd-acl/main.c @@ -1839,7 +1839,7 @@ check_all_ports_link_status(uint32_t port_mask) @@ -69038,21 +96018,17 @@ index fa92a28297..cfbeee962b 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/l3fwd-power/Makefile b/dpdk/examples/l3fwd-power/Makefile -index 729d49639b..74441f98cf 100644 ---- a/dpdk/examples/l3fwd-power/Makefile -+++ b/dpdk/examples/l3fwd-power/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API +@@ -2116,5 +2116,8 @@ main(int argc, char **argv) + return -1; + } ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/l3fwd-power/main.c b/dpdk/examples/l3fwd-power/main.c -index d049d8a5dc..7fe5cbf577 100644 +index d049d8a5dc..fdad035bc0 100644 --- a/dpdk/examples/l3fwd-power/main.c +++ b/dpdk/examples/l3fwd-power/main.c @@ -880,9 +880,6 @@ sleep_until_rx_interrupt(int num) @@ -69101,6 +96077,24 @@ index d049d8a5dc..7fe5cbf577 100644 /** * start receiving packets immediately */ +@@ -1577,7 +1578,7 @@ parse_ep_config(const char *q_arg) + int hgh_edpi; + + ep_med_edpi = EMPTY_POLL_MED_THRESHOLD; +- ep_hgh_edpi = EMPTY_POLL_MED_THRESHOLD; ++ ep_hgh_edpi = EMPTY_POLL_HGH_THRESHOLD; + + strlcpy(s, p, sizeof(s)); + +@@ -1600,7 +1601,7 @@ parse_ep_config(const char *q_arg) + if (med_edpi > 0) + ep_med_edpi = med_edpi; + +- if (med_edpi > 0) ++ if (hgh_edpi > 0) + ep_hgh_edpi = hgh_edpi; + + } else { @@ -1997,7 +1998,7 @@ check_all_ports_link_status(uint32_t port_mask) "Mbps - %s\n", (uint8_t)portid, (unsigned)link.link_speed, @@ -69110,6 +96104,26 @@ index d049d8a5dc..7fe5cbf577 100644 else printf("Port %d Link Down\n", (uint8_t)portid); +@@ -2215,9 +2216,6 @@ main(int argc, char **argv) + uint8_t num_telstats = RTE_DIM(telstats_strings); + const char *ptr_strings[num_telstats]; + +- /* catch SIGINT and restore cpufreq governor to ondemand */ +- signal(SIGINT, signal_exit_now); +- + /* init EAL */ + ret = rte_eal_init(argc, argv); + if (ret < 0) +@@ -2225,6 +2223,9 @@ main(int argc, char **argv) + argc -= ret; + argv += ret; + ++ /* catch SIGINT and restore cpufreq governor to ondemand */ ++ signal(SIGINT, signal_exit_now); ++ + /* init RTE timer library to be used late */ + rte_timer_subsystem_init(); + @@ -2444,9 +2445,7 @@ main(int argc, char **argv) if (add_cb_parse_ptype(portid, queueid) < 0) rte_exit(EXIT_FAILURE, @@ -69133,21 +96147,75 @@ index d049d8a5dc..7fe5cbf577 100644 } check_all_ports_link_status(enabled_port_mask); -diff --git a/dpdk/examples/l3fwd/Makefile b/dpdk/examples/l3fwd/Makefile -index b2dbf26075..38a370c2cf 100644 ---- a/dpdk/examples/l3fwd/Makefile -+++ b/dpdk/examples/l3fwd/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +diff --git a/dpdk/examples/l3fwd/l3fwd_common.h b/dpdk/examples/l3fwd/l3fwd_common.h +index 7d83ff641a..de77711f88 100644 +--- a/dpdk/examples/l3fwd/l3fwd_common.h ++++ b/dpdk/examples/l3fwd/l3fwd_common.h +@@ -236,6 +236,9 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, struct rte_mbuf *m[], - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + /* copy rest of the packets into the TX buffer. */ + len = num - n; ++ if (len == 0) ++ goto exit; ++ + j = 0; + switch (len % FWDSTEP) { + while (j < len) { +@@ -258,6 +261,7 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, struct rte_mbuf *m[], + } + } + ++exit: + qconf->tx_mbufs[port].len = len; + } + +diff --git a/dpdk/examples/l3fwd/l3fwd_lpm.c b/dpdk/examples/l3fwd/l3fwd_lpm.c +index 349de2703c..c6b67cea2e 100644 +--- a/dpdk/examples/l3fwd/l3fwd_lpm.c ++++ b/dpdk/examples/l3fwd/l3fwd_lpm.c +@@ -41,7 +41,10 @@ struct ipv6_l3fwd_lpm_route { + uint8_t if_out; + }; + +-/* 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). */ ++/* ++ * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). ++ * 198.18.{0-7}.0/24 = Port {0-7} ++ */ + static struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { + {RTE_IPV4(198, 18, 0, 0), 24, 0}, + {RTE_IPV4(198, 18, 1, 0), 24, 1}, +@@ -53,16 +56,19 @@ static struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { + {RTE_IPV4(198, 18, 7, 0), 24, 7}, + }; + +-/* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180) */ ++/* ++ * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180). ++ * 2001:200:0:{0-7}::/64 = Port {0-7} ++ */ + static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = { +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 0}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 48, 1}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0}, 48, 2}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0}, 48, 3}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0}, 48, 4}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0}, 48, 5}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0}, 48, 6}, +- {{32, 1, 2, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0}, 48, 7}, ++ {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 0}, ++ {{32, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 1}, ++ {{32, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, ++ {{32, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, ++ {{32, 1, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 4}, ++ {{32, 1, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 5}, ++ {{32, 1, 2, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 6}, ++ {{32, 1, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 7}, + }; + + #define IPV4_L3FWD_LPM_NUM_ROUTES \ diff --git a/dpdk/examples/l3fwd/main.c b/dpdk/examples/l3fwd/main.c -index 4dea12a653..b98040df45 100644 +index 4dea12a653..19722f0c4c 100644 --- a/dpdk/examples/l3fwd/main.c +++ b/dpdk/examples/l3fwd/main.c @@ -53,7 +53,7 @@ @@ -69168,24 +96236,35 @@ index 4dea12a653..b98040df45 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/link_status_interrupt/Makefile b/dpdk/examples/link_status_interrupt/Makefile -index 4f02a89013..879ee7384d 100644 ---- a/dpdk/examples/link_status_interrupt/Makefile -+++ b/dpdk/examples/link_status_interrupt/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1093,6 +1093,10 @@ main(int argc, char **argv) + rte_eth_dev_close(portid); + printf(" Done\n"); + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + printf("Bye...\n"); - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + return ret; diff --git a/dpdk/examples/link_status_interrupt/main.c b/dpdk/examples/link_status_interrupt/main.c -index a924aa2313..6b8c153b58 100644 +index a924aa2313..174888eaae 100644 --- a/dpdk/examples/link_status_interrupt/main.c +++ b/dpdk/examples/link_status_interrupt/main.c -@@ -162,6 +162,8 @@ print_stats(void) +@@ -99,9 +99,10 @@ struct lsi_port_statistics { + struct lsi_port_statistics port_statistics[RTE_MAX_ETHPORTS]; + + /* A tsc-based timer responsible for triggering statistics printout */ +-#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ ++#define TIMER_MILLISECOND (rte_get_timer_hz() / 1000) + #define MAX_TIMER_PERIOD 86400 /* 1 day max */ +-static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */ ++#define DEFAULT_TIMER_PERIOD 10UL /* default period is 10 seconds */ ++static int64_t timer_period; + + /* Print out statistics on packets dropped */ + static void +@@ -162,6 +163,8 @@ print_stats(void) total_packets_rx, total_packets_dropped); printf("\n====================================================\n"); @@ -69194,7 +96273,16 @@ index a924aa2313..6b8c153b58 100644 } static void -@@ -500,7 +502,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) +@@ -366,6 +369,8 @@ lsi_parse_args(int argc, char **argv) + {NULL, 0, 0, 0} + }; + ++ timer_period = DEFAULT_TIMER_PERIOD * TIMER_MILLISECOND * 1000; ++ + argvopt = argv; + + while ((opt = getopt_long(argc, argvopt, "p:q:T:", +@@ -500,7 +505,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) "Port%d Link Up. Speed %u Mbps - %s\n", portid, link.link_speed, (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? @@ -69203,37 +96291,46 @@ index a924aa2313..6b8c153b58 100644 else printf("Port %d Link Down\n", portid); continue; +@@ -739,5 +744,8 @@ main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/meson.build b/dpdk/examples/meson.build -index 1f2b6f5168..9e081f3fb7 100644 +index 1f2b6f5168..bcd40cc302 100644 --- a/dpdk/examples/meson.build +++ b/dpdk/examples/meson.build -@@ -1,9 +1,9 @@ - # SPDX-License-Identifier: BSD-3-Clause - # Copyright(c) 2017-2019 Intel Corporation - --driver_libs = [] -+link_whole_libs = [] - if get_option('default_library') == 'static' -- driver_libs = dpdk_drivers -+ link_whole_libs = dpdk_static_libraries + dpdk_drivers +@@ -6,8 +6,6 @@ if get_option('default_library') == 'static' + driver_libs = dpdk_drivers endif - execinfo = cc.find_library('execinfo', required: false) -@@ -46,13 +46,6 @@ all_examples = [ +-execinfo = cc.find_library('execinfo', required: false) +- + # list of all example apps. Keep 1-3 per line, in alphabetical order. + all_examples = [ + 'bbdev_app', 'bond', +@@ -46,12 +44,11 @@ all_examples = [ 'vm_power_manager/guest_cli', 'vmdq', 'vmdq_dcb', ] -# install all example code on install - irrespective of whether the example in -# question is to be built as part of this build or not. --foreach ex:all_examples ++ ++# on install, skip copying all meson.build files ++ex_file_excludes = ['meson.build'] + foreach ex:all_examples - install_subdir(ex, - install_dir: get_option('datadir') + '/dpdk/examples', - exclude_files: 'meson.build') --endforeach ++ ex_file_excludes += [ex + '/meson.build'] + endforeach if get_option('examples') == '' - subdir_done() -@@ -69,6 +62,10 @@ default_cflags = machine_args +@@ -69,6 +66,10 @@ default_cflags = machine_args if cc.has_argument('-Wno-format-truncation') default_cflags += '-Wno-format-truncation' endif @@ -69244,25 +96341,38 @@ index 1f2b6f5168..9e081f3fb7 100644 foreach example: examples name = example.split('/')[-1] -@@ -76,6 +73,7 @@ foreach example: examples +@@ -76,8 +77,9 @@ foreach example: examples sources = [] allow_experimental_apis = false cflags = default_cflags + ldflags = default_ldflags - ext_deps = [execinfo] +- ext_deps = [execinfo] ++ ext_deps = [] includes = [include_directories(example)] -@@ -99,8 +97,8 @@ foreach example: examples - endif + deps = ['eal', 'mempool', 'net', 'mbuf', 'ethdev', 'cmdline'] + if is_windows +@@ -100,7 +102,7 @@ foreach example: examples executable('dpdk-' + name, sources, include_directories: includes, -- link_whole: driver_libs, + link_whole: driver_libs, - link_args: dpdk_extra_ldflags, -+ link_whole: link_whole_libs, + link_args: ldflags, c_args: cflags, dependencies: dep_objs) elif not allow_skips +diff --git a/dpdk/examples/multi_process/client_server_mp/mp_client/client.c b/dpdk/examples/multi_process/client_server_mp/mp_client/client.c +index 361d90b54b..6d4c246816 100644 +--- a/dpdk/examples/multi_process/client_server_mp/mp_client/client.c ++++ b/dpdk/examples/multi_process/client_server_mp/mp_client/client.c +@@ -268,4 +268,7 @@ main(int argc, char *argv[]) + + need_flush = 1; + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + } diff --git a/dpdk/examples/multi_process/client_server_mp/mp_server/init.c b/dpdk/examples/multi_process/client_server_mp/mp_server/init.c index ad9f46f0aa..c2ec07ac65 100644 --- a/dpdk/examples/multi_process/client_server_mp/mp_server/init.c @@ -69277,7 +96387,7 @@ index ad9f46f0aa..c2ec07ac65 100644 printf("Port %d Link Down\n", (uint8_t)ports->id[portid]); diff --git a/dpdk/examples/multi_process/client_server_mp/mp_server/main.c b/dpdk/examples/multi_process/client_server_mp/mp_server/main.c -index 802e29d10d..1084b303ff 100644 +index 802e29d10d..61cef86a05 100644 --- a/dpdk/examples/multi_process/client_server_mp/mp_server/main.c +++ b/dpdk/examples/multi_process/client_server_mp/mp_server/main.c @@ -59,12 +59,17 @@ static struct client_rx_buf *cl_rx_buf; @@ -69314,6 +96424,25 @@ index 802e29d10d..1084b303ff 100644 } return addresses[port]; } +@@ -230,7 +233,7 @@ process_packets(uint32_t port_num __rte_unused, + struct rte_mbuf *pkts[], uint16_t rx_count) + { + uint16_t i; +- uint8_t client = 0; ++ static uint8_t client; + + for (i = 0; i < rx_count; i++) { + enqueue_rx_packet(client, pkts[i]); +@@ -301,5 +304,9 @@ main(int argc, char *argv[]) + rte_eal_mp_remote_launch(sleep_lcore, NULL, SKIP_MASTER); + + do_packet_forwarding(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/multi_process/client_server_mp/shared/common.h b/dpdk/examples/multi_process/client_server_mp/shared/common.h index 6dd43fcac2..76beca0101 100644 --- a/dpdk/examples/multi_process/client_server_mp/shared/common.h @@ -69327,8 +96456,22 @@ index 6dd43fcac2..76beca0101 100644 { /* buffer for return value. Size calculated by %u being replaced * by maximum 3 digits (plus an extra byte for safety) */ +diff --git a/dpdk/examples/multi_process/simple_mp/main.c b/dpdk/examples/multi_process/simple_mp/main.c +index e6c69d6a33..0304c453ec 100644 +--- a/dpdk/examples/multi_process/simple_mp/main.c ++++ b/dpdk/examples/multi_process/simple_mp/main.c +@@ -121,5 +121,9 @@ main(int argc, char **argv) + cmdline_stdin_exit(cl); + + rte_eal_mp_wait_lcore(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/multi_process/symmetric_mp/main.c b/dpdk/examples/multi_process/symmetric_mp/main.c -index 7f491452a7..c5cd8825e5 100644 +index 7f491452a7..a5ff1fee6e 100644 --- a/dpdk/examples/multi_process/symmetric_mp/main.c +++ b/dpdk/examples/multi_process/symmetric_mp/main.c @@ -389,7 +389,7 @@ check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) @@ -69340,19 +96483,19 @@ index 7f491452a7..c5cd8825e5 100644 else printf("Port %d Link Down\n", portid); continue; +@@ -475,5 +475,8 @@ main(int argc, char **argv) + + rte_eal_mp_remote_launch(lcore_main, NULL, CALL_MASTER); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/ntb/Makefile b/dpdk/examples/ntb/Makefile -index baeba11e85..f41ccfac27 100644 +index baeba11e85..bdc0d6e80f 100644 --- a/dpdk/examples/ntb/Makefile +++ b/dpdk/examples/ntb/Makefile -@@ -26,7 +26,7 @@ LDFLAGS += -pthread - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) @@ -40,7 +40,7 @@ build: .PHONY: clean clean: @@ -69362,8 +96505,25 @@ index baeba11e85..f41ccfac27 100644 else # Build using legacy build system +diff --git a/dpdk/examples/ntb/meson.build b/dpdk/examples/ntb/meson.build +index f5435fe120..b4f9dc395d 100644 +--- a/dpdk/examples/ntb/meson.build ++++ b/dpdk/examples/ntb/meson.build +@@ -9,11 +9,8 @@ + if host_machine.system() != 'linux' + build = false + endif +-deps += 'rawdev' ++deps += ['rawdev','rawdev_ntb'] + cflags += ['-D_FILE_OFFSET_BITS=64'] + sources = files( + 'ntb_fwd.c' + ) +-if dpdk_conf.has('RTE_LIBRTE_PMD_NTB_RAWDEV') +- deps += 'rawdev_ntb' +-endif diff --git a/dpdk/examples/ntb/ntb_fwd.c b/dpdk/examples/ntb/ntb_fwd.c -index c914256dd4..17eedcf0b8 100644 +index c914256dd4..4630ece311 100644 --- a/dpdk/examples/ntb/ntb_fwd.c +++ b/dpdk/examples/ntb/ntb_fwd.c @@ -19,6 +19,7 @@ @@ -69386,23 +96546,28 @@ index c914256dd4..17eedcf0b8 100644 memset(&mbp_priv, 0, sizeof(mbp_priv)); mbp_priv.mbuf_data_room_size = mbuf_seg_size; mbp_priv.mbuf_priv_size = 0; -diff --git a/dpdk/examples/packet_ordering/Makefile b/dpdk/examples/packet_ordering/Makefile -index 261b7f06a8..1e50389421 100644 ---- a/dpdk/examples/packet_ordering/Makefile -+++ b/dpdk/examples/packet_ordering/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1490,5 +1496,8 @@ main(int argc, char **argv) + start_pkt_fwd(); + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/packet_ordering/main.c b/dpdk/examples/packet_ordering/main.c -index b397b318e6..edaf810d94 100644 +index b397b318e6..c9f645e67e 100644 --- a/dpdk/examples/packet_ordering/main.c +++ b/dpdk/examples/packet_ordering/main.c +@@ -293,7 +293,7 @@ configure_eth_port(uint16_t port_id) + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + port_conf.txmode.offloads |= + DEV_TX_OFFLOAD_MBUF_FAST_FREE; +- ret = rte_eth_dev_configure(port_id, rxRings, txRings, &port_conf_default); ++ ret = rte_eth_dev_configure(port_id, rxRings, txRings, &port_conf); + if (ret != 0) + return ret; + @@ -675,7 +675,7 @@ main(int argc, char **argv) /* Initialize EAL */ ret = rte_eal_init(argc, argv); @@ -69421,8 +96586,88 @@ index b397b318e6..edaf810d94 100644 /* Check if we have enought cores */ if (rte_lcore_count() < 3) +@@ -779,5 +779,9 @@ main(int argc, char **argv) + } + + print_stats(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/performance-thread/common/lthread.c b/dpdk/examples/performance-thread/common/lthread.c +index 3f1f48db43..190e5874b1 100644 +--- a/dpdk/examples/performance-thread/common/lthread.c ++++ b/dpdk/examples/performance-thread/common/lthread.c +@@ -20,6 +20,7 @@ + #include + + #include ++#include + #include + #include + +@@ -463,6 +464,5 @@ void lthread_set_funcname(const char *f) + { + struct lthread *lt = THIS_LTHREAD; + +- strncpy(lt->funcname, f, sizeof(lt->funcname)); +- lt->funcname[sizeof(lt->funcname)-1] = 0; ++ strlcpy(lt->funcname, f, sizeof(lt->funcname)); + } +diff --git a/dpdk/examples/performance-thread/common/lthread_cond.c b/dpdk/examples/performance-thread/common/lthread_cond.c +index cdcc7a7b5a..e7be17089a 100644 +--- a/dpdk/examples/performance-thread/common/lthread_cond.c ++++ b/dpdk/examples/performance-thread/common/lthread_cond.c +@@ -20,6 +20,7 @@ + + #include + #include ++#include + + #include "lthread_api.h" + #include "lthread_diag_api.h" +@@ -57,10 +58,9 @@ lthread_cond_init(char *name, struct lthread_cond **cond, + } + + if (name == NULL) +- strncpy(c->name, "no name", sizeof(c->name)); ++ strlcpy(c->name, "no name", sizeof(c->name)); + else +- strncpy(c->name, name, sizeof(c->name)); +- c->name[sizeof(c->name)-1] = 0; ++ strlcpy(c->name, name, sizeof(c->name)); + + c->root_sched = THIS_SCHED; + +diff --git a/dpdk/examples/performance-thread/common/lthread_mutex.c b/dpdk/examples/performance-thread/common/lthread_mutex.c +index 01da6cad4f..709ab9f553 100644 +--- a/dpdk/examples/performance-thread/common/lthread_mutex.c ++++ b/dpdk/examples/performance-thread/common/lthread_mutex.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include "lthread_api.h" + #include "lthread_int.h" +@@ -52,10 +53,9 @@ lthread_mutex_init(char *name, struct lthread_mutex **mutex, + } + + if (name == NULL) +- strncpy(m->name, "no name", sizeof(m->name)); ++ strlcpy(m->name, "no name", sizeof(m->name)); + else +- strncpy(m->name, name, sizeof(m->name)); +- m->name[sizeof(m->name)-1] = 0; ++ strlcpy(m->name, name, sizeof(m->name)); + + m->root_sched = THIS_SCHED; + m->owner = NULL; diff --git a/dpdk/examples/performance-thread/l3fwd-thread/main.c b/dpdk/examples/performance-thread/l3fwd-thread/main.c -index ad540fd842..96fbdcdde2 100644 +index ad540fd842..4792d92122 100644 --- a/dpdk/examples/performance-thread/l3fwd-thread/main.c +++ b/dpdk/examples/performance-thread/l3fwd-thread/main.c @@ -2,6 +2,10 @@ @@ -69455,7 +96700,28 @@ index ad540fd842..96fbdcdde2 100644 struct rte_ring *ring; struct lthread_cond **ready; -@@ -3457,7 +3462,7 @@ check_all_ports_link_status(uint32_t port_mask) +@@ -1880,7 +1885,6 @@ process_burst(struct rte_mbuf *pkts_burst[MAX_PKT_BURST], int nb_rx, + static int __attribute__((noreturn)) + cpu_load_collector(__rte_unused void *arg) { + unsigned i, j, k; +- uint64_t hits; + uint64_t prev_tsc, diff_tsc, cur_tsc; + uint64_t total[MAX_CPU] = { 0 }; + unsigned min_cpu = MAX_CPU; +@@ -1970,12 +1974,10 @@ cpu_load_collector(__rte_unused void *arg) { + printf("cpu# proc%% poll%% overhead%%\n\n"); + + for (i = min_cpu; i <= max_cpu; i++) { +- hits = 0; + printf("CPU %d:", i); + for (j = 0; j < MAX_CPU_COUNTER; j++) { + printf("%7" PRIu64 "", + cpu_load.hits[j][i] * 100 / cpu_load.counter); +- hits += cpu_load.hits[j][i]; + cpu_load.hits[j][i] = 0; + } + printf("%7" PRIu64 "\n", +@@ -3457,7 +3459,7 @@ check_all_ports_link_status(uint32_t port_mask) "Port%d Link Up. Speed %u Mbps - %s\n", portid, link.link_speed, (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? @@ -69464,45 +96730,132 @@ index ad540fd842..96fbdcdde2 100644 else printf("Port %d Link Down\n", portid); continue; -diff --git a/dpdk/examples/ptpclient/Makefile b/dpdk/examples/ptpclient/Makefile -index 82d72b3e31..9e47a60117 100644 ---- a/dpdk/examples/ptpclient/Makefile -+++ b/dpdk/examples/ptpclient/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -3778,5 +3780,8 @@ main(int argc, char **argv) + } + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/qos_meter/Makefile b/dpdk/examples/qos_meter/Makefile -index 7c2bf88a90..f733facaeb 100644 ---- a/dpdk/examples/qos_meter/Makefile -+++ b/dpdk/examples/qos_meter/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - CFLAGS += -DALLOW_EXPERIMENTAL_API - -diff --git a/dpdk/examples/qos_sched/Makefile b/dpdk/examples/qos_sched/Makefile -index 525061ca07..736ac00a36 100644 ---- a/dpdk/examples/qos_sched/Makefile -+++ b/dpdk/examples/qos_sched/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/performance-thread/pthread_shim/main.c b/dpdk/examples/performance-thread/pthread_shim/main.c +index 03ff394369..f169709137 100644 +--- a/dpdk/examples/performance-thread/pthread_shim/main.c ++++ b/dpdk/examples/performance-thread/pthread_shim/main.c +@@ -71,7 +71,7 @@ void *helloworld_pthread(void *arg) + print_count++; - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + /* yield thread to give opportunity for lock contention */ +- pthread_yield(); ++ sched_yield(); + + /* retrieve arg from TLS */ + uint64_t thread_no = (uint64_t) pthread_getspecific(key); +@@ -258,5 +258,9 @@ int main(int argc, char **argv) + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + rte_eal_wait_lcore(lcore_id); + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/ptpclient/ptpclient.c b/dpdk/examples/ptpclient/ptpclient.c +index a1a7ae699a..e29237d67c 100644 +--- a/dpdk/examples/ptpclient/ptpclient.c ++++ b/dpdk/examples/ptpclient/ptpclient.c +@@ -382,6 +382,7 @@ parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) + struct ptp_header *ptp_hdr; + struct clock_id *client_clkid; + struct ptp_message *ptp_msg; ++ struct delay_req_msg *req_msg; + struct rte_mbuf *created_pkt; + struct tstamp *origin_tstamp; + struct rte_ether_addr eth_multicast = ether_multicast; +@@ -419,7 +420,12 @@ parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) + + created_pkt = rte_pktmbuf_alloc(mbuf_pool); + pkt_size = sizeof(struct rte_ether_hdr) + +- sizeof(struct ptp_message); ++ sizeof(struct delay_req_msg); ++ ++ if (rte_pktmbuf_append(created_pkt, pkt_size) == NULL) { ++ rte_pktmbuf_free(created_pkt); ++ return; ++ } + created_pkt->data_len = pkt_size; + created_pkt->pkt_len = pkt_size; + eth_hdr = rte_pktmbuf_mtod(created_pkt, struct rte_ether_hdr *); +@@ -429,22 +435,22 @@ parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) + rte_ether_addr_copy(ð_multicast, ð_hdr->d_addr); + + eth_hdr->ether_type = htons(PTP_PROTOCOL); +- ptp_msg = (struct ptp_message *) +- (rte_pktmbuf_mtod(created_pkt, char *) + +- sizeof(struct rte_ether_hdr)); +- +- ptp_msg->delay_req.hdr.seq_id = htons(ptp_data->seqID_SYNC); +- ptp_msg->delay_req.hdr.msg_type = DELAY_REQ; +- ptp_msg->delay_req.hdr.ver = 2; +- ptp_msg->delay_req.hdr.control = 1; +- ptp_msg->delay_req.hdr.log_message_interval = 127; +- ptp_msg->delay_req.hdr.message_length = ++ req_msg = rte_pktmbuf_mtod_offset(created_pkt, ++ struct delay_req_msg *, sizeof(struct ++ rte_ether_hdr)); ++ ++ req_msg->hdr.seq_id = htons(ptp_data->seqID_SYNC); ++ req_msg->hdr.msg_type = DELAY_REQ; ++ req_msg->hdr.ver = 2; ++ req_msg->hdr.control = 1; ++ req_msg->hdr.log_message_interval = 127; ++ req_msg->hdr.message_length = + htons(sizeof(struct delay_req_msg)); +- ptp_msg->delay_req.hdr.domain_number = ptp_hdr->domain_number; ++ req_msg->hdr.domain_number = ptp_hdr->domain_number; + + /* Set up clock id. */ + client_clkid = +- &ptp_msg->delay_req.hdr.source_port_id.clock_id; ++ &req_msg->hdr.source_port_id.clock_id; + + client_clkid->id[0] = eth_hdr->s_addr.addr_bytes[0]; + client_clkid->id[1] = eth_hdr->s_addr.addr_bytes[1]; +@@ -603,10 +609,6 @@ lcore_main(void) + unsigned nb_rx; + struct rte_mbuf *m; + +- /* +- * Check that the port is on the same NUMA node as the polling thread +- * for best performance. +- */ + printf("\nCore %u Waiting for SYNC packets. [Ctrl+C to quit]\n", + rte_lcore_id()); + +@@ -788,5 +790,8 @@ main(int argc, char *argv[]) + /* Call lcore_main on the master core only. */ + lcore_main(); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/qos_meter/main.c b/dpdk/examples/qos_meter/main.c +index e8112c83a2..03129c85f4 100644 +--- a/dpdk/examples/qos_meter/main.c ++++ b/dpdk/examples/qos_meter/main.c +@@ -463,5 +463,8 @@ main(int argc, char **argv) + return -1; + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/qos_sched/args.c b/dpdk/examples/qos_sched/args.c index 7431b29816..2727fd4f27 100644 --- a/dpdk/examples/qos_sched/args.c @@ -69543,6 +96896,19 @@ index 0a17e0d4d5..9626c15b81 100644 } else { printf(" Link Down\n"); } +diff --git a/dpdk/examples/qos_sched/main.c b/dpdk/examples/qos_sched/main.c +index c0ed16b68f..4dc65e10c2 100644 +--- a/dpdk/examples/qos_sched/main.c ++++ b/dpdk/examples/qos_sched/main.c +@@ -218,5 +218,8 @@ main(int argc, char **argv) + } + } + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/qos_sched/main.h b/dpdk/examples/qos_sched/main.h index baa2b3eadc..23bc418d97 100644 --- a/dpdk/examples/qos_sched/main.h @@ -69559,20 +96925,53 @@ index baa2b3eadc..23bc418d97 100644 extern struct rte_sched_port_params port_params; extern struct rte_sched_subport_params subport_params[MAX_SCHED_SUBPORTS]; diff --git a/dpdk/examples/rxtx_callbacks/Makefile b/dpdk/examples/rxtx_callbacks/Makefile -index 584b9fafb0..eecdcada3e 100644 +index 584b9fafb0..418f47c4d7 100644 --- a/dpdk/examples/rxtx_callbacks/Makefile +++ b/dpdk/examples/rxtx_callbacks/Makefile -@@ -22,7 +22,9 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) +@@ -24,6 +24,8 @@ CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) -+ -+CFLAGS += -DALLOW_EXPERIMENTAL_API + LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) ++CFLAGS += -DALLOW_EXPERIMENTAL_API ++ build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) + +diff --git a/dpdk/examples/rxtx_callbacks/main.c b/dpdk/examples/rxtx_callbacks/main.c +index 07e95e8d1a..ad587c7a13 100644 +--- a/dpdk/examples/rxtx_callbacks/main.c ++++ b/dpdk/examples/rxtx_callbacks/main.c +@@ -295,7 +295,7 @@ main(int argc, char *argv[]) + /* initialize all ports */ + RTE_ETH_FOREACH_DEV(portid) + if (port_init(portid, mbuf_pool) != 0) +- rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8"\n", ++ rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu16"\n", + portid); + + if (rte_lcore_count() > 1) +@@ -304,5 +304,9 @@ main(int argc, char *argv[]) + + /* call lcore_main on master core only */ + lcore_main(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/server_node_efd/node/node.c b/dpdk/examples/server_node_efd/node/node.c +index 67a55808bf..e68606e0ca 100644 +--- a/dpdk/examples/server_node_efd/node/node.c ++++ b/dpdk/examples/server_node_efd/node/node.c +@@ -383,4 +383,7 @@ main(int argc, char *argv[]) + + need_flush = 1; + } ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + } diff --git a/dpdk/examples/server_node_efd/server/init.c b/dpdk/examples/server_node_efd/server/init.c index 00e2e40599..378a74fa5c 100644 --- a/dpdk/examples/server_node_efd/server/init.c @@ -69586,45 +96985,64 @@ index 00e2e40599..378a74fa5c 100644 else printf("Port %d Link Down\n", info->id[portid]); -diff --git a/dpdk/examples/service_cores/Makefile b/dpdk/examples/service_cores/Makefile -index c47055813e..b8669fdf7e 100644 ---- a/dpdk/examples/service_cores/Makefile -+++ b/dpdk/examples/service_cores/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/skeleton/Makefile b/dpdk/examples/skeleton/Makefile -index 2c29004d79..5059f3123f 100644 ---- a/dpdk/examples/skeleton/Makefile -+++ b/dpdk/examples/skeleton/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/tep_termination/Makefile b/dpdk/examples/tep_termination/Makefile -index 645112498d..548ca3cee3 100644 ---- a/dpdk/examples/tep_termination/Makefile -+++ b/dpdk/examples/tep_termination/Makefile -@@ -24,7 +24,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +diff --git a/dpdk/examples/server_node_efd/server/main.c b/dpdk/examples/server_node_efd/server/main.c +index 21c72acda2..c42b6530c0 100644 +--- a/dpdk/examples/server_node_efd/server/main.c ++++ b/dpdk/examples/server_node_efd/server/main.c +@@ -334,5 +334,9 @@ main(int argc, char *argv[]) + rte_eal_mp_remote_launch(sleep_lcore, NULL, SKIP_MASTER); - CFLAGS += -Wno-deprecated-declarations + do_packet_forwarding(); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/service_cores/main.c b/dpdk/examples/service_cores/main.c +index c7c792810d..e0cb4f9acb 100644 +--- a/dpdk/examples/service_cores/main.c ++++ b/dpdk/examples/service_cores/main.c +@@ -118,7 +118,7 @@ apply_profile(int profile_id) + struct profile *p = &profiles[profile_id]; + const uint8_t core_off = 1; + +- if (p->num_cores > rte_lcore_count() + 1) { ++ if (p->num_cores > rte_lcore_count() - 1) { + printf("insufficent cores to run (%s)", + p->name); + return; +@@ -220,5 +220,8 @@ main(int argc, char **argv) + i = 0; + } ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/skeleton/basicfwd.c b/dpdk/examples/skeleton/basicfwd.c +index 73d313b84e..d312afad0b 100644 +--- a/dpdk/examples/skeleton/basicfwd.c ++++ b/dpdk/examples/skeleton/basicfwd.c +@@ -122,7 +122,7 @@ lcore_main(void) + * for best performance. + */ + RTE_ETH_FOREACH_DEV(port) +- if (rte_eth_dev_socket_id(port) > 0 && ++ if (rte_eth_dev_socket_id(port) >= 0 && + rte_eth_dev_socket_id(port) != + (int)rte_socket_id()) + printf("WARNING, port %u is on remote NUMA node to " +@@ -205,5 +205,8 @@ main(int argc, char *argv[]) + /* Call lcore_main on the master core only. */ + lcore_main(); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/tep_termination/main.c b/dpdk/examples/tep_termination/main.c index ab956ad7ce..b9fffca020 100644 --- a/dpdk/examples/tep_termination/main.c @@ -69651,50 +97069,146 @@ index eca119a728..4b44ccc143 100644 if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) RTE_LOG(WARNING, PORT, "hardware TSO offload is not supported\n"); -diff --git a/dpdk/examples/timer/Makefile b/dpdk/examples/timer/Makefile -index bf86339ab7..b34c8baa6b 100644 ---- a/dpdk/examples/timer/Makefile -+++ b/dpdk/examples/timer/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +diff --git a/dpdk/examples/timer/main.c b/dpdk/examples/timer/main.c +index 968a941367..065d1ccb68 100644 +--- a/dpdk/examples/timer/main.c ++++ b/dpdk/examples/timer/main.c +@@ -18,8 +18,7 @@ + #include + #include - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/vdpa/Makefile b/dpdk/examples/vdpa/Makefile -index 6a25497cd8..bc0b6793e6 100644 ---- a/dpdk/examples/vdpa/Makefile -+++ b/dpdk/examples/vdpa/Makefile -@@ -23,7 +23,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +-#define TIMER_RESOLUTION_CYCLES 20000000ULL /* around 10ms at 2 Ghz */ +- ++static uint64_t timer_resolution_cycles; + static struct rte_timer timer0; + static struct rte_timer timer1; - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) -diff --git a/dpdk/examples/vhost/Makefile b/dpdk/examples/vhost/Makefile -index f2b1615418..ef6f3550f3 100644 ---- a/dpdk/examples/vhost/Makefile -+++ b/dpdk/examples/vhost/Makefile -@@ -24,7 +24,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -66,15 +65,14 @@ lcore_mainloop(__attribute__((unused)) void *arg) + + while (1) { + /* +- * Call the timer handler on each core: as we don't +- * need a very precise timer, so only call +- * rte_timer_manage() every ~10ms (at 2Ghz). In a real +- * application, this will enhance performances as +- * reading the HPET timer is not efficient. ++ * Call the timer handler on each core: as we don't need a ++ * very precise timer, so only call rte_timer_manage() ++ * every ~10ms. In a real application, this will enhance ++ * performances as reading the HPET timer is not efficient. + */ +- cur_tsc = rte_rdtsc(); ++ cur_tsc = rte_get_timer_cycles(); + diff_tsc = cur_tsc - prev_tsc; +- if (diff_tsc > TIMER_RESOLUTION_CYCLES) { ++ if (diff_tsc > timer_resolution_cycles) { + rte_timer_manage(); + prev_tsc = cur_tsc; + } +@@ -100,8 +98,10 @@ main(int argc, char **argv) + rte_timer_init(&timer0); + rte_timer_init(&timer1); - CFLAGS += -DALLOW_EXPERIMENTAL_API +- /* load timer0, every second, on master lcore, reloaded automatically */ + hz = rte_get_timer_hz(); ++ timer_resolution_cycles = hz * 10 / 1000; /* around 10ms */ ++ ++ /* load timer0, every second, on main lcore, reloaded automatically */ + lcore_id = rte_lcore_id(); + rte_timer_reset(&timer0, hz, PERIODICAL, lcore_id, timer0_cb, NULL); + +@@ -117,5 +117,8 @@ main(int argc, char **argv) + /* call it on master lcore too */ + (void) lcore_mainloop(NULL); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/vdpa/main.c b/dpdk/examples/vdpa/main.c +index d2e2cb7cd4..c3be9159fb 100644 +--- a/dpdk/examples/vdpa/main.c ++++ b/dpdk/examples/vdpa/main.c +@@ -450,5 +450,8 @@ main(int argc, char *argv[]) + vdpa_sample_quit(); + } ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/vhost/main.c b/dpdk/examples/vhost/main.c -index ab649bf147..312829e8b9 100644 +index ab649bf147..ca6e9a3324 100644 --- a/dpdk/examples/vhost/main.c +++ b/dpdk/examples/vhost/main.c -@@ -1334,6 +1334,8 @@ print_stats(__rte_unused void *arg) +@@ -236,6 +236,10 @@ port_init(uint16_t port) + + return retval; + } ++ if (dev_info.max_vmdq_pools == 0) { ++ RTE_LOG(ERR, VHOST_PORT, "Failed to get VMDq info.\n"); ++ return -1; ++ } + + rxconf = &dev_info.default_rxconf; + txconf = &dev_info.default_txconf; +@@ -1047,24 +1051,6 @@ drain_eth_rx(struct vhost_dev *vdev) + if (!rx_count) + return; + +- /* +- * When "enable_retry" is set, here we wait and retry when there +- * is no enough free slots in the queue to hold @rx_count packets, +- * to diminish packet loss. +- */ +- if (enable_retry && +- unlikely(rx_count > rte_vhost_avail_entries(vdev->vid, +- VIRTIO_RXQ))) { +- uint32_t retry; +- +- for (retry = 0; retry < burst_rx_retry_num; retry++) { +- rte_delay_us(burst_rx_delay_time); +- if (rx_count <= rte_vhost_avail_entries(vdev->vid, +- VIRTIO_RXQ)) +- break; +- } +- } +- + if (builtin_net_driver) { + enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ, + pkts, rx_count); +@@ -1072,6 +1058,28 @@ drain_eth_rx(struct vhost_dev *vdev) + enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ, + pkts, rx_count); + } ++ ++ /* Retry if necessary */ ++ if (enable_retry && unlikely(enqueue_count < rx_count)) { ++ uint32_t retry = 0; ++ ++ while (enqueue_count < rx_count && ++ retry++ < burst_rx_retry_num) { ++ rte_delay_us(burst_rx_delay_time); ++ if (builtin_net_driver) { ++ enqueue_count += vs_enqueue_pkts(vdev, ++ VIRTIO_RXQ, &pkts[enqueue_count], ++ rx_count - enqueue_count); ++ } else { ++ enqueue_count += rte_vhost_enqueue_burst( ++ vdev->vid, ++ VIRTIO_RXQ, ++ &pkts[enqueue_count], ++ rx_count - enqueue_count); ++ } ++ } ++ } ++ + if (enable_stats) { + rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count); + rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count); +@@ -1334,6 +1342,8 @@ print_stats(__rte_unused void *arg) } printf("===================================================\n"); @@ -69703,21 +97217,44 @@ index ab649bf147..312829e8b9 100644 } return NULL; -diff --git a/dpdk/examples/vhost_blk/Makefile b/dpdk/examples/vhost_blk/Makefile -index 39244320d8..3952791784 100644 ---- a/dpdk/examples/vhost_blk/Makefile -+++ b/dpdk/examples/vhost_blk/Makefile -@@ -25,7 +25,7 @@ LDFLAGS += -pthread - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -1569,6 +1579,8 @@ main(int argc, char *argv[]) + RTE_LCORE_FOREACH_SLAVE(lcore_id) + rte_eal_wait_lcore(lcore_id); + +- return 0; ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + ++ return 0; + } +diff --git a/dpdk/examples/vhost/virtio_net.c b/dpdk/examples/vhost/virtio_net.c +index 8ea6b36d59..28e4b00960 100644 +--- a/dpdk/examples/vhost/virtio_net.c ++++ b/dpdk/examples/vhost/virtio_net.c +@@ -23,6 +23,7 @@ vs_vhost_net_setup(struct vhost_dev *dev) + uint16_t i; + int vid = dev->vid; + struct vhost_queue *queue; ++ int ret; - CFLAGS += -DALLOW_EXPERIMENTAL_API + RTE_LOG(INFO, VHOST_CONFIG, + "setting builtin vhost-user net driver\n"); +@@ -33,7 +34,12 @@ vs_vhost_net_setup(struct vhost_dev *dev) + else + dev->hdr_len = sizeof(struct virtio_net_hdr); +- rte_vhost_get_mem_table(vid, &dev->mem); ++ ret = rte_vhost_get_mem_table(vid, &dev->mem); ++ if (ret < 0) { ++ RTE_LOG(ERR, VHOST_CONFIG, "Failed to get " ++ "VM memory layout for device(%d)\n", vid); ++ return; ++ } + + dev->nr_vrings = rte_vhost_get_vring_num(vid); + for (i = 0; i < dev->nr_vrings; i++) { diff --git a/dpdk/examples/vhost_blk/vhost_blk.c b/dpdk/examples/vhost_blk/vhost_blk.c -index 3182a488bb..d0c30a9c6f 100644 +index 3182a488bb..57f0adf50f 100644 --- a/dpdk/examples/vhost_blk/vhost_blk.c +++ b/dpdk/examples/vhost_blk/vhost_blk.c @@ -2,6 +2,12 @@ @@ -69773,7 +97310,7 @@ index 3182a488bb..d0c30a9c6f 100644 if (g_should_stop != -1) { g_should_stop = 1; -@@ -1084,7 +1088,11 @@ int main(int argc, char *argv[]) +@@ -1084,11 +1088,18 @@ int main(int argc, char *argv[]) return -1; } @@ -69786,6 +97323,13 @@ index 3182a488bb..d0c30a9c6f 100644 /* loop for exit the application */ while (1) + sleep(1); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/vhost_blk/vhost_blk.h b/dpdk/examples/vhost_blk/vhost_blk.h index 933e2b7c57..17258d284b 100644 --- a/dpdk/examples/vhost_blk/vhost_blk.h @@ -69801,21 +97345,8 @@ index 933e2b7c57..17258d284b 100644 int vhost_bdev_process_blk_commands(struct vhost_block_dev *bdev, struct vhost_blk_task *task); -diff --git a/dpdk/examples/vhost_crypto/Makefile b/dpdk/examples/vhost_crypto/Makefile -index ae8cb81f87..28e3e4de74 100644 ---- a/dpdk/examples/vhost_crypto/Makefile -+++ b/dpdk/examples/vhost_crypto/Makefile -@@ -23,7 +23,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/vhost_crypto/main.c b/dpdk/examples/vhost_crypto/main.c -index 1d7ba94196..405d16966d 100644 +index 1d7ba94196..03fb238758 100644 --- a/dpdk/examples/vhost_crypto/main.c +++ b/dpdk/examples/vhost_crypto/main.c @@ -195,7 +195,7 @@ vhost_crypto_usage(const char *prgname) @@ -69827,7 +97358,26 @@ index 1d7ba94196..405d16966d 100644 " --%s: zero copy\n" " --%s: guest polling\n", prgname, SOCKET_FILE_KEYWORD, CONFIG_KEYWORD, -@@ -544,7 +544,7 @@ main(int argc, char *argv[]) +@@ -219,7 +219,7 @@ vhost_crypto_parse_args(int argc, char **argv) + + argvopt = argv; + +- while ((opt = getopt_long(argc, argvopt, "s:", ++ while ((opt = getopt_long(argc, argvopt, "", + lgopts, &option_index)) != EOF) { + + switch (opt) { +@@ -455,6 +455,9 @@ free_resource(void) + } + + memset(&options, 0, sizeof(options)); ++ ++ /* clean up the EAL */ ++ rte_eal_cleanup(); + } + + int +@@ -544,7 +547,7 @@ main(int argc, char *argv[]) snprintf(name, 127, "COPPOOL_%u", lo->lcore_id); info->cop_pool = rte_crypto_op_pool_create(name, RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS, @@ -70411,7 +97961,7 @@ index 7362a80d26..2b38c554b5 100644 #ifdef __cplusplus diff --git a/dpdk/examples/vm_power_manager/guest_cli/main.c b/dpdk/examples/vm_power_manager/guest_cli/main.c -index f63b3c988a..4e17f7fb90 100644 +index f63b3c988a..b8fa65ef15 100644 --- a/dpdk/examples/vm_power_manager/guest_cli/main.c +++ b/dpdk/examples/vm_power_manager/guest_cli/main.c @@ -48,10 +48,10 @@ parse_args(int argc, char **argv) @@ -70496,6 +98046,15 @@ index f63b3c988a..4e17f7fb90 100644 else { printf("Invalid policy specified: %s\n", optarg); +@@ -193,5 +200,8 @@ main(int argc, char **argv) + } + run_cli(NULL); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c b/dpdk/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c index 96c1a1ff69..1618030627 100644 --- a/dpdk/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c @@ -70760,7 +98319,7 @@ index 0c2cc1374d..50c435544e 100644 void run_cli(__attribute__((unused)) void *arg); diff --git a/dpdk/examples/vm_power_manager/main.c b/dpdk/examples/vm_power_manager/main.c -index d39f044c1e..2316aace5a 100644 +index d39f044c1e..2f82b878fe 100644 --- a/dpdk/examples/vm_power_manager/main.c +++ b/dpdk/examples/vm_power_manager/main.c @@ -272,7 +272,7 @@ check_all_ports_link_status(uint32_t port_mask) @@ -70781,6 +98340,15 @@ index d39f044c1e..2316aace5a 100644 eth.addr_bytes[5] = w + 0xf0; ret = -ENOTSUP; +@@ -469,5 +469,8 @@ main(int argc, char **argv) + + free(ci->cd); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/examples/vm_power_manager/meson.build b/dpdk/examples/vm_power_manager/meson.build index 20a4a05b3b..8dd5bd2eb6 100644 --- a/dpdk/examples/vm_power_manager/meson.build @@ -70818,21 +98386,8 @@ index 5f64b83fb0..8eb87217e9 100644 struct cmd_quit_result { cmdline_fixed_string_t quit; -diff --git a/dpdk/examples/vmdq/Makefile b/dpdk/examples/vmdq/Makefile -index 0767c715a1..7e59e4d658 100644 ---- a/dpdk/examples/vmdq/Makefile -+++ b/dpdk/examples/vmdq/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) - - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) diff --git a/dpdk/examples/vmdq/main.c b/dpdk/examples/vmdq/main.c -index 6e6fc91ec0..b082bc8c1c 100644 +index 6e6fc91ec0..29e1214a56 100644 --- a/dpdk/examples/vmdq/main.c +++ b/dpdk/examples/vmdq/main.c @@ -59,6 +59,7 @@ static uint32_t enabled_port_mask; @@ -70940,21 +98495,30 @@ index 6e6fc91ec0..b082bc8c1c 100644 printf("%lu ", rxPackets[q]); } printf("\nFinished handling signal %d\n", signum); -diff --git a/dpdk/examples/vmdq_dcb/Makefile b/dpdk/examples/vmdq_dcb/Makefile -index 2a9b04143f..2302577d00 100644 ---- a/dpdk/examples/vmdq_dcb/Makefile -+++ b/dpdk/examples/vmdq_dcb/Makefile -@@ -22,7 +22,7 @@ PKGCONF ?= pkg-config - PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) - CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) - LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) --LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) -+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk) +@@ -632,5 +662,8 @@ main(int argc, char *argv[]) + return -1; + } - build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build - $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } +diff --git a/dpdk/examples/vmdq_dcb/main.c b/dpdk/examples/vmdq_dcb/main.c +index 594c4f1959..5ad94cfd31 100644 +--- a/dpdk/examples/vmdq_dcb/main.c ++++ b/dpdk/examples/vmdq_dcb/main.c +@@ -710,5 +710,8 @@ main(int argc, char *argv[]) + /* call on master too */ + (void) lcore_main((void*)i); + ++ /* clean up the EAL */ ++ rte_eal_cleanup(); ++ + return 0; + } diff --git a/dpdk/kernel/freebsd/contigmem/contigmem.c b/dpdk/kernel/freebsd/contigmem/contigmem.c -index 64e0a7fecd..abb76f241e 100644 +index 64e0a7fecd..bd72f4d620 100644 --- a/dpdk/kernel/freebsd/contigmem/contigmem.c +++ b/dpdk/kernel/freebsd/contigmem/contigmem.c @@ -165,9 +165,11 @@ contigmem_load() @@ -70970,24 +98534,147 @@ index 64e0a7fecd..abb76f241e 100644 if (mtx_initialized(&contigmem_buffers[i].mtx)) mtx_destroy(&contigmem_buffers[i].mtx); } +@@ -297,19 +299,22 @@ contigmem_cdev_pager_fault(vm_object_t object, vm_ooffset_t offset, int prot, + VM_OBJECT_WLOCK(object); + vm_page_updatefake(page, paddr, memattr); + } else { +- vm_page_t mret; + /* + * Replace the passed in reqpage page with our own fake page and + * free up the original page. + */ + page = vm_page_getfake(paddr, memattr); + VM_OBJECT_WLOCK(object); +- mret = vm_page_replace(page, object, (*mres)->pindex); ++#if __FreeBSD__ >= 13 ++ vm_page_replace(page, object, (*mres)->pindex, *mres); ++#else ++ vm_page_t mret = vm_page_replace(page, object, (*mres)->pindex); + KASSERT(mret == *mres, + ("invalid page replacement, old=%p, ret=%p", *mres, mret)); + vm_page_lock(mret); + vm_page_free(mret); + vm_page_unlock(mret); ++#endif + *mres = page; + } + +diff --git a/dpdk/kernel/freebsd/meson.build b/dpdk/kernel/freebsd/meson.build +index dc156a43fd..bc97d784c5 100644 +--- a/dpdk/kernel/freebsd/meson.build ++++ b/dpdk/kernel/freebsd/meson.build +@@ -9,8 +9,8 @@ kmods = ['contigmem', 'nic_uio'] + # right now, which allows us to simplify things. We pull in the sourcer + # files from the individual meson.build files, and then use a custom + # target to call make, passing in the values as env parameters. +-kmod_cflags = ['-I' + meson.build_root(), +- '-I' + join_paths(meson.source_root(), 'config'), ++kmod_cflags = ['-I' + dpdk_build_root, ++ '-I' + join_paths(dpdk_source_root, 'config'), + '-include rte_config.h'] + + # to avoid warnings due to race conditions with creating the dev_if.h, etc. +diff --git a/dpdk/kernel/linux/igb_uio/compat.h b/dpdk/kernel/linux/igb_uio/compat.h +index 8dbb896ae1..850b359f36 100644 +--- a/dpdk/kernel/linux/igb_uio/compat.h ++++ b/dpdk/kernel/linux/igb_uio/compat.h +@@ -152,3 +152,17 @@ static inline bool igbuio_kernel_is_locked_down(void) + return false; + #endif + } ++ ++#ifndef fallthrough ++ ++#ifndef __has_attribute ++#define __has_attribute(x) 0 ++#endif ++ ++#if __has_attribute(__fallthrough__) ++#define fallthrough __attribute__((__fallthrough__)) ++#else ++#define fallthrough do {} while (0) ++#endif ++ ++#endif +diff --git a/dpdk/kernel/linux/igb_uio/igb_uio.c b/dpdk/kernel/linux/igb_uio/igb_uio.c +index 039f5a5f63..57d0c58ab1 100644 +--- a/dpdk/kernel/linux/igb_uio/igb_uio.c ++++ b/dpdk/kernel/linux/igb_uio/igb_uio.c +@@ -236,7 +236,7 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) + } + #endif + +- /* falls through - to MSI */ ++ fallthrough; + case RTE_INTR_MODE_MSI: + #ifndef HAVE_ALLOC_IRQ_VECTORS + if (pci_enable_msi(udev->pdev) == 0) { +@@ -255,7 +255,7 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) + break; + } + #endif +- /* falls through - to INTX */ ++ fallthrough; + case RTE_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(udev->pdev)) { + dev_dbg(&udev->pdev->dev, "using INTX"); +@@ -265,7 +265,7 @@ igbuio_pci_enable_interrupts(struct rte_uio_pci_dev *udev) + break; + } + dev_notice(&udev->pdev->dev, "PCI INTX mask not supported\n"); +- /* falls through - to no IRQ */ ++ fallthrough; + case RTE_INTR_MODE_NONE: + udev->mode = RTE_INTR_MODE_NONE; + udev->info.irq = UIO_IRQ_NONE; +diff --git a/dpdk/kernel/linux/kni/Makefile b/dpdk/kernel/linux/kni/Makefile +index 595bac2612..bf0efab96b 100644 +--- a/dpdk/kernel/linux/kni/Makefile ++++ b/dpdk/kernel/linux/kni/Makefile +@@ -16,6 +16,16 @@ MODULE_CFLAGS += -I$(RTE_OUTPUT)/include + MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h + MODULE_CFLAGS += -Wall -Werror + ++# ++# Use explicit 'source' folder for header path. In SUSE 'source' is not linked to 'build' folder. ++# ++ifdef CONFIG_SUSE_KERNEL ++ KSRC = /lib/modules/$(shell uname -r)/source ++ ifneq ($(shell grep -A 1 "ndo_tx_timeout" $(KSRC)/include/linux/netdevice.h | grep -o txqueue),) ++ MODULE_CFLAGS += -DHAVE_TX_TIMEOUT_TXQUEUE ++ endif ++endif ++ + -include /etc/lsb-release + + ifeq ($(DISTRIB_ID),Ubuntu) diff --git a/dpdk/kernel/linux/kni/compat.h b/dpdk/kernel/linux/kni/compat.h -index 7109474ec5..5f65640d5e 100644 +index 7109474ec5..3a86d12bbc 100644 --- a/dpdk/kernel/linux/kni/compat.h +++ b/dpdk/kernel/linux/kni/compat.h -@@ -130,3 +130,13 @@ +@@ -130,3 +130,22 @@ #if KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE #define HAVE_IOVA_TO_KVA_MAPPING_SUPPORT #endif + +#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE || \ + (defined(RHEL_RELEASE_CODE) && \ -+ RHEL_RELEASE_VERSION(8, 3) <= RHEL_RELEASE_CODE) ++ RHEL_RELEASE_VERSION(8, 3) <= RHEL_RELEASE_CODE) || \ ++ (defined(CONFIG_SUSE_KERNEL) && defined(HAVE_ARG_TX_QUEUE)) +#define HAVE_TX_TIMEOUT_TXQUEUE +#endif + +#if KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE +#define HAVE_TSK_IN_GUP +#endif ++ ++#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE ++#define HAVE_ETH_HW_ADDR_SET ++#endif ++ ++#if KERNEL_VERSION(5, 18, 0) > LINUX_VERSION_CODE ++#define HAVE_NETIF_RX_NI ++#endif diff --git a/dpdk/kernel/linux/kni/kni_dev.h b/dpdk/kernel/linux/kni/kni_dev.h index 5e75c6371f..c15da311ba 100644 --- a/dpdk/kernel/linux/kni/kni_dev.h @@ -71016,7 +98703,7 @@ index 5e75c6371f..c15da311ba 100644 return 0; diff --git a/dpdk/kernel/linux/kni/kni_misc.c b/dpdk/kernel/linux/kni/kni_misc.c -index cda71bde08..2b464c4381 100644 +index cda71bde08..12ece28a84 100644 --- a/dpdk/kernel/linux/kni/kni_misc.c +++ b/dpdk/kernel/linux/kni/kni_misc.c @@ -39,7 +39,7 @@ static uint32_t multiple_kthread_on; @@ -71028,7 +98715,107 @@ index cda71bde08..2b464c4381 100644 #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */ -@@ -554,14 +554,14 @@ static int __init +@@ -180,13 +180,17 @@ kni_dev_remove(struct kni_dev *dev) + if (!dev) + return -ENODEV; + ++ /* ++ * The memory of kni device is allocated and released together ++ * with net device. Release mbuf before freeing net device. ++ */ ++ kni_net_release_fifo_phy(dev); ++ + if (dev->net_dev) { + unregister_netdev(dev->net_dev); + free_netdev(dev->net_dev); + } + +- kni_net_release_fifo_phy(dev); +- + return 0; + } + +@@ -216,8 +220,8 @@ kni_release(struct inode *inode, struct file *file) + dev->pthread = NULL; + } + +- kni_dev_remove(dev); + list_del(&dev->list); ++ kni_dev_remove(dev); + } + up_write(&knet->kni_list_lock); + +@@ -396,14 +400,16 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, + pr_debug("mbuf_size: %u\n", kni->mbuf_size); + + /* if user has provided a valid mac address */ +- if (is_valid_ether_addr(dev_info.mac_addr)) ++ if (is_valid_ether_addr(dev_info.mac_addr)) { ++#ifdef HAVE_ETH_HW_ADDR_SET ++ eth_hw_addr_set(net_dev, dev_info.mac_addr); ++#else + memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN); +- else +- /* +- * Generate random mac address. eth_random_addr() is the +- * newer version of generating mac address in kernel. +- */ +- random_ether_addr(net_dev->dev_addr); ++#endif ++ } else { ++ /* Assign random MAC address. */ ++ eth_hw_addr_random(net_dev); ++ } + + if (dev_info.mtu) + net_dev->mtu = dev_info.mtu; +@@ -469,8 +475,8 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num, + dev->pthread = NULL; + } + +- kni_dev_remove(dev); + list_del(&dev->list); ++ kni_dev_remove(dev); + ret = 0; + break; + } +@@ -481,10 +487,10 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num, + return ret; + } + +-static int +-kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param) ++static long ++kni_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) + { +- int ret = -EINVAL; ++ long ret = -EINVAL; + struct net *net = current->nsproxy->net_ns; + + pr_debug("IOCTL num=0x%0x param=0x%0lx\n", ioctl_num, ioctl_param); +@@ -510,8 +516,8 @@ kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param) + return ret; + } + +-static int +-kni_compat_ioctl(struct inode *inode, uint32_t ioctl_num, ++static long ++kni_compat_ioctl(struct file *file, unsigned int ioctl_num, + unsigned long ioctl_param) + { + /* 32 bits app on 64 bits OS to be supported later */ +@@ -524,8 +530,8 @@ static const struct file_operations kni_fops = { + .owner = THIS_MODULE, + .open = kni_open, + .release = kni_release, +- .unlocked_ioctl = (void *)kni_ioctl, +- .compat_ioctl = (void *)kni_compat_ioctl, ++ .unlocked_ioctl = kni_ioctl, ++ .compat_ioctl = kni_compat_ioctl, + }; + + static struct miscdevice kni_misc = { +@@ -554,14 +560,14 @@ static int __init kni_parse_carrier_state(void) { if (!carrier) { @@ -71046,7 +98833,7 @@ index cda71bde08..2b464c4381 100644 else return -1; -@@ -588,7 +588,7 @@ kni_init(void) +@@ -588,7 +594,7 @@ kni_init(void) return -EINVAL; } @@ -71056,7 +98843,7 @@ index cda71bde08..2b464c4381 100644 else pr_debug("Default carrier state set to on.\n"); diff --git a/dpdk/kernel/linux/kni/kni_net.c b/dpdk/kernel/linux/kni/kni_net.c -index 1ba9b1b99f..c82c881a2c 100644 +index 1ba9b1b99f..46f3f5d669 100644 --- a/dpdk/kernel/linux/kni/kni_net.c +++ b/dpdk/kernel/linux/kni/kni_net.c @@ -158,7 +158,7 @@ kni_net_open(struct net_device *dev) @@ -71068,7 +98855,46 @@ index 1ba9b1b99f..c82c881a2c 100644 netif_carrier_on(dev); else netif_carrier_off(dev); -@@ -623,8 +623,13 @@ kni_net_rx(struct kni_dev *kni) +@@ -223,7 +223,7 @@ kni_fifo_trans_pa2va(struct kni_dev *kni, + break; + + prev_kva = kva; +- kva = pa2kva(kva->next); ++ kva = get_kva(kni, kva->next); + /* Convert physical address to virtual address */ + prev_kva->next = pa2va(prev_kva->next, kva); + } +@@ -400,7 +400,7 @@ kni_net_rx_normal(struct kni_dev *kni) + break; + + prev_kva = kva; +- kva = pa2kva(kva->next); ++ kva = get_kva(kni, kva->next); + data_kva = kva2data_kva(kva); + /* Convert physical address to virtual address */ + prev_kva->next = pa2va(prev_kva->next, kva); +@@ -411,7 +411,11 @@ kni_net_rx_normal(struct kni_dev *kni) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* Call netif interface */ ++#ifdef HAVE_NETIF_RX_NI + netif_rx_ni(skb); ++#else ++ netif_rx(skb); ++#endif + + /* Update statistics */ + dev->stats.rx_bytes += len; +@@ -479,7 +483,7 @@ kni_net_rx_lo_fifo(struct kni_dev *kni) + kni->va[i] = pa2va(kni->pa[i], kva); + + while (kva->next) { +- next_kva = pa2kva(kva->next); ++ next_kva = get_kva(kni, kva->next); + /* Convert physical address to virtual address */ + kva->next = pa2va(kva->next, next_kva); + kva = next_kva; +@@ -623,8 +627,13 @@ kni_net_rx(struct kni_dev *kni) /* * Deal with a transmit timeout. */ @@ -71082,11 +98908,53 @@ index 1ba9b1b99f..c82c881a2c 100644 { pr_debug("Transmit timeout at %ld, latency %ld\n", jiffies, jiffies - dev_trans_start(dev)); +@@ -747,7 +756,11 @@ kni_net_set_mac(struct net_device *netdev, void *p) + return -EADDRNOTAVAIL; + + memcpy(req.mac_addr, addr->sa_data, netdev->addr_len); ++#ifdef HAVE_ETH_HW_ADDR_SET ++ eth_hw_addr_set(netdev, addr->sa_data); ++#else + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++#endif + + kni = netdev_priv(netdev); + ret = kni_net_process_request(kni, &req); diff --git a/dpdk/kernel/linux/kni/meson.build b/dpdk/kernel/linux/kni/meson.build -index 955eec9496..f93e97fa09 100644 +index 955eec9496..eb97ec1491 100644 --- a/dpdk/kernel/linux/kni/meson.build +++ b/dpdk/kernel/linux/kni/meson.build -@@ -23,7 +23,6 @@ custom_target('rte_kni', +@@ -1,6 +1,17 @@ + # SPDX-License-Identifier: BSD-3-Clause + # Copyright(c) 2018 Luca Boccassi + ++# For SUSE build check function arguments of ndo_tx_timeout API ++# Ref: https://jira.devtools.intel.com/browse/DPDK-29263 ++kmod_cflags = '' ++file_path = kernel_source_dir + '/include/linux/netdevice.h' ++run_cmd = run_command('grep', 'ndo_tx_timeout', file_path, check: false) ++ ++if run_cmd.stdout().contains('txqueue') == true ++ kmod_cflags = '-DHAVE_ARG_TX_QUEUE' ++endif ++ ++ + kni_mkfile = custom_target('rte_kni_makefile', + output: 'Makefile', + command: ['touch', '@OUTPUT@']) +@@ -16,14 +27,14 @@ custom_target('rte_kni', + command: ['make', '-j4', '-C', kernel_dir + '/build', + 'M=' + meson.current_build_dir(), + 'src=' + meson.current_source_dir(), +- 'MODULE_CFLAGS=-include ' + meson.source_root() + '/config/rte_config.h' + +- ' -I' + meson.source_root() + '/lib/librte_eal/common/include' + +- ' -I' + meson.source_root() + '/lib/librte_eal/linux/eal/include' + +- ' -I' + meson.build_root() + ++ ' '.join(['MODULE_CFLAGS=', kmod_cflags,'-include ']) ++ + dpdk_source_root + '/config/rte_config.h' + ++ ' -I' + dpdk_source_root + '/lib/librte_eal/common/include' + ++ ' -I' + dpdk_source_root + '/lib/librte_eal/linux/eal/include' + ++ ' -I' + dpdk_build_root + ' -I' + meson.current_source_dir(), 'modules'], depends: kni_mkfile, @@ -71094,6 +98962,34 @@ index 955eec9496..f93e97fa09 100644 install: true, install_dir: kernel_dir + '/extra/dpdk', build_by_default: get_option('enable_kmods')) +diff --git a/dpdk/kernel/linux/meson.build b/dpdk/kernel/linux/meson.build +index 1796cc6861..793c58ef56 100644 +--- a/dpdk/kernel/linux/meson.build ++++ b/dpdk/kernel/linux/meson.build +@@ -10,15 +10,20 @@ if get_option('kernel_dir') == '' and meson.is_cross_build() + endif + + kernel_dir = get_option('kernel_dir') ++kernel_source_dir = get_option('kernel_dir') + if kernel_dir == '' + # use default path for native builds +- kernel_version = run_command('uname', '-r').stdout().strip() ++ kernel_version = run_command('uname', '-r', check: true).stdout().strip() + kernel_dir = '/lib/modules/' + kernel_version ++ if kernel_source_dir == '' ++ # use default path for native builds ++ kernel_source_dir = '/lib/modules/' + kernel_version + '/source' ++ endif + endif + + # test running make in kernel directory, using "make kernelversion" +-make_returncode = run_command('make', '-sC', kernel_dir + '/build', +- 'kernelversion').returncode() ++make_returncode = run_command('make', '-sC', kernel_dir + '/build', 'kernelversion', ++ check: false).returncode() + if make_returncode != 0 + warning('Cannot compile kernel modules as requested - are kernel headers installed?') + subdir_done() diff --git a/dpdk/lib/Makefile b/dpdk/lib/Makefile index 46b91ae1a4..2cbb096f12 100644 --- a/dpdk/lib/Makefile @@ -71107,11 +99003,52 @@ index 46b91ae1a4..2cbb096f12 100644 DIRS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += librte_telemetry DEPDIRS-librte_telemetry := librte_eal librte_metrics librte_ethdev DIRS-$(CONFIG_RTE_LIBRTE_RCU) += librte_rcu +diff --git a/dpdk/lib/librte_acl/acl.h b/dpdk/lib/librte_acl/acl.h +index 39d45a0c2b..6f77b10ecf 100644 +--- a/dpdk/lib/librte_acl/acl.h ++++ b/dpdk/lib/librte_acl/acl.h +@@ -45,7 +45,7 @@ struct rte_acl_bitset { + * Each transition is 64 bit value with the following format: + * | node_type_specific : 32 | node_type : 3 | node_addr : 29 | + * For all node types except RTE_ACL_NODE_MATCH, node_addr is an index +- * to the start of the node in the transtions array. ++ * to the start of the node in the transitions array. + * Few different node types are used: + * RTE_ACL_NODE_MATCH: + * node_addr value is and index into an array that contains the return value +@@ -66,7 +66,7 @@ struct rte_acl_bitset { + * RTE_ACL_NODE_SINGLE: + * always transitions to the same node regardless of the input value. + * RTE_ACL_NODE_DFA: +- * that node consits of up to 256 transitions. ++ * that node consists of up to 256 transitions. + * In attempt to conserve space all transitions are divided into 4 consecutive + * groups, by 64 transitions per group: + * group64[i] contains transitions[i * 64, .. i * 64 + 63]. diff --git a/dpdk/lib/librte_acl/acl_bld.c b/dpdk/lib/librte_acl/acl_bld.c -index b06bbe9207..d1f920b09c 100644 +index b06bbe9207..1d6caf8984 100644 --- a/dpdk/lib/librte_acl/acl_bld.c +++ b/dpdk/lib/librte_acl/acl_bld.c -@@ -778,9 +778,8 @@ acl_build_reset(struct rte_acl_ctx *ctx) +@@ -12,6 +12,9 @@ + /* number of pointers per alloc */ + #define ACL_PTR_ALLOC 32 + ++/* account for situation when all fields are 8B long */ ++#define ACL_MAX_INDEXES (2 * RTE_ACL_MAX_FIELDS) ++ + /* macros for dividing rule sets heuristics */ + #define NODE_MAX 0x4000 + #define NODE_MIN 0x800 +@@ -80,7 +83,7 @@ struct acl_build_context { + struct tb_mem_pool pool; + struct rte_acl_trie tries[RTE_ACL_MAX_TRIES]; + struct rte_acl_bld_trie bld_tries[RTE_ACL_MAX_TRIES]; +- uint32_t data_indexes[RTE_ACL_MAX_TRIES][RTE_ACL_MAX_FIELDS]; ++ uint32_t data_indexes[RTE_ACL_MAX_TRIES][ACL_MAX_INDEXES]; + + /* memory free lists for nodes and blocks used for node ptrs */ + struct acl_mem_block blocks[MEM_BLOCK_NUM]; +@@ -778,9 +781,8 @@ acl_build_reset(struct rte_acl_ctx *ctx) } static void @@ -71123,7 +99060,7 @@ index b06bbe9207..d1f920b09c 100644 { struct rte_acl_node *node, *prev; uint32_t n; -@@ -788,10 +787,71 @@ acl_gen_range(struct acl_build_context *context, +@@ -788,10 +790,71 @@ acl_gen_range(struct acl_build_context *context, prev = root; for (n = size - 1; n > 0; n--) { node = acl_alloc_node(context, level++); @@ -71197,7 +99134,7 @@ index b06bbe9207..d1f920b09c 100644 } static struct rte_acl_node * -@@ -799,52 +859,56 @@ acl_gen_range_trie(struct acl_build_context *context, +@@ -799,52 +862,56 @@ acl_gen_range_trie(struct acl_build_context *context, const void *min, const void *max, int size, int level, struct rte_acl_node **pend) { @@ -71210,11 +99147,11 @@ index b06bbe9207..d1f920b09c 100644 + struct rte_acl_node *node, *prev, *root; + const uint8_t *lo; + const uint8_t *hi; -+ -+ lo = min; -+ hi = max; - *pend = acl_alloc_node(context, level+size); ++ lo = min; ++ hi = max; ++ + *pend = acl_alloc_node(context, level + size); root = acl_alloc_node(context, level++); + prev = root; @@ -71291,6 +99228,64 @@ index b06bbe9207..d1f920b09c 100644 return root; } +@@ -924,7 +991,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head, + */ + uint64_t mask; + mask = RTE_ACL_MASKLEN_TO_BITMASK( +- fld->mask_range.u32, ++ fld->mask_range.u64, + rule->config->defs[n].size); + + /* gen a mini-trie for this field */ +@@ -1237,6 +1304,9 @@ acl_build_index(const struct rte_acl_config *config, uint32_t *data_index) + if (last_header != config->defs[n].input_index) { + last_header = config->defs[n].input_index; + data_index[m++] = config->defs[n].offset; ++ if (config->defs[n].size > sizeof(uint32_t)) ++ data_index[m++] = config->defs[n].offset + ++ sizeof(uint32_t); + } + } + +@@ -1423,14 +1493,14 @@ acl_set_data_indexes(struct rte_acl_ctx *ctx) + memcpy(ctx->data_indexes + ofs, ctx->trie[i].data_index, + n * sizeof(ctx->data_indexes[0])); + ctx->trie[i].data_index = ctx->data_indexes + ofs; +- ofs += RTE_ACL_MAX_FIELDS; ++ ofs += ACL_MAX_INDEXES; + } + } + + /* + * Internal routine, performs 'build' phase of trie generation: + * - setups build context. +- * - analizes given set of rules. ++ * - analyzes given set of rules. + * - builds internal tree(s). + */ + static int +@@ -1548,7 +1618,7 @@ rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg) + /* allocate and fill run-time structures. */ + rc = rte_acl_gen(ctx, bcx.tries, bcx.bld_tries, + bcx.num_tries, bcx.cfg.num_categories, +- RTE_ACL_MAX_FIELDS * RTE_DIM(bcx.tries) * ++ ACL_MAX_INDEXES * RTE_DIM(bcx.tries) * + sizeof(ctx->data_indexes[0]), max_size); + if (rc == 0) { + /* set data indexes. */ +diff --git a/dpdk/lib/librte_acl/acl_run_avx2.h b/dpdk/lib/librte_acl/acl_run_avx2.h +index d06d2e8782..0b8967f22e 100644 +--- a/dpdk/lib/librte_acl/acl_run_avx2.h ++++ b/dpdk/lib/librte_acl/acl_run_avx2.h +@@ -125,7 +125,7 @@ acl_process_matches_avx2x8(const struct rte_acl_ctx *ctx, + /* For each transition: put low 32 into tr_lo and high 32 into tr_hi */ + ACL_TR_HILO(mm256, __m256, t0, t1, lo, hi); + +- /* Keep transitions wth NOMATCH intact. */ ++ /* Keep transitions with NOMATCH intact. */ + *tr_lo = _mm256_blendv_epi8(*tr_lo, lo, matches); + *tr_hi = _mm256_blendv_epi8(*tr_hi, hi, matches); + } diff --git a/dpdk/lib/librte_acl/rte_acl.c b/dpdk/lib/librte_acl/rte_acl.c index 777ec4d340..715b023592 100644 --- a/dpdk/lib/librte_acl/rte_acl.c @@ -71311,6 +99306,43 @@ index 777ec4d340..715b023592 100644 int rte_acl_classify_sse(__rte_unused const struct rte_acl_ctx *ctx, __rte_unused const uint8_t **data, +diff --git a/dpdk/lib/librte_acl/rte_acl_osdep.h b/dpdk/lib/librte_acl/rte_acl_osdep.h +index b2c262dee7..3c1dc402ca 100644 +--- a/dpdk/lib/librte_acl/rte_acl_osdep.h ++++ b/dpdk/lib/librte_acl/rte_acl_osdep.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_ACL_OSDEP_H_ + #define _RTE_ACL_OSDEP_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** + * @file + * +@@ -45,4 +49,8 @@ + #include + #include + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_ACL_OSDEP_H_ */ +diff --git a/dpdk/lib/librte_bbdev/rte_bbdev.c b/dpdk/lib/librte_bbdev/rte_bbdev.c +index f6fe05acaf..8668d3cca2 100644 +--- a/dpdk/lib/librte_bbdev/rte_bbdev.c ++++ b/dpdk/lib/librte_bbdev/rte_bbdev.c +@@ -138,7 +138,7 @@ rte_bbdev_data_alloc(void) + } + + /* +- * Find data alocated for the device or if not found return first unused bbdev ++ * Find data allocated for the device or if not found return first unused bbdev + * data. If all structures are in use and none is used by the device return + * NULL. + */ diff --git a/dpdk/lib/librte_bbdev/rte_bbdev.h b/dpdk/lib/librte_bbdev/rte_bbdev.h index 591fb7914a..6fcf448262 100644 --- a/dpdk/lib/librte_bbdev/rte_bbdev.h @@ -71409,9 +99441,18 @@ index 1e119a757b..6e43495fb4 100644 enum rte_bbdev_op_type type; /**< Type of operations in a pool */ }; diff --git a/dpdk/lib/librte_bbdev/rte_bbdev_pmd.h b/dpdk/lib/librte_bbdev/rte_bbdev_pmd.h -index 24ddcee7af..237e3361d7 100644 +index 24ddcee7af..b8a5cb4015 100644 --- a/dpdk/lib/librte_bbdev/rte_bbdev_pmd.h +++ b/dpdk/lib/librte_bbdev/rte_bbdev_pmd.h +@@ -76,7 +76,7 @@ struct rte_bbdev * + rte_bbdev_get_named_dev(const char *name); + + /** +- * Definitions of all functions exported by a driver through the the generic ++ * Definitions of all functions exported by a driver through the generic + * structure of type *rte_bbdev_ops* supplied in the *rte_bbdev* structure + * associated with a device. + */ @@ -146,18 +146,18 @@ typedef int (*rte_bbdev_queue_intr_disable_t)(struct rte_bbdev *dev, * fields are for non-vital operations */ @@ -71446,8 +99487,72 @@ index 24ddcee7af..237e3361d7 100644 rte_bbdev_queue_stop_t queue_stop; /** Enable queue interrupt. Optional */ +diff --git a/dpdk/lib/librte_bitratestats/rte_bitrate.c b/dpdk/lib/librte_bitratestats/rte_bitrate.c +index d18152365e..e7f5a9aee7 100644 +--- a/dpdk/lib/librte_bitratestats/rte_bitrate.c ++++ b/dpdk/lib/librte_bitratestats/rte_bitrate.c +@@ -49,8 +49,10 @@ rte_stats_bitrate_reg(struct rte_stats_bitrates *bitrate_data) + return -EINVAL; + + return_value = rte_metrics_reg_names(&names[0], RTE_DIM(names)); +- if (return_value >= 0) ++ if (return_value >= 0) { + bitrate_data->id_stats_set = return_value; ++ return 0; ++ } + return return_value; + } + +@@ -72,7 +74,7 @@ rte_stats_bitrate_calc(struct rte_stats_bitrates *bitrate_data, + + ret_code = rte_eth_stats_get(port_id, ð_stats); + if (ret_code != 0) +- return ret_code; ++ return ret_code < 0 ? ret_code : -ret_code; + + port_data = &bitrate_data->port_stats[port_id]; + +diff --git a/dpdk/lib/librte_bpf/bpf_jit_x86.c b/dpdk/lib/librte_bpf/bpf_jit_x86.c +index f70cd6be51..885e8d5c2b 100644 +--- a/dpdk/lib/librte_bpf/bpf_jit_x86.c ++++ b/dpdk/lib/librte_bpf/bpf_jit_x86.c +@@ -1074,7 +1074,7 @@ emit_epilog(struct bpf_jit_state *st) + uint32_t i; + int32_t spil, ofs; + +- /* if we allready have an epilog generate a jump to it */ ++ /* if we already have an epilog generate a jump to it */ + if (st->exit.num++ != 0) { + emit_abs_jmp(st, st->exit.off); + return; +diff --git a/dpdk/lib/librte_bpf/bpf_load_elf.c b/dpdk/lib/librte_bpf/bpf_load_elf.c +index 2b11adeb5e..02a5d8ba0d 100644 +--- a/dpdk/lib/librte_bpf/bpf_load_elf.c ++++ b/dpdk/lib/librte_bpf/bpf_load_elf.c +@@ -80,7 +80,7 @@ resolve_xsym(const char *sn, size_t ofs, struct ebpf_insn *ins, size_t ins_sz, + if (type == RTE_BPF_XTYPE_FUNC) { + + /* we don't support multiple functions per BPF module, +- * so treat EBPF_PSEUDO_CALL to extrernal function ++ * so treat EBPF_PSEUDO_CALL to external function + * as an ordinary EBPF_CALL. + */ + if (ins[idx].src_reg == EBPF_PSEUDO_CALL) { +diff --git a/dpdk/lib/librte_bpf/bpf_pkt.c b/dpdk/lib/librte_bpf/bpf_pkt.c +index 6e8248f0d6..701e8e2c62 100644 +--- a/dpdk/lib/librte_bpf/bpf_pkt.c ++++ b/dpdk/lib/librte_bpf/bpf_pkt.c +@@ -169,7 +169,7 @@ bpf_eth_cbh_add(struct bpf_eth_cbh *cbh, uint16_t port, uint16_t queue) + } + + /* +- * BPF packet processing routinies. ++ * BPF packet processing routines. + */ + + static inline uint32_t diff --git a/dpdk/lib/librte_bpf/bpf_validate.c b/dpdk/lib/librte_bpf/bpf_validate.c -index 6bd6f78e9b..80d21fabbe 100644 +index 6bd6f78e9b..1d7a204f86 100644 --- a/dpdk/lib/librte_bpf/bpf_validate.c +++ b/dpdk/lib/librte_bpf/bpf_validate.c @@ -226,7 +226,7 @@ eval_add(struct bpf_reg_val *rd, const struct bpf_reg_val *rs, uint64_t msk) @@ -71474,6 +99579,68 @@ index 6bd6f78e9b..80d21fabbe 100644 /* * if at least one of the operands is not constant, +@@ -621,8 +621,15 @@ eval_alu(struct bpf_verifier *bvf, const struct ebpf_insn *ins) + + op = BPF_OP(ins->code); + ++ /* Allow self-xor as way to zero register */ ++ if (op == BPF_XOR && BPF_SRC(ins->code) == BPF_X && ++ ins->src_reg == ins->dst_reg) { ++ eval_fill_imm(&rs, UINT64_MAX, 0); ++ eval_fill_imm(rd, UINT64_MAX, 0); ++ } ++ + err = eval_defined((op != EBPF_MOV) ? rd : NULL, +- (op != BPF_NEG) ? &rs : NULL); ++ (op != BPF_NEG) ? &rs : NULL); + if (err != NULL) + return err; + +@@ -1075,7 +1082,7 @@ eval_jcc(struct bpf_verifier *bvf, const struct ebpf_insn *ins) + eval_jsgt_jsle(trd, trs, frd, frs); + else if (op == EBPF_JSLE) + eval_jsgt_jsle(frd, frs, trd, trs); +- else if (op == EBPF_JLT) ++ else if (op == EBPF_JSLT) + eval_jslt_jsge(trd, trs, frd, frs); + else if (op == EBPF_JSGE) + eval_jslt_jsge(frd, frs, trd, trs); +@@ -1645,7 +1652,7 @@ static const struct bpf_ins_check ins_chk[UINT8_MAX + 1] = { + + /* + * make sure that instruction syntax is valid, +- * and it fields don't violate partciular instrcution type restrictions. ++ * and its fields don't violate particular instruction type restrictions. + */ + static const char * + check_syntax(const struct ebpf_insn *ins) +@@ -1876,7 +1883,7 @@ log_loop(const struct bpf_verifier *bvf) + * First pass goes though all instructions in the set, checks that each + * instruction is a valid one (correct syntax, valid field values, etc.) + * and constructs control flow graph (CFG). +- * Then deapth-first search is performed over the constructed graph. ++ * Then depth-first search is performed over the constructed graph. + * Programs with unreachable instructions and/or loops will be rejected. + */ + static int +@@ -1903,7 +1910,7 @@ validate(struct bpf_verifier *bvf) + + /* + * construct CFG, jcc nodes have to outgoing edges, +- * 'exit' nodes - none, all others nodes have exaclty one ++ * 'exit' nodes - none, all other nodes have exactly one + * outgoing edge. + */ + switch (ins->code) { +@@ -2165,7 +2172,7 @@ evaluate(struct bpf_verifier *bvf) + idx = get_node_idx(bvf, node); + op = ins[idx].code; + +- /* for jcc node make a copy of evaluatoion state */ ++ /* for jcc node make a copy of evaluation state */ + if (node->nb_edge > 1) + rc |= save_eval_state(bvf, node); + diff --git a/dpdk/lib/librte_bpf/meson.build b/dpdk/lib/librte_bpf/meson.build index 13fc02db38..76e00e9fd4 100644 --- a/dpdk/lib/librte_bpf/meson.build @@ -71556,6 +99723,109 @@ index 8052efe675..2840c27c6c 100644 * * Defines comp device APIs for the provisioning of compression operations. */ +diff --git a/dpdk/lib/librte_compressdev/rte_compressdev_internal.h b/dpdk/lib/librte_compressdev/rte_compressdev_internal.h +index 22ceac66e2..b3b193e3ee 100644 +--- a/dpdk/lib/librte_compressdev/rte_compressdev_internal.h ++++ b/dpdk/lib/librte_compressdev/rte_compressdev_internal.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_COMPRESSDEV_INTERNAL_H_ + #define _RTE_COMPRESSDEV_INTERNAL_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /* rte_compressdev_internal.h + * This file holds Compressdev private data structures. + */ +@@ -18,7 +22,7 @@ + /* Logging Macros */ + extern int compressdev_logtype; + #define COMPRESSDEV_LOG(level, fmt, args...) \ +- rte_log(RTE_LOG_ ## level, compressdev_logtype, "%s(): "fmt "\n", \ ++ rte_log(RTE_LOG_ ## level, compressdev_logtype, "%s(): " fmt "\n", \ + __func__, ##args) + + /** +@@ -94,7 +98,7 @@ struct rte_compressdev { + struct rte_compressdev_data { + uint8_t dev_id; + /**< Compress device identifier */ +- uint8_t socket_id; ++ int socket_id; + /**< Socket identifier where memory is allocated */ + char name[RTE_COMPRESSDEV_NAME_MAX_LEN]; + /**< Unique identifier name */ +@@ -111,4 +115,9 @@ struct rte_compressdev_data { + void *dev_private; + /**< PMD-specific private data */ + } __rte_cache_aligned; ++ ++#ifdef __cplusplus ++} ++#endif ++ + #endif +diff --git a/dpdk/lib/librte_compressdev/rte_compressdev_pmd.h b/dpdk/lib/librte_compressdev/rte_compressdev_pmd.h +index c8e017577c..d9e45b3585 100644 +--- a/dpdk/lib/librte_compressdev/rte_compressdev_pmd.h ++++ b/dpdk/lib/librte_compressdev/rte_compressdev_pmd.h +@@ -64,7 +64,7 @@ struct rte_compressdev * + rte_compressdev_pmd_get_named_dev(const char *name); + + /** +- * Definitions of all functions exported by a driver through the ++ * Definitions of all functions exported by a driver through + * the generic structure of type *comp_dev_ops* supplied in the + * *rte_compressdev* structure associated with a device. + */ +diff --git a/dpdk/lib/librte_cryptodev/rte_crypto.h b/dpdk/lib/librte_cryptodev/rte_crypto.h +index fd5ef3a876..2ba12cff2e 100644 +--- a/dpdk/lib/librte_cryptodev/rte_crypto.h ++++ b/dpdk/lib/librte_cryptodev/rte_crypto.h +@@ -113,15 +113,24 @@ struct rte_crypto_op { + rte_iova_t phys_addr; + /**< physical address of crypto operation */ + ++/* empty structures do not have zero size in C++ leading to compilation errors ++ * with clang about structure/union having different sizes in C and C++. ++ * While things are clearer with an explicit union, since each field is ++ * zero-sized it's not actually needed, so omit it for C++ ++ */ ++#ifndef __cplusplus + __extension__ + union { ++#endif + struct rte_crypto_sym_op sym[0]; + /**< Symmetric operation parameters */ + + struct rte_crypto_asym_op asym[0]; + /**< Asymmetric operation parameters */ + ++#ifndef __cplusplus + }; /**< operation specific parameters */ ++#endif + }; + + /** +diff --git a/dpdk/lib/librte_cryptodev/rte_crypto_asym.h b/dpdk/lib/librte_cryptodev/rte_crypto_asym.h +index 0d34ce8dfd..f7bd2c6730 100644 +--- a/dpdk/lib/librte_cryptodev/rte_crypto_asym.h ++++ b/dpdk/lib/librte_cryptodev/rte_crypto_asym.h +@@ -133,10 +133,12 @@ enum rte_crypto_rsa_padding_type { + enum rte_crypto_rsa_priv_key_type { + RTE_RSA_KEY_TYPE_EXP, + /**< RSA private key is an exponent */ +- RTE_RSA_KET_TYPE_QT, ++ RTE_RSA_KEY_TYPE_QT, + /**< RSA private key is in quintuple format + * See rte_crypto_rsa_priv_key_qt + */ ++ RTE_RSA_KET_TYPE_QT = RTE_RSA_KEY_TYPE_QT, ++ /**< Backward-compatible definition of old name */ + }; + + /** diff --git a/dpdk/lib/librte_cryptodev/rte_crypto_sym.h b/dpdk/lib/librte_cryptodev/rte_crypto_sym.h index ffa038dc40..4e05c7c6ac 100644 --- a/dpdk/lib/librte_cryptodev/rte_crypto_sym.h @@ -71686,8 +99956,29 @@ index 89aa2ed3e2..ed9de3eb92 100644 if (dev == NULL) return NULL; +diff --git a/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.c b/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.c +index 0912004127..e342daabc4 100644 +--- a/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.c ++++ b/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.c +@@ -140,6 +140,7 @@ int + rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev) + { + int retval; ++ void *dev_priv = cryptodev->data->dev_private; + + CDEV_LOG_INFO("Closing crypto device %s", cryptodev->device->name); + +@@ -149,7 +150,7 @@ rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev) + return retval; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) +- rte_free(cryptodev->data->dev_private); ++ rte_free(dev_priv); + + + cryptodev->device = NULL; diff --git a/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.h b/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.h -index fba14f2fa0..c4935b3307 100644 +index fba14f2fa0..fa5e170624 100644 --- a/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.h +++ b/dpdk/lib/librte_cryptodev/rte_cryptodev_pmd.h @@ -41,7 +41,8 @@ extern "C" { @@ -71700,6 +99991,15 @@ index fba14f2fa0..c4935b3307 100644 }; /** +@@ -112,7 +113,7 @@ extern struct rte_cryptodev *rte_cryptodevs; + + /** + * Definitions of all functions exported by a driver through the +- * the generic structure of type *crypto_dev_ops* supplied in the ++ * generic structure of type *crypto_dev_ops* supplied in the + * *rte_cryptodev* structure associated with a device. + */ + diff --git a/dpdk/lib/librte_distributor/distributor_private.h b/dpdk/lib/librte_distributor/distributor_private.h index 489aef2acb..689fe3e183 100644 --- a/dpdk/lib/librte_distributor/distributor_private.h @@ -71727,7 +100027,7 @@ index 50b91887b5..266af64348 100644 # for clang 32-bit compiles we need libatomic for 64-bit atomic ops if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false diff --git a/dpdk/lib/librte_distributor/rte_distributor.c b/dpdk/lib/librte_distributor/rte_distributor.c -index 6c5b0c86e8..ef34facba6 100644 +index 6c5b0c86e8..50a2d0ee11 100644 --- a/dpdk/lib/librte_distributor/rte_distributor.c +++ b/dpdk/lib/librte_distributor/rte_distributor.c @@ -8,7 +8,6 @@ @@ -72027,7 +100327,8 @@ index 6c5b0c86e8..ef34facba6 100644 + return 0; + while (next_idx < num_mbufs) { - uint16_t matches[RTE_DIST_BURST_SIZE]; +- uint16_t matches[RTE_DIST_BURST_SIZE]; ++ uint16_t matches[RTE_DIST_BURST_SIZE] __rte_aligned(128); unsigned int pkts; - /* Sync with worker on GET_BUF flag. */ @@ -72232,7 +100533,7 @@ index 327c0c4ab2..a073e64612 100644 int rte_distributor_poll_pkt(struct rte_distributor *d, diff --git a/dpdk/lib/librte_distributor/rte_distributor_single.c b/dpdk/lib/librte_distributor/rte_distributor_single.c -index 91d8824c64..f4725b1d0b 100644 +index 91d8824c64..e8a13ce980 100644 --- a/dpdk/lib/librte_distributor/rte_distributor_single.c +++ b/dpdk/lib/librte_distributor/rte_distributor_single.c @@ -9,7 +9,6 @@ @@ -72254,6 +100555,29 @@ index 91d8824c64..f4725b1d0b 100644 /* Sync with distributor on RETURN_BUF flag. */ __atomic_store_n(&(buf->bufptr64), req, __ATOMIC_RELEASE); return 0; +@@ -246,8 +249,7 @@ rte_distributor_process_single(struct rte_distributor_single *d, + * worker given by the bit-position + */ + for (i = 0; i < d->num_workers; i++) +- match |= (!(d->in_flight_tags[i] ^ new_tag) +- << i); ++ match |= ((uint64_t)!(d->in_flight_tags[i] ^ new_tag) << i); + + /* Only turned-on bits are considered as match */ + match &= d->in_flight_bitmask; +diff --git a/dpdk/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/dpdk/lib/librte_eal/common/arch/arm/rte_cpuflags.c +index caf3dc83a5..22a48d505c 100644 +--- a/dpdk/lib/librte_eal/common/arch/arm/rte_cpuflags.c ++++ b/dpdk/lib/librte_eal/common/arch/arm/rte_cpuflags.c +@@ -95,7 +95,7 @@ const struct feature_entry rte_cpu_feature_table[] = { + FEAT_DEF(SHA2, REG_HWCAP, 6) + FEAT_DEF(CRC32, REG_HWCAP, 7) + FEAT_DEF(ATOMICS, REG_HWCAP, 8) +- FEAT_DEF(AARCH64, REG_PLATFORM, 1) ++ FEAT_DEF(AARCH64, REG_PLATFORM, 0) + }; + #endif /* RTE_ARCH */ + diff --git a/dpdk/lib/librte_eal/common/arch/arm/rte_cycles.c b/dpdk/lib/librte_eal/common/arch/arm/rte_cycles.c index 3500d523ef..5bd29b24b1 100644 --- a/dpdk/lib/librte_eal/common/arch/arm/rte_cycles.c @@ -72297,8 +100621,29 @@ index 3500d523ef..5bd29b24b1 100644 #else return 0; #endif +diff --git a/dpdk/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/dpdk/lib/librte_eal/common/arch/x86/rte_cpuflags.c +index 6492df556c..581c9dc1a0 100644 +--- a/dpdk/lib/librte_eal/common/arch/x86/rte_cpuflags.c ++++ b/dpdk/lib/librte_eal/common/arch/x86/rte_cpuflags.c +@@ -99,12 +99,12 @@ const struct feature_entry rte_cpu_feature_table[] = { + FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX, 3) + + FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX, 0) +- FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 2) ++ FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 3) + FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX, 4) + FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX, 5) +- FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 6) +- FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 7) +- FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 8) ++ FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 7) ++ FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 8) ++ FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 9) + FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10) + FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11) + FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16) diff --git a/dpdk/lib/librte_eal/common/eal_common_dev.c b/dpdk/lib/librte_eal/common/eal_common_dev.c -index 9e4f09d83e..363a2ca95e 100644 +index 9e4f09d83e..9d56a0e292 100644 --- a/dpdk/lib/librte_eal/common/eal_common_dev.c +++ b/dpdk/lib/librte_eal/common/eal_common_dev.c @@ -526,6 +526,7 @@ rte_dev_event_callback_unregister(const char *device_name, @@ -72309,11 +100654,31 @@ index 9e4f09d83e..363a2ca95e 100644 free(event_cb); ret++; } else { +@@ -566,7 +567,7 @@ int + rte_dev_iterator_init(struct rte_dev_iterator *it, + const char *dev_str) + { +- struct rte_devargs devargs; ++ struct rte_devargs devargs = { .bus = NULL }; + struct rte_class *cls = NULL; + struct rte_bus *bus = NULL; + diff --git a/dpdk/lib/librte_eal/common/eal_common_fbarray.c b/dpdk/lib/librte_eal/common/eal_common_fbarray.c -index 1312f936b8..de7e772042 100644 +index 1312f936b8..c45c1189b3 100644 --- a/dpdk/lib/librte_eal/common/eal_common_fbarray.c +++ b/dpdk/lib/librte_eal/common/eal_common_fbarray.c -@@ -114,7 +114,7 @@ overlap(const struct mem_area *ma, const void *start, size_t len) +@@ -80,9 +80,8 @@ get_used_mask(void *data, unsigned int elt_sz, unsigned int len) + } + + static int +-resize_and_map(int fd, void *addr, size_t len) ++resize_and_map(int fd, const char *path, void *addr, size_t len) + { +- char path[PATH_MAX]; + void *map_addr; + + if (ftruncate(fd, len)) { +@@ -114,7 +113,7 @@ overlap(const struct mem_area *ma, const void *start, size_t len) if (start >= ma_start && start < ma_end) return 1; /* end overlap? */ @@ -72322,7 +100687,25 @@ index 1312f936b8..de7e772042 100644 return 1; return 0; } -@@ -1337,7 +1337,7 @@ fbarray_find_biggest(struct rte_fbarray *arr, unsigned int start, bool used, +@@ -794,7 +793,7 @@ rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len, + goto fail; + } + +- if (resize_and_map(fd, data, mmap_len)) ++ if (resize_and_map(fd, path, data, mmap_len)) + goto fail; + } + ma->addr = data; +@@ -900,7 +899,7 @@ rte_fbarray_attach(struct rte_fbarray *arr) + goto fail; + } + +- if (resize_and_map(fd, data, mmap_len)) ++ if (resize_and_map(fd, path, data, mmap_len)) + goto fail; + + /* store our new memory area */ +@@ -1337,7 +1336,7 @@ fbarray_find_biggest(struct rte_fbarray *arr, unsigned int start, bool used, */ /* the API's called are thread-safe, but something may still happen @@ -72419,10 +100802,32 @@ index 4a9cc1f19a..4c897a13f1 100644 } diff --git a/dpdk/lib/librte_eal/common/eal_common_options.c b/dpdk/lib/librte_eal/common/eal_common_options.c -index a7f9c5f9bd..f791e9671d 100644 +index a7f9c5f9bd..7dd4d90cf7 100644 --- a/dpdk/lib/librte_eal/common/eal_common_options.c +++ b/dpdk/lib/librte_eal/common/eal_common_options.c -@@ -1039,7 +1039,7 @@ eal_parse_log_level(const char *arg) +@@ -499,10 +499,10 @@ static int + eal_parse_service_corelist(const char *corelist) + { + struct rte_config *cfg = rte_eal_get_configuration(); +- int i, idx = 0; ++ int i; + unsigned count = 0; + char *end = NULL; +- int min, max; ++ uint32_t min, max, idx; + uint32_t taken_lcore_count = 0; + + if (corelist == NULL) +@@ -526,6 +526,8 @@ eal_parse_service_corelist(const char *corelist) + idx = strtoul(corelist, &end, 10); + if (errno || end == NULL) + return -1; ++ if (idx >= RTE_MAX_LCORE) ++ return -1; + while (isblank(*end)) + end++; + if (*end == '-') { +@@ -1039,7 +1041,7 @@ eal_parse_log_level(const char *arg) if (regex) { if (rte_log_set_level_regexp(regex, priority) < 0) { fprintf(stderr, "cannot set log level %s,%d\n", @@ -72432,10 +100837,63 @@ index a7f9c5f9bd..f791e9671d 100644 } if (rte_log_save_regexp(regex, priority) < 0) diff --git a/dpdk/lib/librte_eal/common/eal_common_proc.c b/dpdk/lib/librte_eal/common/eal_common_proc.c -index 935e8fefeb..13ae2b915e 100644 +index 935e8fefeb..d88a1ebafb 100644 --- a/dpdk/lib/librte_eal/common/eal_common_proc.c +++ b/dpdk/lib/librte_eal/common/eal_common_proc.c -@@ -416,7 +416,7 @@ process_async_request(struct pending_request *sr, const struct timespec *now) +@@ -34,6 +34,7 @@ + #include "eal_internal_cfg.h" + + static int mp_fd = -1; ++static pthread_t mp_handle_tid; + static char mp_filter[PATH_MAX]; /* Filter for secondary process sockets */ + static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */ + static pthread_mutex_t mp_mutex_action = PTHREAD_MUTEX_INITIALIZER; +@@ -276,8 +277,17 @@ read_msg(struct mp_msg_internal *m, struct sockaddr_un *s) + msgh.msg_control = control; + msgh.msg_controllen = sizeof(control); + ++retry: + msglen = recvmsg(mp_fd, &msgh, 0); ++ ++ /* zero length message means socket was closed */ ++ if (msglen == 0) ++ return 0; ++ + if (msglen < 0) { ++ if (errno == EINTR) ++ goto retry; ++ + RTE_LOG(ERR, EAL, "recvmsg failed, %s\n", strerror(errno)); + return -1; + } +@@ -305,7 +315,7 @@ read_msg(struct mp_msg_internal *m, struct sockaddr_un *s) + RTE_LOG(ERR, EAL, "invalid received data length\n"); + return -1; + } +- return 0; ++ return msglen; + } + + static void +@@ -376,9 +386,14 @@ mp_handle(void *arg __rte_unused) + struct mp_msg_internal msg; + struct sockaddr_un sa; + +- while (1) { +- if (read_msg(&msg, &sa) == 0) +- process_msg(&msg, &sa); ++ while (mp_fd >= 0) { ++ int ret; ++ ++ ret = read_msg(&msg, &sa); ++ if (ret <= 0) ++ break; ++ ++ process_msg(&msg, &sa); + } + + return NULL; +@@ -416,7 +431,7 @@ process_async_request(struct pending_request *sr, const struct timespec *now) /* did we timeout? */ timeout = timespec_cmp(¶m->end, now) <= 0; @@ -72444,7 +100902,48 @@ index 935e8fefeb..13ae2b915e 100644 if (sr->reply_received == 1 && sr->reply) { struct rte_mp_msg *msg, *user_msgs, *tmp; -@@ -621,7 +621,7 @@ rte_mp_channel_init(void) +@@ -483,14 +498,11 @@ async_reply_handle_thread_unsafe(void *arg) + struct pending_request *req = (struct pending_request *)arg; + enum async_action action; + struct timespec ts_now; +- struct timeval now; + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &ts_now) < 0) { + RTE_LOG(ERR, EAL, "Cannot get current time\n"); + goto no_trigger; + } +- ts_now.tv_nsec = now.tv_usec * 1000; +- ts_now.tv_sec = now.tv_sec; + + action = process_async_request(req, &ts_now); + +@@ -563,14 +575,11 @@ open_socket_fd(void) + } + + static void +-close_socket_fd(void) ++close_socket_fd(int fd) + { + char path[PATH_MAX]; + +- if (mp_fd < 0) +- return; +- +- close(mp_fd); ++ close(fd); + create_socket_path(peer_name, path, sizeof(path)); + unlink(path); + } +@@ -580,7 +589,6 @@ rte_mp_channel_init(void) + { + char path[PATH_MAX]; + int dir_fd; +- pthread_t mp_handle_tid; + + /* in no shared files mode, we do not have secondary processes support, + * so no need to initialize IPC. +@@ -621,7 +629,7 @@ rte_mp_channel_init(void) if (rte_ctrl_thread_create(&mp_handle_tid, "rte_mp_handle", NULL, mp_handle, NULL) < 0) { @@ -72453,6 +100952,205 @@ index 935e8fefeb..13ae2b915e 100644 strerror(errno)); close(mp_fd); close(dir_fd); +@@ -639,7 +647,16 @@ rte_mp_channel_init(void) + void + rte_mp_channel_cleanup(void) + { +- close_socket_fd(); ++ int fd; ++ ++ if (mp_fd < 0) ++ return; ++ ++ fd = mp_fd; ++ mp_fd = -1; ++ pthread_cancel(mp_handle_tid); ++ pthread_join(mp_handle_tid, NULL); ++ close_socket_fd(fd); + } + + /** +@@ -884,6 +901,7 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req, + struct rte_mp_reply *reply, const struct timespec *ts) + { + int ret; ++ pthread_condattr_t attr; + struct rte_mp_msg msg, *tmp; + struct pending_request pending_req, *exist; + +@@ -892,7 +910,9 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req, + strlcpy(pending_req.dst, dst, sizeof(pending_req.dst)); + pending_req.request = req; + pending_req.reply = &msg; +- pthread_cond_init(&pending_req.sync.cond, NULL); ++ pthread_condattr_init(&attr); ++ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); ++ pthread_cond_init(&pending_req.sync.cond, &attr); + + exist = find_pending_request(dst, req->name); + if (exist) { +@@ -955,8 +975,7 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, + int dir_fd, ret = -1; + DIR *mp_dir; + struct dirent *ent; +- struct timeval now; +- struct timespec end; ++ struct timespec now, end; + + RTE_LOG(DEBUG, EAL, "request: %s\n", req->name); + +@@ -973,15 +992,15 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, + return -1; + } + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) { + RTE_LOG(ERR, EAL, "Failed to get current time\n"); + rte_errno = errno; + goto end; + } + +- end.tv_nsec = (now.tv_usec * 1000 + ts->tv_nsec) % 1000000000; ++ end.tv_nsec = (now.tv_nsec + ts->tv_nsec) % 1000000000; + end.tv_sec = now.tv_sec + ts->tv_sec + +- (now.tv_usec * 1000 + ts->tv_nsec) / 1000000000; ++ (now.tv_nsec + ts->tv_nsec) / 1000000000; + + /* for secondary process, send request to the primary process only */ + if (rte_eal_process_type() == RTE_PROC_SECONDARY) { +@@ -1055,7 +1074,7 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + int dir_fd, ret = 0; + DIR *mp_dir; + struct dirent *ent; +- struct timeval now; ++ struct timespec now; + struct timespec *end; + bool dummy_used = false; + +@@ -1070,7 +1089,7 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + return -1; + } + +- if (gettimeofday(&now, NULL) < 0) { ++ if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) { + RTE_LOG(ERR, EAL, "Failed to get current time\n"); + rte_errno = errno; + return -1; +@@ -1092,9 +1111,9 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, + end = ¶m->end; + reply = ¶m->user_reply; + +- end->tv_nsec = (now.tv_usec * 1000 + ts->tv_nsec) % 1000000000; ++ end->tv_nsec = (now.tv_nsec + ts->tv_nsec) % 1000000000; + end->tv_sec = now.tv_sec + ts->tv_sec + +- (now.tv_usec * 1000 + ts->tv_nsec) / 1000000000; ++ (now.tv_nsec + ts->tv_nsec) / 1000000000; + reply->nb_sent = 0; + reply->nb_received = 0; + reply->msgs = NULL; +diff --git a/dpdk/lib/librte_eal/common/eal_common_thread.c b/dpdk/lib/librte_eal/common/eal_common_thread.c +index f9a8cf14d2..b1e5c2a08d 100644 +--- a/dpdk/lib/librte_eal/common/eal_common_thread.c ++++ b/dpdk/lib/librte_eal/common/eal_common_thread.c +@@ -147,20 +147,29 @@ struct rte_thread_ctrl_params { + void *(*start_routine)(void *); + void *arg; + pthread_barrier_t configured; ++ unsigned int refcnt; + }; + ++static void ctrl_params_free(struct rte_thread_ctrl_params *params) ++{ ++ if (__atomic_sub_fetch(¶ms->refcnt, 1, __ATOMIC_ACQ_REL) == 0) { ++ (void)pthread_barrier_destroy(¶ms->configured); ++ free(params); ++ } ++} ++ + static void *rte_thread_init(void *arg) + { +- int ret; + struct rte_thread_ctrl_params *params = arg; +- void *(*start_routine)(void *) = params->start_routine; ++ void *(*start_routine)(void *); + void *routine_arg = params->arg; + +- ret = pthread_barrier_wait(¶ms->configured); +- if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { +- pthread_barrier_destroy(¶ms->configured); +- free(params); +- } ++ pthread_barrier_wait(¶ms->configured); ++ start_routine = params->start_routine; ++ ctrl_params_free(params); ++ ++ if (start_routine == NULL) ++ return NULL; + + return start_routine(routine_arg); + } +@@ -180,14 +189,15 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, + + params->start_routine = start_routine; + params->arg = arg; ++ params->refcnt = 2; + +- pthread_barrier_init(¶ms->configured, NULL, 2); ++ ret = pthread_barrier_init(¶ms->configured, NULL, 2); ++ if (ret != 0) ++ goto fail_no_barrier; + + ret = pthread_create(thread, attr, rte_thread_init, (void *)params); +- if (ret != 0) { +- free(params); +- return -ret; +- } ++ if (ret != 0) ++ goto fail_with_barrier; + + if (name != NULL) { + ret = rte_thread_setname(*thread, name); +@@ -197,24 +207,24 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name, + } + + ret = pthread_setaffinity_np(*thread, sizeof(*cpuset), cpuset); +- if (ret) +- goto fail; ++ if (ret != 0) ++ params->start_routine = NULL; + +- ret = pthread_barrier_wait(¶ms->configured); +- if (ret == PTHREAD_BARRIER_SERIAL_THREAD) { +- pthread_barrier_destroy(¶ms->configured); +- free(params); +- } ++ pthread_barrier_wait(¶ms->configured); ++ ctrl_params_free(params); + +- return 0; ++ if (ret != 0) ++ /* start_routine has been set to NULL above; */ ++ /* ctrl thread will exit immediately */ ++ pthread_join(*thread, NULL); ++ ++ return -ret; ++ ++fail_with_barrier: ++ (void)pthread_barrier_destroy(¶ms->configured); ++ ++fail_no_barrier: ++ free(params); + +-fail: +- if (PTHREAD_BARRIER_SERIAL_THREAD == +- pthread_barrier_wait(¶ms->configured)) { +- pthread_barrier_destroy(¶ms->configured); +- free(params); +- } +- pthread_cancel(*thread); +- pthread_join(*thread, NULL); + return -ret; + } diff --git a/dpdk/lib/librte_eal/common/include/arch/arm/meson.build b/dpdk/lib/librte_eal/common/include/arch/arm/meson.build index 77893fa359..faa3d84f67 100644 --- a/dpdk/lib/librte_eal/common/include/arch/arm/meson.build @@ -72733,9 +101431,17 @@ index 0000000000..1551a94544 + +#endif /* _RTE_ALTIVEC_H_ */ diff --git a/dpdk/lib/librte_eal/common/include/arch/ppc_64/rte_memcpy.h b/dpdk/lib/librte_eal/common/include/arch/ppc_64/rte_memcpy.h -index 25311ba1d7..e63a1211a8 100644 +index 25311ba1d7..10ed5159af 100644 --- a/dpdk/lib/librte_eal/common/include/arch/ppc_64/rte_memcpy.h +++ b/dpdk/lib/librte_eal/common/include/arch/ppc_64/rte_memcpy.h +@@ -1,6 +1,6 @@ + /* + * SPDX-License-Identifier: BSD-3-Clause +- * Copyright (C) IBM Corporation 2014. ++ * Copyright (C) IBM Corporation 2014,2021 + */ + + #ifndef _RTE_MEMCPY_PPC_64_H_ @@ -8,8 +8,10 @@ #include @@ -72749,23 +101455,32 @@ index 25311ba1d7..e63a1211a8 100644 #ifdef __cplusplus extern "C" { -@@ -17,6 +19,11 @@ extern "C" { +@@ -17,6 +19,16 @@ extern "C" { #include "generic/rte_memcpy.h" -+#if (GCC_VERSION >= 90000 && GCC_VERSION < 90400) ++#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 90000) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + ++#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 100000) ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wstringop-overflow" ++#endif ++ static inline void rte_mov16(uint8_t *dst, const uint8_t *src) { -@@ -192,6 +199,10 @@ rte_memcpy_func(void *dst, const void *src, size_t n) +@@ -192,6 +204,14 @@ rte_memcpy_func(void *dst, const void *src, size_t n) return ret; } -+#if (GCC_VERSION >= 90000 && GCC_VERSION < 90400) ++#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 100000) ++#pragma GCC diagnostic pop ++#endif ++ ++#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 90000) +#pragma GCC diagnostic pop +#endif + @@ -72818,7 +101533,7 @@ index 148398f50a..b9dcd30aba 100644 * Basic idea is to use lock prefixed add with some dummy memory location * as the destination. From their experiments 128B(2 cache lines) below diff --git a/dpdk/lib/librte_eal/common/include/arch/x86/rte_memcpy.h b/dpdk/lib/librte_eal/common/include/arch/x86/rte_memcpy.h -index ba44c4a328..d01832fa15 100644 +index ba44c4a328..0c3a2caa91 100644 --- a/dpdk/lib/librte_eal/common/include/arch/x86/rte_memcpy.h +++ b/dpdk/lib/librte_eal/common/include/arch/x86/rte_memcpy.h @@ -22,6 +22,11 @@ @@ -72833,19 +101548,332 @@ index ba44c4a328..d01832fa15 100644 /** * Copy bytes from one location to another. The locations must not overlap. * -@@ -40,7 +45,7 @@ extern "C" { +@@ -40,7 +45,53 @@ extern "C" { static __rte_always_inline void * rte_memcpy(void *dst, const void *src, size_t n); -#ifdef RTE_MACHINE_CPUFLAG_AVX512F ++/** ++ * Copy bytes from one location to another, ++ * locations should not overlap. ++ * Use with n <= 15. ++ */ ++static __rte_always_inline void * ++rte_mov15_or_less(void *dst, const void *src, size_t n) ++{ ++ /** ++ * Use the following structs to avoid violating C standard ++ * alignment requirements and to avoid strict aliasing bugs ++ */ ++ struct rte_uint64_alias { ++ uint64_t val; ++ } __rte_packed __rte_may_alias; ++ struct rte_uint32_alias { ++ uint32_t val; ++ } __rte_packed __rte_may_alias; ++ struct rte_uint16_alias { ++ uint16_t val; ++ } __rte_packed __rte_may_alias; ++ ++ void *ret = dst; ++ if (n & 8) { ++ ((struct rte_uint64_alias *)dst)->val = ++ ((const struct rte_uint64_alias *)src)->val; ++ src = (const uint64_t *)src + 1; ++ dst = (uint64_t *)dst + 1; ++ } ++ if (n & 4) { ++ ((struct rte_uint32_alias *)dst)->val = ++ ((const struct rte_uint32_alias *)src)->val; ++ src = (const uint32_t *)src + 1; ++ dst = (uint32_t *)dst + 1; ++ } ++ if (n & 2) { ++ ((struct rte_uint16_alias *)dst)->val = ++ ((const struct rte_uint16_alias *)src)->val; ++ src = (const uint16_t *)src + 1; ++ dst = (uint16_t *)dst + 1; ++ } ++ if (n & 1) ++ *(uint8_t *)dst = *(const uint8_t *)src; ++ return ret; ++} ++ +#if defined RTE_MACHINE_CPUFLAG_AVX512F && defined RTE_MEMCPY_AVX512 #define ALIGNMENT_MASK 0x3F -@@ -869,6 +874,10 @@ rte_memcpy(void *dst, const void *src, size_t n) +@@ -166,8 +217,6 @@ rte_mov512blocks(uint8_t *dst, const uint8_t *src, size_t n) + static __rte_always_inline void * + rte_memcpy_generic(void *dst, const void *src, size_t n) + { +- uintptr_t dstu = (uintptr_t)dst; +- uintptr_t srcu = (uintptr_t)src; + void *ret = dst; + size_t dstofss; + size_t bits; +@@ -176,24 +225,7 @@ rte_memcpy_generic(void *dst, const void *src, size_t n) + * Copy less than 16 bytes + */ + if (n < 16) { +- if (n & 0x01) { +- *(uint8_t *)dstu = *(const uint8_t *)srcu; +- srcu = (uintptr_t)((const uint8_t *)srcu + 1); +- dstu = (uintptr_t)((uint8_t *)dstu + 1); +- } +- if (n & 0x02) { +- *(uint16_t *)dstu = *(const uint16_t *)srcu; +- srcu = (uintptr_t)((const uint16_t *)srcu + 1); +- dstu = (uintptr_t)((uint16_t *)dstu + 1); +- } +- if (n & 0x04) { +- *(uint32_t *)dstu = *(const uint32_t *)srcu; +- srcu = (uintptr_t)((const uint32_t *)srcu + 1); +- dstu = (uintptr_t)((uint32_t *)dstu + 1); +- } +- if (n & 0x08) +- *(uint64_t *)dstu = *(const uint64_t *)srcu; +- return ret; ++ return rte_mov15_or_less(dst, src, n); + } + + /** +@@ -298,8 +330,8 @@ rte_mov16(uint8_t *dst, const uint8_t *src) + { + __m128i xmm0; + +- xmm0 = _mm_loadu_si128((const __m128i *)src); +- _mm_storeu_si128((__m128i *)dst, xmm0); ++ xmm0 = _mm_loadu_si128((const __m128i *)(const void *)src); ++ _mm_storeu_si128((__m128i *)(void *)dst, xmm0); + } + + /** +@@ -311,8 +343,8 @@ rte_mov32(uint8_t *dst, const uint8_t *src) + { + __m256i ymm0; + +- ymm0 = _mm256_loadu_si256((const __m256i *)src); +- _mm256_storeu_si256((__m256i *)dst, ymm0); ++ ymm0 = _mm256_loadu_si256((const __m256i *)(const void *)src); ++ _mm256_storeu_si256((__m256i *)(void *)dst, ymm0); + } + + /** +@@ -349,16 +381,24 @@ rte_mov128blocks(uint8_t *dst, const uint8_t *src, size_t n) + __m256i ymm0, ymm1, ymm2, ymm3; + + while (n >= 128) { +- ymm0 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 0 * 32)); ++ ymm0 = _mm256_loadu_si256((const __m256i *)(const void *) ++ ((const uint8_t *)src + 0 * 32)); + n -= 128; +- ymm1 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 1 * 32)); +- ymm2 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 2 * 32)); +- ymm3 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 3 * 32)); ++ ymm1 = _mm256_loadu_si256((const __m256i *)(const void *) ++ ((const uint8_t *)src + 1 * 32)); ++ ymm2 = _mm256_loadu_si256((const __m256i *)(const void *) ++ ((const uint8_t *)src + 2 * 32)); ++ ymm3 = _mm256_loadu_si256((const __m256i *)(const void *) ++ ((const uint8_t *)src + 3 * 32)); + src = (const uint8_t *)src + 128; +- _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 0 * 32), ymm0); +- _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 1 * 32), ymm1); +- _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 2 * 32), ymm2); +- _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 3 * 32), ymm3); ++ _mm256_storeu_si256((__m256i *)(void *) ++ ((uint8_t *)dst + 0 * 32), ymm0); ++ _mm256_storeu_si256((__m256i *)(void *) ++ ((uint8_t *)dst + 1 * 32), ymm1); ++ _mm256_storeu_si256((__m256i *)(void *) ++ ((uint8_t *)dst + 2 * 32), ymm2); ++ _mm256_storeu_si256((__m256i *)(void *) ++ ((uint8_t *)dst + 3 * 32), ymm3); + dst = (uint8_t *)dst + 128; + } + } +@@ -366,8 +406,6 @@ rte_mov128blocks(uint8_t *dst, const uint8_t *src, size_t n) + static __rte_always_inline void * + rte_memcpy_generic(void *dst, const void *src, size_t n) + { +- uintptr_t dstu = (uintptr_t)dst; +- uintptr_t srcu = (uintptr_t)src; + void *ret = dst; + size_t dstofss; + size_t bits; +@@ -376,25 +414,7 @@ rte_memcpy_generic(void *dst, const void *src, size_t n) + * Copy less than 16 bytes + */ + if (n < 16) { +- if (n & 0x01) { +- *(uint8_t *)dstu = *(const uint8_t *)srcu; +- srcu = (uintptr_t)((const uint8_t *)srcu + 1); +- dstu = (uintptr_t)((uint8_t *)dstu + 1); +- } +- if (n & 0x02) { +- *(uint16_t *)dstu = *(const uint16_t *)srcu; +- srcu = (uintptr_t)((const uint16_t *)srcu + 1); +- dstu = (uintptr_t)((uint16_t *)dstu + 1); +- } +- if (n & 0x04) { +- *(uint32_t *)dstu = *(const uint32_t *)srcu; +- srcu = (uintptr_t)((const uint32_t *)srcu + 1); +- dstu = (uintptr_t)((uint32_t *)dstu + 1); +- } +- if (n & 0x08) { +- *(uint64_t *)dstu = *(const uint64_t *)srcu; +- } +- return ret; ++ return rte_mov15_or_less(dst, src, n); + } + + /** +@@ -491,8 +511,8 @@ rte_mov16(uint8_t *dst, const uint8_t *src) + { + __m128i xmm0; + +- xmm0 = _mm_loadu_si128((const __m128i *)(const __m128i *)src); +- _mm_storeu_si128((__m128i *)dst, xmm0); ++ xmm0 = _mm_loadu_si128((const __m128i *)(const void *)src); ++ _mm_storeu_si128((__m128i *)(void *)dst, xmm0); + } + + /** +@@ -576,25 +596,25 @@ rte_mov256(uint8_t *dst, const uint8_t *src) + __extension__ ({ \ + size_t tmp; \ + while (len >= 128 + 16 - offset) { \ +- xmm0 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 0 * 16)); \ ++ xmm0 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 0 * 16)); \ + len -= 128; \ +- xmm1 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 1 * 16)); \ +- xmm2 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 2 * 16)); \ +- xmm3 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 3 * 16)); \ +- xmm4 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 4 * 16)); \ +- xmm5 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 5 * 16)); \ +- xmm6 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 6 * 16)); \ +- xmm7 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 7 * 16)); \ +- xmm8 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 8 * 16)); \ ++ xmm1 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 1 * 16)); \ ++ xmm2 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 2 * 16)); \ ++ xmm3 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 3 * 16)); \ ++ xmm4 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 4 * 16)); \ ++ xmm5 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 5 * 16)); \ ++ xmm6 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 6 * 16)); \ ++ xmm7 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 7 * 16)); \ ++ xmm8 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 8 * 16)); \ + src = (const uint8_t *)src + 128; \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 2 * 16), _mm_alignr_epi8(xmm3, xmm2, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 3 * 16), _mm_alignr_epi8(xmm4, xmm3, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 4 * 16), _mm_alignr_epi8(xmm5, xmm4, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 5 * 16), _mm_alignr_epi8(xmm6, xmm5, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 6 * 16), _mm_alignr_epi8(xmm7, xmm6, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 7 * 16), _mm_alignr_epi8(xmm8, xmm7, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 2 * 16), _mm_alignr_epi8(xmm3, xmm2, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 3 * 16), _mm_alignr_epi8(xmm4, xmm3, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 4 * 16), _mm_alignr_epi8(xmm5, xmm4, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 5 * 16), _mm_alignr_epi8(xmm6, xmm5, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 6 * 16), _mm_alignr_epi8(xmm7, xmm6, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 7 * 16), _mm_alignr_epi8(xmm8, xmm7, offset)); \ + dst = (uint8_t *)dst + 128; \ + } \ + tmp = len; \ +@@ -604,13 +624,13 @@ __extension__ ({ + dst = (uint8_t *)dst + tmp; \ + if (len >= 32 + 16 - offset) { \ + while (len >= 32 + 16 - offset) { \ +- xmm0 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 0 * 16)); \ ++ xmm0 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 0 * 16)); \ + len -= 32; \ +- xmm1 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 1 * 16)); \ +- xmm2 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 2 * 16)); \ ++ xmm1 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 1 * 16)); \ ++ xmm2 = _mm_loadu_si128((const __m128i *)(const void *)((const uint8_t *)src - offset + 2 * 16)); \ + src = (const uint8_t *)src + 32; \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \ +- _mm_storeu_si128((__m128i *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \ ++ _mm_storeu_si128((__m128i *)(void *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \ + dst = (uint8_t *)dst + 32; \ + } \ + tmp = len; \ +@@ -659,8 +679,6 @@ static __rte_always_inline void * + rte_memcpy_generic(void *dst, const void *src, size_t n) + { + __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; +- uintptr_t dstu = (uintptr_t)dst; +- uintptr_t srcu = (uintptr_t)src; + void *ret = dst; + size_t dstofss; + size_t srcofs; +@@ -669,25 +687,7 @@ rte_memcpy_generic(void *dst, const void *src, size_t n) + * Copy less than 16 bytes + */ + if (n < 16) { +- if (n & 0x01) { +- *(uint8_t *)dstu = *(const uint8_t *)srcu; +- srcu = (uintptr_t)((const uint8_t *)srcu + 1); +- dstu = (uintptr_t)((uint8_t *)dstu + 1); +- } +- if (n & 0x02) { +- *(uint16_t *)dstu = *(const uint16_t *)srcu; +- srcu = (uintptr_t)((const uint16_t *)srcu + 1); +- dstu = (uintptr_t)((uint16_t *)dstu + 1); +- } +- if (n & 0x04) { +- *(uint32_t *)dstu = *(const uint32_t *)srcu; +- srcu = (uintptr_t)((const uint32_t *)srcu + 1); +- dstu = (uintptr_t)((uint32_t *)dstu + 1); +- } +- if (n & 0x08) { +- *(uint64_t *)dstu = *(const uint64_t *)srcu; +- } +- return ret; ++ return rte_mov15_or_less(dst, src, n); + } + + /** +@@ -805,27 +805,9 @@ rte_memcpy_aligned(void *dst, const void *src, size_t n) + { + void *ret = dst; + +- /* Copy size <= 16 bytes */ ++ /* Copy size < 16 bytes */ + if (n < 16) { +- if (n & 0x01) { +- *(uint8_t *)dst = *(const uint8_t *)src; +- src = (const uint8_t *)src + 1; +- dst = (uint8_t *)dst + 1; +- } +- if (n & 0x02) { +- *(uint16_t *)dst = *(const uint16_t *)src; +- src = (const uint16_t *)src + 1; +- dst = (uint16_t *)dst + 1; +- } +- if (n & 0x04) { +- *(uint32_t *)dst = *(const uint32_t *)src; +- src = (const uint32_t *)src + 1; +- dst = (uint32_t *)dst + 1; +- } +- if (n & 0x08) +- *(uint64_t *)dst = *(const uint64_t *)src; +- +- return ret; ++ return rte_mov15_or_less(dst, src, n); + } + + /* Copy 16 <= size <= 32 bytes */ +@@ -869,6 +851,12 @@ rte_memcpy(void *dst, const void *src, size_t n) return rte_memcpy_generic(dst, src, n); } ++#undef ALIGNMENT_MASK ++ +#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 100000) +#pragma GCC diagnostic pop +#endif @@ -72913,11 +101941,87 @@ index 701e550c31..e7f0f8eaa9 100644 * @param dst * Pointer to the destination of the data. * @param src +diff --git a/dpdk/lib/librte_eal/common/include/generic/rte_ticketlock.h b/dpdk/lib/librte_eal/common/include/generic/rte_ticketlock.h +index d9bec87692..5f432cfbe8 100644 +--- a/dpdk/lib/librte_eal/common/include/generic/rte_ticketlock.h ++++ b/dpdk/lib/librte_eal/common/include/generic/rte_ticketlock.h +@@ -96,13 +96,13 @@ __rte_experimental + static inline int + rte_ticketlock_trylock(rte_ticketlock_t *tl) + { +- rte_ticketlock_t old, new; +- old.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_RELAXED); +- new.tickets = old.tickets; +- new.s.next++; +- if (old.s.next == old.s.current) { +- if (__atomic_compare_exchange_n(&tl->tickets, &old.tickets, +- new.tickets, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) ++ rte_ticketlock_t oldl, newl; ++ oldl.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_RELAXED); ++ newl.tickets = oldl.tickets; ++ newl.s.next++; ++ if (oldl.s.next == oldl.s.current) { ++ if (__atomic_compare_exchange_n(&tl->tickets, &oldl.tickets, ++ newl.tickets, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + return 1; + } + +diff --git a/dpdk/lib/librte_eal/common/include/rte_bitmap.h b/dpdk/lib/librte_eal/common/include/rte_bitmap.h +index 6b846f251b..9f9465ab12 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_bitmap.h ++++ b/dpdk/lib/librte_eal/common/include/rte_bitmap.h +@@ -185,9 +185,8 @@ rte_bitmap_init(uint32_t n_bits, uint8_t *mem, uint32_t mem_size) + size = __rte_bitmap_get_memory_footprint(n_bits, + &array1_byte_offset, &array1_slabs, + &array2_byte_offset, &array2_slabs); +- if (size < mem_size) { ++ if (size > mem_size) + return NULL; +- } + + /* Setup bitmap */ + memset(mem, 0, size); +diff --git a/dpdk/lib/librte_eal/common/include/rte_branch_prediction.h b/dpdk/lib/librte_eal/common/include/rte_branch_prediction.h +index 854ef9e5dd..0256a9de60 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_branch_prediction.h ++++ b/dpdk/lib/librte_eal/common/include/rte_branch_prediction.h +@@ -10,6 +10,10 @@ + #ifndef _RTE_BRANCH_PREDICTION_H_ + #define _RTE_BRANCH_PREDICTION_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** + * Check if a branch is likely to be taken. + * +@@ -38,4 +42,8 @@ + #define unlikely(x) __builtin_expect(!!(x), 0) + #endif /* unlikely */ + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_BRANCH_PREDICTION_H_ */ diff --git a/dpdk/lib/librte_eal/common/include/rte_common.h b/dpdk/lib/librte_eal/common/include/rte_common.h -index 459d082d14..fe7539af26 100644 +index 459d082d14..fc938eadcd 100644 --- a/dpdk/lib/librte_eal/common/include/rte_common.h +++ b/dpdk/lib/librte_eal/common/include/rte_common.h -@@ -245,7 +245,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) +@@ -68,6 +68,11 @@ typedef uint16_t unaligned_uint16_t; + */ + #define __rte_packed __attribute__((__packed__)) + ++/** ++ * Macro to mark a type that is not subject to type-based aliasing rules ++ */ ++#define __rte_may_alias __attribute__((__may_alias__)) ++ + /******* Macro to mark functions and fields scheduled for removal *****/ + #define __rte_deprecated __attribute__((__deprecated__)) + +@@ -245,7 +250,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) * than the first parameter. */ #define RTE_ALIGN_MUL_CEIL(v, mul) \ @@ -72926,7 +102030,7 @@ index 459d082d14..fe7539af26 100644 /** * Macro to align a value to the multiple of given value. The resultant -@@ -253,7 +253,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) +@@ -253,7 +258,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) * than the first parameter. */ #define RTE_ALIGN_MUL_FLOOR(v, mul) \ @@ -72935,7 +102039,7 @@ index 459d082d14..fe7539af26 100644 /** * Macro to align value to the nearest multiple of the given value. -@@ -264,7 +264,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) +@@ -264,7 +269,7 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void) ({ \ typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul); \ typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul); \ @@ -72944,7 +102048,7 @@ index 459d082d14..fe7539af26 100644 }) /** -@@ -347,7 +347,7 @@ typedef uint64_t rte_iova_t; +@@ -347,7 +352,7 @@ typedef uint64_t rte_iova_t; * The combined value. */ static inline uint32_t @@ -72953,7 +102057,7 @@ index 459d082d14..fe7539af26 100644 { x |= x >> 1; x |= x >> 2; -@@ -369,7 +369,7 @@ rte_combine32ms1b(register uint32_t x) +@@ -369,7 +374,7 @@ rte_combine32ms1b(register uint32_t x) * The combined value. */ static inline uint64_t @@ -72962,7 +102066,7 @@ index 459d082d14..fe7539af26 100644 { v |= v >> 1; v |= v >> 2; -@@ -538,6 +538,9 @@ rte_bsf32_safe(uint64_t v, uint32_t *pos) +@@ -538,6 +543,9 @@ rte_bsf32_safe(uint64_t v, uint32_t *pos) /** * Return the rounded-up log2 of a integer. * @@ -72972,7 +102076,7 @@ index 459d082d14..fe7539af26 100644 * @param v * The input parameter. * @return -@@ -632,6 +635,9 @@ rte_fls_u64(uint64_t x) +@@ -632,6 +640,9 @@ rte_fls_u64(uint64_t x) /** * Return the rounded-up log2 of a 64-bit integer. * @@ -72982,6 +102086,54 @@ index 459d082d14..fe7539af26 100644 * @param v * The input parameter. * @return +diff --git a/dpdk/lib/librte_eal/common/include/rte_compat.h b/dpdk/lib/librte_eal/common/include/rte_compat.h +index 3eb33784b3..0b8ba4353a 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_compat.h ++++ b/dpdk/lib/librte_eal/common/include/rte_compat.h +@@ -6,6 +6,10 @@ + #ifndef _RTE_COMPAT_H_ + #define _RTE_COMPAT_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #ifndef ALLOW_EXPERIMENTAL_API + + #define __rte_experimental \ +@@ -19,4 +23,8 @@ __attribute__((section(".text.experimental"))) + + #endif + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_COMPAT_H_ */ +diff --git a/dpdk/lib/librte_eal/common/include/rte_dev.h b/dpdk/lib/librte_eal/common/include/rte_dev.h +index a5c35f00c0..606f4b7cc1 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_dev.h ++++ b/dpdk/lib/librte_eal/common/include/rte_dev.h +@@ -339,10 +339,6 @@ rte_dev_iterator_next(struct rte_dev_iterator *it); + dev != NULL; \ + dev = rte_dev_iterator_next(it)) + +-#ifdef __cplusplus +-} +-#endif +- + /** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice +@@ -515,4 +511,8 @@ int + rte_dev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, + size_t len); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_DEV_H_ */ diff --git a/dpdk/lib/librte_eal/common/include/rte_eal.h b/dpdk/lib/librte_eal/common/include/rte_eal.h index 2f9ed298de..58f41d329f 100644 --- a/dpdk/lib/librte_eal/common/include/rte_eal.h @@ -72998,24 +102150,158 @@ index 2f9ed298de..58f41d329f 100644 */ int rte_eal_cleanup(void); +diff --git a/dpdk/lib/librte_eal/common/include/rte_function_versioning.h b/dpdk/lib/librte_eal/common/include/rte_function_versioning.h +index c924351d5e..a3b34a50ea 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_function_versioning.h ++++ b/dpdk/lib/librte_eal/common/include/rte_function_versioning.h +@@ -15,7 +15,7 @@ + + /* + * Provides backwards compatibility when updating exported functions. +- * When a symol is exported from a library to provide an API, it also provides a ++ * When a symbol is exported from a library to provide an API, it also provides a + * calling convention (ABI) that is embodied in its name, return type, + * arguments, etc. On occasion that function may need to change to accommodate + * new functionality, behavior, etc. When that occurs, it is desirable to +diff --git a/dpdk/lib/librte_eal/common/include/rte_hypervisor.h b/dpdk/lib/librte_eal/common/include/rte_hypervisor.h +index 5fe719c1d4..1666431ce3 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_hypervisor.h ++++ b/dpdk/lib/librte_eal/common/include/rte_hypervisor.h +@@ -5,6 +5,10 @@ + #ifndef RTE_HYPERVISOR_H + #define RTE_HYPERVISOR_H + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** + * @file + * Hypervisor awareness. +@@ -30,4 +34,8 @@ rte_hypervisor_get(void); + const char * + rte_hypervisor_get_name(enum rte_hypervisor id); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* RTE_HYPERVISOR_H */ +diff --git a/dpdk/lib/librte_eal/common/include/rte_keepalive.h b/dpdk/lib/librte_eal/common/include/rte_keepalive.h +index 4bda7ca56f..cd50992952 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_keepalive.h ++++ b/dpdk/lib/librte_eal/common/include/rte_keepalive.h +@@ -11,6 +11,10 @@ + #ifndef _KEEPALIVE_H_ + #define _KEEPALIVE_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + #include + +@@ -139,4 +143,8 @@ rte_keepalive_register_relay_callback(struct rte_keepalive *keepcfg, + rte_keepalive_relay_callback_t callback, + void *data); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _KEEPALIVE_H_ */ +diff --git a/dpdk/lib/librte_eal/common/include/rte_pci_dev_feature_defs.h b/dpdk/lib/librte_eal/common/include/rte_pci_dev_feature_defs.h +index e12c22081f..c5bb631286 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_pci_dev_feature_defs.h ++++ b/dpdk/lib/librte_eal/common/include/rte_pci_dev_feature_defs.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_PCI_DEV_DEFS_H_ + #define _RTE_PCI_DEV_DEFS_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /* interrupt mode */ + enum rte_intr_mode { + RTE_INTR_MODE_NONE = 0, +@@ -13,4 +17,8 @@ enum rte_intr_mode { + RTE_INTR_MODE_MSIX + }; + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_PCI_DEV_DEFS_H_ */ +diff --git a/dpdk/lib/librte_eal/common/include/rte_pci_dev_features.h b/dpdk/lib/librte_eal/common/include/rte_pci_dev_features.h +index 6104123d27..ee6e10590c 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_pci_dev_features.h ++++ b/dpdk/lib/librte_eal/common/include/rte_pci_dev_features.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_PCI_DEV_FEATURES_H + #define _RTE_PCI_DEV_FEATURES_H + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + + #define RTE_INTR_MODE_NONE_NAME "none" +@@ -12,4 +16,8 @@ + #define RTE_INTR_MODE_MSI_NAME "msi" + #define RTE_INTR_MODE_MSIX_NAME "msix" + ++#ifdef __cplusplus ++} ++#endif ++ + #endif diff --git a/dpdk/lib/librte_eal/common/include/rte_reciprocal.h b/dpdk/lib/librte_eal/common/include/rte_reciprocal.h -index 63e16fde0a..735adb029b 100644 +index 63e16fde0a..fa1cb4854e 100644 --- a/dpdk/lib/librte_eal/common/include/rte_reciprocal.h +++ b/dpdk/lib/librte_eal/common/include/rte_reciprocal.h -@@ -27,6 +27,8 @@ +@@ -27,6 +27,12 @@ #include +#include + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ struct rte_reciprocal { uint32_t m; uint8_t sh1, sh2; +@@ -87,4 +93,8 @@ rte_reciprocal_divide_u64(uint64_t a, const struct rte_reciprocal_u64 *R) + struct rte_reciprocal rte_reciprocal_value(uint32_t d); + struct rte_reciprocal_u64 rte_reciprocal_value_u64(uint64_t d); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_RECIPROCAL_H_ */ diff --git a/dpdk/lib/librte_eal/common/include/rte_service.h b/dpdk/lib/librte_eal/common/include/rte_service.h -index d8701dd4cf..e2d0a6dd32 100644 +index d8701dd4cf..b91d738de9 100644 --- a/dpdk/lib/librte_eal/common/include/rte_service.h +++ b/dpdk/lib/librte_eal/common/include/rte_service.h -@@ -104,12 +104,16 @@ int32_t rte_service_probe_capability(uint32_t id, uint32_t capability); +@@ -47,10 +47,7 @@ extern "C" { + #define RTE_SERVICE_CAP_MT_SAFE (1 << 0) + + /** +- * Return the number of services registered. +- * +- * The number of services registered can be passed to *rte_service_get_by_id*, +- * enabling the application to retrieve the specification of each service. ++ * Return the number of services registered. + * + * @return The number of services registered. + */ +@@ -104,12 +101,16 @@ int32_t rte_service_probe_capability(uint32_t id, uint32_t capability); * Each core can be added or removed from running a specific service. This * function enables or disables *lcore* to run *service_id*. * @@ -73034,7 +102320,7 @@ index d8701dd4cf..e2d0a6dd32 100644 * @param service_id the service to apply the lcore to * @param lcore The lcore that will be mapped to service * @param enable Zero to unmap or disable the core, non-zero to enable -@@ -300,6 +304,10 @@ int32_t rte_service_lcore_count(void); +@@ -300,6 +301,10 @@ int32_t rte_service_lcore_count(void); * from duty, just unmaps all services / cores, and stops() the service cores. * The runstate of services is not modified. * @@ -73090,6 +102376,30 @@ index 16eab79eea..9e66ee7e29 100644 +#endif + #endif /* _SERVICE_PRIVATE_H_ */ +diff --git a/dpdk/lib/librte_eal/common/include/rte_time.h b/dpdk/lib/librte_eal/common/include/rte_time.h +index 5ad7c8841a..ec25f7b93d 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_time.h ++++ b/dpdk/lib/librte_eal/common/include/rte_time.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_TIME_H_ + #define _RTE_TIME_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + #include + +@@ -98,4 +102,8 @@ rte_ns_to_timespec(uint64_t nsec) + return ts; + } + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_TIME_H_ */ diff --git a/dpdk/lib/librte_eal/common/include/rte_uuid.h b/dpdk/lib/librte_eal/common/include/rte_uuid.h index 044afbdfab..8b42e070af 100644 --- a/dpdk/lib/librte_eal/common/include/rte_uuid.h @@ -73103,6 +102413,52 @@ index 044afbdfab..8b42e070af 100644 /** * Struct describing a Universal Unique Identifier +diff --git a/dpdk/lib/librte_eal/common/include/rte_vfio.h b/dpdk/lib/librte_eal/common/include/rte_vfio.h +index 20ed8c45a9..7bdb8932b2 100644 +--- a/dpdk/lib/librte_eal/common/include/rte_vfio.h ++++ b/dpdk/lib/librte_eal/common/include/rte_vfio.h +@@ -14,6 +14,7 @@ + extern "C" { + #endif + ++#include + #include + + /* +@@ -149,14 +150,13 @@ int rte_vfio_enable(const char *modname); + /** + * Check whether a VFIO-related kmod is enabled. + * +- * This function is only relevant to linux and will return +- * an error on BSD. ++ * This function is only relevant to Linux. + * + * @param modname + * kernel module name. + * + * @return +- * !0 if true. ++ * 1 if true. + * 0 otherwise. + */ + int rte_vfio_is_enabled(const char *modname); +@@ -164,12 +164,12 @@ int rte_vfio_is_enabled(const char *modname); + /** + * Whether VFIO NOIOMMU mode is enabled. + * +- * This function is only relevant to linux and will return +- * an error on BSD. ++ * This function is only relevant to Linux. + * + * @return +- * !0 if true. +- * 0 otherwise. ++ * 1 if true. ++ * 0 if false. ++ * <0 for errors. + */ + int rte_vfio_noiommu_is_enabled(void); + diff --git a/dpdk/lib/librte_eal/common/malloc_elem.c b/dpdk/lib/librte_eal/common/malloc_elem.c index 885d00424b..a0f2d22774 100644 --- a/dpdk/lib/librte_eal/common/malloc_elem.c @@ -73136,7 +102492,7 @@ index 885d00424b..a0f2d22774 100644 /* diff --git a/dpdk/lib/librte_eal/common/malloc_heap.c b/dpdk/lib/librte_eal/common/malloc_heap.c -index 842eb9de75..bd5065698d 100644 +index 842eb9de75..03a263a004 100644 --- a/dpdk/lib/librte_eal/common/malloc_heap.c +++ b/dpdk/lib/librte_eal/common/malloc_heap.c @@ -241,6 +241,9 @@ heap_alloc(struct malloc_heap *heap, const char *type __rte_unused, size_t size, @@ -73149,6 +102505,39 @@ index 842eb9de75..bd5065698d 100644 elem = find_suitable_element(heap, size, flags, align, bound, contig); if (elem != NULL) { elem = malloc_elem_alloc(elem, size, align, bound, contig); +@@ -394,7 +397,7 @@ try_expand_heap_primary(struct malloc_heap *heap, uint64_t pg_sz, + bool callback_triggered = false; + + alloc_sz = RTE_ALIGN_CEIL(align + elt_size + +- MALLOC_ELEM_TRAILER_LEN, pg_sz); ++ MALLOC_ELEM_OVERHEAD, pg_sz); + n_segs = alloc_sz / pg_sz; + + /* we can't know in advance how many pages we'll need, so we malloc */ +diff --git a/dpdk/lib/librte_eal/common/malloc_mp.c b/dpdk/lib/librte_eal/common/malloc_mp.c +index 1f212f8349..f9d558ba64 100644 +--- a/dpdk/lib/librte_eal/common/malloc_mp.c ++++ b/dpdk/lib/librte_eal/common/malloc_mp.c +@@ -170,9 +170,7 @@ handle_sync(const struct rte_mp_msg *msg, const void *peer) + resp->id = req->id; + resp->result = ret == 0 ? REQ_RESULT_SUCCESS : REQ_RESULT_FAIL; + +- rte_mp_reply(&reply, peer); +- +- return 0; ++ return rte_mp_reply(&reply, peer); + } + + static int +@@ -188,7 +186,7 @@ handle_alloc_request(const struct malloc_mp_req *m, + void *map_addr; + + alloc_sz = RTE_ALIGN_CEIL(ar->align + ar->elt_size + +- MALLOC_ELEM_TRAILER_LEN, ar->page_sz); ++ MALLOC_ELEM_OVERHEAD, ar->page_sz); + n_segs = alloc_sz / ar->page_sz; + + heap = ar->heap; diff --git a/dpdk/lib/librte_eal/common/rte_random.c b/dpdk/lib/librte_eal/common/rte_random.c index 57ec8fb2b3..b7a089ac4f 100644 --- a/dpdk/lib/librte_eal/common/rte_random.c @@ -73163,7 +102552,7 @@ index 57ec8fb2b3..b7a089ac4f 100644 RTE_INIT(rte_rand_init) diff --git a/dpdk/lib/librte_eal/common/rte_service.c b/dpdk/lib/librte_eal/common/rte_service.c -index 79235c03f8..8fcccac85c 100644 +index 79235c03f8..d11027fcba 100644 --- a/dpdk/lib/librte_eal/common/rte_service.c +++ b/dpdk/lib/librte_eal/common/rte_service.c @@ -50,6 +50,10 @@ struct rte_service_spec_impl { @@ -73351,7 +102740,29 @@ index 79235c03f8..8fcccac85c 100644 /* returns -EBUSY if the core is already launched, 0 on success */ return ret; } -@@ -774,13 +772,9 @@ rte_service_lcore_attr_get(uint32_t lcore, uint32_t attr_id, +@@ -710,13 +708,20 @@ rte_service_lcore_stop(uint32_t lcore) + return -EALREADY; + + uint32_t i; +- uint64_t service_mask = lcore_states[lcore].service_mask; ++ struct core_state *cs = &lcore_states[lcore]; ++ uint64_t service_mask = cs->service_mask; ++ + for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) { + int32_t enabled = service_mask & (UINT64_C(1) << i); + int32_t service_running = rte_service_runstate_get(i); + int32_t only_core = (1 == + rte_atomic32_read(&rte_services[i].num_mapped_cores)); + ++ /* Switch off this core for all services, to ensure that future ++ * calls to may_be_active() know this core is switched off. ++ */ ++ cs->service_active_on_lcore[i] = 0; ++ + /* if the core is mapped, and the service is running, and this + * is the only core that is mapped, the service would cease to + * run if this core stopped, so fail instead. +@@ -774,13 +779,9 @@ rte_service_lcore_attr_get(uint32_t lcore, uint32_t attr_id, } static void @@ -73366,7 +102777,7 @@ index 79235c03f8..8fcccac85c 100644 int calls = 1; if (s->calls != 0) calls = s->calls; -@@ -807,7 +801,7 @@ rte_service_attr_reset_all(uint32_t id) +@@ -807,7 +808,7 @@ rte_service_attr_reset_all(uint32_t id) SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL); int reset = 1; @@ -73375,7 +102786,7 @@ index 79235c03f8..8fcccac85c 100644 return 0; } -@@ -851,21 +845,13 @@ rte_service_dump(FILE *f, uint32_t id) +@@ -851,21 +852,13 @@ rte_service_dump(FILE *f, uint32_t id) uint32_t i; int print_one = (id != UINT32_MAX); @@ -73398,7 +102809,7 @@ index 79235c03f8..8fcccac85c 100644 return 0; } -@@ -875,7 +861,7 @@ rte_service_dump(FILE *f, uint32_t id) +@@ -875,7 +868,7 @@ rte_service_dump(FILE *f, uint32_t id) if (!service_valid(i)) continue; uint32_t reset = 0; @@ -73408,10 +102819,21 @@ index 79235c03f8..8fcccac85c 100644 fprintf(f, "Service Cores Summary\n"); diff --git a/dpdk/lib/librte_eal/freebsd/eal/eal.c b/dpdk/lib/librte_eal/freebsd/eal/eal.c -index 6ae37e7e69..2a995ee3f4 100644 +index 6ae37e7e69..554323a39b 100644 --- a/dpdk/lib/librte_eal/freebsd/eal/eal.c +++ b/dpdk/lib/librte_eal/freebsd/eal/eal.c -@@ -949,7 +949,7 @@ rte_eal_init(int argc, char **argv) +@@ -743,6 +743,10 @@ rte_eal_init(int argc, char **argv) + + /* FreeBSD always uses legacy memory model */ + internal_config.legacy_mem = true; ++ if (internal_config.in_memory) { ++ RTE_LOG(WARNING, EAL, "Warning: ignoring unsupported flag, '%s'\n", OPT_IN_MEMORY); ++ internal_config.in_memory = false; ++ } + + if (eal_plugins_init() < 0) { + rte_eal_init_alert("Cannot init plugins"); +@@ -949,7 +953,7 @@ rte_eal_init(int argc, char **argv) * place, so no cleanup needed. */ if (!internal_config.no_shconf && eal_clean_runtime_dir() < 0) { @@ -73420,6 +102842,30 @@ index 6ae37e7e69..2a995ee3f4 100644 return -1; } +@@ -1024,7 +1028,7 @@ int rte_vfio_noiommu_is_enabled(void) + + int rte_vfio_clear_group(__rte_unused int vfio_group_fd) + { +- return 0; ++ return -1; + } + + int +diff --git a/dpdk/lib/librte_eal/freebsd/eal/eal_hugepage_info.c b/dpdk/lib/librte_eal/freebsd/eal/eal_hugepage_info.c +index 32012e1427..a2327b6edd 100644 +--- a/dpdk/lib/librte_eal/freebsd/eal/eal_hugepage_info.c ++++ b/dpdk/lib/librte_eal/freebsd/eal/eal_hugepage_info.c +@@ -85,6 +85,10 @@ eal_hugepage_info_init(void) + RTE_LOG(ERR, EAL, "could not open "CONTIGMEM_DEV"\n"); + return -1; + } ++ if (flock(fd, LOCK_EX | LOCK_NB) < 0) { ++ RTE_LOG(ERR, EAL, "could not lock memory. Is another DPDK process running?\n"); ++ return -1; ++ } + + if (buffer_size >= 1<<30) + RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dGB\n", diff --git a/dpdk/lib/librte_eal/freebsd/eal/eal_interrupts.c b/dpdk/lib/librte_eal/freebsd/eal/eal_interrupts.c index f6831b7902..3fee762be9 100644 --- a/dpdk/lib/librte_eal/freebsd/eal/eal_interrupts.c @@ -73538,7 +102984,7 @@ index f6831b7902..3fee762be9 100644 TAILQ_REMOVE(&intr_sources, src, next); free(src); diff --git a/dpdk/lib/librte_eal/freebsd/eal/eal_memory.c b/dpdk/lib/librte_eal/freebsd/eal/eal_memory.c -index a97d8f0f0c..fb1549fbe6 100644 +index a97d8f0f0c..1cc36dff60 100644 --- a/dpdk/lib/librte_eal/freebsd/eal/eal_memory.c +++ b/dpdk/lib/librte_eal/freebsd/eal/eal_memory.c @@ -193,7 +193,7 @@ rte_eal_hugepage_init(void) @@ -73559,8 +103005,120 @@ index a97d8f0f0c..fb1549fbe6 100644 * that are non-contiguous. */ avail_segs = (hpi->num_pages[0] * 2) - 1; +@@ -508,8 +508,8 @@ memseg_secondary_init(void) + + msl = &mcfg->memsegs[msl_idx]; + +- /* skip empty memseg lists */ +- if (msl->memseg_arr.len == 0) ++ /* skip empty and external memseg lists */ ++ if (msl->memseg_arr.len == 0 || msl->external) + continue; + + if (rte_fbarray_attach(&msl->memseg_arr)) { +diff --git a/dpdk/lib/librte_eal/freebsd/eal/eal_thread.c b/dpdk/lib/librte_eal/freebsd/eal/eal_thread.c +index 309b587266..76992e2164 100644 +--- a/dpdk/lib/librte_eal/freebsd/eal/eal_thread.c ++++ b/dpdk/lib/librte_eal/freebsd/eal/eal_thread.c +@@ -152,6 +152,8 @@ eal_thread_loop(__attribute__((unused)) void *arg) + fct_arg = lcore_config[lcore_id].arg; + ret = lcore_config[lcore_id].f(fct_arg); + lcore_config[lcore_id].ret = ret; ++ lcore_config[lcore_id].f = NULL; ++ lcore_config[lcore_id].arg = NULL; + rte_wmb(); + lcore_config[lcore_id].state = FINISHED; + } +diff --git a/dpdk/lib/librte_eal/freebsd/eal/include/rte_os.h b/dpdk/lib/librte_eal/freebsd/eal/include/rte_os.h +index a5efe618f5..908c37e9aa 100644 +--- a/dpdk/lib/librte_eal/freebsd/eal/include/rte_os.h ++++ b/dpdk/lib/librte_eal/freebsd/eal/include/rte_os.h +@@ -5,15 +5,19 @@ + #ifndef _RTE_OS_H_ + #define _RTE_OS_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** +- * This is header should contain any function/macro definition +- * which are not supported natively or named differently in the +- * freebsd OS. Functions will be added in future releases. ++ * This header should contain any definition ++ * which is not supported natively or named differently in FreeBSD. + */ + + #include + + typedef cpuset_t rte_cpuset_t; ++#ifdef RTE_EAL_FREEBSD_CPUSET_LEGACY + #define RTE_CPU_AND(dst, src1, src2) do \ + { \ + cpuset_t tmp; \ +@@ -29,6 +33,9 @@ typedef cpuset_t rte_cpuset_t; + CPU_COPY(&tmp, dst); \ + } while (0) + #define RTE_CPU_FILL(set) CPU_FILL(set) ++ ++/* In FreeBSD 13 CPU_NAND macro is CPU_ANDNOT */ ++#ifdef CPU_NAND + #define RTE_CPU_NOT(dst, src) do \ + { \ + cpuset_t tmp; \ +@@ -36,5 +43,31 @@ typedef cpuset_t rte_cpuset_t; + CPU_NAND(&tmp, src); \ + CPU_COPY(&tmp, dst); \ + } while (0) ++#else ++#define RTE_CPU_NOT(dst, src) do \ ++{ \ ++ cpuset_t tmp; \ ++ CPU_FILL(&tmp); \ ++ CPU_ANDNOT(&tmp, src); \ ++ CPU_COPY(&tmp, dst); \ ++} while (0) ++#endif /* CPU_NAND */ ++ ++#else /* RTE_EAL_FREEBSD_CPUSET_LEGACY */ ++ ++#define RTE_CPU_AND CPU_AND ++#define RTE_CPU_OR CPU_OR ++#define RTE_CPU_FILL CPU_FILL ++#define RTE_CPU_NOT(dst, src) do { \ ++ cpu_set_t tmp; \ ++ CPU_FILL(&tmp); \ ++ CPU_XOR(dst, src, &tmp); \ ++} while (0) ++ ++#endif /* RTE_EAL_FREEBSD_CPUSET_LEGACY */ ++ ++#ifdef __cplusplus ++} ++#endif + + #endif /* _RTE_OS_H_ */ +diff --git a/dpdk/lib/librte_eal/freebsd/eal/meson.build b/dpdk/lib/librte_eal/freebsd/eal/meson.build +index 1426f7e5f1..deb367f44c 100644 +--- a/dpdk/lib/librte_eal/freebsd/eal/meson.build ++++ b/dpdk/lib/librte_eal/freebsd/eal/meson.build +@@ -20,3 +20,14 @@ env_sources = files('eal_alarm.c', + ) + + deps += ['kvargs'] ++ ++# test for version of cpuset macros ++cpuset_test_code = ''' ++ #include ++ #include ++ void cpu_test_or(cpuset_t *s) { CPU_OR(s, s, s); } ++''' ++ ++if not cc.compiles(cpuset_test_code, name: 'Detect argument count for CPU_OR') ++ dpdk_conf.set('RTE_EAL_FREEBSD_CPUSET_LEGACY', 1) ++endif diff --git a/dpdk/lib/librte_eal/linux/eal/eal.c b/dpdk/lib/librte_eal/linux/eal/eal.c -index c4233ec3c8..8f1bcab390 100644 +index c4233ec3c8..5fa8c82c63 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal.c +++ b/dpdk/lib/librte_eal/linux/eal/eal.c @@ -25,6 +25,7 @@ @@ -73571,7 +103129,23 @@ index c4233ec3c8..8f1bcab390 100644 #include #include -@@ -1076,7 +1077,7 @@ rte_eal_init(int argc, char **argv) +@@ -586,7 +587,6 @@ eal_parse_socket_arg(char *strval, volatile uint64_t *socket_arg) + char * arg[RTE_MAX_NUMA_NODES]; + char *end; + int arg_num, i, len; +- uint64_t total_mem = 0; + + len = strnlen(strval, SOCKET_MEM_STRLEN); + if (len == SOCKET_MEM_STRLEN) { +@@ -618,7 +618,6 @@ eal_parse_socket_arg(char *strval, volatile uint64_t *socket_arg) + (arg[i][0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + val <<= 20; +- total_mem += val; + socket_arg[i] = val; + } + +@@ -1076,7 +1075,7 @@ rte_eal_init(int argc, char **argv) #if defined(RTE_LIBRTE_KNI) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) } else if (rte_eal_check_module("rte_kni") == 1) { iova_mode = RTE_IOVA_PA; @@ -73580,7 +103154,7 @@ index c4233ec3c8..8f1bcab390 100644 #endif } else if (is_iommu_enabled()) { /* we have an IOMMU, pick IOVA as VA mode */ -@@ -1287,7 +1288,7 @@ rte_eal_init(int argc, char **argv) +@@ -1287,7 +1286,7 @@ rte_eal_init(int argc, char **argv) * place, so no cleanup needed. */ if (!internal_config.no_shconf && eal_clean_runtime_dir() < 0) { @@ -73589,11 +103163,33 @@ index c4233ec3c8..8f1bcab390 100644 return -1; } +@@ -1324,7 +1323,11 @@ rte_eal_cleanup(void) + */ + if (rte_eal_process_type() == RTE_PROC_PRIMARY) + rte_memseg_walk(mark_freeable, NULL); ++ + rte_service_finalize(); ++#ifdef VFIO_PRESENT ++ vfio_mp_sync_cleanup(); ++#endif + rte_mp_channel_cleanup(); + eal_cleanup_config(&internal_config); + return 0; diff --git a/dpdk/lib/librte_eal/linux/eal/eal_dev.c b/dpdk/lib/librte_eal/linux/eal/eal_dev.c -index 83c9cd6607..803979ff46 100644 +index 83c9cd6607..eb3e2642e0 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_dev.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_dev.c -@@ -189,7 +189,7 @@ dev_uev_parse(const char *buf, struct rte_dev_event *event, int length) +@@ -151,6 +151,9 @@ dev_uev_parse(const char *buf, struct rte_dev_event *event, int length) + break; + buf++; + } ++ if (i >= length) ++ break; ++ + /** + * check device uevent from kernel side, no need to check + * uevent from udev. +@@ -189,7 +192,7 @@ dev_uev_parse(const char *buf, struct rte_dev_event *event, int length) else if (!strncmp(subsystem, "vfio", 4)) event->subsystem = EAL_DEV_EVENT_SUBSYSTEM_VFIO; else @@ -73602,7 +103198,7 @@ index 83c9cd6607..803979ff46 100644 /* parse the action type */ if (!strncmp(action, "add", 3)) -@@ -197,8 +197,11 @@ dev_uev_parse(const char *buf, struct rte_dev_event *event, int length) +@@ -197,8 +200,11 @@ dev_uev_parse(const char *buf, struct rte_dev_event *event, int length) else if (!strncmp(action, "remove", 6)) event->type = RTE_DEV_EVENT_REMOVE; else @@ -73615,7 +103211,23 @@ index 83c9cd6607..803979ff46 100644 } static void -@@ -234,8 +237,7 @@ dev_uev_handler(__rte_unused void *param) +@@ -214,13 +220,13 @@ dev_uev_handler(__rte_unused void *param) + { + struct rte_dev_event uevent; + int ret; +- char buf[EAL_UEV_MSG_LEN]; ++ char buf[EAL_UEV_MSG_LEN + 1]; + struct rte_bus *bus; + struct rte_device *dev; + const char *busname = ""; + + memset(&uevent, 0, sizeof(struct rte_dev_event)); +- memset(buf, 0, EAL_UEV_MSG_LEN); ++ memset(buf, 0, EAL_UEV_MSG_LEN + 1); + + ret = recv(intr_handle.fd, buf, EAL_UEV_MSG_LEN, MSG_DONTWAIT); + if (ret < 0 && errno == EAGAIN) +@@ -234,8 +240,7 @@ dev_uev_handler(__rte_unused void *param) ret = dev_uev_parse(buf, &uevent, EAL_UEV_MSG_LEN); if (ret < 0) { @@ -73625,7 +103237,7 @@ index 83c9cd6607..803979ff46 100644 return; } -@@ -277,12 +279,14 @@ dev_uev_handler(__rte_unused void *param) +@@ -277,12 +282,14 @@ dev_uev_handler(__rte_unused void *param) rte_spinlock_unlock(&failure_handle_lock); } rte_dev_event_callback_process(uevent.devname, uevent.type); @@ -73641,10 +103253,31 @@ index 83c9cd6607..803979ff46 100644 int diff --git a/dpdk/lib/librte_eal/linux/eal/eal_interrupts.c b/dpdk/lib/librte_eal/linux/eal/eal_interrupts.c -index 1955324d30..e570c0684e 100644 +index 1955324d30..348aef2ece 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_interrupts.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_interrupts.c -@@ -984,7 +984,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds) +@@ -877,17 +877,14 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds) + bytes_read = sizeof(buf.timerfd_num); + break; + #ifdef VFIO_PRESENT ++#ifdef HAVE_VFIO_DEV_REQ_INTERFACE ++ case RTE_INTR_HANDLE_VFIO_REQ: ++#endif + case RTE_INTR_HANDLE_VFIO_MSIX: + case RTE_INTR_HANDLE_VFIO_MSI: + case RTE_INTR_HANDLE_VFIO_LEGACY: + bytes_read = sizeof(buf.vfio_intr_count); + break; +-#ifdef HAVE_VFIO_DEV_REQ_INTERFACE +- case RTE_INTR_HANDLE_VFIO_REQ: +- bytes_read = 0; +- call = true; +- break; +-#endif + #endif + case RTE_INTR_HANDLE_VDEV: + case RTE_INTR_HANDLE_EXT: +@@ -984,7 +981,7 @@ eal_intr_process_interrupts(struct epoll_event *events, int nfds) } /* notify the pipe fd waited by epoll_wait to rebuild the wait list */ @@ -73653,7 +103286,7 @@ index 1955324d30..e570c0684e 100644 rte_spinlock_unlock(&intr_lock); return -EPIPE; } -@@ -1045,8 +1045,6 @@ eal_intr_handle_interrupts(int pfd, unsigned totalfds) +@@ -1045,8 +1042,6 @@ eal_intr_handle_interrupts(int pfd, unsigned totalfds) static __attribute__((noreturn)) void * eal_intr_thread_main(__rte_unused void *arg) { @@ -73662,7 +103295,7 @@ index 1955324d30..e570c0684e 100644 /* host thread, never break out */ for (;;) { /* build up the epoll fd with all descriptors we are to -@@ -1078,8 +1076,11 @@ eal_intr_thread_main(__rte_unused void *arg) +@@ -1078,8 +1073,11 @@ eal_intr_thread_main(__rte_unused void *arg) rte_spinlock_lock(&intr_lock); TAILQ_FOREACH(src, &intr_sources, next) { @@ -73674,7 +103307,7 @@ index 1955324d30..e570c0684e 100644 ev.events = EPOLLIN | EPOLLPRI | EPOLLRDHUP | EPOLLHUP; ev.data.fd = src->intr_handle.fd; -@@ -1204,7 +1205,7 @@ eal_epoll_process_event(struct epoll_event *evs, unsigned int n, +@@ -1204,7 +1202,7 @@ eal_epoll_process_event(struct epoll_event *evs, unsigned int n, events[count].status = RTE_EPOLL_VALID; events[count].fd = rev->fd; events[count].epfd = rev->epfd; @@ -73683,11 +103316,75 @@ index 1955324d30..e570c0684e 100644 events[count].epdata.data = rev->epdata.data; if (rev->epdata.cb_fun) rev->epdata.cb_fun(rev->fd, +diff --git a/dpdk/lib/librte_eal/linux/eal/eal_log.c b/dpdk/lib/librte_eal/linux/eal/eal_log.c +index 9d02dddbed..bd5358ca24 100644 +--- a/dpdk/lib/librte_eal/linux/eal/eal_log.c ++++ b/dpdk/lib/librte_eal/linux/eal/eal_log.c +@@ -27,9 +27,9 @@ console_log_write(__attribute__((unused)) void *c, const char *buf, size_t size) + { + ssize_t ret; + +- /* write on stdout */ +- ret = fwrite(buf, 1, size, stdout); +- fflush(stdout); ++ /* write on stderr */ ++ ret = fwrite(buf, 1, size, stderr); ++ fflush(stderr); + + /* Syslog error levels are from 0 to 7, so subtract 1 to convert */ + syslog(rte_log_cur_msg_loglevel() - 1, "%.*s", (int)size, buf); diff --git a/dpdk/lib/librte_eal/linux/eal/eal_memalloc.c b/dpdk/lib/librte_eal/linux/eal/eal_memalloc.c -index af6d0d023a..22f1ff68eb 100644 +index af6d0d023a..7499ba0b15 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_memalloc.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_memalloc.c -@@ -325,6 +325,21 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi, +@@ -107,7 +107,7 @@ static struct rte_memseg_list local_memsegs[RTE_MAX_MEMSEG_LISTS]; + + static sigjmp_buf huge_jmpenv; + +-static void __rte_unused huge_sigbus_handler(int signo __rte_unused) ++static void huge_sigbus_handler(int signo __rte_unused) + { + siglongjmp(huge_jmpenv, 1); + } +@@ -116,7 +116,7 @@ static void __rte_unused huge_sigbus_handler(int signo __rte_unused) + * non-static local variable in the stack frame calling sigsetjmp might be + * clobbered by a call to longjmp. + */ +-static int __rte_unused huge_wrap_sigsetjmp(void) ++static int huge_wrap_sigsetjmp(void) + { + return sigsetjmp(huge_jmpenv, 1); + } +@@ -124,7 +124,7 @@ static int __rte_unused huge_wrap_sigsetjmp(void) + static struct sigaction huge_action_old; + static int huge_need_recover; + +-static void __rte_unused ++static void + huge_register_sigbus(void) + { + sigset_t mask; +@@ -139,7 +139,7 @@ huge_register_sigbus(void) + huge_need_recover = !sigaction(SIGBUS, &action, &huge_action_old); + } + +-static void __rte_unused ++static void + huge_recover_sigbus(void) + { + if (huge_need_recover) { +@@ -304,8 +304,8 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi, + if (fd < 0) { + fd = open(path, O_CREAT | O_RDWR, 0600); + if (fd < 0) { +- RTE_LOG(ERR, EAL, "%s(): open failed: %s\n", +- __func__, strerror(errno)); ++ RTE_LOG(ERR, EAL, "%s(): open '%s' failed: %s\n", ++ __func__, path, strerror(errno)); + return -1; + } + /* take out a read lock and keep it indefinitely */ +@@ -325,10 +325,25 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi, fd = fd_list[list_idx].fds[seg_idx]; if (fd < 0) { @@ -73708,8 +103405,23 @@ index af6d0d023a..22f1ff68eb 100644 + fd = open(path, O_CREAT | O_RDWR, 0600); if (fd < 0) { - RTE_LOG(DEBUG, EAL, "%s(): open failed: %s\n", -@@ -599,17 +614,25 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id, +- RTE_LOG(DEBUG, EAL, "%s(): open failed: %s\n", +- __func__, strerror(errno)); ++ RTE_LOG(ERR, EAL, "%s(): open '%s' failed: %s\n", ++ __func__, path, strerror(errno)); + return -1; + } + /* take out a read lock */ +@@ -550,6 +565,8 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id, + mmap_flags = MAP_SHARED | MAP_POPULATE | MAP_FIXED; + } + ++ huge_register_sigbus(); ++ + /* + * map the segment, and populate page tables, the kernel fills + * this segment with zeros if it's a new page. +@@ -599,17 +616,25 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id, } #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES @@ -73746,7 +103458,29 @@ index af6d0d023a..22f1ff68eb 100644 } #else if (rte_socket_count() > 1) -@@ -680,13 +703,16 @@ free_seg(struct rte_memseg *ms, struct hugepage_info *hi, +@@ -617,6 +642,8 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id, + __func__); + #endif + ++ huge_recover_sigbus(); ++ + ms->addr = addr; + ms->hugepage_sz = alloc_sz; + ms->len = alloc_sz; +@@ -630,6 +657,7 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id, + mapped: + munmap(addr, alloc_sz); + unmapped: ++ huge_recover_sigbus(); + flags = MAP_FIXED; + new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0, flags); + if (new_addr != addr) { +@@ -675,29 +703,22 @@ free_seg(struct rte_memseg *ms, struct hugepage_info *hi, + uint64_t map_offset; + char path[PATH_MAX]; + int fd, ret = 0; +- bool exit_early; + /* erase page data */ memset(ms->addr, 0, ms->len); @@ -73758,14 +103492,34 @@ index af6d0d023a..22f1ff68eb 100644 return -1; } +- exit_early = false; + if (madvise(ms->addr, ms->len, MADV_DONTDUMP) != 0) + RTE_LOG(DEBUG, EAL, "madvise failed: %s\n", strerror(errno)); -+ - exit_early = false; /* if we're using anonymous hugepages, nothing to be done */ +- if (internal_config.in_memory && !memfd_create_supported) +- exit_early = true; +- +- /* if we've already unlinked the page, nothing needs to be done */ +- if (!internal_config.in_memory && internal_config.hugepage_unlink) +- exit_early = true; +- +- if (exit_early) { ++ if (internal_config.in_memory && !memfd_create_supported) { + memset(ms, 0, sizeof(*ms)); + return 0; + } +@@ -723,7 +744,7 @@ free_seg(struct rte_memseg *ms, struct hugepage_info *hi, + /* if we're able to take out a write lock, we're the last one + * holding onto this page. + */ +- if (!internal_config.in_memory) { ++ if (!internal_config.in_memory && !internal_config.hugepage_unlink) { + ret = lock(fd, LOCK_EX); + if (ret >= 0) { + /* no one else is using this page */ diff --git a/dpdk/lib/librte_eal/linux/eal/eal_memory.c b/dpdk/lib/librte_eal/linux/eal/eal_memory.c -index 43e4ffc757..c93d9bb2b8 100644 +index 43e4ffc757..e7ab3aaf17 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_memory.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_memory.c @@ -703,7 +703,7 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end) @@ -73880,11 +103634,78 @@ index 43e4ffc757..c93d9bb2b8 100644 if (hp != NULL && hp != MAP_FAILED) munmap(hp, size); if (fd_hugepage >= 0) +@@ -2410,8 +2423,8 @@ memseg_secondary_init(void) + + msl = &mcfg->memsegs[msl_idx]; + +- /* skip empty memseg lists */ +- if (msl->memseg_arr.len == 0) ++ /* skip empty and external memseg lists */ ++ if (msl->memseg_arr.len == 0 || msl->external) + continue; + + if (rte_fbarray_attach(&msl->memseg_arr)) { +diff --git a/dpdk/lib/librte_eal/linux/eal/eal_thread.c b/dpdk/lib/librte_eal/linux/eal/eal_thread.c +index 379773b683..4f7d97a0d2 100644 +--- a/dpdk/lib/librte_eal/linux/eal/eal_thread.c ++++ b/dpdk/lib/librte_eal/linux/eal/eal_thread.c +@@ -152,6 +152,8 @@ eal_thread_loop(__attribute__((unused)) void *arg) + fct_arg = lcore_config[lcore_id].arg; + ret = lcore_config[lcore_id].f(fct_arg); + lcore_config[lcore_id].ret = ret; ++ lcore_config[lcore_id].f = NULL; ++ lcore_config[lcore_id].arg = NULL; + rte_wmb(); + + /* when a service core returns, it should go directly to WAIT diff --git a/dpdk/lib/librte_eal/linux/eal/eal_vfio.c b/dpdk/lib/librte_eal/linux/eal/eal_vfio.c -index 95f615c2e3..1be02e7f13 100644 +index 95f615c2e3..cb7de6f810 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_vfio.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_vfio.c -@@ -293,7 +293,7 @@ vfio_open_group_fd(int iommu_group_num) +@@ -69,6 +69,7 @@ static const struct vfio_iommu_type iommu_types[] = { + { + .type_id = RTE_VFIO_TYPE1, + .name = "Type 1", ++ .partial_unmap = false, + .dma_map_func = &vfio_type1_dma_map, + .dma_user_map_func = &vfio_type1_dma_mem_map + }, +@@ -76,6 +77,7 @@ static const struct vfio_iommu_type iommu_types[] = { + { + .type_id = RTE_VFIO_SPAPR, + .name = "sPAPR", ++ .partial_unmap = true, + .dma_map_func = &vfio_spapr_dma_map, + .dma_user_map_func = &vfio_spapr_dma_mem_map + }, +@@ -83,6 +85,7 @@ static const struct vfio_iommu_type iommu_types[] = { + { + .type_id = RTE_VFIO_NOIOMMU, + .name = "No-IOMMU", ++ .partial_unmap = true, + .dma_map_func = &vfio_noiommu_dma_map, + .dma_user_map_func = &vfio_noiommu_dma_mem_map + }, +@@ -167,6 +170,10 @@ adjust_map(struct user_mem_map *src, struct user_mem_map *end, + static int + merge_map(struct user_mem_map *left, struct user_mem_map *right) + { ++ /* merge the same maps into one */ ++ if (memcmp(left, right, sizeof(struct user_mem_map)) == 0) ++ goto out; ++ + if (left->addr + left->len != right->addr) + return 0; + if (left->iova + left->len != right->iova) +@@ -174,6 +181,7 @@ merge_map(struct user_mem_map *left, struct user_mem_map *right) + + left->len += right->len; + ++out: + memset(right, 0, sizeof(*right)); + + return 1; +@@ -293,7 +301,7 @@ vfio_open_group_fd(int iommu_group_num) strerror(errno)); return -1; } @@ -73893,7 +103714,7 @@ index 95f615c2e3..1be02e7f13 100644 } /* noiommu group found */ } -@@ -318,12 +318,12 @@ vfio_open_group_fd(int iommu_group_num) +@@ -318,12 +326,12 @@ vfio_open_group_fd(int iommu_group_num) vfio_group_fd = mp_rep->fds[0]; } else if (p->result == SOCKET_NO_FD) { RTE_LOG(ERR, EAL, " bad VFIO group fd\n"); @@ -73908,7 +103729,7 @@ index 95f615c2e3..1be02e7f13 100644 RTE_LOG(ERR, EAL, " cannot request group fd\n"); return vfio_group_fd; } -@@ -381,7 +381,7 @@ vfio_get_group_fd(struct vfio_config *vfio_cfg, +@@ -381,7 +389,7 @@ vfio_get_group_fd(struct vfio_config *vfio_cfg, vfio_group_fd = vfio_open_group_fd(iommu_group_num); if (vfio_group_fd < 0) { RTE_LOG(ERR, EAL, "Failed to open group %d\n", iommu_group_num); @@ -73917,19 +103738,29 @@ index 95f615c2e3..1be02e7f13 100644 } cur_grp->group_num = iommu_group_num; -@@ -514,9 +514,11 @@ static void - vfio_mem_event_callback(enum rte_mem_event type, const void *addr, size_t len, - void *arg __rte_unused) - { -+ rte_iova_t iova_start, iova_expected; - struct rte_memseg_list *msl; - struct rte_memseg *ms; - size_t cur_len = 0; -+ uint64_t va_start; - - msl = rte_mem_virt2memseg_list(addr); - -@@ -532,25 +534,88 @@ vfio_mem_event_callback(enum rte_mem_event type, const void *addr, size_t len, +@@ -523,15 +531,33 @@ vfio_mem_event_callback(enum rte_mem_event type, const void *addr, size_t len, + /* for IOVA as VA mode, no need to care for IOVA addresses */ + if (rte_eal_iova_mode() == RTE_IOVA_VA && msl->external == 0) { + uint64_t vfio_va = (uint64_t)(uintptr_t)addr; +- if (type == RTE_MEM_EVENT_ALLOC) +- vfio_dma_mem_map(default_vfio_cfg, vfio_va, vfio_va, +- len, 1); +- else +- vfio_dma_mem_map(default_vfio_cfg, vfio_va, vfio_va, +- len, 0); ++ uint64_t page_sz = msl->page_sz; ++ ++ /* Maintain granularity of DMA map/unmap to memseg size */ ++ for (; cur_len < len; cur_len += page_sz) { ++ if (type == RTE_MEM_EVENT_ALLOC) ++ vfio_dma_mem_map(default_vfio_cfg, vfio_va, ++ vfio_va, page_sz, 1); ++ else ++ vfio_dma_mem_map(default_vfio_cfg, vfio_va, ++ vfio_va, page_sz, 0); ++ vfio_va += page_sz; ++ } ++ return; } @@ -73946,72 +103777,11 @@ index 95f615c2e3..1be02e7f13 100644 +#endif /* memsegs are contiguous in memory */ ms = rte_mem_virt2memseg(addr, msl); -+ -+ /* -+ * This memory is not guaranteed to be contiguous, but it still could -+ * be, or it could have some small contiguous chunks. Since the number -+ * of VFIO mappings is limited, and VFIO appears to not concatenate -+ * adjacent mappings, we have to do this ourselves. -+ * -+ * So, find contiguous chunks, then map them. -+ */ -+ va_start = ms->addr_64; -+ iova_start = iova_expected = ms->iova; while (cur_len < len) { -+ bool new_contig_area = ms->iova != iova_expected; -+ bool last_seg = (len - cur_len) == ms->len; -+ bool skip_last = false; -+ -+ /* only do mappings when current contiguous area ends */ -+ if (new_contig_area) { -+ if (type == RTE_MEM_EVENT_ALLOC) -+ vfio_dma_mem_map(default_vfio_cfg, va_start, -+ iova_start, -+ iova_expected - iova_start, 1); -+ else -+ vfio_dma_mem_map(default_vfio_cfg, va_start, -+ iova_start, -+ iova_expected - iova_start, 0); -+ va_start = ms->addr_64; -+ iova_start = ms->iova; -+ } - /* some memory segments may have invalid IOVA */ - if (ms->iova == RTE_BAD_IOVA) { - RTE_LOG(DEBUG, EAL, "Memory segment at %p has bad IOVA, skipping\n", - ms->addr); -- goto next; -+ skip_last = true; - } -- if (type == RTE_MEM_EVENT_ALLOC) -- vfio_dma_mem_map(default_vfio_cfg, ms->addr_64, -- ms->iova, ms->len, 1); -- else -- vfio_dma_mem_map(default_vfio_cfg, ms->addr_64, -- ms->iova, ms->len, 0); --next: -+ iova_expected = ms->iova + ms->len; -+ cur_len += ms->len; -+ ++ms; -+ -+ /* -+ * don't count previous segment, and don't attempt to -+ * dereference a potentially invalid pointer. -+ */ -+ if (skip_last && !last_seg) { -+ iova_expected = iova_start = ms->iova; -+ va_start = ms->addr_64; -+ } else if (!skip_last && last_seg) { -+ /* this is the last segment and we're not skipping */ -+ if (type == RTE_MEM_EVENT_ALLOC) -+ vfio_dma_mem_map(default_vfio_cfg, va_start, -+ iova_start, -+ iova_expected - iova_start, 1); -+ else -+ vfio_dma_mem_map(default_vfio_cfg, va_start, -+ iova_start, -+ iova_expected - iova_start, 0); -+ } -+ } +@@ -551,6 +577,17 @@ vfio_mem_event_callback(enum rte_mem_event type, const void *addr, size_t len, + cur_len += ms->len; + ++ms; + } +#ifdef RTE_ARCH_PPC_64 + cur_len = 0; + ms = rte_mem_virt2memseg(addr, msl); @@ -74019,14 +103789,14 @@ index 95f615c2e3..1be02e7f13 100644 + int idx = rte_fbarray_find_idx(&msl->memseg_arr, ms); + + rte_fbarray_set_used(&msl->memseg_arr, idx); - cur_len += ms->len; - ++ms; - } ++ cur_len += ms->len; ++ ++ms; ++ } +#endif } static int -@@ -663,11 +728,14 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr, +@@ -663,11 +700,14 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr, /* get the actual group fd */ vfio_group_fd = rte_vfio_get_group_fd(iommu_group_num); @@ -74044,7 +103814,7 @@ index 95f615c2e3..1be02e7f13 100644 RTE_LOG(WARNING, EAL, " %s not managed by VFIO driver, skipping\n", dev_addr); return 1; -@@ -864,9 +932,6 @@ int +@@ -864,9 +904,6 @@ int rte_vfio_release_device(const char *sysfs_base, const char *dev_addr, int vfio_dev_fd) { @@ -74054,7 +103824,7 @@ index 95f615c2e3..1be02e7f13 100644 struct vfio_config *vfio_cfg; int vfio_group_fd; int iommu_group_num; -@@ -890,10 +955,10 @@ rte_vfio_release_device(const char *sysfs_base, const char *dev_addr, +@@ -890,10 +927,10 @@ rte_vfio_release_device(const char *sysfs_base, const char *dev_addr, /* get the actual group fd */ vfio_group_fd = rte_vfio_get_group_fd(iommu_group_num); @@ -74067,7 +103837,7 @@ index 95f615c2e3..1be02e7f13 100644 goto out; } -@@ -1027,6 +1092,7 @@ vfio_get_default_container_fd(void) +@@ -1027,6 +1064,7 @@ vfio_get_default_container_fd(void) struct rte_mp_reply mp_reply = {0}; struct timespec ts = {.tv_sec = 5, .tv_nsec = 0}; struct vfio_mp_param *p = (struct vfio_mp_param *)mp_req.param; @@ -74075,7 +103845,7 @@ index 95f615c2e3..1be02e7f13 100644 if (default_vfio_cfg->vfio_enabled) return default_vfio_cfg->vfio_container_fd; -@@ -1049,8 +1115,9 @@ vfio_get_default_container_fd(void) +@@ -1049,8 +1087,9 @@ vfio_get_default_container_fd(void) mp_rep = &mp_reply.msgs[0]; p = (struct vfio_mp_param *)mp_rep->param; if (p->result == SOCKET_OK && mp_rep->num_fds == 1) { @@ -74086,7 +103856,20 @@ index 95f615c2e3..1be02e7f13 100644 } } -@@ -1416,16 +1483,11 @@ vfio_spapr_dma_do_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, +@@ -1316,6 +1355,12 @@ vfio_type1_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, + RTE_LOG(ERR, EAL, " cannot clear DMA remapping, error %i (%s)\n", + errno, strerror(errno)); + return -1; ++ } else if (dma_unmap.size != len) { ++ RTE_LOG(ERR, EAL, " unexpected size %"PRIu64" of DMA " ++ "remapping cleared instead of %"PRIu64"\n", ++ (uint64_t)dma_unmap.size, len); ++ rte_errno = EIO; ++ return -1; + } + } + +@@ -1416,16 +1461,11 @@ vfio_spapr_dma_do_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, return 0; } @@ -74104,7 +103887,7 @@ index 95f615c2e3..1be02e7f13 100644 /* skip external memory that isn't a heap */ if (msl->external && !msl->heap) -@@ -1435,10 +1497,7 @@ vfio_spapr_map_walk(const struct rte_memseg_list *msl, +@@ -1435,10 +1475,7 @@ vfio_spapr_map_walk(const struct rte_memseg_list *msl, if (ms->iova == RTE_BAD_IOVA) return 0; @@ -74116,7 +103899,7 @@ index 95f615c2e3..1be02e7f13 100644 ms->len, 1); } -@@ -1446,7 +1505,7 @@ static int +@@ -1446,7 +1483,7 @@ static int vfio_spapr_unmap_walk(const struct rte_memseg_list *msl, const struct rte_memseg *ms, void *arg) { @@ -74125,7 +103908,7 @@ index 95f615c2e3..1be02e7f13 100644 /* skip external memory that isn't a heap */ if (msl->external && !msl->heap) -@@ -1456,17 +1515,13 @@ vfio_spapr_unmap_walk(const struct rte_memseg_list *msl, +@@ -1456,17 +1493,13 @@ vfio_spapr_unmap_walk(const struct rte_memseg_list *msl, if (ms->iova == RTE_BAD_IOVA) return 0; @@ -74144,7 +103927,7 @@ index 95f615c2e3..1be02e7f13 100644 }; static int -@@ -1484,10 +1539,6 @@ vfio_spapr_window_size_walk(const struct rte_memseg_list *msl, +@@ -1484,10 +1517,6 @@ vfio_spapr_window_size_walk(const struct rte_memseg_list *msl, if (ms->iova == RTE_BAD_IOVA) return 0; @@ -74155,7 +103938,7 @@ index 95f615c2e3..1be02e7f13 100644 if (max > param->window_size) { param->hugepage_sz = ms->hugepage_sz; param->window_size = max; -@@ -1531,20 +1582,11 @@ vfio_spapr_create_new_dma_window(int vfio_container_fd, +@@ -1531,20 +1560,11 @@ vfio_spapr_create_new_dma_window(int vfio_container_fd, /* try possible page_shift and levels for workaround */ uint32_t levels; @@ -74181,7 +103964,7 @@ index 95f615c2e3..1be02e7f13 100644 } #endif if (ret) { -@@ -1585,7 +1627,6 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, +@@ -1585,7 +1605,6 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, /* check if window size needs to be adjusted */ memset(¶m, 0, sizeof(param)); @@ -74189,7 +103972,7 @@ index 95f615c2e3..1be02e7f13 100644 /* we're inside a callback so use thread-unsafe version */ if (rte_memseg_walk_thread_unsafe(vfio_spapr_window_size_walk, -@@ -1610,14 +1651,9 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, +@@ -1610,14 +1629,9 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, if (do_map) { /* re-create window and remap the entire memory */ if (iova + len > create.window_size) { @@ -74205,7 +103988,7 @@ index 95f615c2e3..1be02e7f13 100644 RTE_LOG(ERR, EAL, "Could not release DMA maps\n"); ret = -1; goto out; -@@ -1644,7 +1680,7 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, +@@ -1644,7 +1658,7 @@ vfio_spapr_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, /* we're inside a callback, so use thread-unsafe version */ if (rte_memseg_walk_thread_unsafe(vfio_spapr_map_walk, @@ -74214,7 +103997,7 @@ index 95f615c2e3..1be02e7f13 100644 RTE_LOG(ERR, EAL, "Could not recreate DMA maps\n"); ret = -1; goto out; -@@ -1691,7 +1727,6 @@ vfio_spapr_dma_map(int vfio_container_fd) +@@ -1691,7 +1705,6 @@ vfio_spapr_dma_map(int vfio_container_fd) struct spapr_walk_param param; memset(¶m, 0, sizeof(param)); @@ -74222,8 +104005,41 @@ index 95f615c2e3..1be02e7f13 100644 /* create DMA window from 0 to max(phys_addr + len) */ rte_memseg_walk(vfio_spapr_window_size_walk, ¶m); +@@ -1818,6 +1831,12 @@ container_dma_unmap(struct vfio_config *vfio_cfg, uint64_t vaddr, uint64_t iova, + /* we're partially unmapping a previously mapped region, so we + * need to split entry into two. + */ ++ if (!vfio_cfg->vfio_iommu_type->partial_unmap) { ++ RTE_LOG(DEBUG, EAL, "DMA partial unmap unsupported\n"); ++ rte_errno = ENOTSUP; ++ ret = -1; ++ goto out; ++ } + if (user_mem_maps->n_maps == VFIO_MAX_USER_MEM_MAPS) { + RTE_LOG(ERR, EAL, "Not enough space to store partial mapping\n"); + rte_errno = ENOMEM; +diff --git a/dpdk/lib/librte_eal/linux/eal/eal_vfio.h b/dpdk/lib/librte_eal/linux/eal/eal_vfio.h +index cb2d35fb12..921ee59538 100644 +--- a/dpdk/lib/librte_eal/linux/eal/eal_vfio.h ++++ b/dpdk/lib/librte_eal/linux/eal/eal_vfio.h +@@ -113,6 +113,7 @@ typedef int (*vfio_dma_user_func_t)(int fd, uint64_t vaddr, uint64_t iova, + struct vfio_iommu_type { + int type_id; + const char *name; ++ bool partial_unmap; + vfio_dma_user_func_t dma_user_map_func; + vfio_dma_func_t dma_map_func; + }; +@@ -132,6 +133,7 @@ int + vfio_has_supported_extensions(int vfio_container_fd); + + int vfio_mp_sync_setup(void); ++void vfio_mp_sync_cleanup(void); + + #define EAL_VFIO_MP "eal_vfio_mp_sync" + diff --git a/dpdk/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c b/dpdk/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c -index 5f2a5fc1d9..6254696ae5 100644 +index 5f2a5fc1d9..76877f5b54 100644 --- a/dpdk/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c +++ b/dpdk/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c @@ -44,9 +44,9 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer) @@ -74238,17 +104054,158 @@ index 5f2a5fc1d9..6254696ae5 100644 /* if VFIO group exists but isn't bound to VFIO driver */ r->result = SOCKET_NO_FD; else { +@@ -120,4 +120,12 @@ vfio_mp_sync_setup(void) + return 0; + } + ++void ++vfio_mp_sync_cleanup(void) ++{ ++ if (rte_eal_process_type() != RTE_PROC_PRIMARY) ++ return; ++ ++ rte_mp_action_unregister(EAL_VFIO_MP); ++} + #endif +diff --git a/dpdk/lib/librte_eal/linux/eal/include/rte_kni_common.h b/dpdk/lib/librte_eal/linux/eal/include/rte_kni_common.h +index 7313ef504e..cfbba2a704 100644 +--- a/dpdk/lib/librte_eal/linux/eal/include/rte_kni_common.h ++++ b/dpdk/lib/librte_eal/linux/eal/include/rte_kni_common.h +@@ -6,6 +6,10 @@ + #ifndef _RTE_KNI_COMMON_H_ + #define _RTE_KNI_COMMON_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #ifdef __KERNEL__ + #include + #include +@@ -134,4 +138,8 @@ struct rte_kni_device_info { + #define RTE_KNI_IOCTL_CREATE _IOWR(0, 2, struct rte_kni_device_info) + #define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info) + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_KNI_COMMON_H_ */ +diff --git a/dpdk/lib/librte_eal/linux/eal/include/rte_os.h b/dpdk/lib/librte_eal/linux/eal/include/rte_os.h +index 218d4fa86e..afa28ece91 100644 +--- a/dpdk/lib/librte_eal/linux/eal/include/rte_os.h ++++ b/dpdk/lib/librte_eal/linux/eal/include/rte_os.h +@@ -5,10 +5,13 @@ + #ifndef _RTE_OS_H_ + #define _RTE_OS_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** +- * This is header should contain any function/macro definition +- * which are not supported natively or named differently in the +- * linux OS. Functions will be added in future releases. ++ * This header should contain any definition ++ * which is not supported natively or named differently in Linux. + */ + + #include +@@ -30,4 +33,8 @@ typedef cpu_set_t rte_cpuset_t; + CPU_XOR(dst, &tmp, src); \ + } while (0) + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_OS_H_ */ diff --git a/dpdk/lib/librte_eal/rte_eal_exports.def b/dpdk/lib/librte_eal/rte_eal_exports.def -index 12a6c79d6a..c1bdee1c40 100644 +index 12a6c79d6a..61b4082a54 100644 --- a/dpdk/lib/librte_eal/rte_eal_exports.def +++ b/dpdk/lib/librte_eal/rte_eal_exports.def -@@ -1,6 +1,5 @@ +@@ -1,6 +1,6 @@ EXPORTS __rte_panic - rte_eal_get_configuration ++ rte_eal_cleanup rte_eal_init rte_eal_mp_remote_launch rte_eal_mp_wait_lcore +diff --git a/dpdk/lib/librte_eal/rte_eal_version.map b/dpdk/lib/librte_eal/rte_eal_version.map +index e38d02530c..9ff3f76a87 100644 +--- a/dpdk/lib/librte_eal/rte_eal_version.map ++++ b/dpdk/lib/librte_eal/rte_eal_version.map +@@ -159,7 +159,6 @@ DPDK_20.0 { + rte_service_component_unregister; + rte_service_dump; + rte_service_finalize; +- rte_service_get_by_id; + rte_service_get_by_name; + rte_service_get_count; + rte_service_get_name; +diff --git a/dpdk/lib/librte_eal/windows/eal/eal.c b/dpdk/lib/librte_eal/windows/eal/eal.c +index ce460481f8..7cfa8451a3 100644 +--- a/dpdk/lib/librte_eal/windows/eal/eal.c ++++ b/dpdk/lib/librte_eal/windows/eal/eal.c +@@ -82,3 +82,9 @@ rte_eal_init(int argc __rte_unused, char **argv __rte_unused) + rte_eal_mp_wait_lcore(); + return 0; + } ++ ++int ++rte_eal_cleanup(void) ++{ ++ return 0; ++} +diff --git a/dpdk/lib/librte_eal/windows/eal/eal_thread.c b/dpdk/lib/librte_eal/windows/eal/eal_thread.c +index 0591d4c7fb..563988fe40 100644 +--- a/dpdk/lib/librte_eal/windows/eal/eal_thread.c ++++ b/dpdk/lib/librte_eal/windows/eal/eal_thread.c +@@ -124,6 +124,8 @@ eal_thread_loop(void *arg __rte_unused) + fct_arg = lcore_config[lcore_id].arg; + ret = lcore_config[lcore_id].f(fct_arg); + lcore_config[lcore_id].ret = ret; ++ lcore_config[lcore_id].f = NULL; ++ lcore_config[lcore_id].arg = NULL; + rte_wmb(); + + /* when a service core returns, it should go directly to WAIT +@@ -143,12 +145,17 @@ eal_thread_create(pthread_t *thread) + HANDLE th; + + th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)eal_thread_loop, +- NULL, 0, (LPDWORD)thread); ++ NULL, CREATE_SUSPENDED, (LPDWORD)thread); + if (!th) + return -1; + +- SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); +- SetThreadPriority(th, THREAD_PRIORITY_TIME_CRITICAL); ++ SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); ++ SetThreadPriority(th, THREAD_PRIORITY_NORMAL); ++ ++ if (ResumeThread(th) == (DWORD)-1) { ++ (void)CloseHandle(th); ++ return -1; ++ } + + return 0; + } +diff --git a/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h b/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h +index 41b574312c..a9eef9418d 100644 +--- a/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h ++++ b/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h +@@ -21,7 +21,7 @@ extern "C" { + * with the given regular expression pattern. + * + * @param pattern +- * regular expression notation decribing the pattern to match ++ * regular expression notation describing the pattern to match + * + * @param string + * source string to searcg for the pattern diff --git a/dpdk/lib/librte_eal/windows/eal/include/sched.h b/dpdk/lib/librte_eal/windows/eal/include/sched.h index 257060594c..29868c93d1 100644 --- a/dpdk/lib/librte_eal/windows/eal/include/sched.h @@ -74283,9 +104240,18 @@ index 257060594c..29868c93d1 100644 } while (0) diff --git a/dpdk/lib/librte_efd/rte_efd.c b/dpdk/lib/librte_efd/rte_efd.c -index 4deeb17924..3fd1f1c97b 100644 +index 4deeb17924..7b72e8572f 100644 --- a/dpdk/lib/librte_efd/rte_efd.c +++ b/dpdk/lib/librte_efd/rte_efd.c +@@ -494,7 +494,7 @@ efd_search_hash(struct rte_efd_table * const table, + + struct rte_efd_table * + rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len, +- uint8_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket) ++ uint64_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket) + { + struct rte_efd_table *table = NULL; + uint8_t *key_array = NULL; @@ -707,6 +707,7 @@ rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len, error_unlock_exit: @@ -74294,6 +104260,19 @@ index 4deeb17924..3fd1f1c97b 100644 rte_efd_free(table); return NULL; +diff --git a/dpdk/lib/librte_efd/rte_efd.h b/dpdk/lib/librte_efd/rte_efd.h +index c2be4c09ae..d3d7befd0c 100644 +--- a/dpdk/lib/librte_efd/rte_efd.h ++++ b/dpdk/lib/librte_efd/rte_efd.h +@@ -139,7 +139,7 @@ typedef uint16_t efd_hashfunc_t; + */ + struct rte_efd_table * + rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len, +- uint8_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket); ++ uint64_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket); + + /** + * Releases the resources from an EFD table diff --git a/dpdk/lib/librte_ethdev/ethdev_profile.h b/dpdk/lib/librte_ethdev/ethdev_profile.h index 65031e6f3f..e5ee4df824 100644 --- a/dpdk/lib/librte_ethdev/ethdev_profile.h @@ -74312,6 +104291,30 @@ index 65031e6f3f..e5ee4df824 100644 +#endif /* RTE_ETHDEV_PROFILE_WITH_VTUNE */ + #endif +diff --git a/dpdk/lib/librte_ethdev/rte_dev_info.h b/dpdk/lib/librte_ethdev/rte_dev_info.h +index 7a6b61fdb7..cacb989ced 100644 +--- a/dpdk/lib/librte_ethdev/rte_dev_info.h ++++ b/dpdk/lib/librte_ethdev/rte_dev_info.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_DEV_INFO_H_ + #define _RTE_DEV_INFO_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + + /* +@@ -48,4 +52,8 @@ struct rte_eth_dev_module_info { + #define RTE_ETH_MODULE_SFF_8436_LEN 256 + #define RTE_ETH_MODULE_SFF_8436_MAX_LEN 640 + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_DEV_INFO_H_ */ diff --git a/dpdk/lib/librte_ethdev/rte_eth_ctrl.h b/dpdk/lib/librte_ethdev/rte_eth_ctrl.h index 1416c371fb..906cd4f458 100644 --- a/dpdk/lib/librte_ethdev/rte_eth_ctrl.h @@ -74325,10 +104328,21 @@ index 1416c371fb..906cd4f458 100644 /** * @deprecated Please use rte_flow API instead of this legacy one. diff --git a/dpdk/lib/librte_ethdev/rte_ethdev.c b/dpdk/lib/librte_ethdev/rte_ethdev.c -index 6e9cb243ea..fb0912a4a8 100644 +index 6e9cb243ea..eb82e12ea4 100644 --- a/dpdk/lib/librte_ethdev/rte_ethdev.c +++ b/dpdk/lib/librte_ethdev/rte_ethdev.c -@@ -279,7 +279,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) +@@ -251,7 +251,9 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) + } + + /* Convert bus args to new syntax for use with new API dev_iterate. */ +- if (strcmp(iter->bus->name, "vdev") == 0) { ++ if ((strcmp(iter->bus->name, "vdev") == 0) || ++ (strcmp(iter->bus->name, "fslmc") == 0) || ++ (strcmp(iter->bus->name, "dpaa_bus") == 0)) { + bus_param_key = "name"; + } else if (strcmp(iter->bus->name, "pci") == 0) { + bus_param_key = "addr"; +@@ -279,7 +281,7 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) error: if (ret == -ENOTSUP) @@ -74337,7 +104351,7 @@ index 6e9cb243ea..fb0912a4a8 100644 iter->bus->name); free(devargs.args); free(bus_str); -@@ -408,7 +408,9 @@ is_allocated(const struct rte_eth_dev *ethdev) +@@ -408,7 +410,9 @@ is_allocated(const struct rte_eth_dev *ethdev) static struct rte_eth_dev * _rte_eth_dev_allocated(const char *name) { @@ -74348,7 +104362,7 @@ index 6e9cb243ea..fb0912a4a8 100644 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { if (rte_eth_devices[i].data != NULL && -@@ -437,7 +439,7 @@ rte_eth_dev_allocated(const char *name) +@@ -437,7 +441,7 @@ rte_eth_dev_allocated(const char *name) static uint16_t rte_eth_dev_find_free_port(void) { @@ -74357,7 +104371,24 @@ index 6e9cb243ea..fb0912a4a8 100644 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { /* Using shared name field to find a free port. */ -@@ -800,7 +802,7 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) +@@ -698,10 +702,13 @@ rte_eth_dev_owner_delete(const uint64_t owner_id) + rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock); + + if (rte_eth_is_valid_owner_id(owner_id)) { +- for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) +- if (rte_eth_devices[port_id].data->owner.id == owner_id) +- memset(&rte_eth_devices[port_id].data->owner, 0, ++ for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { ++ struct rte_eth_dev_data *data = ++ rte_eth_devices[port_id].data; ++ if (data != NULL && data->owner.id == owner_id) ++ memset(&data->owner, 0, + sizeof(struct rte_eth_dev_owner)); ++ } + RTE_ETHDEV_LOG(NOTICE, + "All port owners owned by %016"PRIx64" identifier have removed\n", + owner_id); +@@ -800,7 +807,7 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name) int rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id) { @@ -74366,7 +104397,7 @@ index 6e9cb243ea..fb0912a4a8 100644 if (name == NULL) { RTE_ETHDEV_LOG(ERR, "Null pointer is specified\n"); -@@ -1166,14 +1168,14 @@ check_lro_pkt_size(uint16_t port_id, uint32_t config_size, +@@ -1166,14 +1173,14 @@ check_lro_pkt_size(uint16_t port_id, uint32_t config_size, /* * Validate offloads that are requested through rte_eth_dev_configure against @@ -74383,7 +104414,7 @@ index 6e9cb243ea..fb0912a4a8 100644 * @param offload_type * The offload type i.e. Rx/Tx string. * @param offload_name -@@ -1202,7 +1204,7 @@ validate_offloads(uint16_t port_id, uint64_t req_offloads, +@@ -1202,7 +1209,7 @@ validate_offloads(uint16_t port_id, uint64_t req_offloads, ret = -EINVAL; } @@ -74392,7 +104423,7 @@ index 6e9cb243ea..fb0912a4a8 100644 if (offload & set_offloads) { RTE_ETHDEV_LOG(DEBUG, "Port %u %s offload %s is not requested but enabled\n", -@@ -1222,8 +1224,10 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, +@@ -1222,8 +1229,10 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, struct rte_eth_dev *dev; struct rte_eth_dev_info dev_info; struct rte_eth_conf orig_conf; @@ -74403,7 +104434,7 @@ index 6e9cb243ea..fb0912a4a8 100644 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); -@@ -1249,10 +1253,20 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, +@@ -1249,10 +1258,20 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf)); @@ -74424,7 +104455,7 @@ index 6e9cb243ea..fb0912a4a8 100644 /* If number of queues specified by application for both Rx and Tx is * zero, use driver preferred values. This cannot be done individually * as it is valid for either Tx or Rx (but not both) to be zero. -@@ -1339,12 +1353,17 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, +@@ -1339,12 +1358,17 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, ret = -EINVAL; goto rollback; } @@ -74445,7 +104476,7 @@ index 6e9cb243ea..fb0912a4a8 100644 } /* -@@ -1478,6 +1497,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, +@@ -1478,6 +1502,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, rte_eth_dev_tx_queue_config(dev, 0); rollback: memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); @@ -74454,7 +104485,7 @@ index 6e9cb243ea..fb0912a4a8 100644 return ret; } -@@ -1814,7 +1835,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, +@@ -1814,7 +1840,7 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, } mbp_buf_size = rte_pktmbuf_data_room_size(mp); @@ -74463,7 +104494,26 @@ index 6e9cb243ea..fb0912a4a8 100644 RTE_ETHDEV_LOG(ERR, "%s mbuf_data_room_size %d < %d (RTE_PKTMBUF_HEADROOM=%d + min_rx_bufsize(dev)=%d)\n", mp->name, (int)mbp_buf_size, -@@ -2968,6 +2989,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) +@@ -2836,7 +2862,8 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); +- ++ if (xstats == NULL && n > 0) ++ return -EINVAL; + dev = &rte_eth_devices[port_id]; + + nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS); +@@ -2852,7 +2879,7 @@ rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, + * xstats struct. + */ + xcount = (*dev->dev_ops->xstats_get)(dev, +- xstats ? xstats + count : NULL, ++ (n > count) ? xstats + count : NULL, + (n > count) ? n - count : 0); + + if (xcount < 0) +@@ -2968,6 +2995,7 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info) * return status and does not know if get is successful or not. */ memset(dev_info, 0, sizeof(struct rte_eth_dev_info)); @@ -74471,7 +104521,7 @@ index 6e9cb243ea..fb0912a4a8 100644 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); dev = &rte_eth_devices[port_id]; -@@ -3248,58 +3270,60 @@ rte_eth_dev_set_vlan_ether_type(uint16_t port_id, +@@ -3248,58 +3276,60 @@ rte_eth_dev_set_vlan_ether_type(uint16_t port_id, int rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) { @@ -74547,7 +104597,7 @@ index 6e9cb243ea..fb0912a4a8 100644 mask |= ETH_QINQ_STRIP_MASK; } -@@ -3307,11 +3331,28 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) +@@ -3307,11 +3337,28 @@ rte_eth_dev_set_vlan_offload(uint16_t port_id, int offload_mask) if (mask == 0) return ret; @@ -74577,7 +104627,50 @@ index 6e9cb243ea..fb0912a4a8 100644 } return eth_err(port_id, ret); -@@ -3934,7 +3975,7 @@ rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id) +@@ -3457,6 +3504,7 @@ rte_eth_dev_rss_reta_update(uint16_t port_id, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) + { ++ enum rte_eth_rx_mq_mode mq_mode; + struct rte_eth_dev *dev; + int ret; + +@@ -3474,6 +3522,12 @@ rte_eth_dev_rss_reta_update(uint16_t port_id, + if (ret < 0) + return ret; + ++ mq_mode = dev->data->dev_conf.rxmode.mq_mode; ++ if (!(mq_mode & ETH_MQ_RX_RSS_FLAG)) { ++ RTE_ETHDEV_LOG(ERR, "Multi-queue RSS mode isn't enabled.\n"); ++ return -ENOTSUP; ++ } ++ + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->reta_update, -ENOTSUP); + return eth_err(port_id, (*dev->dev_ops->reta_update)(dev, reta_conf, + reta_size)); +@@ -3506,6 +3560,7 @@ rte_eth_dev_rss_hash_update(uint16_t port_id, + { + struct rte_eth_dev *dev; + struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, }; ++ enum rte_eth_rx_mq_mode mq_mode; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); +@@ -3525,6 +3580,13 @@ rte_eth_dev_rss_hash_update(uint16_t port_id, + dev_info.flow_type_rss_offloads); + return -EINVAL; + } ++ ++ mq_mode = dev->data->dev_conf.rxmode.mq_mode; ++ if (!(mq_mode & ETH_MQ_RX_RSS_FLAG)) { ++ RTE_ETHDEV_LOG(ERR, "Multi-queue RSS mode isn't enabled.\n"); ++ return -ENOTSUP; ++ } ++ + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP); + return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev, + rss_conf)); +@@ -3934,7 +3996,7 @@ rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id) RTE_INIT(eth_dev_init_cb_lists) { @@ -74586,7 +104679,7 @@ index 6e9cb243ea..fb0912a4a8 100644 for (i = 0; i < RTE_MAX_ETHPORTS; i++) TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs); -@@ -3947,7 +3988,7 @@ rte_eth_dev_callback_register(uint16_t port_id, +@@ -3947,7 +4009,7 @@ rte_eth_dev_callback_register(uint16_t port_id, { struct rte_eth_dev *dev; struct rte_eth_dev_callback *user_cb; @@ -74595,7 +104688,7 @@ index 6e9cb243ea..fb0912a4a8 100644 uint16_t last_port; if (!cb_fn) -@@ -4010,7 +4051,7 @@ rte_eth_dev_callback_unregister(uint16_t port_id, +@@ -4010,7 +4072,7 @@ rte_eth_dev_callback_unregister(uint16_t port_id, int ret; struct rte_eth_dev *dev; struct rte_eth_dev_callback *cb, *next; @@ -74604,7 +104697,7 @@ index 6e9cb243ea..fb0912a4a8 100644 uint16_t last_port; if (!cb_fn) -@@ -4039,7 +4080,7 @@ rte_eth_dev_callback_unregister(uint16_t port_id, +@@ -4039,7 +4101,7 @@ rte_eth_dev_callback_unregister(uint16_t port_id, next = TAILQ_NEXT(cb, next); if (cb->cb_fn != cb_fn || cb->event != event || @@ -74613,7 +104706,7 @@ index 6e9cb243ea..fb0912a4a8 100644 continue; /* -@@ -4219,7 +4260,8 @@ rte_eth_dev_create(struct rte_device *device, const char *name, +@@ -4219,7 +4281,8 @@ rte_eth_dev_create(struct rte_device *device, const char *name, device->numa_node); if (!ethdev->data->dev_private) { @@ -74623,7 +104716,7 @@ index 6e9cb243ea..fb0912a4a8 100644 retval = -ENOMEM; goto probe_failed; } -@@ -4227,8 +4269,8 @@ rte_eth_dev_create(struct rte_device *device, const char *name, +@@ -4227,8 +4290,8 @@ rte_eth_dev_create(struct rte_device *device, const char *name, } else { ethdev = rte_eth_dev_attach_secondary(name); if (!ethdev) { @@ -74634,7 +104727,7 @@ index 6e9cb243ea..fb0912a4a8 100644 return -ENODEV; } } -@@ -4238,15 +4280,15 @@ rte_eth_dev_create(struct rte_device *device, const char *name, +@@ -4238,15 +4301,15 @@ rte_eth_dev_create(struct rte_device *device, const char *name, if (ethdev_bus_specific_init) { retval = ethdev_bus_specific_init(ethdev, bus_init_params); if (retval) { @@ -74653,7 +104746,7 @@ index 6e9cb243ea..fb0912a4a8 100644 goto probe_failed; } -@@ -4414,12 +4456,20 @@ rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -4414,12 +4477,20 @@ rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; if (!tail) { @@ -74676,7 +104769,7 @@ index 6e9cb243ea..fb0912a4a8 100644 } rte_spinlock_unlock(&rte_eth_rx_cb_lock); -@@ -4452,7 +4502,7 @@ rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -4452,7 +4523,7 @@ rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, cb->param = user_param; rte_spinlock_lock(&rte_eth_rx_cb_lock); @@ -74685,7 +104778,7 @@ index 6e9cb243ea..fb0912a4a8 100644 cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id]; rte_smp_wmb(); rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb; -@@ -4500,12 +4550,20 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, +@@ -4500,12 +4571,20 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id]; if (!tail) { @@ -74708,7 +104801,7 @@ index 6e9cb243ea..fb0912a4a8 100644 } rte_spinlock_unlock(&rte_eth_tx_cb_lock); -@@ -4536,7 +4594,7 @@ rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -4536,7 +4615,7 @@ rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, cb = *prev_cb; if (cb == user_cb) { /* Remove the user cb from the callback list. */ @@ -74717,7 +104810,7 @@ index 6e9cb243ea..fb0912a4a8 100644 ret = 0; break; } -@@ -4570,7 +4628,7 @@ rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, +@@ -4570,7 +4649,7 @@ rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id, cb = *prev_cb; if (cb == user_cb) { /* Remove the user cb from the callback list. */ @@ -74726,7 +104819,52 @@ index 6e9cb243ea..fb0912a4a8 100644 ret = 0; break; } -@@ -5060,12 +5118,11 @@ static struct rte_eth_dev_switch { +@@ -4815,6 +4894,8 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (info == NULL) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); +@@ -4839,6 +4920,8 @@ rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (info == NULL) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP); +@@ -4851,6 +4934,8 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (info == NULL) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP); +@@ -4864,6 +4949,8 @@ rte_eth_dev_get_module_info(uint16_t port_id, + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (modinfo == NULL) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP); +@@ -4877,6 +4964,8 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id, + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); ++ if (info == NULL || info->data == NULL || info->length == 0) ++ return -EINVAL; + + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP); +@@ -5060,12 +5149,11 @@ static struct rte_eth_dev_switch { int rte_eth_switch_domain_alloc(uint16_t *domain_id) { @@ -74742,9 +104880,18 @@ index 6e9cb243ea..fb0912a4a8 100644 RTE_ETH_SWITCH_DOMAIN_UNUSED) { rte_eth_switch_domains[i].state = diff --git a/dpdk/lib/librte_ethdev/rte_ethdev.h b/dpdk/lib/librte_ethdev/rte_ethdev.h -index 18a9defc24..017459e595 100644 +index 18a9defc24..2aea6cb196 100644 --- a/dpdk/lib/librte_ethdev/rte_ethdev.h +++ b/dpdk/lib/librte_ethdev/rte_ethdev.h +@@ -74,7 +74,7 @@ + * rte_eth_rx_queue_setup()), it must call rte_eth_dev_stop() first to stop the + * device and then do the reconfiguration before calling rte_eth_dev_start() + * again. The transmit and receive functions should not be invoked when the +- * device is stopped. ++ * device or the queue is stopped. + * + * Please note that some configuration is not stored between calls to + * rte_eth_dev_stop()/rte_eth_dev_start(). The following configuration will @@ -1160,17 +1160,20 @@ struct rte_eth_conf { #define DEV_TX_OFFLOAD_IP_TNL_TSO 0x00080000 /** Device supports outer UDP checksum */ @@ -74781,7 +104928,105 @@ index 18a9defc24..017459e595 100644 /** * Ethernet device associated switch information -@@ -3612,7 +3615,8 @@ struct rte_eth_rxtx_callback; +@@ -1224,7 +1227,7 @@ struct rte_eth_switch_info { + * device, etc... + */ + struct rte_eth_dev_info { +- struct rte_device *device; /** Generic device information */ ++ struct rte_device *device; /**< Generic device information */ + const char *driver_name; /**< Device Driver name. */ + unsigned int if_index; /**< Index to bound host interface, or 0 if none. + Use if_indextoname() to translate into an interface name. */ +@@ -1238,8 +1241,8 @@ struct rte_eth_dev_info { + uint16_t max_rx_queues; /**< Maximum number of RX queues. */ + uint16_t max_tx_queues; /**< Maximum number of TX queues. */ + uint32_t max_mac_addrs; /**< Maximum number of MAC addresses. */ +- uint32_t max_hash_mac_addrs; + /** Maximum number of hash MAC addresses for MTA and UTA. */ ++ uint32_t max_hash_mac_addrs; + uint16_t max_vfs; /**< Maximum number of VFs. */ + uint16_t max_vmdq_pools; /**< Maximum number of VMDq pools. */ + uint64_t rx_offload_capa; +@@ -2360,9 +2363,13 @@ int rte_eth_xstats_get_names(uint16_t port_id, + * @param xstats + * A pointer to a table of structure of type *rte_eth_xstat* + * to be filled with device statistics ids and values. +- * This parameter can be set to NULL if n is 0. ++ * This parameter can be set to NULL if and only if n is 0. + * @param n + * The size of the xstats array (number of elements). ++ * If lower than the required number of elements, the function returns ++ * the required number of elements. ++ * If equal to zero, the xstats must be NULL, the function returns the ++ * required number of elements. + * @return + * - A positive value lower or equal to n: success. The return value + * is the number of entries filled in the stats table. +@@ -2381,21 +2388,23 @@ int rte_eth_xstats_get(uint16_t port_id, struct rte_eth_xstat *xstats, + * @param port_id + * The port identifier of the Ethernet device. + * @param xstats_names +- * An rte_eth_xstat_name array of at least *size* elements to +- * be filled. If set to NULL, the function returns the required number +- * of elements. +- * @param ids +- * IDs array given by app to retrieve specific statistics ++ * Array to be filled in with names of requested device statistics. ++ * Must not be NULL if @p ids are specified (not NULL). + * @param size +- * The size of the xstats_names array (number of elements). ++ * Number of elements in @p xstats_names array (if not NULL) and in ++ * @p ids array (if not NULL). Must be 0 if both array pointers are NULL. ++ * @param ids ++ * IDs array given by app to retrieve specific statistics. May be NULL to ++ * retrieve names of all available statistics or, if @p xstats_names is ++ * NULL as well, just the number of available statistics. + * @return + * - A positive value lower or equal to size: success. The return value + * is the number of entries filled in the stats table. +- * - A positive value higher than size: error, the given statistics table ++ * - A positive value higher than size: success. The given statistics table + * is too small. The return value corresponds to the size that should + * be given to succeed. The entries in the table are not valid and + * shall not be used by the caller. +- * - A negative value on error (invalid port id). ++ * - A negative value on error. + */ + int + rte_eth_xstats_get_names_by_id(uint16_t port_id, +@@ -2408,22 +2417,23 @@ rte_eth_xstats_get_names_by_id(uint16_t port_id, + * @param port_id + * The port identifier of the Ethernet device. + * @param ids +- * A pointer to an ids array passed by application. This tells which +- * statistics values function should retrieve. This parameter +- * can be set to NULL if size is 0. In this case function will retrieve +- * all available statistics. ++ * IDs array given by app to retrieve specific statistics. May be NULL to ++ * retrieve all available statistics or, if @p values is NULL as well, ++ * just the number of available statistics. + * @param values +- * A pointer to a table to be filled with device statistics values. ++ * Array to be filled in with requested device statistics. ++ * Must not be NULL if ids are specified (not NULL). + * @param size +- * The size of the ids array (number of elements). ++ * Number of elements in @p values array (if not NULL) and in @p ids ++ * array (if not NULL). Must be 0 if both array pointers are NULL. + * @return + * - A positive value lower or equal to size: success. The return value + * is the number of entries filled in the stats table. +- * - A positive value higher than size: error, the given statistics table ++ * - A positive value higher than size: success: The given statistics table + * is too small. The return value corresponds to the size that should + * be given to succeed. The entries in the table are not valid and + * shall not be used by the caller. +- * - A negative value on error (invalid port id). ++ * - A negative value on error. + */ + int rte_eth_xstats_get_by_id(uint16_t port_id, const uint64_t *ids, + uint64_t *values, unsigned int size); +@@ -3612,7 +3622,8 @@ struct rte_eth_rxtx_callback; * The callback function * @param user_param * A generic pointer parameter which will be passed to each invocation of the @@ -74791,7 +105036,7 @@ index 18a9defc24..017459e595 100644 * * @return * NULL on error. -@@ -3641,7 +3645,8 @@ rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -3641,7 +3652,8 @@ rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id, * The callback function * @param user_param * A generic pointer parameter which will be passed to each invocation of the @@ -74801,7 +105046,7 @@ index 18a9defc24..017459e595 100644 * * @return * NULL on error. -@@ -3669,7 +3674,8 @@ rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -3669,7 +3681,8 @@ rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id, * The callback function * @param user_param * A generic pointer parameter which will be passed to each invocation of the @@ -74811,7 +105056,7 @@ index 18a9defc24..017459e595 100644 * * @return * NULL on error. -@@ -3694,7 +3700,9 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, +@@ -3694,7 +3707,9 @@ rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id, * on that queue. * * - After a short delay - where the delay is sufficient to allow any @@ -74822,7 +105067,7 @@ index 18a9defc24..017459e595 100644 * * @param port_id * The port identifier of the Ethernet device. -@@ -3727,7 +3735,9 @@ int rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, +@@ -3727,7 +3742,9 @@ int rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id, * on that queue. * * - After a short delay - where the delay is sufficient to allow any @@ -74833,7 +105078,47 @@ index 18a9defc24..017459e595 100644 * * @param port_id * The port identifier of the Ethernet device. -@@ -4388,10 +4398,18 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, +@@ -3843,6 +3860,7 @@ int rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id, + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port_id* invalid. ++ * - (-EINVAL) if bad parameter. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. + */ +@@ -3873,6 +3891,7 @@ int rte_eth_dev_get_eeprom_length(uint16_t port_id); + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. ++ * - (-EINVAL) if bad parameter. + * - (-ENODEV) if *port_id* invalid. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. +@@ -3890,6 +3909,7 @@ int rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info); + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. ++ * - (-EINVAL) if bad parameter. + * - (-ENODEV) if *port_id* invalid. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. +@@ -3910,6 +3930,7 @@ int rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info); + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port_id* invalid. ++ * - (-EINVAL) if bad parameter. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. + */ +@@ -3932,6 +3953,7 @@ rte_eth_dev_get_module_info(uint16_t port_id, + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. ++ * - (-EINVAL) if bad parameter. + * - (-ENODEV) if *port_id* invalid. + * - (-EIO) if device is removed. + * - others depends on the specific operations implementation. +@@ -4388,10 +4410,18 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id, rx_pkts, nb_pkts); #ifdef RTE_ETHDEV_RXTX_CALLBACKS @@ -74855,7 +105140,7 @@ index 18a9defc24..017459e595 100644 do { nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx, nb_pkts, cb->param); -@@ -4652,7 +4670,16 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id, +@@ -4652,7 +4682,16 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id, #endif #ifdef RTE_ETHDEV_RXTX_CALLBACKS @@ -74873,11 +105158,147 @@ index 18a9defc24..017459e595 100644 if (unlikely(cb != NULL)) { do { +diff --git a/dpdk/lib/librte_ethdev/rte_ethdev_core.h b/dpdk/lib/librte_ethdev/rte_ethdev_core.h +index 7bf97e24ed..1106b6160a 100644 +--- a/dpdk/lib/librte_ethdev/rte_ethdev_core.h ++++ b/dpdk/lib/librte_ethdev/rte_ethdev_core.h +@@ -71,7 +71,7 @@ typedef int (*eth_is_removed_t)(struct rte_eth_dev *dev); + * @retval -E_RTE_SECONDARY + * Function was called from a secondary process instance and not supported. + * @retval -ETIMEDOUT +- * Attempt to enable promiscuos mode failed because of timeout. ++ * Attempt to enable promiscuous mode failed because of timeout. + * @retval -EAGAIN + * Failed to enable promiscuous mode. + */ +@@ -96,7 +96,7 @@ typedef int (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev); + * @retval -E_RTE_SECONDARY + * Function was called from a secondary process instance and not supported. + * @retval -ETIMEDOUT +- * Attempt to disable promiscuos mode failed because of timeout. ++ * Attempt to disable promiscuous mode failed because of timeout. + * @retval -EAGAIN + * Failed to disable promiscuous mode. + */ diff --git a/dpdk/lib/librte_ethdev/rte_ethdev_pci.h b/dpdk/lib/librte_ethdev/rte_ethdev_pci.h -index ccdbb46ec0..d44a8e2a39 100644 +index ccdbb46ec0..b20c32dfde 100644 --- a/dpdk/lib/librte_ethdev/rte_ethdev_pci.h +++ b/dpdk/lib/librte_ethdev/rte_ethdev_pci.h -@@ -3,32 +3,6 @@ +@@ -3,37 +3,15 @@ + * + * Copyright(c) 2017 Brocade Communications Systems, Inc. + * Author: Jan Blunck +- * +- * 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 the copyright holder 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. + */ + + #ifndef _RTE_ETHDEV_PCI_H_ + #define _RTE_ETHDEV_PCI_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + #include + #include +@@ -42,6 +20,8 @@ + + /** + * Copy pci device info to the Ethernet device data. ++ * Shared memory (eth_dev->data) only updated by primary process, so it is safe ++ * to call this function from both primary and secondary processes. + * + * @param eth_dev + * The *eth_dev* pointer is the address of the *rte_eth_dev* structure. +@@ -60,19 +40,22 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, + + eth_dev->intr_handle = &pci_dev->intr_handle; + +- eth_dev->data->dev_flags = 0; +- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC) +- eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; +- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV) +- eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV; +- +- eth_dev->data->kdrv = pci_dev->kdrv; +- eth_dev->data->numa_node = pci_dev->device.numa_node; ++ if (rte_eal_process_type() == RTE_PROC_PRIMARY) { ++ eth_dev->data->dev_flags = 0; ++ if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC) ++ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; ++ if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV) ++ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV; ++ ++ eth_dev->data->kdrv = pci_dev->kdrv; ++ eth_dev->data->numa_node = pci_dev->device.numa_node; ++ } + } + + static inline int +-eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) { +- struct rte_pci_device *pci_dev = bus_device; ++eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) ++{ ++ struct rte_pci_device *pci_dev = (struct rte_pci_device *)bus_device; + + if (!pci_dev) + return -ENODEV; +@@ -186,6 +169,16 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev, + if (!eth_dev) + return 0; + ++ /* ++ * In secondary process, a released eth device can be found by its name ++ * in shared memory. ++ * If the state of the eth device is RTE_ETH_DEV_UNUSED, it means the ++ * eth device has been released. ++ */ ++ if (rte_eal_process_type() == RTE_PROC_SECONDARY && ++ eth_dev->state == RTE_ETH_DEV_UNUSED) ++ return 0; ++ + if (dev_uninit) { + ret = dev_uninit(eth_dev); + if (ret) +@@ -196,4 +189,8 @@ rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev, + return 0; + } + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_ETHDEV_PCI_H_ */ +diff --git a/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h b/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h +index 259feda3f7..a1110f54b2 100644 +--- a/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h ++++ b/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h +@@ -3,37 +3,15 @@ * * Copyright(c) 2017 Brocade Communications Systems, Inc. * Author: Jan Blunck @@ -74909,80 +105330,27 @@ index ccdbb46ec0..d44a8e2a39 100644 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef _RTE_ETHDEV_PCI_H_ -@@ -42,6 +16,8 @@ - - /** - * Copy pci device info to the Ethernet device data. -+ * Shared memory (eth_dev->data) only updated by primary process, so it is safe -+ * to call this function from both primary and secondary processes. - * - * @param eth_dev - * The *eth_dev* pointer is the address of the *rte_eth_dev* structure. -@@ -60,14 +36,16 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, - - eth_dev->intr_handle = &pci_dev->intr_handle; + #ifndef _RTE_ETHDEV_VDEV_H_ + #define _RTE_ETHDEV_VDEV_H_ -- eth_dev->data->dev_flags = 0; -- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC) -- eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; -- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV) -- eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV; -- -- eth_dev->data->kdrv = pci_dev->kdrv; -- eth_dev->data->numa_node = pci_dev->device.numa_node; -+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) { -+ eth_dev->data->dev_flags = 0; -+ if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC) -+ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; -+ if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV) -+ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV; ++#ifdef __cplusplus ++extern "C" { ++#endif + -+ eth_dev->data->kdrv = pci_dev->kdrv; -+ eth_dev->data->numa_node = pci_dev->device.numa_node; -+ } + #include + #include + #include +@@ -81,4 +59,8 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size) + return eth_dev; } - static inline int -diff --git a/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h b/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h -index 259feda3f7..0abce0d21c 100644 ---- a/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h -+++ b/dpdk/lib/librte_ethdev/rte_ethdev_vdev.h -@@ -3,32 +3,6 @@ - * - * Copyright(c) 2017 Brocade Communications Systems, Inc. - * Author: Jan Blunck -- * -- * 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 the copyright holder 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. - */ - - #ifndef _RTE_ETHDEV_VDEV_H_ ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_ETHDEV_VDEV_H_ */ diff --git a/dpdk/lib/librte_ethdev/rte_flow.c b/dpdk/lib/librte_ethdev/rte_flow.c -index 87a3e8c4c6..9964a241cb 100644 +index 87a3e8c4c6..32b676ca01 100644 --- a/dpdk/lib/librte_ethdev/rte_flow.c +++ b/dpdk/lib/librte_ethdev/rte_flow.c @@ -19,7 +19,7 @@ @@ -75039,6 +105407,15 @@ index 87a3e8c4c6..9964a241cb 100644 off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key)); tmp = sizeof(*src.rss->key) * src.rss->key_len; if (size >= off + tmp) +@@ -1054,7 +1062,7 @@ rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size, + const struct rte_flow_expand_node graph[], + int graph_root_index) + { +- const int elt_n = 8; ++ const int elt_n = 16; + const struct rte_flow_item *item; + const struct rte_flow_expand_node *node = &graph[graph_root_index]; + const int *next_node; @@ -1104,10 +1112,14 @@ rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size, memset(flow_items, 0, sizeof(flow_items)); user_pattern_size -= sizeof(*item); @@ -75056,8 +105433,41 @@ index 87a3e8c4c6..9964a241cb 100644 if (missed_item.type != RTE_FLOW_ITEM_TYPE_VOID) { next = NULL; missed = 1; +@@ -1173,7 +1185,7 @@ rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size, + } + } + /* Go deeper. */ +- if (node->next) { ++ if (!node->optional && node->next) { + next_node = node->next; + if (stack_pos++ == elt_n) { + rte_errno = E2BIG; +@@ -1192,23 +1204,5 @@ rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size, + } + node = *next_node ? &graph[*next_node] : NULL; + }; +- /* no expanded flows but we have missed item, create one rule for it */ +- if (buf->entries == 1 && missed != 0) { +- elt = 2; +- lsize += elt * sizeof(*item) + user_pattern_size; +- if (lsize <= size) { +- buf->entry[buf->entries].priority = 1; +- buf->entry[buf->entries].pattern = addr; +- buf->entries++; +- flow_items[0].type = missed_item.type; +- flow_items[1].type = RTE_FLOW_ITEM_TYPE_END; +- rte_memcpy(addr, buf->entry[0].pattern, +- user_pattern_size); +- addr = (void *)(((uintptr_t)addr) + user_pattern_size); +- rte_memcpy(addr, flow_items, elt * sizeof(*item)); +- addr = (void *)(((uintptr_t)addr) + +- elt * sizeof(*item)); +- } +- } + return lsize; + } diff --git a/dpdk/lib/librte_ethdev/rte_flow.h b/dpdk/lib/librte_ethdev/rte_flow.h -index 452d359a16..693824da8a 100644 +index 452d359a16..12f69b6365 100644 --- a/dpdk/lib/librte_ethdev/rte_flow.h +++ b/dpdk/lib/librte_ethdev/rte_flow.h @@ -502,7 +502,7 @@ enum rte_flow_item_type { @@ -75069,6 +105479,23 @@ index 452d359a16..693824da8a 100644 * [META] * * Matches a tag value. +@@ -1302,14 +1302,14 @@ static const struct rte_flow_item_meta rte_flow_item_meta_mask = { + */ + struct rte_flow_item_gtp_psc { + uint8_t pdu_type; /**< PDU type. */ +- uint8_t qfi; /**< QoS flow identifier. */ ++ uint8_t qfi; /**< PPP, RQI, QoS flow identifier. */ + }; + + /** Default mask for RTE_FLOW_ITEM_TYPE_GTP_PSC. */ + #ifndef __cplusplus + static const struct rte_flow_item_gtp_psc + rte_flow_item_gtp_psc_mask = { +- .qfi = 0x3f, ++ .qfi = 0xff, + }; + #endif + @@ -2531,7 +2531,7 @@ struct rte_flow_action_set_meta { }; @@ -75078,8 +105505,30 @@ index 452d359a16..693824da8a 100644 /* Mbuf dynamic field flag mask for metadata. */ extern uint64_t rte_flow_dynf_metadata_mask; +@@ -2558,7 +2558,7 @@ rte_flow_dynf_metadata_set(struct rte_mbuf *m, uint32_t v) + *RTE_FLOW_DYNF_METADATA(m) = v; + } + +-/* ++/** + * Definition of a single action. + * + * A list of actions is terminated by a END action. +diff --git a/dpdk/lib/librte_ethdev/rte_flow_driver.h b/dpdk/lib/librte_ethdev/rte_flow_driver.h +index a0359853e6..d608d25d36 100644 +--- a/dpdk/lib/librte_ethdev/rte_flow_driver.h ++++ b/dpdk/lib/librte_ethdev/rte_flow_driver.h +@@ -133,6 +133,8 @@ struct rte_flow_expand_node { + * RSS types bit-field associated with this node + * (see ETH_RSS_* definitions). + */ ++ uint8_t optional; ++ /**< optional expand field. Default 0 to expand, 1 not go deeper. */ + }; + + /** Object returned by rte_flow_expand_rss(). */ diff --git a/dpdk/lib/librte_eventdev/rte_event_crypto_adapter.c b/dpdk/lib/librte_eventdev/rte_event_crypto_adapter.c -index 22d9108168..db9af8c200 100644 +index 22d9108168..3c330c6cbb 100644 --- a/dpdk/lib/librte_eventdev/rte_event_crypto_adapter.c +++ b/dpdk/lib/librte_eventdev/rte_event_crypto_adapter.c @@ -240,6 +240,7 @@ rte_event_crypto_adapter_create_ext(uint8_t id, uint8_t dev_id, @@ -75090,11 +105539,67 @@ index 22d9108168..db9af8c200 100644 return ret; } +@@ -856,6 +857,7 @@ rte_event_crypto_adapter_queue_pair_add(uint8_t id, + * b. OP_NEW mode -> SW Dequeue + */ + if ((cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW && ++ !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && + adapter->mode == RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD) || + (!(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW) && + !(cap & RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) && +diff --git a/dpdk/lib/librte_eventdev/rte_event_eth_rx_adapter.c b/dpdk/lib/librte_eventdev/rte_event_eth_rx_adapter.c +index 95dd478201..d59b3dee6a 100644 +--- a/dpdk/lib/librte_eventdev/rte_event_eth_rx_adapter.c ++++ b/dpdk/lib/librte_eventdev/rte_event_eth_rx_adapter.c +@@ -1294,12 +1294,11 @@ rxa_create_intr_thread(struct rte_event_eth_rx_adapter *rx_adapter) + + err = rte_ctrl_thread_create(&rx_adapter->rx_intr_thread, thread_name, + NULL, rxa_intr_thread, rx_adapter); +- if (!err) { +- rte_thread_setname(rx_adapter->rx_intr_thread, thread_name); ++ if (!err) + return 0; +- } + + RTE_EDEV_LOG_ERR("Failed to create interrupt thread err = %d\n", err); ++ rte_free(rx_adapter->epoll_events); + error: + rte_ring_free(rx_adapter->intr_ring); + rx_adapter->intr_ring = NULL; +@@ -2245,6 +2244,11 @@ rte_event_eth_rx_adapter_queue_del(uint8_t id, uint16_t eth_dev_id, + rx_adapter->eth_rx_poll = rx_poll; + rx_adapter->wrr_sched = rx_wrr; + rx_adapter->wrr_len = nb_wrr; ++ /* ++ * reset next poll start position (wrr_pos) to avoid buffer ++ * overrun when wrr_len is reduced in case of queue delete ++ */ ++ rx_adapter->wrr_pos = 0; + rx_adapter->num_intr_vec += num_intr_vec; + + if (dev_info->nb_dev_queues == 0) { diff --git a/dpdk/lib/librte_eventdev/rte_event_eth_tx_adapter.c b/dpdk/lib/librte_eventdev/rte_event_eth_tx_adapter.c -index d02ef57f4e..8a1573e75f 100644 +index d02ef57f4e..e64c7ff2b6 100644 --- a/dpdk/lib/librte_eventdev/rte_event_eth_tx_adapter.c +++ b/dpdk/lib/librte_eventdev/rte_event_eth_tx_adapter.c -@@ -733,6 +733,8 @@ txa_service_queue_add(uint8_t id, +@@ -223,7 +223,7 @@ txa_service_data_init(void) + if (txa_service_data_array == NULL) { + txa_service_data_array = + txa_memzone_array_get("txa_service_data_array", +- sizeof(int), ++ sizeof(*txa_service_data_array), + RTE_EVENT_ETH_TX_ADAPTER_MAX_INSTANCE); + if (txa_service_data_array == NULL) + return -ENOMEM; +@@ -285,7 +285,6 @@ txa_service_conf_cb(uint8_t __rte_unused id, uint8_t dev_id, + return ret; + } + +- pc->disable_implicit_release = 0; + ret = rte_event_port_setup(dev_id, port_id, pc); + if (ret) { + RTE_EDEV_LOG_ERR("failed to setup event port %u\n", +@@ -733,6 +732,8 @@ txa_service_queue_add(uint8_t id, qdone = rte_zmalloc(txa->mem_name, nb_queues * sizeof(*qdone), 0); @@ -75103,10 +105608,117 @@ index d02ef57f4e..8a1573e75f 100644 j = 0; for (i = 0; i < nb_queues; i++) { if (txa_service_is_queue_added(txa, eth_dev, i)) +@@ -758,10 +759,8 @@ txa_service_queue_add(uint8_t id, + + rte_spinlock_lock(&txa->tx_lock); + +- if (txa_service_is_queue_added(txa, eth_dev, tx_queue_id)) { +- rte_spinlock_unlock(&txa->tx_lock); +- return 0; +- } ++ if (txa_service_is_queue_added(txa, eth_dev, tx_queue_id)) ++ goto ret_unlock; + + ret = txa_service_queue_array_alloc(txa, eth_dev->data->port_id); + if (ret) +@@ -773,6 +772,8 @@ txa_service_queue_add(uint8_t id, + + tdi = &txa->txa_ethdev[eth_dev->data->port_id]; + tqi = txa_service_queue(txa, eth_dev->data->port_id, tx_queue_id); ++ if (tqi == NULL) ++ goto err_unlock; + + txa_retry = &tqi->txa_retry; + txa_retry->id = txa->id; +@@ -788,6 +789,10 @@ txa_service_queue_add(uint8_t id, + tdi->nb_queues++; + txa->nb_queues++; + ++ret_unlock: ++ rte_spinlock_unlock(&txa->tx_lock); ++ return 0; ++ + err_unlock: + if (txa->nb_queues == 0) { + txa_service_queue_array_free(txa, +@@ -796,7 +801,7 @@ txa_service_queue_add(uint8_t id, + } + + rte_spinlock_unlock(&txa->tx_lock); +- return 0; ++ return -1; + } + + static int +@@ -816,7 +821,7 @@ txa_service_queue_del(uint8_t id, + uint16_t i, q, nb_queues; + int ret = 0; + +- nb_queues = txa->nb_queues; ++ nb_queues = txa->txa_ethdev[port_id].nb_queues; + if (nb_queues == 0) + return 0; + +@@ -839,9 +844,10 @@ txa_service_queue_del(uint8_t id, + + txa = txa_service_id_to_data(id); + ++ rte_spinlock_lock(&txa->tx_lock); + tqi = txa_service_queue(txa, port_id, tx_queue_id); + if (tqi == NULL || !tqi->added) +- return 0; ++ goto ret_unlock; + + tb = tqi->tx_buf; + tqi->added = 0; +@@ -851,6 +857,9 @@ txa_service_queue_del(uint8_t id, + txa->txa_ethdev[port_id].nb_queues--; + + txa_service_queue_array_free(txa, port_id); ++ ++ret_unlock: ++ rte_spinlock_unlock(&txa->tx_lock); + return 0; + } + +diff --git a/dpdk/lib/librte_eventdev/rte_event_ring.h b/dpdk/lib/librte_eventdev/rte_event_ring.h +index 827a3209ea..f76e508c54 100644 +--- a/dpdk/lib/librte_eventdev/rte_event_ring.h ++++ b/dpdk/lib/librte_eventdev/rte_event_ring.h +@@ -13,6 +13,10 @@ + #ifndef _RTE_EVENT_RING_ + #define _RTE_EVENT_RING_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + + #include +@@ -275,4 +279,9 @@ rte_event_ring_get_capacity(const struct rte_event_ring *r) + { + return rte_ring_get_capacity(&r->r); + } ++ ++#ifdef __cplusplus ++} ++#endif ++ + #endif diff --git a/dpdk/lib/librte_eventdev/rte_event_timer_adapter.c b/dpdk/lib/librte_eventdev/rte_event_timer_adapter.c -index 161e21a685..36c13fe3b5 100644 +index 161e21a685..8e340d67e6 100644 --- a/dpdk/lib/librte_eventdev/rte_event_timer_adapter.c +++ b/dpdk/lib/librte_eventdev/rte_event_timer_adapter.c +@@ -489,7 +489,7 @@ event_buffer_flush(struct event_buffer *bufp, uint8_t dev_id, uint8_t port_id, + + RTE_ASSERT(head_idx < EVENT_BUFFER_SZ && tail_idx < EVENT_BUFFER_SZ); + +- /* Determine the largest contigous run we can attempt to enqueue to the ++ /* Determine the largest contiguous run we can attempt to enqueue to the + * event device. + */ + if (head_idx > tail_idx) @@ -550,7 +550,7 @@ struct swtim { uint32_t timer_data_id; /* Track which cores have actually armed a timer */ @@ -75307,6 +105919,19 @@ index 161e21a685..36c13fe3b5 100644 } return i; +diff --git a/dpdk/lib/librte_eventdev/rte_event_timer_adapter.h b/dpdk/lib/librte_eventdev/rte_event_timer_adapter.h +index 7f6dc5c292..9f5021454a 100644 +--- a/dpdk/lib/librte_eventdev/rte_event_timer_adapter.h ++++ b/dpdk/lib/librte_eventdev/rte_event_timer_adapter.h +@@ -658,4 +658,8 @@ rte_event_timer_cancel_burst(const struct rte_event_timer_adapter *adapter, + return adapter->cancel_burst(adapter, evtims, nb_evtims); + } + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* __RTE_EVENT_TIMER_ADAPTER_H__ */ diff --git a/dpdk/lib/librte_eventdev/rte_eventdev.c b/dpdk/lib/librte_eventdev/rte_eventdev.c index b987e07454..9aca7fbd52 100644 --- a/dpdk/lib/librte_eventdev/rte_eventdev.c @@ -75335,10 +105960,30 @@ index b987e07454..9aca7fbd52 100644 } diff --git a/dpdk/lib/librte_eventdev/rte_eventdev_pmd.h b/dpdk/lib/librte_eventdev/rte_eventdev_pmd.h -index d118b9e5ba..c5d41ddad8 100644 +index d118b9e5ba..2ecdd56308 100644 --- a/dpdk/lib/librte_eventdev/rte_eventdev_pmd.h +++ b/dpdk/lib/librte_eventdev/rte_eventdev_pmd.h -@@ -155,9 +155,6 @@ rte_event_pmd_is_valid_dev(uint8_t dev_id) +@@ -5,6 +5,10 @@ + #ifndef _RTE_EVENTDEV_PMD_H_ + #define _RTE_EVENTDEV_PMD_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** @file + * RTE Event PMD APIs + * +@@ -144,7 +148,7 @@ rte_event_pmd_is_valid_dev(uint8_t dev_id) + + /** + * Definitions of all functions exported by a driver through the +- * the generic structure of type *event_dev_ops* supplied in the ++ * generic structure of type *event_dev_ops* supplied in the + * *rte_eventdev* structure associated with a device. + */ + +@@ -155,9 +159,6 @@ rte_event_pmd_is_valid_dev(uint8_t dev_id) * Event device pointer * @param dev_info * Event device information structure @@ -75348,11 +105993,31 @@ index d118b9e5ba..c5d41ddad8 100644 */ typedef void (*eventdev_info_get_t)(struct rte_eventdev *dev, struct rte_event_dev_info *dev_info); +@@ -1115,4 +1116,8 @@ rte_event_pmd_release(struct rte_eventdev *eventdev); + } + #endif + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_EVENTDEV_PMD_H_ */ diff --git a/dpdk/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/dpdk/lib/librte_eventdev/rte_eventdev_pmd_pci.h -index 8fb61386fd..443cd38c23 100644 +index 8fb61386fd..92eeed6411 100644 --- a/dpdk/lib/librte_eventdev/rte_eventdev_pmd_pci.h +++ b/dpdk/lib/librte_eventdev/rte_eventdev_pmd_pci.h -@@ -112,9 +112,11 @@ rte_event_pmd_pci_remove(struct rte_pci_device *pci_dev, +@@ -5,6 +5,10 @@ + #ifndef _RTE_EVENTDEV_PMD_PCI_H_ + #define _RTE_EVENTDEV_PMD_PCI_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** @file + * RTE Eventdev PCI PMD APIs + * +@@ -112,9 +116,11 @@ rte_event_pmd_pci_remove(struct rte_pci_device *pci_dev, if (eventdev == NULL) return -ENODEV; @@ -75367,6 +106032,21 @@ index 8fb61386fd..443cd38c23 100644 /* Invoke PMD device un-init function */ if (devuninit) +diff --git a/dpdk/lib/librte_eventdev/rte_eventdev_pmd_vdev.h b/dpdk/lib/librte_eventdev/rte_eventdev_pmd_vdev.h +index 8c64a06743..ff79d82530 100644 +--- a/dpdk/lib/librte_eventdev/rte_eventdev_pmd_vdev.h ++++ b/dpdk/lib/librte_eventdev/rte_eventdev_pmd_vdev.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_EVENTDEV_PMD_VDEV_H_ + #define _RTE_EVENTDEV_PMD_VDEV_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** @file + * RTE Eventdev VDEV PMD APIs + * diff --git a/dpdk/lib/librte_fib/rte_fib.h b/dpdk/lib/librte_fib/rte_fib.h index d06c5ef55a..04c490ed6e 100644 --- a/dpdk/lib/librte_fib/rte_fib.h @@ -75513,6 +106193,25 @@ index 124aa8b98b..2ae2add4f3 100644 next_hop << 1, dp->nh_sz, *ip_part); } tbl8_recycle(dp, &val, tbl8_idx); +diff --git a/dpdk/lib/librte_flow_classify/rte_flow_classify.c b/dpdk/lib/librte_flow_classify/rte_flow_classify.c +index 5ff585803b..c7c57e17b6 100644 +--- a/dpdk/lib/librte_flow_classify/rte_flow_classify.c ++++ b/dpdk/lib/librte_flow_classify/rte_flow_classify.c +@@ -584,12 +584,12 @@ rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls, + &rule->u.key.key_del, + &rule->key_found, + &rule->entry); +- ++ if (ret == 0) ++ free(rule); + return ret; + } + } + } +- free(rule); + return ret; + } + diff --git a/dpdk/lib/librte_flow_classify/rte_flow_classify.h b/dpdk/lib/librte_flow_classify/rte_flow_classify.h index 74d1ecaf50..82ea92b6a6 100644 --- a/dpdk/lib/librte_flow_classify/rte_flow_classify.h @@ -75652,10 +106351,48 @@ index 0d73370dc4..ab7be1d528 100644 */ #define RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF 0x20 +diff --git a/dpdk/lib/librte_hash/rte_thash.h b/dpdk/lib/librte_hash/rte_thash.h +index b4aaabe3d8..3b1128b0b7 100644 +--- a/dpdk/lib/librte_hash/rte_thash.h ++++ b/dpdk/lib/librte_hash/rte_thash.h +@@ -8,20 +8,16 @@ + /** + * @file + * +- * toeplitz hash functions. +- */ +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-/** + * Software implementation of the Toeplitz hash function used by RSS. + * Can be used either for packet distribution on single queue NIC + * or for simulating of RSS computation on specific NIC (for example + * after GRE header decapsulating) + */ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + #include + #include diff --git a/dpdk/lib/librte_ip_frag/rte_ipv4_reassembly.c b/dpdk/lib/librte_ip_frag/rte_ipv4_reassembly.c -index 1dda8aca02..69666c8b82 100644 +index 1dda8aca02..4a89a5f536 100644 --- a/dpdk/lib/librte_ip_frag/rte_ipv4_reassembly.c +++ b/dpdk/lib/librte_ip_frag/rte_ipv4_reassembly.c +@@ -80,7 +80,7 @@ ipv4_frag_reassemble(struct ip_frag_pkt *fp) + + /* + * Process new mbuf with fragment of IPV4 packet. +- * Incoming mbuf should have it's l2_len/l3_len fields setuped correclty. ++ * Incoming mbuf should have it's l2_len/l3_len fields setup correctly. + * @param tbl + * Table where to lookup/add the fragmented packet. + * @param mb @@ -104,6 +104,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl, const unaligned_uint64_t *psd; uint16_t flag_offset, ip_ofs, ip_flag; @@ -75693,6 +106430,19 @@ index 1dda8aca02..69666c8b82 100644 /* try to find/add entry into the fragment's table. */ if ((fp = ip_frag_find(tbl, dr, &key, tms)) == NULL) { IP_FRAG_MBUF2DR(dr, mb); +diff --git a/dpdk/lib/librte_ip_frag/rte_ipv6_fragmentation.c b/dpdk/lib/librte_ip_frag/rte_ipv6_fragmentation.c +index 43449970e5..c7357092e4 100644 +--- a/dpdk/lib/librte_ip_frag/rte_ipv6_fragmentation.c ++++ b/dpdk/lib/librte_ip_frag/rte_ipv6_fragmentation.c +@@ -81,7 +81,7 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in, + + /* + * Ensure the IP payload length of all fragments (except the +- * the last fragment) are a multiple of 8 bytes per RFC2460. ++ * last fragment) are a multiple of 8 bytes per RFC2460. + */ + + frag_size = mtu_size - sizeof(struct rte_ipv6_hdr) - diff --git a/dpdk/lib/librte_ip_frag/rte_ipv6_reassembly.c b/dpdk/lib/librte_ip_frag/rte_ipv6_reassembly.c index ad01055184..6bc0bf792a 100644 --- a/dpdk/lib/librte_ip_frag/rte_ipv6_reassembly.c @@ -75735,10 +106485,54 @@ index ad01055184..6bc0bf792a 100644 /* try to find/add entry into the fragment's table. */ fp = ip_frag_find(tbl, dr, &key, tms); if (fp == NULL) { +diff --git a/dpdk/lib/librte_ipsec/esp_inb.c b/dpdk/lib/librte_ipsec/esp_inb.c +index 5c653dd394..03d921f7cb 100644 +--- a/dpdk/lib/librte_ipsec/esp_inb.c ++++ b/dpdk/lib/librte_ipsec/esp_inb.c +@@ -359,7 +359,7 @@ trs_process_check(struct rte_mbuf *mb, struct rte_mbuf **ml, + + /* + * packet checks for tunnel mode: +- * - same as for trasnport mode ++ * - same as for transport mode + * - esp tail next proto contains expected for that SA value + */ + static inline int32_t +@@ -445,7 +445,7 @@ trs_process_step3(struct rte_mbuf *mb) + static inline void + tun_process_step3(struct rte_mbuf *mb, uint64_t txof_msk, uint64_t txof_val) + { +- /* reset mbuf metatdata: L2/L3 len, packet type */ ++ /* reset mbuf metadata: L2/L3 len, packet type */ + mb->packet_type = RTE_PTYPE_UNKNOWN; + mb->tx_offload = (mb->tx_offload & txof_msk) | txof_val; + +diff --git a/dpdk/lib/librte_ipsec/esp_outb.c b/dpdk/lib/librte_ipsec/esp_outb.c +index e983b25a3f..31b920f651 100644 +--- a/dpdk/lib/librte_ipsec/esp_outb.c ++++ b/dpdk/lib/librte_ipsec/esp_outb.c +@@ -405,7 +405,7 @@ esp_outb_trs_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[], + + /* + * process outbound packets for SA with ESN support, +- * for algorithms that require SQN.hibits to be implictly included ++ * for algorithms that require SQN.hibits to be implicitly included + * into digest computation. + * In that case we have to move ICV bytes back to their proper place. + */ diff --git a/dpdk/lib/librte_ipsec/ipsec_sad.c b/dpdk/lib/librte_ipsec/ipsec_sad.c -index db2c44c804..31b5956d89 100644 +index db2c44c804..e4e304f359 100644 --- a/dpdk/lib/librte_ipsec/ipsec_sad.c +++ b/dpdk/lib/librte_ipsec/ipsec_sad.c +@@ -59,7 +59,7 @@ EAL_REGISTER_TAILQ(rte_ipsec_sad_tailq) + * Inserts a rule into an appropriate hash table, + * updates the value for a given SPI in SPI_ONLY hash table + * reflecting presence of more specific rule type in two LSBs. +- * Updates a counter that reflects the number of rules whith the same SPI. ++ * Updates a counter that reflects the number of rules with the same SPI. + */ + static inline int + add_specific(struct rte_ipsec_sad *sad, const void *key, @@ -94,6 +94,8 @@ add_specific(struct rte_ipsec_sad *sad, const void *key, /* Update a counter for a given SPI */ @@ -75767,6 +106561,23 @@ index f3b1f936b9..f2da7ace9c 100644 * librte_ipsec provides a framework for data-path IPsec protocol * processing (ESP/AH). */ +diff --git a/dpdk/lib/librte_ipsec/rte_ipsec_group.h b/dpdk/lib/librte_ipsec/rte_ipsec_group.h +index 47b33ca5ec..27a2f6f26d 100644 +--- a/dpdk/lib/librte_ipsec/rte_ipsec_group.h ++++ b/dpdk/lib/librte_ipsec/rte_ipsec_group.h +@@ -51,10 +51,10 @@ rte_ipsec_ses_from_crypto(const struct rte_crypto_op *cop) + + if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) { + ss = cop->sym[0].sec_session; +- return (void *)(uintptr_t)ss->opaque_data; ++ return (struct rte_ipsec_session *)(uintptr_t)ss->opaque_data; + } else if (cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { + cs = cop->sym[0].session; +- return (void *)(uintptr_t)cs->opaque_data; ++ return (struct rte_ipsec_session *)(uintptr_t)cs->opaque_data; + } + return NULL; + } diff --git a/dpdk/lib/librte_ipsec/rte_ipsec_sad.h b/dpdk/lib/librte_ipsec/rte_ipsec_sad.h index 8386f73df7..cf50a11cb4 100644 --- a/dpdk/lib/librte_ipsec/rte_ipsec_sad.h @@ -75780,21 +106591,36 @@ index 8386f73df7..cf50a11cb4 100644 #include /** +diff --git a/dpdk/lib/librte_ipsec/sa.c b/dpdk/lib/librte_ipsec/sa.c +index 6f1d92c3c2..5e8a417cfd 100644 +--- a/dpdk/lib/librte_ipsec/sa.c ++++ b/dpdk/lib/librte_ipsec/sa.c +@@ -126,7 +126,7 @@ ipsec_sa_size(uint64_t type, uint32_t *wnd_sz, uint32_t *nb_bucket) + /* + * RFC 4303 recommends 64 as minimum window size. + * there is no point to use ESN mode without SQN window, +- * so make sure we have at least 64 window when ESN is enalbed. ++ * so make sure we have at least 64 window when ESN is enabled. + */ + wsz = ((type & RTE_IPSEC_SATP_ESN_MASK) == + RTE_IPSEC_SATP_ESN_DISABLE) ? diff --git a/dpdk/lib/librte_ipsec/sa.h b/dpdk/lib/librte_ipsec/sa.h -index 51e69ad05a..0cfe82f634 100644 +index 51e69ad05a..6e1b9ebe85 100644 --- a/dpdk/lib/librte_ipsec/sa.h +++ b/dpdk/lib/librte_ipsec/sa.h -@@ -113,7 +113,7 @@ struct rte_ipsec_sa { +@@ -113,8 +113,8 @@ struct rte_ipsec_sa { * sqn and replay window * In case of SA handled by multiple threads *sqn* cacheline * could be shared by multiple cores. - * To minimise perfomance impact, we try to locate in a separate +- * place from other frequently accesed data. + * To minimise performance impact, we try to locate in a separate - * place from other frequently accesed data. ++ * place from other frequently accessed data. */ union { + union { diff --git a/dpdk/lib/librte_kni/rte_kni.c b/dpdk/lib/librte_kni/rte_kni.c -index e388751e33..bcf82cc2d5 100644 +index e388751e33..691bdd276b 100644 --- a/dpdk/lib/librte_kni/rte_kni.c +++ b/dpdk/lib/librte_kni/rte_kni.c @@ -145,31 +145,38 @@ kni_reserve_mz(struct rte_kni *kni) @@ -75843,6 +106669,47 @@ index e388751e33..bcf82cc2d5 100644 KNI_MEM_CHECK(kni->m_sync_addr == NULL, sync_addr_fail); return 0; +@@ -507,6 +514,8 @@ kni_config_promiscusity(uint16_t port_id, uint8_t to_on) + static int + kni_config_allmulticast(uint16_t port_id, uint8_t to_on) + { ++ int ret; ++ + if (!rte_eth_dev_is_valid_port(port_id)) { + RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id); + return -EINVAL; +@@ -516,11 +525,16 @@ kni_config_allmulticast(uint16_t port_id, uint8_t to_on) + port_id, to_on); + + if (to_on) +- rte_eth_allmulticast_enable(port_id); ++ ret = rte_eth_allmulticast_enable(port_id); + else +- rte_eth_allmulticast_disable(port_id); ++ ret = rte_eth_allmulticast_disable(port_id); ++ if (ret != 0) ++ RTE_LOG(ERR, KNI, ++ "Failed to %s allmulticast mode for port %u: %s\n", ++ to_on ? "enable" : "disable", port_id, ++ rte_strerror(-ret)); + +- return 0; ++ return ret; + } + + int +@@ -667,8 +681,9 @@ kni_allocate_mbufs(struct rte_kni *kni) + return; + } + +- allocq_free = (kni->alloc_q->read - kni->alloc_q->write - 1) +- & (MAX_MBUF_BURST_NUM - 1); ++ allocq_free = kni_fifo_free_count(kni->alloc_q); ++ allocq_free = (allocq_free > MAX_MBUF_BURST_NUM) ? ++ MAX_MBUF_BURST_NUM : allocq_free; + for (i = 0; i < allocq_free; i++) { + pkts[i] = rte_pktmbuf_alloc(kni->pktmbuf_pool); + if (unlikely(pkts[i] == NULL)) { diff --git a/dpdk/lib/librte_kni/rte_kni.h b/dpdk/lib/librte_kni/rte_kni.h index f1bb782c68..855facd1a3 100644 --- a/dpdk/lib/librte_kni/rte_kni.h @@ -75940,7 +106807,7 @@ index b78c487447..2687564194 100644 #include "rte_lpm.h" diff --git a/dpdk/lib/librte_lpm/rte_lpm6.c b/dpdk/lib/librte_lpm/rte_lpm6.c -index c46e557e23..6e1b18d6fd 100644 +index c46e557e23..b7a087554e 100644 --- a/dpdk/lib/librte_lpm/rte_lpm6.c +++ b/dpdk/lib/librte_lpm/rte_lpm6.c @@ -25,7 +25,6 @@ @@ -75951,7 +106818,25 @@ index c46e557e23..6e1b18d6fd 100644 #include "rte_lpm6.h" -@@ -727,7 +726,8 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, +@@ -81,7 +80,7 @@ struct rte_lpm6_rule { + /** Rules tbl entry key. */ + struct rte_lpm6_rule_key { + uint8_t ip[RTE_LPM6_IPV6_ADDR_SIZE]; /**< Rule IP address. */ +- uint8_t depth; /**< Rule depth. */ ++ uint32_t depth; /**< Rule depth. */ + }; + + /* Header of tbl8 */ +@@ -260,6 +259,8 @@ rte_lpm6_create(const char *name, int socket_id, + lpm_list = RTE_TAILQ_CAST(rte_lpm6_tailq.head, rte_lpm6_list); + + RTE_BUILD_BUG_ON(sizeof(struct rte_lpm6_tbl_entry) != sizeof(uint32_t)); ++ RTE_BUILD_BUG_ON(sizeof(struct rte_lpm6_rule_key) % ++ sizeof(uint32_t) != 0); + + /* Check user arguments. */ + if ((name == NULL) || (socket_id < -1) || (config == NULL) || +@@ -727,7 +728,8 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, tbl8_group_start = tbl8_gindex * RTE_LPM6_TBL8_GROUP_NUM_ENTRIES; memset(&lpm->tbl8[tbl8_group_start], 0, @@ -75961,7 +106846,7 @@ index c46e557e23..6e1b18d6fd 100644 /* init the new table's header: * save the reference to the owner table -@@ -814,7 +814,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, +@@ -814,7 +816,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, * * Returns: * 0 on success @@ -75970,7 +106855,7 @@ index c46e557e23..6e1b18d6fd 100644 */ static int simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth) -@@ -844,7 +844,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth) +@@ -844,7 +846,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth) } if (tbl8_available(lpm) < total_need_tbl_nb) @@ -75979,7 +106864,7 @@ index c46e557e23..6e1b18d6fd 100644 return -ENOSPC; return 0; -@@ -1212,7 +1212,7 @@ rule_find_range(struct rte_lpm6 *lpm, const uint8_t *ip, uint8_t depth, +@@ -1212,7 +1214,7 @@ rule_find_range(struct rte_lpm6 *lpm, const uint8_t *ip, uint8_t depth, /* minus top level */ depth -= 24; @@ -76100,9 +106985,18 @@ index 44770b6ff8..eaa863c522 100644 tbl[3] = *ptbl; } diff --git a/dpdk/lib/librte_mbuf/rte_mbuf.h b/dpdk/lib/librte_mbuf/rte_mbuf.h -index 219b110b76..6d080527f6 100644 +index 219b110b76..55205b8ece 100644 --- a/dpdk/lib/librte_mbuf/rte_mbuf.h +++ b/dpdk/lib/librte_mbuf/rte_mbuf.h +@@ -1288,7 +1288,7 @@ rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp); + * set of mbufs. The private data are is not copied. + * + * @param m +- * The packet mbuf to be copiedd. ++ * The packet mbuf to be copied. + * @param mp + * The mempool from which the "clone" mbufs are allocated. + * @param offset @@ -1535,7 +1535,7 @@ static inline int rte_pktmbuf_trim(struct rte_mbuf *m, uint16_t len) static inline int rte_pktmbuf_is_contiguous(const struct rte_mbuf *m) { @@ -76113,7 +107007,7 @@ index 219b110b76..6d080527f6 100644 /** diff --git a/dpdk/lib/librte_mbuf/rte_mbuf_core.h b/dpdk/lib/librte_mbuf/rte_mbuf_core.h -index 9a8557d1cc..e7f38422e7 100644 +index 9a8557d1cc..b97b811366 100644 --- a/dpdk/lib/librte_mbuf/rte_mbuf_core.h +++ b/dpdk/lib/librte_mbuf/rte_mbuf_core.h @@ -15,7 +15,9 @@ @@ -76126,8 +107020,17 @@ index 9a8557d1cc..e7f38422e7 100644 #include #ifdef __cplusplus +@@ -737,7 +739,7 @@ struct rte_mbuf_ext_shared_info { + * The type to cast the result into. + */ + #define rte_pktmbuf_mtod_offset(m, t, o) \ +- ((t)((char *)(m)->buf_addr + (m)->data_off + (o))) ++ ((t)(void *)((char *)(m)->buf_addr + (m)->data_off + (o))) + + /** + * A macro that points to the start of the data in the mbuf. diff --git a/dpdk/lib/librte_mbuf/rte_mbuf_dyn.c b/dpdk/lib/librte_mbuf/rte_mbuf_dyn.c -index d6931f8471..5762008b7e 100644 +index d6931f8471..27e117c2be 100644 --- a/dpdk/lib/librte_mbuf/rte_mbuf_dyn.c +++ b/dpdk/lib/librte_mbuf/rte_mbuf_dyn.c @@ -19,7 +19,6 @@ @@ -76178,7 +107081,19 @@ index d6931f8471..5762008b7e 100644 } } -@@ -168,7 +172,7 @@ __mbuf_dynfield_lookup(const char *name) +@@ -110,8 +114,10 @@ init_shared_mem(void) + } else { + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME); + } +- if (mz == NULL) ++ if (mz == NULL) { ++ RTE_LOG(ERR, MBUF, "Failed to get mbuf dyn shared memory\n"); + return -1; ++ } + + shm = mz->addr; + +@@ -168,7 +174,7 @@ __mbuf_dynfield_lookup(const char *name) break; } @@ -76187,7 +107102,7 @@ index d6931f8471..5762008b7e 100644 rte_errno = ENOENT; return NULL; } -@@ -181,19 +185,15 @@ rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params) +@@ -181,19 +187,15 @@ rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params) { struct mbuf_dynfield_elt *mbuf_dynfield; @@ -76212,7 +107127,7 @@ index d6931f8471..5762008b7e 100644 if (params != NULL) memcpy(params, &mbuf_dynfield->params, sizeof(*params)); -@@ -279,12 +279,15 @@ __rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params, +@@ -279,12 +281,15 @@ __rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params, mbuf_dynfield_tailq.head, mbuf_dynfield_list); te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0); @@ -76229,7 +107144,7 @@ index d6931f8471..5762008b7e 100644 return -1; } -@@ -377,19 +380,15 @@ rte_mbuf_dynflag_lookup(const char *name, +@@ -377,19 +382,15 @@ rte_mbuf_dynflag_lookup(const char *name, { struct mbuf_dynflag_elt *mbuf_dynflag; @@ -76254,7 +107169,7 @@ index d6931f8471..5762008b7e 100644 if (params != NULL) memcpy(params, &mbuf_dynflag->params, sizeof(*params)); -@@ -457,12 +456,15 @@ __rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params, +@@ -457,12 +458,15 @@ __rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params, mbuf_dynflag_tailq.head, mbuf_dynflag_list); te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0); @@ -76271,7 +107186,31 @@ index d6931f8471..5762008b7e 100644 return -1; } -@@ -542,7 +544,7 @@ void rte_mbuf_dyn_dump(FILE *out) +@@ -493,6 +497,10 @@ rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params, + { + int ret; + ++ if (params->flags != 0) { ++ rte_errno = EINVAL; ++ return -1; ++ } + if (req >= RTE_SIZEOF_FIELD(struct rte_mbuf, ol_flags) * CHAR_BIT && + req != UINT_MAX) { + rte_errno = EINVAL; +@@ -522,7 +530,11 @@ void rte_mbuf_dyn_dump(FILE *out) + size_t i; + + rte_mcfg_tailq_write_lock(); +- init_shared_mem(); ++ if (shm == NULL && init_shared_mem() < 0) { ++ rte_mcfg_tailq_write_unlock(); ++ return; ++ } ++ + fprintf(out, "Reserved fields:\n"); + mbuf_dynfield_list = RTE_TAILQ_CAST( + mbuf_dynfield_tailq.head, mbuf_dynfield_list); +@@ -542,7 +554,7 @@ void rte_mbuf_dyn_dump(FILE *out) dynflag->params.name, dynflag->bitnum, dynflag->params.flags); } @@ -76558,25 +107497,64 @@ index 46410b0369..3fc7ddd199 100644 rte_meter_trtcm_rfc4115_config; rte_meter_trtcm_rfc4115_profile_config; }; +diff --git a/dpdk/lib/librte_net/rte_ether.h b/dpdk/lib/librte_net/rte_ether.h +index e069dc7fe0..8a31988f21 100644 +--- a/dpdk/lib/librte_net/rte_ether.h ++++ b/dpdk/lib/librte_net/rte_ether.h +@@ -358,7 +358,7 @@ static inline int rte_vlan_insert(struct rte_mbuf **m) + return -EINVAL; + + oh = rte_pktmbuf_mtod(*m, struct rte_ether_hdr *); +- nh = (struct rte_ether_hdr *) ++ nh = (struct rte_ether_hdr *)(void *) + rte_pktmbuf_prepend(*m, sizeof(struct rte_vlan_hdr)); + if (nh == NULL) + return -ENOSPC; diff --git a/dpdk/lib/librte_net/rte_ip.h b/dpdk/lib/librte_net/rte_ip.h -index 1ceb7b7931..d34c0611f0 100644 +index 1ceb7b7931..279e88ee39 100644 --- a/dpdk/lib/librte_net/rte_ip.h +++ b/dpdk/lib/librte_net/rte_ip.h -@@ -139,8 +139,11 @@ __rte_raw_cksum(const void *buf, size_t len, uint32_t sum) - } +@@ -119,28 +119,20 @@ struct rte_ipv4_hdr { + static inline uint32_t + __rte_raw_cksum(const void *buf, size_t len, uint32_t sum) + { +- /* workaround gcc strict-aliasing warning */ +- uintptr_t ptr = (uintptr_t)buf; ++ /* extend strict-aliasing rules */ + typedef uint16_t __attribute__((__may_alias__)) u16_p; +- const u16_p *u16_buf = (const u16_p *)ptr; +- +- while (len >= (sizeof(*u16_buf) * 4)) { +- sum += u16_buf[0]; +- sum += u16_buf[1]; +- sum += u16_buf[2]; +- sum += u16_buf[3]; +- len -= sizeof(*u16_buf) * 4; +- u16_buf += 4; +- } +- while (len >= sizeof(*u16_buf)) { ++ const u16_p *u16_buf = (const u16_p *)buf; ++ const u16_p *end = u16_buf + len / sizeof(*u16_buf); ++ ++ for (; u16_buf != end; ++u16_buf) + sum += *u16_buf; +- len -= sizeof(*u16_buf); +- u16_buf += 1; +- } - /* if length is in odd bytes */ +- /* if length is in odd bytes */ - if (len == 1) - sum += *((const uint8_t *)u16_buf); -+ if (len == 1) { ++ /* if length is odd, keeping it byte order independent */ ++ if (unlikely(len % 2)) { + uint16_t left = 0; -+ *(uint8_t *)&left = *(const uint8_t *)u16_buf; ++ *(unsigned char *)&left = *(const unsigned char *)end; + sum += left; + } return sum; } -@@ -222,6 +225,9 @@ rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, +@@ -222,6 +214,9 @@ rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, break; off -= seglen; } @@ -76586,7 +107564,7 @@ index 1ceb7b7931..d34c0611f0 100644 seglen -= off; buf = rte_pktmbuf_mtod_offset(seg, const char *, off); if (seglen >= len) { -@@ -267,7 +273,7 @@ rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr) +@@ -267,7 +262,7 @@ rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr) { uint16_t cksum; cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct rte_ipv4_hdr)); @@ -76595,17 +107573,26 @@ index 1ceb7b7931..d34c0611f0 100644 } /** -@@ -324,8 +330,7 @@ rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags) +@@ -316,16 +311,14 @@ rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags) + /** + * Process the IPv4 UDP or TCP checksum. + * +- * The IPv4 header should not contains options. The IP and layer 4 +- * checksum must be set to 0 in the packet by the caller. ++ * The layer 4 checksum must be set to 0 in the L4 header by the caller. + * + * @param ipv4_hdr + * The pointer to the contiguous IPv4 header. * @param l4_hdr * The pointer to the beginning of the L4 header. * @return - * The complemented checksum to set in the IP packet - * or 0 on error -+ * The complemented checksum to set in the IP packet. ++ * The complemented checksum to set in the L4 header. */ static inline uint16_t rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr) -@@ -344,7 +349,12 @@ rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr) +@@ -344,7 +337,12 @@ rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr) cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); cksum = (~cksum) & 0xffff; @@ -76619,7 +107606,35 @@ index 1ceb7b7931..d34c0611f0 100644 cksum = 0xffff; return (uint16_t)cksum; -@@ -436,7 +446,12 @@ rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr) +@@ -355,7 +353,7 @@ rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr) + */ + struct rte_ipv6_hdr { + rte_be32_t vtc_flow; /**< IP version, traffic class & flow label. */ +- rte_be16_t payload_len; /**< IP packet length - includes header size */ ++ rte_be16_t payload_len; /**< IP payload size, including ext. headers */ + uint8_t proto; /**< Protocol, next header. */ + uint8_t hop_limits; /**< Hop limits. */ + uint8_t src_addr[16]; /**< IP address of source host. */ +@@ -413,15 +411,15 @@ rte_ipv6_phdr_cksum(const struct rte_ipv6_hdr *ipv6_hdr, uint64_t ol_flags) + /** + * Process the IPv6 UDP or TCP checksum. + * +- * The IPv4 header should not contains options. The layer 4 checksum +- * must be set to 0 in the packet by the caller. ++ * The IPv6 header must not be followed by extension headers. The layer 4 ++ * checksum must be set to 0 in the L4 header by the caller. + * + * @param ipv6_hdr + * The pointer to the contiguous IPv6 header. + * @param l4_hdr + * The pointer to the beginning of the L4 header. + * @return +- * The complemented checksum to set in the IP packet. ++ * The complemented checksum to set in the L4 header. + */ + static inline uint16_t + rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr) +@@ -436,7 +434,12 @@ rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr) cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff); cksum = (~cksum) & 0xffff; @@ -76871,7 +107886,7 @@ index adc8e5ca27..0000000000 - -#endif /* CHANNEL_COMMANDS_H_ */ diff --git a/dpdk/lib/librte_power/guest_channel.c b/dpdk/lib/librte_power/guest_channel.c -index b984d55bc8..4dadf5ef9f 100644 +index b984d55bc8..6cf93f4bec 100644 --- a/dpdk/lib/librte_power/guest_channel.c +++ b/dpdk/lib/librte_power/guest_channel.c @@ -14,9 +14,9 @@ @@ -76922,6 +107937,42 @@ index b984d55bc8..4dadf5ef9f 100644 unsigned int lcore_id) { return guest_channel_send_msg(pkt, lcore_id); +@@ -139,6 +140,17 @@ int power_guest_channel_read_msg(void *pkt, + if (pkt_len == 0 || pkt == NULL) + return -1; + ++ if (lcore_id >= RTE_MAX_LCORE) { ++ RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n", ++ lcore_id, RTE_MAX_LCORE-1); ++ return -1; ++ } ++ ++ if (global_fds[lcore_id] < 0) { ++ RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n"); ++ return -1; ++ } ++ + fds.fd = global_fds[lcore_id]; + fds.events = POLLIN; + +@@ -152,17 +164,6 @@ int power_guest_channel_read_msg(void *pkt, + return -1; + } + +- if (lcore_id >= RTE_MAX_LCORE) { +- RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n", +- lcore_id, RTE_MAX_LCORE-1); +- return -1; +- } +- +- if (global_fds[lcore_id] < 0) { +- RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n"); +- return -1; +- } +- + while (pkt_len > 0) { + ret = read(global_fds[lcore_id], + pkt, pkt_len); diff --git a/dpdk/lib/librte_power/guest_channel.h b/dpdk/lib/librte_power/guest_channel.h index 025961606c..b790f3661a 100644 --- a/dpdk/lib/librte_power/guest_channel.h @@ -77014,6 +108065,190 @@ index cdf08f6df3..6281adfe17 100644 +headers = files('rte_power.h','rte_power_empty_poll.h', + 'rte_power_guest_channel.h') deps += ['timer'] +diff --git a/dpdk/lib/librte_power/power_acpi_cpufreq.c b/dpdk/lib/librte_power/power_acpi_cpufreq.c +index f443fce69f..8a5b536678 100644 +--- a/dpdk/lib/librte_power/power_acpi_cpufreq.c ++++ b/dpdk/lib/librte_power/power_acpi_cpufreq.c +@@ -78,7 +78,7 @@ enum power_state { + /** + * Power info per lcore. + */ +-struct rte_power_info { ++struct acpi_power_info { + unsigned int lcore_id; /**< Logical core id */ + uint32_t freqs[RTE_MAX_LCORE_FREQS]; /**< Frequency array */ + uint32_t nb_freqs; /**< number of available freqs */ +@@ -90,14 +90,14 @@ struct rte_power_info { + uint16_t turbo_enable; /**< Turbo Boost enable/disable */ + } __rte_cache_aligned; + +-static struct rte_power_info lcore_power_info[RTE_MAX_LCORE]; ++static struct acpi_power_info lcore_power_info[RTE_MAX_LCORE]; + + /** + * It is to set specific freq for specific logical core, according to the index + * of supported frequencies. + */ + static int +-set_freq_internal(struct rte_power_info *pi, uint32_t idx) ++set_freq_internal(struct acpi_power_info *pi, uint32_t idx) + { + if (idx >= RTE_MAX_LCORE_FREQS || idx >= pi->nb_freqs) { + RTE_LOG(ERR, POWER, "Invalid frequency index %u, which " +@@ -133,7 +133,7 @@ set_freq_internal(struct rte_power_info *pi, uint32_t idx) + * governor will be saved for rolling back. + */ + static int +-power_set_governor_userspace(struct rte_power_info *pi) ++power_set_governor_userspace(struct acpi_power_info *pi) + { + FILE *f; + int ret = -1; +@@ -152,6 +152,9 @@ power_set_governor_userspace(struct rte_power_info *pi) + /* Strip off terminating '\n' */ + strtok(buf, "\n"); + ++ /* Save the original governor */ ++ rte_strscpy(pi->governor_ori, buf, sizeof(pi->governor_ori)); ++ + /* Check if current governor is userspace */ + if (strncmp(buf, POWER_GOVERNOR_USERSPACE, + sizeof(POWER_GOVERNOR_USERSPACE)) == 0) { +@@ -160,8 +163,6 @@ power_set_governor_userspace(struct rte_power_info *pi) + "already userspace\n", pi->lcore_id); + goto out; + } +- /* Save the original governor */ +- strlcpy(pi->governor_ori, buf, sizeof(pi->governor_ori)); + + /* Write 'userspace' to the governor */ + val = fseek(f, 0, SEEK_SET); +@@ -188,7 +189,7 @@ power_set_governor_userspace(struct rte_power_info *pi) + * sys file. + */ + static int +-power_get_available_freqs(struct rte_power_info *pi) ++power_get_available_freqs(struct acpi_power_info *pi) + { + FILE *f; + int ret = -1, i, count; +@@ -225,7 +226,7 @@ power_get_available_freqs(struct rte_power_info *pi) + goto out; + } + +- /* Store the available frequncies into power context */ ++ /* Store the available frequencies into power context */ + for (i = 0, pi->nb_freqs = 0; i < count; i++) { + POWER_DEBUG_TRACE("Lcore %u frequency[%d]: %s\n", pi->lcore_id, + i, freqs[i]); +@@ -258,7 +259,7 @@ power_get_available_freqs(struct rte_power_info *pi) + * It is to fopen the sys file for the future setting the lcore frequency. + */ + static int +-power_init_for_setting_freq(struct rte_power_info *pi) ++power_init_for_setting_freq(struct acpi_power_info *pi) + { + FILE *f; + char fullpath[PATH_MAX]; +@@ -292,7 +293,7 @@ power_init_for_setting_freq(struct rte_power_info *pi) + int + power_acpi_cpufreq_init(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n", +@@ -354,7 +355,7 @@ power_acpi_cpufreq_init(unsigned int lcore_id) + * needed by writing the sys file. + */ + static int +-power_set_governor_original(struct rte_power_info *pi) ++power_set_governor_original(struct acpi_power_info *pi) + { + FILE *f; + int ret = -1; +@@ -400,7 +401,7 @@ power_set_governor_original(struct rte_power_info *pi) + int + power_acpi_cpufreq_exit(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n", +@@ -442,7 +443,7 @@ power_acpi_cpufreq_exit(unsigned int lcore_id) + uint32_t + power_acpi_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -489,7 +490,7 @@ power_acpi_cpufreq_set_freq(unsigned int lcore_id, uint32_t index) + int + power_acpi_cpufreq_freq_down(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -507,7 +508,7 @@ power_acpi_cpufreq_freq_down(unsigned int lcore_id) + int + power_acpi_cpufreq_freq_up(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -548,7 +549,7 @@ power_acpi_cpufreq_freq_max(unsigned int lcore_id) + int + power_acpi_cpufreq_freq_min(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -565,7 +566,7 @@ power_acpi_cpufreq_freq_min(unsigned int lcore_id) + int + power_acpi_turbo_status(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -581,7 +582,7 @@ power_acpi_turbo_status(unsigned int lcore_id) + int + power_acpi_enable_turbo(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -614,7 +615,7 @@ power_acpi_enable_turbo(unsigned int lcore_id) + int + power_acpi_disable_turbo(unsigned int lcore_id) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); +@@ -641,7 +642,7 @@ power_acpi_disable_turbo(unsigned int lcore_id) + int power_acpi_get_capabilities(unsigned int lcore_id, + struct rte_power_core_capabilities *caps) + { +- struct rte_power_info *pi; ++ struct acpi_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); diff --git a/dpdk/lib/librte_power/power_kvm_vm.c b/dpdk/lib/librte_power/power_kvm_vm.c index 277ebbeaeb..b34773d9c6 100644 --- a/dpdk/lib/librte_power/power_kvm_vm.c @@ -77091,7 +108326,7 @@ index 277ebbeaeb..b34773d9c6 100644 struct rte_power_core_capabilities; diff --git a/dpdk/lib/librte_power/power_pstate_cpufreq.c b/dpdk/lib/librte_power/power_pstate_cpufreq.c -index 2d8a9499dc..fa16b44146 100644 +index 2d8a9499dc..103c5375e9 100644 --- a/dpdk/lib/librte_power/power_pstate_cpufreq.c +++ b/dpdk/lib/librte_power/power_pstate_cpufreq.c @@ -52,6 +52,9 @@ @@ -77104,7 +108339,26 @@ index 2d8a9499dc..fa16b44146 100644 #define POWER_CONVERT_TO_DECIMAL 10 #define BUS_FREQ 100000 -@@ -531,6 +534,57 @@ power_get_available_freqs(struct pstate_power_info *pi) +@@ -347,6 +350,9 @@ power_set_governor_performance(struct pstate_power_info *pi) + /* Strip off terminating '\n' */ + strtok(buf, "\n"); + ++ /* Save the original governor */ ++ rte_strscpy(pi->governor_ori, buf, sizeof(pi->governor_ori)); ++ + /* Check if current governor is performance */ + if (strncmp(buf, POWER_GOVERNOR_PERF, + sizeof(POWER_GOVERNOR_PERF)) == 0) { +@@ -355,8 +361,6 @@ power_set_governor_performance(struct pstate_power_info *pi) + "already performance\n", pi->lcore_id); + goto out; + } +- /* Save the original governor */ +- strlcpy(pi->governor_ori, buf, sizeof(pi->governor_ori)); + + /* Write 'performance' to the governor */ + val = fseek(f, 0, SEEK_SET); +@@ -531,6 +535,57 @@ power_get_available_freqs(struct pstate_power_info *pi) return ret; } @@ -77162,7 +108416,7 @@ index 2d8a9499dc..fa16b44146 100644 int power_pstate_cpufreq_init(unsigned int lcore_id) { -@@ -571,6 +625,11 @@ power_pstate_cpufreq_init(unsigned int lcore_id) +@@ -571,6 +626,11 @@ power_pstate_cpufreq_init(unsigned int lcore_id) goto fail; } @@ -77186,12 +108440,33 @@ index 427058b811..04dc4cb1da 100644 #ifdef __cplusplus extern "C" { +diff --git a/dpdk/lib/librte_power/rte_power_empty_poll.c b/dpdk/lib/librte_power/rte_power_empty_poll.c +index 0a8024ddca..6aa5a5735f 100644 +--- a/dpdk/lib/librte_power/rte_power_empty_poll.c ++++ b/dpdk/lib/librte_power/rte_power_empty_poll.c +@@ -207,7 +207,7 @@ update_training_stats(struct priority_worker *poll_stats, + static inline uint32_t __attribute__((always_inline)) + update_stats(struct priority_worker *poll_stats) + { +- uint64_t tot_edpi = 0, tot_ppi = 0; ++ uint64_t tot_edpi = 0; + uint32_t j, percent; + + struct priority_worker *s = poll_stats; +@@ -237,7 +237,6 @@ update_stats(struct priority_worker *poll_stats) + + for (j = 0; j < BINS_AV; j++) { + tot_edpi += s->edpi_av[j]; +- tot_ppi += s->ppi_av[j]; + } + + tot_edpi = tot_edpi / BINS_AV; diff --git a/dpdk/lib/librte_power/rte_power_guest_channel.h b/dpdk/lib/librte_power/rte_power_guest_channel.h new file mode 100644 -index 0000000000..ed4fbfdcd3 +index 0000000000..b5de1bd243 --- /dev/null +++ b/dpdk/lib/librte_power/rte_power_guest_channel.h -@@ -0,0 +1,176 @@ +@@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2021 Intel Corporation + */ @@ -77313,11 +108588,6 @@ index 0000000000..ed4fbfdcd3 +}; + +/** -+ * @internal -+ * -+ * @warning -+ * @b EXPERIMENTAL: this API may change without prior notice. -+ * + * Send a message contained in pkt over the Virtio-Serial to the host endpoint. + * + * @param pkt @@ -77330,13 +108600,10 @@ index 0000000000..ed4fbfdcd3 + * - 0 on success. + * - Negative on error. + */ -+__rte_experimental +int rte_power_guest_channel_send_msg(struct rte_power_channel_packet *pkt, + unsigned int lcore_id); + +/** -+ * @internal -+ * + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * @@ -77369,17 +108636,15 @@ index 0000000000..ed4fbfdcd3 + +#endif /* RTE_POWER_GUEST_CHANNEL_H_ */ diff --git a/dpdk/lib/librte_power/rte_power_version.map b/dpdk/lib/librte_power/rte_power_version.map -index 55a168f56e..0fe85377ab 100644 +index 55a168f56e..e6ef3a7811 100644 --- a/dpdk/lib/librte_power/rte_power_version.map +++ b/dpdk/lib/librte_power/rte_power_version.map -@@ -33,4 +33,8 @@ EXPERIMENTAL { +@@ -33,4 +33,6 @@ EXPERIMENTAL { rte_power_guest_channel_receive_msg; rte_power_poll_stat_fetch; rte_power_poll_stat_update; + + # added in 21.02 -+ rte_power_guest_channel_receive_msg; -+ rte_power_guest_channel_send_msg; }; diff --git a/dpdk/lib/librte_rawdev/rte_rawdev.c b/dpdk/lib/librte_rawdev/rte_rawdev.c index b6f1e1c779..fe289cefdf 100644 @@ -77438,7 +108703,7 @@ index ed011ca228..32f6b8bb03 100644 * @return * - 0: Success, driver updates the contextual information of the raw device diff --git a/dpdk/lib/librte_rawdev/rte_rawdev_pmd.h b/dpdk/lib/librte_rawdev/rte_rawdev_pmd.h -index cb3555ab50..4395a2182d 100644 +index cb3555ab50..440acda70f 100644 --- a/dpdk/lib/librte_rawdev/rte_rawdev_pmd.h +++ b/dpdk/lib/librte_rawdev/rte_rawdev_pmd.h @@ -11,9 +11,6 @@ @@ -77451,6 +108716,15 @@ index cb3555ab50..4395a2182d 100644 */ #ifdef __cplusplus +@@ -129,7 +126,7 @@ rte_rawdev_pmd_is_valid_dev(uint8_t dev_id) + } + + /** +- * Definitions of all functions exported by a driver through the ++ * Definitions of all functions exported by a driver through + * the generic structure of type *rawdev_ops* supplied in the + * *rte_rawdev* structure associated with a device. + */ diff --git a/dpdk/lib/librte_rawdev/rte_rawdev_version.map b/dpdk/lib/librte_rawdev/rte_rawdev_version.map index d847c9e0d3..63b54f598b 100644 --- a/dpdk/lib/librte_rawdev/rte_rawdev_version.map @@ -77490,7 +108764,7 @@ index 2f3fad776e..58d58c5be5 100644 __atomic_load_n( &v->qsbr_cnt[id + t].cnt, diff --git a/dpdk/lib/librte_rcu/rte_rcu_qsbr.h b/dpdk/lib/librte_rcu/rte_rcu_qsbr.h -index 0b5585925f..430cdfb58a 100644 +index 0b5585925f..0d30c4620a 100644 --- a/dpdk/lib/librte_rcu/rte_rcu_qsbr.h +++ b/dpdk/lib/librte_rcu/rte_rcu_qsbr.h @@ -7,7 +7,12 @@ @@ -77507,6 +108781,15 @@ index 0b5585925f..430cdfb58a 100644 * * Quiescent State (QS) is any point in the thread execution * where the thread does not hold a reference to a data structure +@@ -304,7 +309,7 @@ rte_rcu_qsbr_thread_offline(struct rte_rcu_qsbr *v, unsigned int thread_id) + + /* The reader can go offline only after the load of the + * data structure is completed. i.e. any load of the +- * data strcture can not move after this store. ++ * data structure can not move after this store. + */ + + __atomic_store_n(&v->qsbr_cnt[thread_id].cnt, @@ -465,7 +470,7 @@ rte_rcu_qsbr_quiescent(struct rte_rcu_qsbr *v, unsigned int thread_id) __atomic_store_n(&v->qsbr_cnt[thread_id].cnt, t, __ATOMIC_RELEASE); @@ -77548,10 +108831,19 @@ index 0b5585925f..430cdfb58a 100644 /* Counter is not checked for wrap-around condition diff --git a/dpdk/lib/librte_rib/rte_rib.c b/dpdk/lib/librte_rib/rte_rib.c -index 55d612dc2e..07b3c068ed 100644 +index 55d612dc2e..b502317f93 100644 --- a/dpdk/lib/librte_rib/rte_rib.c +++ b/dpdk/lib/librte_rib/rte_rib.c -@@ -301,7 +301,7 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth) +@@ -73,6 +73,8 @@ is_covered(uint32_t ip1, uint32_t ip2, uint8_t depth) + static inline struct rte_rib_node * + get_nxt_node(struct rte_rib_node *node, uint32_t ip) + { ++ if (node->depth == RIB_MAXDEPTH) ++ return NULL; + return (ip & (1 << (31 - node->depth))) ? node->right : node->left; + } + +@@ -301,7 +303,7 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth) /* closest node found, new_node should be inserted in the middle */ common_depth = RTE_MIN(depth, (*tmp)->depth); common_prefix = ip ^ (*tmp)->ip; @@ -77599,6 +108891,61 @@ index 6b70de980a..93cd93b4ae 100644 +#endif + #endif /* _RTE_RIB_H_ */ +diff --git a/dpdk/lib/librte_rib/rte_rib6.c b/dpdk/lib/librte_rib/rte_rib6.c +index 78b8dcfd94..21e3e1c01a 100644 +--- a/dpdk/lib/librte_rib/rte_rib6.c ++++ b/dpdk/lib/librte_rib/rte_rib6.c +@@ -79,20 +79,33 @@ is_covered(const uint8_t ip1[RTE_RIB6_IPV6_ADDR_SIZE], + static inline int + get_dir(const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth) + { +- int i = 0; +- uint8_t p_depth, msk; +- +- for (p_depth = depth; p_depth >= 8; p_depth -= 8) +- i++; +- +- msk = 1 << (7 - p_depth); +- return (ip[i] & msk) != 0; ++ uint8_t index, msk; ++ ++ /* ++ * depth & 127 clamps depth to values that will not ++ * read off the end of ip. ++ * depth is the number of bits deep into ip to traverse, and ++ * is incremented in blocks of 8 (1 byte). This means the last ++ * 3 bits are irrelevant to what the index of ip should be. ++ */ ++ index = (depth & INT8_MAX) / CHAR_BIT; ++ ++ /* ++ * msk is the bitmask used to extract the bit used to decide the ++ * direction of the next step of the binary search. ++ */ ++ msk = 1 << (7 - (depth & 7)); ++ ++ return (ip[index] & msk) != 0; + } + + static inline struct rte_rib6_node * + get_nxt_node(struct rte_rib6_node *node, + const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE]) + { ++ if (node->depth == RIB6_MAXDEPTH) ++ return NULL; ++ + return (get_dir(ip, node->depth)) ? node->right : node->left; + } + +@@ -186,7 +199,7 @@ rte_rib6_lookup_exact(struct rte_rib6 *rib, + } + + /* +- * Traverses on subtree and retreeves more specific routes ++ * Traverses on subtree and retrieves more specific routes + * for a given in args ip/depth prefix + * last = NULL means the first invocation + */ diff --git a/dpdk/lib/librte_rib/rte_rib6.h b/dpdk/lib/librte_rib/rte_rib6.h index 871457138d..b80665bf44 100644 --- a/dpdk/lib/librte_rib/rte_rib6.h @@ -77637,8 +108984,47 @@ index 871457138d..b80665bf44 100644 +#endif + +#endif /* _RTE_RIB6_H_ */ +diff --git a/dpdk/lib/librte_ring/rte_ring.c b/dpdk/lib/librte_ring/rte_ring.c +index d9b308036c..6e740e8f9e 100644 +--- a/dpdk/lib/librte_ring/rte_ring.c ++++ b/dpdk/lib/librte_ring/rte_ring.c +@@ -137,7 +137,7 @@ rte_ring_create(const char *name, unsigned count, int socket_id, + + ring_size = rte_ring_get_memsize(count); + if (ring_size < 0) { +- rte_errno = ring_size; ++ rte_errno = -ring_size; + return NULL; + } + +diff --git a/dpdk/lib/librte_ring/rte_ring_c11_mem.h b/dpdk/lib/librte_ring/rte_ring_c11_mem.h +index 0fb73a3371..ae886532ee 100644 +--- a/dpdk/lib/librte_ring/rte_ring_c11_mem.h ++++ b/dpdk/lib/librte_ring/rte_ring_c11_mem.h +@@ -111,7 +111,7 @@ __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp, + * @param is_sc + * Indicates whether multi-consumer path is needed or not + * @param n +- * The number of elements we will want to enqueue, i.e. how far should the ++ * The number of elements we will want to dequeue, i.e. how far should the + * head be moved + * @param behavior + * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring +diff --git a/dpdk/lib/librte_ring/rte_ring_generic.h b/dpdk/lib/librte_ring/rte_ring_generic.h +index 953cdbbd5e..79ae4ecb14 100644 +--- a/dpdk/lib/librte_ring/rte_ring_generic.h ++++ b/dpdk/lib/librte_ring/rte_ring_generic.h +@@ -107,7 +107,7 @@ __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp, + * @param is_sc + * Indicates whether multi-consumer path is needed or not + * @param n +- * The number of elements we will want to enqueue, i.e. how far should the ++ * The number of elements we will want to dequeue, i.e. how far should the + * head be moved + * @param behavior + * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring diff --git a/dpdk/lib/librte_sched/rte_sched.c b/dpdk/lib/librte_sched/rte_sched.c -index c0983ddda4..0fa0741664 100644 +index c0983ddda4..bad1c4d271 100644 --- a/dpdk/lib/librte_sched/rte_sched.c +++ b/dpdk/lib/librte_sched/rte_sched.c @@ -222,6 +222,7 @@ struct rte_sched_port { @@ -77658,6 +109044,15 @@ index c0983ddda4..0fa0741664 100644 { uint32_t i; +@@ -492,7 +493,7 @@ rte_sched_subport_config_qsize(struct rte_sched_subport *subport) + + subport->qsize_add[0] = 0; + +- /* Strict prority traffic class */ ++ /* Strict priority traffic class */ + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->qsize_add[i] = subport->qsize_add[i-1] + subport->qsize[i-1]; + @@ -624,7 +625,7 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport *subport, static void @@ -77899,8 +109294,37 @@ index 546779df2b..b4b4eb2d85 100644 */ int rte_security_session_destroy(struct rte_security_ctx *instance, +diff --git a/dpdk/lib/librte_stack/meson.build b/dpdk/lib/librte_stack/meson.build +index f420a5c223..ef29dd6959 100644 +--- a/dpdk/lib/librte_stack/meson.build ++++ b/dpdk/lib/librte_stack/meson.build +@@ -8,4 +8,6 @@ headers = files('rte_stack.h', + 'rte_stack_std.h', + 'rte_stack_lf.h', + 'rte_stack_lf_generic.h', +- 'rte_stack_lf_c11.h') ++ 'rte_stack_lf_c11.h', ++ 'rte_stack_lf_stubs.h', ++) +diff --git a/dpdk/lib/librte_stack/rte_stack.c b/dpdk/lib/librte_stack/rte_stack.c +index d19824f004..112f2f99ce 100644 +--- a/dpdk/lib/librte_stack/rte_stack.c ++++ b/dpdk/lib/librte_stack/rte_stack.c +@@ -61,9 +61,11 @@ rte_stack_create(const char *name, unsigned int count, int socket_id, + + #ifdef RTE_ARCH_64 + RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) != 16); +-#else ++#endif ++#if !defined(RTE_STACK_LF_SUPPORTED) + if (flags & RTE_STACK_F_LF) { + STACK_LOG_ERR("Lock-free stack is not supported on your platform\n"); ++ rte_errno = ENOTSUP; + return NULL; + } + #endif diff --git a/dpdk/lib/librte_stack/rte_stack.h b/dpdk/lib/librte_stack/rte_stack.h -index 27ddb199e5..abf6420766 100644 +index 27ddb199e5..ee94a758b3 100644 --- a/dpdk/lib/librte_stack/rte_stack.h +++ b/dpdk/lib/librte_stack/rte_stack.h @@ -4,9 +4,12 @@ @@ -77918,6 +109342,39 @@ index 27ddb199e5..abf6420766 100644 * * librte_stack provides an API for configuration and use of a bounded stack of * pointers. Push and pop operations are MT-safe, allowing concurrent access, +@@ -90,7 +93,7 @@ struct rte_stack { + + /** + * The stack uses lock-free push and pop functions. This flag is only +- * supported on x86_64 platforms, currently. ++ * supported on x86_64 or arm64 platforms, currently. + */ + #define RTE_STACK_F_LF 0x0001 + +@@ -225,6 +228,7 @@ rte_stack_free_count(struct rte_stack *s) + * - EEXIST - a stack with the same name already exists + * - ENOMEM - insufficient memory to create the stack + * - ENAMETOOLONG - name size exceeds RTE_STACK_NAMESIZE ++ * - ENOTSUP - platform does not support given flags combination. + */ + __rte_experimental + struct rte_stack * +diff --git a/dpdk/lib/librte_stack/rte_stack_lf.h b/dpdk/lib/librte_stack/rte_stack_lf.h +index e67630c277..3d3bd0f798 100644 +--- a/dpdk/lib/librte_stack/rte_stack_lf.h ++++ b/dpdk/lib/librte_stack/rte_stack_lf.h +@@ -13,6 +13,11 @@ + #else + #include "rte_stack_lf_generic.h" + #endif ++ ++/** ++ * Indicates that RTE_STACK_F_LF is supported. ++ */ ++#define RTE_STACK_LF_SUPPORTED + #endif + + /** diff --git a/dpdk/lib/librte_stack/rte_stack_lf_c11.h b/dpdk/lib/librte_stack/rte_stack_lf_c11.h index 999359f081..94129c3e8a 100644 --- a/dpdk/lib/librte_stack/rte_stack_lf_c11.h @@ -77935,7 +109392,7 @@ index 999359f081..94129c3e8a 100644 new_head.top = tmp; new_head.cnt = old_head.cnt + 1; diff --git a/dpdk/lib/librte_stack/rte_stack_lf_generic.h b/dpdk/lib/librte_stack/rte_stack_lf_generic.h -index 3abbb53428..4850a05ee7 100644 +index 3abbb53428..7fa29cedb2 100644 --- a/dpdk/lib/librte_stack/rte_stack_lf_generic.h +++ b/dpdk/lib/librte_stack/rte_stack_lf_generic.h @@ -78,7 +78,7 @@ __rte_stack_lf_pop_elems(struct rte_stack_lf_list *list, @@ -77947,6 +109404,110 @@ index 3abbb53428..4850a05ee7 100644 /* Reserve num elements, if available */ while (1) { +@@ -128,8 +128,10 @@ __rte_stack_lf_pop_elems(struct rte_stack_lf_list *list, + /* If NULL was encountered, the list was modified while + * traversing it. Retry. + */ +- if (i != num) ++ if (i != num) { ++ old_head = list->head; + continue; ++ } + + new_head.top = tmp; + new_head.cnt = old_head.cnt + 1; +diff --git a/dpdk/lib/librte_table/rte_table_hash_func.h b/dpdk/lib/librte_table/rte_table_hash_func.h +index 350c795649..d4f126ab5f 100644 +--- a/dpdk/lib/librte_table/rte_table_hash_func.h ++++ b/dpdk/lib/librte_table/rte_table_hash_func.h +@@ -58,8 +58,8 @@ static inline uint64_t + rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t crc0; + + crc0 = rte_crc32_u64(seed, k[0] & m[0]); +@@ -72,8 +72,8 @@ static inline uint64_t + rte_table_hash_crc_key16(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, crc0, crc1; + + k0 = k[0] & m[0]; +@@ -91,8 +91,8 @@ static inline uint64_t + rte_table_hash_crc_key24(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, crc0, crc1; + + k0 = k[0] & m[0]; +@@ -113,8 +113,8 @@ static inline uint64_t + rte_table_hash_crc_key32(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; +@@ -139,8 +139,8 @@ static inline uint64_t + rte_table_hash_crc_key40(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; +@@ -165,8 +165,8 @@ static inline uint64_t + rte_table_hash_crc_key48(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; +@@ -192,8 +192,8 @@ static inline uint64_t + rte_table_hash_crc_key56(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5; + + k0 = k[0] & m[0]; +@@ -222,8 +222,8 @@ static inline uint64_t + rte_table_hash_crc_key64(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) + { +- uint64_t *k = key; +- uint64_t *m = mask; ++ uint64_t *k = (uint64_t *)key; ++ uint64_t *m = (uint64_t *)mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5; + + k0 = k[0] & m[0]; diff --git a/dpdk/lib/librte_table/rte_table_hash_key16.c b/dpdk/lib/librte_table/rte_table_hash_key16.c index 2cca1c924a..c4384b114d 100644 --- a/dpdk/lib/librte_table/rte_table_hash_key16.c @@ -78064,12 +109625,34 @@ index 26a331140b..f65f1f4acf 100644 if jansson.found() ext_deps += jansson dpdk_app_link_libraries += ['telemetry'] +diff --git a/dpdk/lib/librte_telemetry/rte_telemetry.c b/dpdk/lib/librte_telemetry/rte_telemetry.c +index eb20cc6515..98d5f9168d 100644 +--- a/dpdk/lib/librte_telemetry/rte_telemetry.c ++++ b/dpdk/lib/librte_telemetry/rte_telemetry.c +@@ -1005,10 +1005,10 @@ rte_telemetry_init(void) + } + TAILQ_INIT(&static_telemetry->client_list_head); + ++ static_telemetry->thread_status = 1; + ret = rte_ctrl_thread_create(&static_telemetry->thread_id, + telemetry_ctrl_thread, &attr, rte_telemetry_run_thread_func, + (void *)static_telemetry); +- static_telemetry->thread_status = 1; + + if (ret < 0) { + ret = rte_telemetry_cleanup(); diff --git a/dpdk/lib/librte_telemetry/rte_telemetry.h b/dpdk/lib/librte_telemetry/rte_telemetry.h -index aedb318598..f1376ea35f 100644 +index aedb318598..a5ff0e75f3 100644 --- a/dpdk/lib/librte_telemetry/rte_telemetry.h +++ b/dpdk/lib/librte_telemetry/rte_telemetry.h -@@ -9,7 +9,12 @@ +@@ -7,9 +7,18 @@ + #ifndef _RTE_TELEMETRY_H_ + #define _RTE_TELEMETRY_H_ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ /** * @file - * RTE Telemetry @@ -78082,6 +109665,15 @@ index aedb318598..f1376ea35f 100644 * * The telemetry library provides a method to retrieve statistics from * DPDK by sending a JSON encoded message over a socket. DPDK will send +@@ -66,4 +75,8 @@ __rte_experimental + int32_t + rte_telemetry_selftest(void); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif diff --git a/dpdk/lib/librte_telemetry/rte_telemetry_parser.c b/dpdk/lib/librte_telemetry/rte_telemetry_parser.c index 9601323970..e8c269e85e 100644 --- a/dpdk/lib/librte_telemetry/rte_telemetry_parser.c @@ -78228,11 +109820,49 @@ index 4a1d8c1253..2e90a63bb1 100644 if (!vq->iotlb_pool) { RTE_LOG(ERR, VHOST_CONFIG, "Failed to create IOTLB cache pool (%s)\n", +diff --git a/dpdk/lib/librte_vhost/rte_vdpa.h b/dpdk/lib/librte_vhost/rte_vdpa.h +index 9a3deb31df..9203c6d37a 100644 +--- a/dpdk/lib/librte_vhost/rte_vdpa.h ++++ b/dpdk/lib/librte_vhost/rte_vdpa.h +@@ -5,6 +5,10 @@ + #ifndef _RTE_VDPA_H_ + #define _RTE_VDPA_H_ + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + /** + * @file + * +@@ -200,4 +204,9 @@ rte_vhost_host_notifier_ctrl(int vid, bool enable); + __rte_experimental + int + rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m); ++ ++#ifdef __cplusplus ++} ++#endif ++ + #endif /* _RTE_VDPA_H_ */ diff --git a/dpdk/lib/librte_vhost/rte_vhost.h b/dpdk/lib/librte_vhost/rte_vhost.h -index 7b5dc87c2e..53a30a0623 100644 +index 7b5dc87c2e..08bb6a8fe9 100644 --- a/dpdk/lib/librte_vhost/rte_vhost.h +++ b/dpdk/lib/librte_vhost/rte_vhost.h -@@ -35,6 +35,23 @@ extern "C" { +@@ -20,10 +20,12 @@ + extern "C" { + #endif + ++#ifndef __cplusplus + /* These are not C++-aware. */ + #include + #include + #include ++#endif + + #define RTE_VHOST_USER_CLIENT (1ULL << 0) + #define RTE_VHOST_USER_NO_RECONNECT (1ULL << 1) +@@ -35,6 +37,23 @@ extern "C" { /* support only linear buffers (no chained mbufs) */ #define RTE_VHOST_USER_LINEARBUF_SUPPORT (1ULL << 6) @@ -78256,7 +109886,7 @@ index 7b5dc87c2e..53a30a0623 100644 /** Protocol features. */ #ifndef VHOST_USER_PROTOCOL_F_MQ #define VHOST_USER_PROTOCOL_F_MQ 0 -@@ -68,6 +85,10 @@ extern "C" { +@@ -68,6 +87,10 @@ extern "C" { #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8 #endif @@ -78267,7 +109897,7 @@ index 7b5dc87c2e..53a30a0623 100644 #ifndef VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD #define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10 #endif -@@ -85,6 +106,7 @@ extern "C" { +@@ -85,6 +108,7 @@ extern "C" { #define VHOST_USER_F_PROTOCOL_FEATURES 30 #endif @@ -78275,7 +109905,7 @@ index 7b5dc87c2e..53a30a0623 100644 /** * Information relating to memory regions including offsets to * addresses in QEMUs memory file. -@@ -253,7 +275,7 @@ struct vhost_device_ops { +@@ -253,7 +277,7 @@ struct vhost_device_ops { /** * This callback gets called each time a guest gets notified @@ -78284,12 +109914,36 @@ index 7b5dc87c2e..53a30a0623 100644 * the eventfd_write(callfd), which can be used for counting these * "slow" syscalls. */ +@@ -733,7 +757,7 @@ rte_vhost_get_vhost_ring_inflight(int vid, uint16_t vring_idx, + /** + * Set split inflight descriptor. + * +- * This function save descriptors that has been comsumed in available ++ * This function save descriptors that has been consumed in available + * ring + * + * @param vid +@@ -753,7 +777,7 @@ rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx, + /** + * Set packed inflight descriptor and get corresponding inflight entry + * +- * This function save descriptors that has been comsumed ++ * This function save descriptors that has been consumed + * + * @param vid + * vhost device ID diff --git a/dpdk/lib/librte_vhost/rte_vhost_crypto.h b/dpdk/lib/librte_vhost/rte_vhost_crypto.h -index d29871c7ea..b54d61db69 100644 +index d29871c7ea..83ce06c553 100644 --- a/dpdk/lib/librte_vhost/rte_vhost_crypto.h +++ b/dpdk/lib/librte_vhost/rte_vhost_crypto.h -@@ -7,9 +7,12 @@ +@@ -5,11 +5,18 @@ + #ifndef _VHOST_CRYPTO_H_ + #define _VHOST_CRYPTO_H_ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ #define VHOST_CRYPTO_MBUF_POOL_SIZE (8192) #define VHOST_CRYPTO_MAX_BURST_SIZE (64) +#define VHOST_CRYPTO_MAX_DATA_SIZE (4096) @@ -78301,8 +109955,17 @@ index d29871c7ea..b54d61db69 100644 enum rte_vhost_crypto_zero_copy { RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE = 0, +@@ -114,4 +121,8 @@ uint16_t + rte_vhost_crypto_finalize_requests(struct rte_crypto_op **ops, + uint16_t nb_ops, int *callfds, uint16_t *nb_callfds); + ++#ifdef __cplusplus ++} ++#endif ++ + #endif /**< _VHOST_CRYPTO_H_ */ diff --git a/dpdk/lib/librte_vhost/socket.c b/dpdk/lib/librte_vhost/socket.c -index ebb2ff6c28..dc3ee1e99d 100644 +index ebb2ff6c28..2d1f5f64ec 100644 --- a/dpdk/lib/librte_vhost/socket.c +++ b/dpdk/lib/librte_vhost/socket.c @@ -127,7 +127,8 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds, @@ -78315,6 +109978,15 @@ index ebb2ff6c28..dc3ee1e99d 100644 return ret; } +@@ -240,7 +241,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) + if (vsocket->linearbuf) + vhost_enable_linearbuf(vid); + +- RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", vid); ++ RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d, path is %s\n", vid, vsocket->path); + + if (vsocket->notify_ops->new_connection) { + ret = vsocket->notify_ops->new_connection(vid); @@ -318,16 +319,16 @@ vhost_user_read_cb(int connfd, void *dat, int *remove) vhost_destroy_device(conn->vid); @@ -78337,6 +110009,28 @@ index ebb2ff6c28..dc3ee1e99d 100644 } } +@@ -498,7 +499,7 @@ vhost_user_reconnect_init(void) + + ret = pthread_mutex_init(&reconn_list.mutex, NULL); + if (ret < 0) { +- RTE_LOG(ERR, VHOST_CONFIG, "failed to initialize mutex"); ++ RTE_LOG(ERR, VHOST_CONFIG, "failed to initialize mutex\n"); + return ret; + } + TAILQ_INIT(&reconn_list.head); +@@ -506,10 +507,10 @@ vhost_user_reconnect_init(void) + ret = rte_ctrl_thread_create(&reconn_tid, "vhost_reconn", NULL, + vhost_user_client_reconnect, NULL); + if (ret != 0) { +- RTE_LOG(ERR, VHOST_CONFIG, "failed to create reconnect thread"); ++ RTE_LOG(ERR, VHOST_CONFIG, "failed to create reconnect thread\n"); + if (pthread_mutex_destroy(&reconn_list.mutex)) { + RTE_LOG(ERR, VHOST_CONFIG, +- "failed to destroy reconnect mutex"); ++ "failed to destroy reconnect mutex\n"); + } + } + @@ -877,6 +878,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags) "error: failed to init connection mutex\n"); goto out_free; @@ -78390,8 +110084,17 @@ index ebb2ff6c28..dc3ee1e99d 100644 close(vsocket->socket_fd); unlink(path); } else if (vsocket->reconnect) { +@@ -1157,7 +1173,7 @@ rte_vhost_driver_start(const char *path) + &vhost_user.fdset); + if (ret != 0) { + RTE_LOG(ERR, VHOST_CONFIG, +- "failed to create fdset handling thread"); ++ "failed to create fdset handling thread\n"); + + fdset_pipe_uninit(&vhost_user.fdset); + return -1; diff --git a/dpdk/lib/librte_vhost/vhost.c b/dpdk/lib/librte_vhost/vhost.c -index 1cbe948f74..2d5bb2cfde 100644 +index 1cbe948f74..0b88fc1a49 100644 --- a/dpdk/lib/librte_vhost/vhost.c +++ b/dpdk/lib/librte_vhost/vhost.c @@ -26,6 +26,7 @@ @@ -78502,7 +110205,7 @@ index 1cbe948f74..2d5bb2cfde 100644 - vq->avail_wrap_counter = 1; - vq->used_wrap_counter = 1; - vq->signalled_used_valid = false; -+ vq = rte_malloc(NULL, sizeof(struct vhost_virtqueue), 0); ++ vq = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), 0); + if (vq == NULL) { + RTE_LOG(ERR, VHOST_CONFIG, + "Failed to allocate memory for vring:%u.\n", i); @@ -78552,7 +110255,33 @@ index 1cbe948f74..2d5bb2cfde 100644 dev->vid = i; dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET; dev->slave_req_fd = -1; -@@ -1195,7 +1264,12 @@ rte_vhost_avail_entries(int vid, uint16_t queue_id) +@@ -1105,6 +1174,9 @@ rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx, + if (unlikely(!vq->inflight_split)) + return -1; + ++ if (unlikely(idx >= vq->size)) ++ return -1; ++ + vq->inflight_split->last_inflight_io = idx; + return 0; + } +@@ -1176,11 +1248,15 @@ rte_vhost_vring_call(int vid, uint16_t vring_idx) + if (!vq) + return -1; + ++ rte_spinlock_lock(&vq->access_lock); ++ + if (vq_is_packed(dev)) + vhost_vring_call_packed(dev, vq); + else + vhost_vring_call_split(dev, vq); + ++ rte_spinlock_unlock(&vq->access_lock); ++ + return 0; + } + +@@ -1195,7 +1271,12 @@ rte_vhost_avail_entries(int vid, uint16_t queue_id) if (!dev) return 0; @@ -78565,7 +110294,7 @@ index 1cbe948f74..2d5bb2cfde 100644 rte_spinlock_lock(&vq->access_lock); -@@ -1265,7 +1339,12 @@ rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable) +@@ -1265,7 +1346,12 @@ rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable) if (!dev) return -1; @@ -78578,7 +110307,7 @@ index 1cbe948f74..2d5bb2cfde 100644 rte_spinlock_lock(&vq->access_lock); -@@ -1376,6 +1455,9 @@ int rte_vhost_get_vring_base(int vid, uint16_t queue_id, +@@ -1376,6 +1462,9 @@ int rte_vhost_get_vring_base(int vid, uint16_t queue_id, if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL) return -1; @@ -78588,7 +110317,7 @@ index 1cbe948f74..2d5bb2cfde 100644 vq = dev->virtqueue[queue_id]; if (!vq) return -1; -@@ -1402,6 +1484,9 @@ int rte_vhost_set_vring_base(int vid, uint16_t queue_id, +@@ -1402,6 +1491,9 @@ int rte_vhost_set_vring_base(int vid, uint16_t queue_id, if (!dev) return -1; @@ -78598,7 +110327,7 @@ index 1cbe948f74..2d5bb2cfde 100644 vq = dev->virtqueue[queue_id]; if (!vq) return -1; -@@ -1426,15 +1511,23 @@ rte_vhost_get_vring_base_from_inflight(int vid, +@@ -1426,15 +1518,23 @@ rte_vhost_get_vring_base_from_inflight(int vid, uint16_t *last_used_idx) { struct rte_vhost_inflight_info_packed *inflight_info; @@ -78698,7 +110427,7 @@ index 9f11b28a31..deeca18f8f 100644 static __rte_always_inline uint64_t diff --git a/dpdk/lib/librte_vhost/vhost_crypto.c b/dpdk/lib/librte_vhost/vhost_crypto.c -index 684fddc30b..e08f9c6d75 100644 +index 684fddc30b..4f91715c33 100644 --- a/dpdk/lib/librte_vhost/vhost_crypto.c +++ b/dpdk/lib/librte_vhost/vhost_crypto.c @@ -40,11 +40,20 @@ @@ -78874,27 +110603,86 @@ index 684fddc30b..e08f9c6d75 100644 uint8_t perm) { void *data; -@@ -551,12 +566,13 @@ get_data_ptr(struct vhost_crypto_data_req *vc_req, struct vring_desc *cur_desc, +@@ -551,106 +566,60 @@ get_data_ptr(struct vhost_crypto_data_req *vc_req, struct vring_desc *cur_desc, return data; } -static int -+static __rte_always_inline int - copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, +-copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, - struct vring_desc **cur_desc, uint32_t size, - uint32_t *nb_descs, uint32_t vq_size) -+ struct vhost_crypto_desc *head, -+ struct vhost_crypto_desc **cur_desc, -+ uint32_t size, uint32_t max_n_descs) ++static __rte_always_inline uint32_t ++copy_data_from_desc(void *dst, struct vhost_crypto_data_req *vc_req, ++ struct vhost_crypto_desc *desc, uint32_t size) { - struct vring_desc *desc = *cur_desc; -+ struct vhost_crypto_desc *desc = *cur_desc; - uint64_t remain, addr, dlen, len; - uint32_t to_copy; - uint8_t *data = dst_data; -@@ -595,17 +611,10 @@ copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, +- uint64_t remain, addr, dlen, len; +- uint32_t to_copy; +- uint8_t *data = dst_data; +- uint8_t *src; +- int left = size; +- +- to_copy = RTE_MIN(desc->len, (uint32_t)left); +- dlen = to_copy; +- src = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, &dlen, +- VHOST_ACCESS_RO); +- if (unlikely(!src || !dlen)) +- return -1; +- +- rte_memcpy((uint8_t *)data, src, dlen); +- data += dlen; +- +- if (unlikely(dlen < to_copy)) { +- remain = to_copy - dlen; +- addr = desc->addr + dlen; +- +- while (remain) { +- len = remain; +- src = IOVA_TO_VVA(uint8_t *, vc_req, addr, &len, +- VHOST_ACCESS_RO); +- if (unlikely(!src || !len)) { +- VC_LOG_ERR("Failed to map descriptor"); +- return -1; +- } ++ uint64_t remain; ++ uint64_t addr; ++ ++ remain = RTE_MIN(desc->len, size); ++ addr = desc->addr; ++ do { ++ uint64_t len; ++ void *src; ++ ++ len = remain; ++ src = IOVA_TO_VVA(void *, vc_req, addr, &len, VHOST_ACCESS_RO); ++ if (unlikely(src == NULL || len == 0)) ++ return 0; ++ ++ rte_memcpy(dst, src, len); ++ remain -= len; ++ /* cast is needed for 32-bit architecture */ ++ dst = RTE_PTR_ADD(dst, (size_t)len); ++ addr += len; ++ } while (unlikely(remain != 0)); ++ ++ return RTE_MIN(desc->len, size); ++} + +- rte_memcpy(data, src, len); +- addr += len; +- remain -= len; +- data += len; +- } +- } - left -= to_copy; +- left -= to_copy; ++static __rte_always_inline int ++copy_data(void *data, struct vhost_crypto_data_req *vc_req, ++ struct vhost_crypto_desc *head, struct vhost_crypto_desc **cur_desc, ++ uint32_t size, uint32_t max_n_descs) ++{ ++ struct vhost_crypto_desc *desc = *cur_desc; ++ uint32_t left = size; - while ((desc->flags & VRING_DESC_F_NEXT) && left > 0) { - if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) { @@ -78902,23 +110690,59 @@ index 684fddc30b..e08f9c6d75 100644 - return -1; - } - (*nb_descs)--; -- ++ do { ++ uint32_t copied; + - desc = &vc_req->head[desc->next]; - rte_prefetch0(&vc_req->head[desc->next]); -+ while (desc >= head && desc - head < (int)max_n_descs && left) { -+ desc++; - to_copy = RTE_MIN(desc->len, (uint32_t)left); +- to_copy = RTE_MIN(desc->len, (uint32_t)left); - dlen = desc->len; -+ dlen = to_copy; - src = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, &dlen, - VHOST_ACCESS_RO); - if (unlikely(!src || !dlen)) { -@@ -644,13 +653,10 @@ copy_data(void *dst_data, struct vhost_crypto_data_req *vc_req, +- src = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, &dlen, +- VHOST_ACCESS_RO); +- if (unlikely(!src || !dlen)) { +- VC_LOG_ERR("Failed to map descriptor"); ++ copied = copy_data_from_desc(data, vc_req, desc, left); ++ if (copied == 0) + return -1; +- } +- +- rte_memcpy(data, src, dlen); +- data += dlen; +- +- if (unlikely(dlen < to_copy)) { +- remain = to_copy - dlen; +- addr = desc->addr + dlen; +- +- while (remain) { +- len = remain; +- src = IOVA_TO_VVA(uint8_t *, vc_req, addr, &len, +- VHOST_ACCESS_RO); +- if (unlikely(!src || !len)) { +- VC_LOG_ERR("Failed to map descriptor"); +- return -1; +- } ++ left -= copied; ++ data = RTE_PTR_ADD(data, copied); ++ } while (left != 0 && ++desc < head + max_n_descs); + +- rte_memcpy(data, src, len); +- addr += len; +- remain -= len; +- data += len; +- } +- } +- +- left -= to_copy; +- } +- +- if (unlikely(left > 0)) { +- VC_LOG_ERR("Incorrect virtio descriptor"); ++ if (unlikely(left != 0)) return -1; - } +- } - if (unlikely(*nb_descs == 0)) -+ if (unlikely(desc - head == (int)max_n_descs)) ++ if (unlikely(desc == head + max_n_descs)) *cur_desc = NULL; - else { - if (unlikely(desc->next >= vq_size)) @@ -78930,7 +110754,7 @@ index 684fddc30b..e08f9c6d75 100644 return 0; } -@@ -662,6 +668,7 @@ write_back_data(struct vhost_crypto_data_req *vc_req) +@@ -662,6 +631,7 @@ write_back_data(struct vhost_crypto_data_req *vc_req) while (wb_data) { rte_memcpy(wb_data->dst, wb_data->src, wb_data->len); @@ -78938,7 +110762,7 @@ index 684fddc30b..e08f9c6d75 100644 wb_last = wb_data; wb_data = wb_data->next; rte_mempool_put(vc_req->wb_pool, wb_last); -@@ -703,17 +710,18 @@ free_wb_data(struct vhost_crypto_writeback_data *wb_data, +@@ -703,17 +673,18 @@ free_wb_data(struct vhost_crypto_writeback_data *wb_data, * @return * The pointer to the start of the write back data linked list. */ @@ -78961,7 +110785,7 @@ index 684fddc30b..e08f9c6d75 100644 uint64_t dlen; uint8_t *dst; int ret; -@@ -730,14 +738,14 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, +@@ -730,14 +701,14 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, wb_data->src = src + offset; dlen = desc->len; dst = IOVA_TO_VVA(uint8_t *, vc_req, desc->addr, @@ -78979,7 +110803,7 @@ index 684fddc30b..e08f9c6d75 100644 write_back_len -= wb_data->len; src += offset + wb_data->len; offset = 0; -@@ -756,14 +764,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, +@@ -756,14 +727,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, } else offset -= desc->len; @@ -78998,7 +110822,7 @@ index 684fddc30b..e08f9c6d75 100644 if (unlikely(!(desc->flags & VRING_DESC_F_WRITE))) { VC_LOG_ERR("incorrect descriptor"); goto error_exit; -@@ -782,7 +786,7 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, +@@ -782,7 +749,7 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, goto error_exit; } @@ -79007,7 +110831,7 @@ index 684fddc30b..e08f9c6d75 100644 wb_data->dst = dst; wb_data->len = RTE_MIN(desc->len - offset, write_back_len); write_back_len -= wb_data->len; -@@ -802,13 +806,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, +@@ -802,13 +769,10 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, wb_data->next = NULL; } @@ -79024,7 +110848,7 @@ index 684fddc30b..e08f9c6d75 100644 *end_wb_data = wb_data; -@@ -821,31 +822,44 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, +@@ -821,31 +785,45 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, return NULL; } @@ -79066,6 +110890,7 @@ index 684fddc30b..e08f9c6d75 100644 - nb_descs, vq_size) < 0)) { + if (unlikely(copy_data(iv_data, vc_req, head, &desc, + cipher->para.iv_len, max_n_descs))) { ++ VC_LOG_ERR("Incorrect virtio descriptor"); ret = VIRTIO_CRYPTO_BADMSG; goto error_exit; } @@ -79078,7 +110903,7 @@ index 684fddc30b..e08f9c6d75 100644 m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, cipher->para.src_data_len); m_src->buf_addr = get_data_ptr(vc_req, desc, VHOST_ACCESS_RO); -@@ -856,9 +870,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -856,9 +834,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, goto error_exit; } @@ -79090,7 +110915,7 @@ index 684fddc30b..e08f9c6d75 100644 VC_LOG_ERR("Incorrect descriptor"); ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -867,16 +880,10 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -867,16 +844,11 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, break; case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: vc_req->wb_pool = vcrypto->wb_pool; @@ -79107,10 +110932,11 @@ index 684fddc30b..e08f9c6d75 100644 - nb_descs, vq_size) < 0)) { + vc_req, head, &desc, cipher->para.src_data_len, + max_n_descs) < 0)) { ++ VC_LOG_ERR("Incorrect virtio descriptor"); ret = VIRTIO_CRYPTO_BADMSG; goto error_exit; } -@@ -887,7 +894,7 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -887,7 +859,7 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, } /* dst */ @@ -79119,7 +110945,7 @@ index 684fddc30b..e08f9c6d75 100644 if (unlikely(!desc)) { VC_LOG_ERR("Cannot find write location"); ret = VIRTIO_CRYPTO_BADMSG; -@@ -905,9 +912,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -905,9 +877,8 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, goto error_exit; } @@ -79131,7 +110957,7 @@ index 684fddc30b..e08f9c6d75 100644 VC_LOG_ERR("Incorrect descriptor"); ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -916,9 +922,9 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -916,9 +887,9 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, m_dst->data_len = cipher->para.dst_data_len; break; case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: @@ -79143,7 +110969,7 @@ index 684fddc30b..e08f9c6d75 100644 if (unlikely(vc_req->wb == NULL)) { ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -956,33 +962,58 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -956,33 +927,59 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, return ret; } @@ -79199,6 +111025,7 @@ index 684fddc30b..e08f9c6d75 100644 - chain->para.iv_len, nb_descs, vq_size) < 0)) { + if (unlikely(copy_data(iv_data, vc_req, head, &desc, + chain->para.iv_len, max_n_descs) < 0)) { ++ VC_LOG_ERR("Incorrect virtio descriptor"); ret = VIRTIO_CRYPTO_BADMSG; goto error_exit; } @@ -79211,7 +111038,7 @@ index 684fddc30b..e08f9c6d75 100644 m_dst->data_len = chain->para.dst_data_len; m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, -@@ -994,9 +1025,8 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -994,9 +991,8 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, goto error_exit; } @@ -79223,7 +111050,7 @@ index 684fddc30b..e08f9c6d75 100644 VC_LOG_ERR("Incorrect descriptor"); ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -1004,16 +1034,10 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1004,16 +1000,11 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, break; case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: vc_req->wb_pool = vcrypto->wb_pool; @@ -79240,10 +111067,11 @@ index 684fddc30b..e08f9c6d75 100644 - nb_descs, vq_size) < 0)) { + vc_req, head, &desc, chain->para.src_data_len, + max_n_descs) < 0)) { ++ VC_LOG_ERR("Incorrect virtio descriptor"); ret = VIRTIO_CRYPTO_BADMSG; goto error_exit; } -@@ -1025,7 +1049,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1025,7 +1016,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, } /* dst */ @@ -79252,7 +111080,7 @@ index 684fddc30b..e08f9c6d75 100644 if (unlikely(!desc)) { VC_LOG_ERR("Cannot find write location"); ret = VIRTIO_CRYPTO_BADMSG; -@@ -1044,8 +1068,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1044,8 +1035,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, } if (unlikely(move_desc(vc_req->head, &desc, @@ -79262,7 +111090,7 @@ index 684fddc30b..e08f9c6d75 100644 VC_LOG_ERR("Incorrect descriptor"); ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -1061,9 +1084,9 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1061,9 +1051,9 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, goto error_exit; } @@ -79274,7 +111102,7 @@ index 684fddc30b..e08f9c6d75 100644 VC_LOG_ERR("Incorrect descriptor"); ret = VIRTIO_CRYPTO_ERR; goto error_exit; -@@ -1071,34 +1094,34 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1071,34 +1061,35 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, break; case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: @@ -79315,10 +111143,11 @@ index 684fddc30b..e08f9c6d75 100644 chain->para.hash_result_len, - nb_descs, vq_size) < 0)) { + max_n_descs) < 0)) { ++ VC_LOG_ERR("Incorrect virtio descriptor"); ret = VIRTIO_CRYPTO_BADMSG; goto error_exit; } -@@ -1148,74 +1171,103 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, +@@ -1148,74 +1139,103 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, static __rte_always_inline int vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, struct vhost_virtqueue *vq, struct rte_crypto_op *op, @@ -79435,8 +111264,9 @@ index 684fddc30b..e08f9c6d75 100644 - goto error_exit; } + src_desc = &head[src_desc->next]; -+ } -+ + } + +- switch (req->header.opcode) { + vc_req->head = head; + vc_req->zero_copy = vcrypto->option; + @@ -79447,9 +111277,8 @@ index 684fddc30b..e08f9c6d75 100644 + err = VIRTIO_CRYPTO_BADMSG; + VC_LOG_ERR("Invalid descriptor"); + goto error_exit; - } - -- switch (req->header.opcode) { ++ } ++ + if (unlikely(copy_data(&req, vc_req, descs, &desc, sizeof(req), + max_n_descs) < 0)) { + err = VIRTIO_CRYPTO_BADMSG; @@ -79468,7 +111297,7 @@ index 684fddc30b..e08f9c6d75 100644 /* one branch to avoid unnecessary table lookup */ if (vcrypto->cache_session_id != session_id) { -@@ -1241,19 +1293,19 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, +@@ -1241,19 +1261,19 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, goto error_exit; } @@ -79493,7 +111322,7 @@ index 684fddc30b..e08f9c6d75 100644 break; } if (unlikely(err != 0)) { -@@ -1262,8 +1314,9 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, +@@ -1262,8 +1282,9 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, } break; default: @@ -79504,7 +111333,7 @@ index 684fddc30b..e08f9c6d75 100644 goto error_exit; } -@@ -1271,7 +1324,7 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, +@@ -1271,7 +1292,7 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto, error_exit: @@ -79513,18 +111342,20 @@ index 684fddc30b..e08f9c6d75 100644 if (likely(inhdr != NULL)) inhdr->status = (uint8_t)err; -@@ -1285,17 +1338,16 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, +@@ -1285,17 +1306,18 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, struct rte_mbuf *m_src = op->sym->m_src; struct rte_mbuf *m_dst = op->sym->m_dst; struct vhost_crypto_data_req *vc_req = rte_mbuf_to_priv(m_src); - uint16_t desc_idx; -+ struct vhost_virtqueue *vq = vc_req->vq; -+ uint16_t used_idx = vc_req->desc_idx, desc_idx; ++ struct vhost_virtqueue *vq; ++ uint16_t used_idx, desc_idx; if (unlikely(!vc_req)) { VC_LOG_ERR("Failed to retrieve vc_req"); return NULL; } ++ vq = vc_req->vq; ++ used_idx = vc_req->desc_idx; - if (old_vq && (vc_req->vq != old_vq)) - return vc_req->vq; @@ -79535,7 +111366,7 @@ index 684fddc30b..e08f9c6d75 100644 if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) vc_req->inhdr->status = VIRTIO_CRYPTO_ERR; -@@ -1304,8 +1356,9 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, +@@ -1304,8 +1326,9 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op, write_back_data(vc_req); } @@ -79547,7 +111378,7 @@ index 684fddc30b..e08f9c6d75 100644 rte_mempool_put(m_src->pool, (void *)m_src); -@@ -1403,7 +1456,7 @@ rte_vhost_crypto_create(int vid, uint8_t cryptodev_id, +@@ -1403,7 +1426,7 @@ rte_vhost_crypto_create(int vid, uint8_t cryptodev_id, vcrypto->mbuf_pool = rte_pktmbuf_pool_create(name, VHOST_CRYPTO_MBUF_POOL_SIZE, 512, sizeof(struct vhost_crypto_data_req), @@ -79556,7 +111387,7 @@ index 684fddc30b..e08f9c6d75 100644 rte_socket_id()); if (!vcrypto->mbuf_pool) { VC_LOG_ERR("Failed to creath mbuf pool"); -@@ -1529,6 +1582,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1529,6 +1552,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, struct rte_crypto_op **ops, uint16_t nb_ops) { struct rte_mbuf *mbufs[VHOST_CRYPTO_MAX_BURST_SIZE * 2]; @@ -79564,7 +111395,7 @@ index 684fddc30b..e08f9c6d75 100644 struct virtio_net *dev = get_device(vid); struct vhost_crypto *vcrypto; struct vhost_virtqueue *vq; -@@ -1539,18 +1593,18 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1539,18 +1563,18 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, if (unlikely(dev == NULL)) { VC_LOG_ERR("Invalid vid %i", vid); @@ -79586,7 +111417,7 @@ index 684fddc30b..e08f9c6d75 100644 } vq = dev->virtqueue[qid]; -@@ -1572,7 +1626,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1572,7 +1596,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, if (unlikely(rte_mempool_get_bulk(vcrypto->mbuf_pool, (void **)mbufs, count * 2) < 0)) { VC_LOG_ERR("Insufficient memory"); @@ -79595,7 +111426,7 @@ index 684fddc30b..e08f9c6d75 100644 } for (i = 0; i < count; i++) { -@@ -1587,7 +1641,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1587,7 +1611,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, op->sym->m_dst->data_off = 0; if (unlikely(vhost_crypto_process_one_req(vcrypto, vq, @@ -79604,7 +111435,7 @@ index 684fddc30b..e08f9c6d75 100644 break; } -@@ -1602,7 +1656,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1602,7 +1626,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, if (unlikely(rte_mempool_get_bulk(vcrypto->mbuf_pool, (void **)mbufs, count) < 0)) { VC_LOG_ERR("Insufficient memory"); @@ -79613,7 +111444,7 @@ index 684fddc30b..e08f9c6d75 100644 } for (i = 0; i < count; i++) { -@@ -1616,7 +1670,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, +@@ -1616,7 +1640,7 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid, op->sym->m_src->data_off = 0; if (unlikely(vhost_crypto_process_one_req(vcrypto, vq, @@ -79623,7 +111454,7 @@ index 684fddc30b..e08f9c6d75 100644 } diff --git a/dpdk/lib/librte_vhost/vhost_user.c b/dpdk/lib/librte_vhost/vhost_user.c -index 0cfb8b792b..e94fdc70e8 100644 +index 0cfb8b792b..af44d1e69c 100644 --- a/dpdk/lib/librte_vhost/vhost_user.c +++ b/dpdk/lib/librte_vhost/vhost_user.c @@ -97,8 +97,15 @@ close_msg_fds(struct VhostUserMsg *msg) @@ -79644,6 +111475,15 @@ index 0cfb8b792b..e94fdc70e8 100644 } /* +@@ -191,7 +198,7 @@ vhost_backend_cleanup(struct virtio_net *dev) + dev->mem = NULL; + } + +- free(dev->guest_pages); ++ rte_free(dev->guest_pages); + dev->guest_pages = NULL; + + if (dev->log_addr) { @@ -206,7 +213,7 @@ vhost_backend_cleanup(struct virtio_net *dev) dev->inflight_info->addr = NULL; } @@ -79664,7 +111504,59 @@ index 0cfb8b792b..e94fdc70e8 100644 dev->vhost_hlen = sizeof(struct virtio_net_hdr_mrg_rxbuf); } else { dev->vhost_hlen = sizeof(struct virtio_net_hdr); -@@ -656,13 +665,11 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -489,8 +498,8 @@ vhost_user_set_vring_num(struct virtio_net **pdev, + } + + /* +- * Reallocate virtio_dev and vhost_virtqueue data structure to make them on the +- * same numa node as the memory of vring descriptor. ++ * Reallocate virtio_dev, vhost_virtqueue and related data structures to ++ * make them on the same numa node as the memory of vring descriptor. + */ + #ifdef RTE_LIBRTE_VHOST_NUMA + static struct virtio_net* +@@ -584,6 +593,10 @@ numa_realloc(struct virtio_net *dev, int index) + goto out; + } + if (oldnode != newnode) { ++ struct rte_vhost_memory *old_mem; ++ struct guest_page *old_gp; ++ ssize_t mem_size, gp_size; ++ + RTE_LOG(INFO, VHOST_CONFIG, + "reallocate dev from %d to %d node\n", + oldnode, newnode); +@@ -595,6 +608,29 @@ numa_realloc(struct virtio_net *dev, int index) + + memcpy(dev, old_dev, sizeof(*dev)); + rte_free(old_dev); ++ ++ mem_size = sizeof(struct rte_vhost_memory) + ++ sizeof(struct rte_vhost_mem_region) * dev->mem->nregions; ++ old_mem = dev->mem; ++ dev->mem = rte_malloc_socket(NULL, mem_size, 0, newnode); ++ if (!dev->mem) { ++ dev->mem = old_mem; ++ goto out; ++ } ++ ++ memcpy(dev->mem, old_mem, mem_size); ++ rte_free(old_mem); ++ ++ gp_size = dev->max_guest_pages * sizeof(*dev->guest_pages); ++ old_gp = dev->guest_pages; ++ dev->guest_pages = rte_malloc_socket(NULL, gp_size, RTE_CACHE_LINE_SIZE, newnode); ++ if (!dev->guest_pages) { ++ dev->guest_pages = old_gp; ++ goto out; ++ } ++ ++ memcpy(dev->guest_pages, old_gp, gp_size); ++ rte_free(old_gp); + } + + out: +@@ -656,13 +692,11 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, { if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { uint64_t vva; @@ -79681,7 +111573,7 @@ index 0cfb8b792b..e94fdc70e8 100644 return vva; } -@@ -670,37 +677,16 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -670,37 +704,16 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, return qva_to_vva(dev, ra, size); } @@ -79725,7 +111617,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } static struct virtio_net * -@@ -712,7 +698,7 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index) +@@ -712,7 +725,7 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index) if (addr->flags & (1 << VHOST_VRING_F_LOG)) { vq->log_guest_addr = @@ -79734,7 +111626,24 @@ index 0cfb8b792b..e94fdc70e8 100644 if (vq->log_guest_addr == 0) { RTE_LOG(DEBUG, VHOST_CONFIG, "(%d) failed to map log_guest_addr.\n", -@@ -1053,7 +1039,6 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -926,11 +939,12 @@ add_one_guest_page(struct virtio_net *dev, uint64_t guest_phys_addr, + if (dev->nr_guest_pages == dev->max_guest_pages) { + dev->max_guest_pages *= 2; + old_pages = dev->guest_pages; +- dev->guest_pages = realloc(dev->guest_pages, +- dev->max_guest_pages * sizeof(*page)); +- if (!dev->guest_pages) { ++ dev->guest_pages = rte_realloc(dev->guest_pages, ++ dev->max_guest_pages * sizeof(*page), ++ RTE_CACHE_LINE_SIZE); ++ if (dev->guest_pages == NULL) { + RTE_LOG(ERR, VHOST_CONFIG, "cannot realloc guest_pages\n"); +- free(old_pages); ++ rte_free(old_pages); + return -1; + } + } +@@ -1053,7 +1067,6 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, uint64_t alignment; uint32_t i; int populate; @@ -79742,7 +111651,7 @@ index 0cfb8b792b..e94fdc70e8 100644 if (validate_msg_fds(msg, memory->nregions) != 0) return RTE_VHOST_MSG_RESULT_ERR; -@@ -1061,7 +1046,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1061,7 +1074,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, if (memory->nregions > VHOST_MEMORY_MAX_NREGIONS) { RTE_LOG(ERR, VHOST_CONFIG, "too many memory regions (%u)\n", memory->nregions); @@ -79751,7 +111660,21 @@ index 0cfb8b792b..e94fdc70e8 100644 } if (dev->mem && !vhost_memory_changed(memory, dev->mem)) { -@@ -1094,7 +1079,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1085,16 +1098,18 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, + vhost_user_iotlb_flush_all(dev->virtqueue[i]); + + dev->nr_guest_pages = 0; +- if (!dev->guest_pages) { ++ if (dev->guest_pages == NULL) { + dev->max_guest_pages = 8; +- dev->guest_pages = malloc(dev->max_guest_pages * +- sizeof(struct guest_page)); ++ dev->guest_pages = rte_zmalloc(NULL, ++ dev->max_guest_pages * ++ sizeof(struct guest_page), ++ RTE_CACHE_LINE_SIZE); + if (dev->guest_pages == NULL) { + RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to allocate memory " "for dev->guest_pages\n", dev->vid); @@ -79760,7 +111683,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } } -@@ -1104,18 +1089,23 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1104,18 +1119,23 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to allocate memory for dev->mem\n", dev->vid); @@ -79787,7 +111710,7 @@ index 0cfb8b792b..e94fdc70e8 100644 mmap_offset = memory->regions[i].mmap_offset; -@@ -1125,7 +1115,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1125,7 +1145,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, "mmap_offset (%#"PRIx64") and memory_size " "(%#"PRIx64") overflow\n", mmap_offset, reg->size); @@ -79796,7 +111719,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } mmap_size = reg->size + mmap_offset; -@@ -1138,22 +1128,37 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1138,22 +1158,37 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, * to avoid failure, make sure in caller to keep length * aligned. */ @@ -79838,7 +111761,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } reg->mmap_addr = mmap_addr; -@@ -1166,7 +1171,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1166,7 +1201,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, RTE_LOG(ERR, VHOST_CONFIG, "adding guest pages to region %u failed.\n", i); @@ -79847,7 +111770,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } RTE_LOG(INFO, VHOST_CONFIG, -@@ -1209,17 +1214,17 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1209,17 +1244,17 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, if (read_vhost_message(main_fd, &ack_msg) <= 0) { RTE_LOG(ERR, VHOST_CONFIG, "Failed to read qemu ack on postcopy set-mem-table\n"); @@ -79868,7 +111791,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } /* Now userfault register and we can use the memory */ -@@ -1243,7 +1248,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1243,7 +1278,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, "Failed to register ufd for region %d: (ufd = %d) %s\n", i, dev->postcopy_ufd, strerror(errno)); @@ -79877,7 +111800,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } RTE_LOG(INFO, VHOST_CONFIG, "\t userfaultfd registered for range : " -@@ -1252,7 +1257,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1252,7 +1287,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, (uint64_t)reg_struct.range.start + (uint64_t)reg_struct.range.len - 1); #else @@ -79886,7 +111809,7 @@ index 0cfb8b792b..e94fdc70e8 100644 #endif } } -@@ -1271,7 +1276,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1271,7 +1306,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, dev = translate_ring_addresses(dev, i); if (!dev) { dev = *pdev; @@ -79895,7 +111818,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } *pdev = dev; -@@ -1282,10 +1287,15 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1282,10 +1317,15 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, return RTE_VHOST_MSG_RESULT_OK; @@ -79912,7 +111835,7 @@ index 0cfb8b792b..e94fdc70e8 100644 return RTE_VHOST_MSG_RESULT_ERR; } -@@ -1298,7 +1308,8 @@ vq_is_ready(struct virtio_net *dev, struct vhost_virtqueue *vq) +@@ -1298,7 +1338,8 @@ vq_is_ready(struct virtio_net *dev, struct vhost_virtqueue *vq) return false; if (vq_is_packed(dev)) @@ -79922,7 +111845,7 @@ index 0cfb8b792b..e94fdc70e8 100644 else rings_ok = vq->desc && vq->avail && vq->used; -@@ -1400,6 +1411,9 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, +@@ -1400,6 +1441,9 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, int fd, i, j; void *addr; @@ -79932,7 +111855,7 @@ index 0cfb8b792b..e94fdc70e8 100644 if (msg->size != sizeof(msg->payload.inflight)) { RTE_LOG(ERR, VHOST_CONFIG, "invalid get_inflight_fd message size is %d\n", -@@ -1415,6 +1429,7 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, +@@ -1415,6 +1459,7 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, "failed to alloc dev inflight area\n"); return RTE_VHOST_MSG_RESULT_ERR; } @@ -79940,7 +111863,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } num_queues = msg->payload.inflight.num_queues; -@@ -1440,6 +1455,16 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, +@@ -1440,6 +1485,16 @@ vhost_user_get_inflight_fd(struct virtio_net **pdev, } memset(addr, 0, mmap_size); @@ -79957,7 +111880,7 @@ index 0cfb8b792b..e94fdc70e8 100644 dev->inflight_info->addr = addr; dev->inflight_info->size = msg->payload.inflight.mmap_size = mmap_size; dev->inflight_info->fd = msg->fds[0] = fd; -@@ -1482,6 +1507,9 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, +@@ -1482,6 +1537,9 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, void *addr; int fd, i; @@ -79967,7 +111890,7 @@ index 0cfb8b792b..e94fdc70e8 100644 fd = msg->fds[0]; if (msg->size != sizeof(msg->payload.inflight) || fd < 0) { RTE_LOG(ERR, VHOST_CONFIG, -@@ -1522,10 +1550,13 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, +@@ -1522,10 +1580,13 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, "failed to alloc dev inflight area\n"); return RTE_VHOST_MSG_RESULT_ERR; } @@ -79982,7 +111905,7 @@ index 0cfb8b792b..e94fdc70e8 100644 addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_offset); -@@ -1534,8 +1565,10 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, +@@ -1534,8 +1595,10 @@ vhost_user_set_inflight_fd(struct virtio_net **pdev, VhostUserMsg *msg, return RTE_VHOST_MSG_RESULT_ERR; } @@ -79994,7 +111917,7 @@ index 0cfb8b792b..e94fdc70e8 100644 dev->inflight_info->fd = fd; dev->inflight_info->addr = addr; -@@ -1629,8 +1662,11 @@ vhost_check_queue_inflights_split(struct virtio_net *dev, +@@ -1629,8 +1692,11 @@ vhost_check_queue_inflights_split(struct virtio_net *dev, (1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))) return RTE_VHOST_MSG_RESULT_OK; @@ -80007,7 +111930,7 @@ index 0cfb8b792b..e94fdc70e8 100644 if (!vq->inflight_split->version) { vq->inflight_split->version = INFLIGHT_VERSION; -@@ -1710,8 +1746,11 @@ vhost_check_queue_inflights_packed(struct virtio_net *dev, +@@ -1710,8 +1776,11 @@ vhost_check_queue_inflights_packed(struct virtio_net *dev, (1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))) return RTE_VHOST_MSG_RESULT_OK; @@ -80020,7 +111943,7 @@ index 0cfb8b792b..e94fdc70e8 100644 if (!vq->inflight_packed->version) { vq->inflight_packed->version = INFLIGHT_VERSION; -@@ -1811,8 +1850,12 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1811,8 +1880,12 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg, /* Interpret ring addresses only when ring is started. */ dev = translate_ring_addresses(dev, file.index); @@ -80034,7 +111957,7 @@ index 0cfb8b792b..e94fdc70e8 100644 *pdev = dev; -@@ -1857,6 +1900,7 @@ free_zmbufs(struct vhost_virtqueue *vq) +@@ -1857,6 +1930,7 @@ free_zmbufs(struct vhost_virtqueue *vq) drain_zmbuf_list(vq); rte_free(vq->zmbufs); @@ -80042,7 +111965,16 @@ index 0cfb8b792b..e94fdc70e8 100644 } /* -@@ -2054,18 +2098,18 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -1929,6 +2003,8 @@ vhost_user_get_vring_base(struct virtio_net **pdev, + msg->size = sizeof(msg->payload.state); + msg->fd_num = 0; + ++ vhost_user_iotlb_flush_all(vq); ++ + vring_invalidate(dev, vq); + + return RTE_VHOST_MSG_RESULT_REPLY; +@@ -2054,18 +2130,18 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, RTE_LOG(ERR, VHOST_CONFIG, "invalid log base msg size: %"PRId32" != %d\n", msg->size, (int)sizeof(VhostUserLog)); @@ -80066,7 +111998,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } RTE_LOG(INFO, VHOST_CONFIG, -@@ -2102,6 +2146,10 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, +@@ -2102,6 +2178,10 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, msg->fd_num = 0; return RTE_VHOST_MSG_RESULT_REPLY; @@ -80077,7 +112009,7 @@ index 0cfb8b792b..e94fdc70e8 100644 } static int vhost_user_set_log_fd(struct virtio_net **pdev __rte_unused, -@@ -2229,6 +2277,13 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg) +@@ -2229,6 +2309,13 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg) if (ra->used_user_addr < end && (ra->used_user_addr + len) > start) return 1; @@ -80091,7 +112023,7 @@ index 0cfb8b792b..e94fdc70e8 100644 return 0; } -@@ -2254,6 +2309,13 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg) +@@ -2254,6 +2341,13 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg) if (ra->used_user_addr < end && (ra->used_user_addr + len) > start) return 1; @@ -80105,7 +112037,33 @@ index 0cfb8b792b..e94fdc70e8 100644 return 0; } -@@ -2440,8 +2502,13 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg) +@@ -2292,8 +2386,11 @@ vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg, + vhost_user_iotlb_cache_insert(vq, imsg->iova, vva, + len, imsg->perm); + +- if (is_vring_iotlb(dev, vq, imsg)) ++ if (is_vring_iotlb(dev, vq, imsg)) { ++ rte_spinlock_lock(&vq->access_lock); + *pdev = dev = translate_ring_addresses(dev, i); ++ rte_spinlock_unlock(&vq->access_lock); ++ } + } + break; + case VHOST_IOTLB_INVALIDATE: +@@ -2303,8 +2400,11 @@ vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg, + vhost_user_iotlb_cache_remove(vq, imsg->iova, + imsg->size); + +- if (is_vring_iotlb(dev, vq, imsg)) ++ if (is_vring_iotlb(dev, vq, imsg)) { ++ rte_spinlock_lock(&vq->access_lock); + vring_invalidate(dev, vq); ++ rte_spinlock_unlock(&vq->access_lock); ++ } + } + break; + default: +@@ -2440,8 +2540,13 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg) ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE, msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num); @@ -80120,7 +112078,7 @@ index 0cfb8b792b..e94fdc70e8 100644 if (msg->size) { if (msg->size > sizeof(msg->payload)) { -@@ -2508,7 +2575,7 @@ static int +@@ -2508,7 +2613,7 @@ static int vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, struct VhostUserMsg *msg) { @@ -80129,7 +112087,14 @@ index 0cfb8b792b..e94fdc70e8 100644 switch (msg->request.master) { case VHOST_USER_SET_VRING_KICK: -@@ -2524,6 +2591,9 @@ vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, +@@ -2518,12 +2623,16 @@ vhost_user_check_and_alloc_queue_pair(struct virtio_net *dev, + break; + case VHOST_USER_SET_VRING_NUM: + case VHOST_USER_SET_VRING_BASE: ++ case VHOST_USER_GET_VRING_BASE: + case VHOST_USER_SET_VRING_ENABLE: + vring_idx = msg->payload.state.index; + break; case VHOST_USER_SET_VRING_ADDR: vring_idx = msg->payload.addr.index; break; @@ -80139,7 +112104,7 @@ index 0cfb8b792b..e94fdc70e8 100644 default: return 0; } -@@ -2758,7 +2828,7 @@ vhost_user_msg_handler(int vid, int fd) +@@ -2758,7 +2867,7 @@ vhost_user_msg_handler(int vid, int fd) return -1; } @@ -80148,7 +112113,7 @@ index 0cfb8b792b..e94fdc70e8 100644 dev->flags |= VIRTIO_DEV_READY; if (!(dev->flags & VIRTIO_DEV_RUNNING)) { -@@ -2794,11 +2864,19 @@ static int process_slave_message_reply(struct virtio_net *dev, +@@ -2794,11 +2903,19 @@ static int process_slave_message_reply(struct virtio_net *dev, if ((msg->flags & VHOST_USER_NEED_REPLY) == 0) return 0; @@ -80170,10 +112135,18 @@ index 0cfb8b792b..e94fdc70e8 100644 RTE_LOG(ERR, VHOST_CONFIG, "Received unexpected msg type (%u), expected %u\n", diff --git a/dpdk/lib/librte_vhost/virtio_net.c b/dpdk/lib/librte_vhost/virtio_net.c -index 21c311732a..f397e9a13a 100644 +index 21c311732a..af735f9c2b 100644 --- a/dpdk/lib/librte_vhost/virtio_net.c +++ b/dpdk/lib/librte_vhost/virtio_net.c -@@ -43,6 +43,36 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring) +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -43,6 +44,36 @@ is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring) return (is_tx ^ (idx & 1)) == 0 && idx < nr_vring; } @@ -80210,7 +112183,7 @@ index 21c311732a..f397e9a13a 100644 static __rte_always_inline void do_flush_shadow_used_ring_split(struct virtio_net *dev, struct vhost_virtqueue *vq, -@@ -186,6 +216,11 @@ vhost_flush_enqueue_batch_packed(struct virtio_net *dev, +@@ -186,6 +217,11 @@ vhost_flush_enqueue_batch_packed(struct virtio_net *dev, uint16_t i; uint16_t flags; @@ -80222,7 +112195,7 @@ index 21c311732a..f397e9a13a 100644 flags = PACKED_DESC_ENQUEUE_USED_FLAG(vq->used_wrap_counter); vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { -@@ -325,36 +360,6 @@ vhost_shadow_dequeue_single_packed_inorder(struct vhost_virtqueue *vq, +@@ -325,36 +361,6 @@ vhost_shadow_dequeue_single_packed_inorder(struct vhost_virtqueue *vq, vq_inc_last_used_packed(vq, count); } @@ -80259,7 +112232,7 @@ index 21c311732a..f397e9a13a 100644 static __rte_always_inline void vhost_shadow_enqueue_single_packed(struct virtio_net *dev, struct vhost_virtqueue *vq, -@@ -382,25 +387,6 @@ vhost_shadow_enqueue_single_packed(struct virtio_net *dev, +@@ -382,25 +388,6 @@ vhost_shadow_enqueue_single_packed(struct virtio_net *dev, } } @@ -80285,7 +112258,87 @@ index 21c311732a..f397e9a13a 100644 /* avoid write operation when necessary, to lessen cache issues */ #define ASSIGN_UNLESS_EQUAL(var, val) do { \ if ((var) != (val)) \ -@@ -1086,6 +1072,8 @@ virtio_dev_rx_batch_packed(struct virtio_net *dev, +@@ -416,6 +403,16 @@ virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr) + csum_l4 |= PKT_TX_TCP_CKSUM; + + if (csum_l4) { ++ /* ++ * Pseudo-header checksum must be set as per Virtio spec. ++ * ++ * Note: We don't propagate rte_net_intel_cksum_prepare() ++ * errors, as it would have an impact on performance, and an ++ * error would mean the packet is dropped by the guest instead ++ * of being dropped here. ++ */ ++ rte_net_intel_cksum_prepare(m_buf); ++ + net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len; + +@@ -560,10 +557,11 @@ fill_vec_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq, + return -1; + } + +- len += descs[idx].len; ++ dlen = descs[idx].len; ++ len += dlen; + + if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id, +- descs[idx].addr, descs[idx].len, ++ descs[idx].addr, dlen, + perm))) { + free_ind_table(idesc); + return -1; +@@ -680,9 +678,10 @@ fill_vec_buf_packed_indirect(struct virtio_net *dev, + return -1; + } + +- *len += descs[i].len; ++ dlen = descs[i].len; ++ *len += dlen; + if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id, +- descs[i].addr, descs[i].len, ++ descs[i].addr, dlen, + perm))) + return -1; + } +@@ -703,6 +702,7 @@ fill_vec_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq, + bool wrap_counter = vq->avail_wrap_counter; + struct vring_packed_desc *descs = vq->desc_packed; + uint16_t vec_id = *vec_idx; ++ uint64_t dlen; + + if (avail_idx < vq->last_avail_idx) + wrap_counter ^= 1; +@@ -735,11 +735,12 @@ fill_vec_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq, + len, perm) < 0)) + return -1; + } else { +- *len += descs[avail_idx].len; ++ dlen = descs[avail_idx].len; ++ *len += dlen; + + if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id, + descs[avail_idx].addr, +- descs[avail_idx].len, ++ dlen, + perm))) + return -1; + } +@@ -820,9 +821,10 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq, + + hdr_mbuf = m; + hdr_addr = buf_addr; +- if (unlikely(buf_len < dev->vhost_hlen)) ++ if (unlikely(buf_len < dev->vhost_hlen)) { ++ memset(&tmp_hdr, 0, sizeof(struct virtio_net_hdr_mrg_rxbuf)); + hdr = &tmp_hdr; +- else ++ } else + hdr = (struct virtio_net_hdr_mrg_rxbuf *)(uintptr_t)hdr_addr; + + VHOST_LOG_DEBUG(VHOST_DATA, "(%d) RX: num merge buffers %d\n", +@@ -1086,6 +1088,8 @@ virtio_dev_rx_batch_packed(struct virtio_net *dev, VHOST_ACCESS_RW); vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { @@ -80294,7 +112347,89 @@ index 21c311732a..f397e9a13a 100644 if (unlikely(lens[i] != descs[avail_idx + i].len)) return -1; } -@@ -1607,16 +1595,8 @@ virtio_dev_extbuf_alloc(struct rte_mbuf *pkt, uint32_t size) +@@ -1395,26 +1399,22 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint32_t buf_avail, buf_offset; + uint64_t buf_addr, buf_iova, buf_len; + uint32_t mbuf_avail, mbuf_offset; ++ uint32_t hdr_remain = dev->vhost_hlen; + uint32_t cpy_len; + struct rte_mbuf *cur = m, *prev = m; + struct virtio_net_hdr tmp_hdr; + struct virtio_net_hdr *hdr = NULL; +- /* A counter to avoid desc dead loop chain */ +- uint16_t vec_idx = 0; ++ uint16_t vec_idx; + struct batch_copy_elem *batch_copy = vq->batch_copy_elems; + int error = 0; + +- buf_addr = buf_vec[vec_idx].buf_addr; +- buf_iova = buf_vec[vec_idx].buf_iova; +- buf_len = buf_vec[vec_idx].buf_len; +- +- if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) { +- error = -1; +- goto out; +- } ++ /* ++ * The caller has checked the descriptors chain is larger than the ++ * header size. ++ */ + + if (virtio_net_with_host_offload(dev)) { +- if (unlikely(buf_len < sizeof(struct virtio_net_hdr))) { ++ if (unlikely(buf_vec[0].buf_len < sizeof(struct virtio_net_hdr))) { + /* + * No luck, the virtio-net header doesn't fit + * in a contiguous virtual area. +@@ -1422,36 +1422,23 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq, + copy_vnet_hdr_from_desc(&tmp_hdr, buf_vec); + hdr = &tmp_hdr; + } else { +- hdr = (struct virtio_net_hdr *)((uintptr_t)buf_addr); ++ hdr = (struct virtio_net_hdr *)((uintptr_t)buf_vec[0].buf_addr); + } + } + +- /* +- * A virtio driver normally uses at least 2 desc buffers +- * for Tx: the first for storing the header, and others +- * for storing the data. +- */ +- if (unlikely(buf_len < dev->vhost_hlen)) { +- buf_offset = dev->vhost_hlen - buf_len; +- vec_idx++; +- buf_addr = buf_vec[vec_idx].buf_addr; +- buf_iova = buf_vec[vec_idx].buf_iova; +- buf_len = buf_vec[vec_idx].buf_len; +- buf_avail = buf_len - buf_offset; +- } else if (buf_len == dev->vhost_hlen) { +- if (unlikely(++vec_idx >= nr_vec)) +- goto out; +- buf_addr = buf_vec[vec_idx].buf_addr; +- buf_iova = buf_vec[vec_idx].buf_iova; +- buf_len = buf_vec[vec_idx].buf_len; ++ for (vec_idx = 0; vec_idx < nr_vec; vec_idx++) { ++ if (buf_vec[vec_idx].buf_len > hdr_remain) ++ break; + +- buf_offset = 0; +- buf_avail = buf_len; +- } else { +- buf_offset = dev->vhost_hlen; +- buf_avail = buf_vec[vec_idx].buf_len - dev->vhost_hlen; ++ hdr_remain -= buf_vec[vec_idx].buf_len; + } + ++ buf_addr = buf_vec[vec_idx].buf_addr; ++ buf_iova = buf_vec[vec_idx].buf_iova; ++ buf_len = buf_vec[vec_idx].buf_len; ++ buf_offset = hdr_remain; ++ buf_avail = buf_vec[vec_idx].buf_len - hdr_remain; ++ + PRINT_PACKET(dev, + (uintptr_t)(buf_addr + buf_offset), + (uint32_t)buf_avail, 0); +@@ -1607,16 +1594,8 @@ virtio_dev_extbuf_alloc(struct rte_mbuf *pkt, uint32_t size) rte_iova_t iova; void *buf; @@ -80313,7 +112448,7 @@ index 21c311732a..f397e9a13a 100644 if (unlikely(total_len > UINT16_MAX)) return -ENOSPC; -@@ -1627,18 +1607,12 @@ virtio_dev_extbuf_alloc(struct rte_mbuf *pkt, uint32_t size) +@@ -1627,18 +1606,12 @@ virtio_dev_extbuf_alloc(struct rte_mbuf *pkt, uint32_t size) return -ENOMEM; /* Initialize shinfo */ @@ -80338,7 +112473,7 @@ index 21c311732a..f397e9a13a 100644 } iova = rte_malloc_virt2iova(buf); -@@ -1688,6 +1662,8 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -1688,6 +1661,8 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, { uint16_t i; uint16_t free_entries; @@ -80347,9 +112482,18 @@ index 21c311732a..f397e9a13a 100644 if (unlikely(dev->dequeue_zero_copy)) { struct zcopy_mbuf *zmbuf, *next; -@@ -1751,13 +1727,35 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -1750,14 +1725,44 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, + if (likely(dev->dequeue_zero_copy == 0)) update_shadow_used_ring_split(vq, head_idx, 0); ++ if (unlikely(buf_len <= dev->vhost_hlen)) { ++ dropped += 1; ++ i++; ++ break; ++ } ++ ++ buf_len -= dev->vhost_hlen; ++ pkts[i] = virtio_dev_pktmbuf_alloc(dev, mbuf_pool, buf_len); - if (unlikely(pkts[i] == NULL)) + if (unlikely(pkts[i] == NULL)) { @@ -80384,7 +112528,7 @@ index 21c311732a..f397e9a13a 100644 break; } -@@ -1767,6 +1765,8 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -1767,6 +1772,8 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, zmbuf = get_zmbuf(vq); if (!zmbuf) { rte_pktmbuf_free(pkts[i]); @@ -80393,7 +112537,7 @@ index 21c311732a..f397e9a13a 100644 break; } zmbuf->mbuf = pkts[i]; -@@ -1796,7 +1796,7 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, +@@ -1796,7 +1803,7 @@ virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, } } @@ -80402,7 +112546,7 @@ index 21c311732a..f397e9a13a 100644 } static __rte_always_inline int -@@ -1810,7 +1810,6 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, +@@ -1810,7 +1817,6 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, { bool wrap = vq->avail_wrap_counter; struct vring_packed_desc *descs = vq->desc_packed; @@ -80410,7 +112554,7 @@ index 21c311732a..f397e9a13a 100644 uint64_t lens[PACKED_BATCH_SIZE]; uint64_t buf_lens[PACKED_BATCH_SIZE]; uint32_t buf_offset = dev->vhost_hlen; -@@ -1841,6 +1840,8 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, +@@ -1841,6 +1847,8 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, } vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { @@ -80419,7 +112563,13 @@ index 21c311732a..f397e9a13a 100644 if (unlikely((lens[i] != descs[avail_idx + i].len))) return -1; } -@@ -1865,13 +1866,6 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, +@@ -1860,18 +1868,11 @@ vhost_reserve_avail_batch_packed(struct virtio_net *dev, + } + + vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { +- pkts[i]->pkt_len = descs[avail_idx + i].len - buf_offset; ++ pkts[i]->pkt_len = lens[i] - buf_offset; + pkts[i]->data_len = pkts[i]->pkt_len; ids[i] = descs[avail_idx + i].id; } @@ -80433,7 +112583,7 @@ index 21c311732a..f397e9a13a 100644 return 0; free_buf: -@@ -1889,6 +1883,7 @@ virtio_dev_tx_batch_packed(struct virtio_net *dev, +@@ -1889,6 +1890,7 @@ virtio_dev_tx_batch_packed(struct virtio_net *dev, { uint16_t avail_idx = vq->last_avail_idx; uint32_t buf_offset = dev->vhost_hlen; @@ -80441,7 +112591,7 @@ index 21c311732a..f397e9a13a 100644 uintptr_t desc_addrs[PACKED_BATCH_SIZE]; uint16_t ids[PACKED_BATCH_SIZE]; uint16_t i; -@@ -1905,6 +1900,13 @@ virtio_dev_tx_batch_packed(struct virtio_net *dev, +@@ -1905,6 +1907,13 @@ virtio_dev_tx_batch_packed(struct virtio_net *dev, (void *)(uintptr_t)(desc_addrs[i] + buf_offset), pkts[i]->pkt_len); @@ -80455,7 +112605,7 @@ index 21c311732a..f397e9a13a 100644 if (virtio_net_is_inorder(dev)) vhost_shadow_dequeue_batch_packed_inorder(vq, ids[PACKED_BATCH_SIZE - 1]); -@@ -1928,6 +1930,7 @@ vhost_dequeue_single_packed(struct virtio_net *dev, +@@ -1928,6 +1937,7 @@ vhost_dequeue_single_packed(struct virtio_net *dev, uint32_t buf_len; uint16_t nr_vec = 0; int err; @@ -80463,8 +112613,15 @@ index 21c311732a..f397e9a13a 100644 if (unlikely(fill_vec_buf_packed(dev, vq, vq->last_avail_idx, desc_count, -@@ -1938,14 +1941,24 @@ vhost_dequeue_single_packed(struct virtio_net *dev, +@@ -1936,16 +1946,31 @@ vhost_dequeue_single_packed(struct virtio_net *dev, + VHOST_ACCESS_RO) < 0)) + return -1; ++ if (unlikely(buf_len <= dev->vhost_hlen)) ++ return -1; ++ ++ buf_len -= dev->vhost_hlen; ++ *pkts = virtio_dev_pktmbuf_alloc(dev, mbuf_pool, buf_len); if (unlikely(*pkts == NULL)) { - RTE_LOG(ERR, VHOST_DATA, @@ -80490,7 +112647,7 @@ index 21c311732a..f397e9a13a 100644 rte_pktmbuf_free(*pkts); return -1; } -@@ -1960,21 +1973,24 @@ virtio_dev_tx_single_packed(struct virtio_net *dev, +@@ -1960,21 +1985,24 @@ virtio_dev_tx_single_packed(struct virtio_net *dev, struct rte_mbuf **pkts) { @@ -80526,7 +112683,7 @@ index 21c311732a..f397e9a13a 100644 } static __rte_always_inline int -@@ -2004,7 +2020,7 @@ virtio_dev_tx_batch_packed_zmbuf(struct virtio_net *dev, +@@ -2004,7 +2032,7 @@ virtio_dev_tx_batch_packed_zmbuf(struct virtio_net *dev, vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { zmbufs[i]->mbuf = pkts[i]; @@ -80535,7 +112692,7 @@ index 21c311732a..f397e9a13a 100644 zmbufs[i]->desc_count = 1; } -@@ -2045,7 +2061,7 @@ virtio_dev_tx_single_packed_zmbuf(struct virtio_net *dev, +@@ -2045,7 +2073,7 @@ virtio_dev_tx_single_packed_zmbuf(struct virtio_net *dev, return -1; } zmbuf->mbuf = *pkts; @@ -80544,7 +112701,7 @@ index 21c311732a..f397e9a13a 100644 zmbuf->desc_count = desc_count; rte_mbuf_refcnt_update(*pkts, 1); -@@ -2149,7 +2165,6 @@ virtio_dev_tx_packed(struct virtio_net *dev, +@@ -2149,7 +2177,6 @@ virtio_dev_tx_packed(struct virtio_net *dev, if (remained >= PACKED_BATCH_SIZE) { if (!virtio_dev_tx_batch_packed(dev, vq, mbuf_pool, &pkts[pkt_idx])) { @@ -80552,7 +112709,7 @@ index 21c311732a..f397e9a13a 100644 pkt_idx += PACKED_BATCH_SIZE; remained -= PACKED_BATCH_SIZE; continue; -@@ -2159,15 +2174,18 @@ virtio_dev_tx_packed(struct virtio_net *dev, +@@ -2159,15 +2186,18 @@ virtio_dev_tx_packed(struct virtio_net *dev, if (virtio_dev_tx_single_packed(dev, vq, mbuf_pool, &pkts[pkt_idx])) break; @@ -80574,18 +112731,9 @@ index 21c311732a..f397e9a13a 100644 } diff --git a/dpdk/lib/meson.build b/dpdk/lib/meson.build -index 6ceb5e756e..b60396428c 100644 +index 6ceb5e756e..f8da4f3168 100644 --- a/dpdk/lib/meson.build +++ b/dpdk/lib/meson.build -@@ -127,7 +127,7 @@ foreach l:libraries - dependencies: static_deps, - include_directories: includes, - install: true) -- static_dep = declare_dependency(link_with: static_lib, -+ static_dep = declare_dependency( - include_directories: includes, - dependencies: static_deps) - @@ -148,12 +148,18 @@ foreach l:libraries command: [map_to_def_cmd, '@INPUT@', '@OUTPUT@'], input: version_map, @@ -80609,6 +112757,27 @@ index 6ceb5e756e..b60396428c 100644 # on unix systems check the output of the # experimental syms script, using it as a # dependency of the .so build +diff --git a/dpdk/license/README b/dpdk/license/README +index 874abaf4cd..79dac86440 100644 +--- a/dpdk/license/README ++++ b/dpdk/license/README +@@ -49,7 +49,7 @@ with SPDX-License-Identifiers. + Any exception to the DPDK IP policies shall be approved by DPDK Tech Board and + DPDK Governing Board. Steps for any exception approval: + 1. Mention the appropriate license identifier form SPDX. If the license is not +- listed in SPDX Licenses. It is the submitters responsibiliity to get it ++ listed in SPDX Licenses. It is the submitters responsibility to get it + first listed. + 2. Get the required approval from the DPDK Technical Board. Technical Board may + advise the author to check alternate means first. If no other alternative +@@ -72,6 +72,6 @@ DPDK project supported licenses are: + URL: http://spdx.org/licenses/GPL-2.0.html#licenseText + DPDK License text: licenses/gpl-2.0.txt + 3. GNU Lesser General Public License v2.1 +- SPDX-License-Identifieri: LGPL-2.1 ++ SPDX-License-Identifier: LGPL-2.1 + URL: http://spdx.org/licenses/LGPL-2.1.html#licenseText + DPDK License text: licenses/lgpl-2.1.txt diff --git a/dpdk/license/bsd-2-clause.txt b/dpdk/license/bsd-2-clause.txt new file mode 100644 index 0000000000..dfb3f1adea @@ -80677,51 +112846,60 @@ index 0000000000..c4037a4605 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dpdk/meson.build b/dpdk/meson.build -index b7ae9c8d9a..00949de995 100644 +index b7ae9c8d9a..94f51a8c6c 100644 --- a/dpdk/meson.build +++ b/dpdk/meson.build -@@ -48,6 +48,9 @@ subdir('doc') +@@ -4,15 +4,21 @@ + project('DPDK', 'C', + # Get version number from file. + # Fallback to "more" for Windows compatibility. +- version: run_command(find_program('cat', 'more'), +- files('VERSION')).stdout().strip(), ++ version: run_command(find_program('cat', 'more'), files('VERSION'), ++ check: true).stdout().strip(), + license: 'BSD', +- default_options: ['buildtype=release', 'default_library=static'], ++ default_options: [ ++ 'buildtype=release', ++ 'default_library=static', ++ 'warning_level=2', ++ ], + meson_version: '>= 0.47.1' + ) + + # set up some global vars for compiler, platform, configuration, etc. + cc = meson.get_compiler('c') ++dpdk_source_root = meson.current_source_dir() ++dpdk_build_root = meson.current_build_dir() + dpdk_conf = configuration_data() + dpdk_libraries = [] + dpdk_static_libraries = [] +@@ -48,6 +54,9 @@ subdir('doc') # build any examples explicitly requested - useful for developers - and # install any example code into the appropriate install path subdir('examples') +install_subdir('examples', + install_dir: get_option('datadir') + '/dpdk', -+ exclude_files: 'meson.build') ++ exclude_files: ex_file_excludes) # build kernel modules if enabled if get_option('enable_kmods') -@@ -61,29 +64,8 @@ configure_file(output: build_cfg, +@@ -61,9 +70,14 @@ configure_file(output: build_cfg, install_dir: join_paths(get_option('includedir'), get_option('include_subdir_arch'))) --# for static builds, include the drivers as libs and we need to "whole-archive" --# them. ++platform_flags = [] ++if not is_windows ++ platform_flags += ['-Wl,--export-dynamic'] # ELF only ++endif ++ + # for static builds, include the drivers as libs and we need to "whole-archive" + # them. -dpdk_drivers = ['-Wl,--whole-archive'] + dpdk_drivers + ['-Wl,--no-whole-archive'] -- --pkg = import('pkgconfig') --pkg_extra_cflags = ['-include', 'rte_config.h'] + machine_args --if is_freebsd -- pkg_extra_cflags += ['-D__BSD_VISIBLE'] --endif --pkg.generate(name: meson.project_name(), -- filebase: 'lib' + meson.project_name().to_lower(), -- version: meson.project_version(), -- libraries: dpdk_libraries, -- libraries_private: dpdk_drivers + dpdk_static_libraries + -- ['-Wl,-Bdynamic'] + dpdk_extra_ldflags, -- requires: libbsd, # apps using rte_string_fns.h may need this if enabled -- # if libbsd is not enabled, then this is blank -- description: '''The Data Plane Development Kit (DPDK). --Note that CFLAGS might contain an -march flag higher than typical baseline. --This is required for a number of static inline functions in the public headers.''', -- subdirs: [get_option('include_subdir_arch'), '.'], -- extra_cflags: pkg_extra_cflags --) -+# build pkg-config files for dpdk -+subdir('buildtools/pkg-config') - - # final output, list all the libs and drivers to be built - # this does not affect any part of the build, for information only. ++dpdk_drivers = ['-Wl,--whole-archive'] + dpdk_drivers + ['-Wl,--no-whole-archive'] + platform_flags + + pkg = import('pkgconfig') + pkg_extra_cflags = ['-include', 'rte_config.h'] + machine_args diff --git a/dpdk/meson_options.txt b/dpdk/meson_options.txt index bc369d06c9..0de16b4fdb 100644 --- a/dpdk/meson_options.txt @@ -88944,10 +121122,80 @@ index add3aabcc2..391d6d8f7c 100644 AC_DEFUN([OVS_CHECK_WIN64], [AC_CACHE_CHECK( diff --git a/ofproto/bond.c b/ofproto/bond.c -index 405202fb64..54e06211a6 100644 +index 405202fb64..89d9013038 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c -@@ -1165,7 +1165,7 @@ insert_bal(struct ovs_list *bals, struct bond_slave *slave) +@@ -185,9 +185,13 @@ static struct bond_slave *choose_output_slave(const struct bond *, + struct flow_wildcards *, + uint16_t vlan) + OVS_REQ_RDLOCK(rwlock); +-static void update_recirc_rules__(struct bond *bond); ++static void update_recirc_rules__(struct bond *); ++static bool bond_may_recirc(const struct bond *); ++static void bond_update_post_recirc_rules__(struct bond *, bool force) ++ OVS_REQ_WRLOCK(rwlock); + static bool bond_is_falling_back_to_ab(const struct bond *); + ++ + /* Attempts to parse 's' as the name of a bond balancing mode. If successful, + * stores the mode in '*balance' and returns true. Otherwise returns false + * without modifying '*balance'. */ +@@ -472,6 +476,12 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s) + bond_entry_reset(bond); + } + ++ if (bond->ofproto->backer->rt_support.odp.recirc ++ && bond_may_recirc(bond)) { ++ /* Update rules to reflect possible recirc_id changes. */ ++ update_recirc_rules(bond); ++ } ++ + ovs_rwlock_unlock(&rwlock); + return revalidate; + } +@@ -667,6 +677,12 @@ bond_run(struct bond *bond, enum lacp_status lacp_status) + bond_choose_active_slave(bond); + } + ++ if (bond->ofproto->backer->rt_support.odp.recirc ++ && bond_may_recirc(bond)) { ++ /* Update rules to reflect possible link state changes. */ ++ bond_update_post_recirc_rules__(bond, false); ++ } ++ + revalidate = bond->bond_revalidate; + bond->bond_revalidate = false; + ovs_rwlock_unlock(&rwlock); +@@ -968,7 +984,7 @@ bond_may_recirc(const struct bond *bond) + } + + static void +-bond_update_post_recirc_rules__(struct bond* bond, const bool force) ++bond_update_post_recirc_rules__(struct bond* bond, bool force) + OVS_REQ_WRLOCK(rwlock) + { + struct bond_entry *e; +@@ -1016,6 +1032,19 @@ bond_update_post_recirc_rules(struct bond *bond, uint32_t *recirc_id, + } + } + ++void ++bond_get_recirc_id_and_hash_basis(struct bond *bond, uint32_t *recirc_id, ++ uint32_t *hash_basis) ++{ ++ ovs_rwlock_rdlock(&rwlock); ++ if (bond_may_recirc(bond)) { ++ *recirc_id = bond->recirc_id; ++ *hash_basis = bond->basis; ++ } else { ++ *recirc_id = *hash_basis = 0; ++ } ++ ovs_rwlock_unlock(&rwlock); ++} + + /* Rebalancing. */ + +@@ -1165,7 +1194,7 @@ insert_bal(struct ovs_list *bals, struct bond_slave *slave) break; } } @@ -88956,6 +121204,19 @@ index 405202fb64..54e06211a6 100644 } /* Removes 'slave' from its current list and then inserts it into 'bals' so +diff --git a/ofproto/bond.h b/ofproto/bond.h +index e7c3d9bc35..aa7ffde76f 100644 +--- a/ofproto/bond.h ++++ b/ofproto/bond.h +@@ -122,4 +122,8 @@ void bond_rebalance(struct bond *); + */ + void bond_update_post_recirc_rules(struct bond *, uint32_t *recirc_id, + uint32_t *hash_basis); ++ ++void bond_get_recirc_id_and_hash_basis(struct bond *, uint32_t *recirc_id, ++ uint32_t *hash_basis); ++ + #endif /* bond.h */ diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 51d656cba9..fd926cbb82 100644 --- a/ofproto/connmgr.c @@ -89302,10 +121563,32 @@ index f9ea47a2f1..2f0d3795b5 100644 /* Build a flow sample. */ memset(&fs, 0, sizeof fs); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 409286ab15..61d5cf9782 100644 +index 409286ab15..ac257d0e43 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c -@@ -1093,7 +1093,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout, +@@ -360,6 +360,10 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux); + static void upcall_unixctl_purge(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux); ++static void upcall_unixctl_pause(struct unixctl_conn *conn, int argc, ++ const char *argv[], void *aux); ++static void upcall_unixctl_resume(struct unixctl_conn *conn, int argc, ++ const char *argv[], void *aux); + + static struct udpif_key *ukey_create_from_upcall(struct upcall *, + struct flow_wildcards *); +@@ -432,6 +436,10 @@ udpif_init(void) + upcall_unixctl_dump_wait, NULL); + unixctl_command_register("revalidator/purge", "", 0, 0, + upcall_unixctl_purge, NULL); ++ unixctl_command_register("revalidator/pause", NULL, 0, 0, ++ upcall_unixctl_pause, NULL); ++ unixctl_command_register("revalidator/resume", NULL, 0, 0, ++ upcall_unixctl_resume, NULL); + ovsthread_once_done(&once); + } + } +@@ -1093,7 +1101,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout, } odp_put_userspace_action(pid, &cookie, sizeof cookie, @@ -89314,7 +121597,7 @@ index 409286ab15..61d5cf9782 100644 if (meter_id != UINT32_MAX) { nl_msg_end_nested(buf, ac_offset); -@@ -1545,7 +1545,8 @@ process_upcall(struct udpif *udpif, struct upcall *upcall, +@@ -1545,7 +1553,8 @@ process_upcall(struct udpif *udpif, struct upcall *upcall, flow_clear_conntrack(&frozen_flow); } @@ -89324,7 +121607,7 @@ index 409286ab15..61d5cf9782 100644 flow_get_metadata(&frozen_flow, &am->pin.up.base.flow_metadata); ofproto_dpif_send_async_msg(upcall->ofproto, am); -@@ -2888,11 +2889,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, +@@ -2888,11 +2897,11 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, } ds_put_char(&ds, '\n'); @@ -89338,6 +121621,38 @@ index 409286ab15..61d5cf9782 100644 elements += cmap_count(&udpif->ukeys[j].cmap); } ds_put_format(&ds, " %u: (keys %d)\n", revalidator->id, elements); +@@ -3016,6 +3025,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED, + unixctl_command_reply(conn, ""); + } + ++static void ++upcall_unixctl_pause(struct unixctl_conn *conn, int argc OVS_UNUSED, ++ const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) ++{ ++ struct udpif *udpif; ++ ++ LIST_FOR_EACH (udpif, list_node, &all_udpifs) { ++ udpif_pause_revalidators(udpif); ++ } ++ unixctl_command_reply(conn, ""); ++} ++ ++static void ++upcall_unixctl_resume(struct unixctl_conn *conn, int argc OVS_UNUSED, ++ const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) ++{ ++ struct udpif *udpif; ++ ++ LIST_FOR_EACH (udpif, list_node, &all_udpifs) { ++ udpif_resume_revalidators(udpif); ++ } ++ unixctl_command_reply(conn, ""); ++} ++ ++ + /* Flows are sorted in the following order: + * netdev, flow state (offloaded/kernel path), flow_pps_rate. + */ diff --git a/ofproto/ofproto-dpif-xlate-cache.c b/ofproto/ofproto-dpif-xlate-cache.c index dcc91cb380..9224ee2e6d 100644 --- a/ofproto/ofproto-dpif-xlate-cache.c @@ -89375,7 +121690,7 @@ index 114aff8ea3..0fc6d2ea60 100644 enum xc_type type; union { diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c -index 4407f9c97a..3c4ad52c88 100644 +index 4407f9c97a..477e0ef85f 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -460,7 +460,7 @@ static void xlate_commit_actions(struct xlate_ctx *ctx); @@ -89484,7 +121799,29 @@ index 4407f9c97a..3c4ad52c88 100644 /* If this mirror selects on the basis of VLAN, and it does not select -@@ -2991,7 +3030,7 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -2420,9 +2459,18 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, + /* In case recirculation is not actually in use, 'xr.recirc_id' + * will be set to '0', since a valid 'recirc_id' can + * not be zero. */ +- bond_update_post_recirc_rules(out_xbundle->bond, +- &xr.recirc_id, +- &xr.hash_basis); ++ if (ctx->xin->allow_side_effects) { ++ bond_update_post_recirc_rules(out_xbundle->bond, ++ &xr.recirc_id, ++ &xr.hash_basis); ++ } else { ++ /* If side effects are not allowed, only getting the bond ++ * configuration. Rule updates will be handled by the ++ * main thread later. */ ++ bond_get_recirc_id_and_hash_basis(out_xbundle->bond, ++ &xr.recirc_id, ++ &xr.hash_basis); ++ } + if (xr.recirc_id) { + /* Use recirculation instead of output. */ + use_recirc = true; +@@ -2991,7 +3039,7 @@ xlate_normal(struct xlate_ctx *ctx) bool is_grat_arp = is_gratuitous_arp(flow, wc); if (ctx->xin->allow_side_effects && flow->packet_type == htonl(PT_ETH) @@ -89493,7 +121830,7 @@ index 4407f9c97a..3c4ad52c88 100644 ) { update_learning_table(ctx, in_xbundle, flow->dl_src, vlan, is_grat_arp); -@@ -3000,12 +3039,14 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3000,12 +3048,14 @@ xlate_normal(struct xlate_ctx *ctx) struct xc_entry *entry; /* Save just enough info to update mac learning table later. */ @@ -89514,7 +121851,7 @@ index 4407f9c97a..3c4ad52c88 100644 } /* Determine output bundle. */ -@@ -3024,7 +3065,6 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3024,7 +3074,6 @@ xlate_normal(struct xlate_ctx *ctx) */ ctx->xout->slow |= SLOW_ACTION; @@ -89522,7 +121859,7 @@ index 4407f9c97a..3c4ad52c88 100644 if (mcast_snooping_is_membership(flow->tp_src) || mcast_snooping_is_query(flow->tp_src)) { if (ctx->xin->allow_side_effects && ctx->xin->packet) { -@@ -3076,6 +3116,7 @@ xlate_normal(struct xlate_ctx *ctx) +@@ -3076,6 +3125,7 @@ xlate_normal(struct xlate_ctx *ctx) xlate_report(ctx, OFT_DETAIL, "MLD query, flooding"); xlate_normal_flood(ctx, in_xbundle, &xvlan); } @@ -89530,7 +121867,7 @@ index 4407f9c97a..3c4ad52c88 100644 } else { if (is_ip_local_multicast(flow, wc)) { /* RFC4541: section 2.1.2, item 2: Packets with a dst IP -@@ -3198,12 +3239,11 @@ compose_sample_action(struct xlate_ctx *ctx, +@@ -3198,12 +3248,11 @@ compose_sample_action(struct xlate_ctx *ctx, odp_port_t odp_port = ofp_port_to_odp_port( ctx->xbridge, ctx->xin->flow.in_port.ofp_port); uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); @@ -89548,7 +121885,7 @@ index 4407f9c97a..3c4ad52c88 100644 if (is_sample) { nl_msg_end_nested(ctx->odp_actions, actions_offset); nl_msg_end_nested(ctx->odp_actions, sample_offset); -@@ -3248,7 +3288,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) +@@ -3248,7 +3297,9 @@ compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port) struct dpif_ipfix *ipfix = ctx->xbridge->ipfix; odp_port_t tunnel_out_port = ODPP_NONE; @@ -89559,7 +121896,7 @@ index 4407f9c97a..3c4ad52c88 100644 return; } -@@ -3497,6 +3539,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, +@@ -3497,6 +3548,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow, dst_flow->dl_dst = dmac; dst_flow->dl_src = smac; @@ -89569,7 +121906,7 @@ index 4407f9c97a..3c4ad52c88 100644 dst_flow->packet_type = htonl(PT_ETH); dst_flow->nw_dst = src_flow->tunnel.ip_dst; dst_flow->nw_src = src_flow->tunnel.ip_src; -@@ -3572,7 +3617,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac, +@@ -3572,7 +3626,7 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac, static int native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, const struct flow *flow, odp_port_t tunnel_odp_port, @@ -89578,7 +121915,7 @@ index 4407f9c97a..3c4ad52c88 100644 { struct netdev_tnl_build_header_params tnl_params; struct ovs_action_push_tnl tnl_push_data; -@@ -3702,7 +3747,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, +@@ -3702,7 +3756,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, entry->tunnel_hdr.hdr_size = tnl_push_data.header_len; entry->tunnel_hdr.operation = ADD; @@ -89587,7 +121924,7 @@ index 4407f9c97a..3c4ad52c88 100644 /* Similar to the stats update in revalidation, the x_cache entries * are populated by the previous translation are used to update the -@@ -3796,7 +3841,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co +@@ -3796,7 +3850,7 @@ xlate_flow_is_protected(const struct xlate_ctx *ctx, const struct flow *flow, co */ static void patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, @@ -89596,7 +121933,7 @@ index 4407f9c97a..3c4ad52c88 100644 { struct flow *flow = &ctx->xin->flow; struct flow old_flow = ctx->xin->flow; -@@ -3838,8 +3883,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3838,8 +3892,9 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, if (!process_special(ctx, out_dev) && may_receive(out_dev, ctx)) { if (xport_stp_forward_state(out_dev) && xport_rstp_forward_state(out_dev)) { @@ -89607,7 +121944,7 @@ index 4407f9c97a..3c4ad52c88 100644 if (!ctx->freezing) { xlate_action_set(ctx); } -@@ -3854,7 +3900,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, +@@ -3854,7 +3909,7 @@ patch_port_output(struct xlate_ctx *ctx, const struct xport *in_dev, mirror_mask_t old_mirrors2 = ctx->mirrors; xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true, @@ -89616,7 +121953,7 @@ index 4407f9c97a..3c4ad52c88 100644 ctx->mirrors = old_mirrors2; ctx->base_flow = old_base_flow; ctx->odp_actions->size = old_size; -@@ -4071,7 +4117,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4071,7 +4126,21 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, (flow->dl_type == htons(ETH_TYPE_ARP) || flow->nw_proto == IPPROTO_ICMPV6) && is_neighbor_reply_correct(ctx, flow)) { @@ -89639,7 +121976,7 @@ index 4407f9c97a..3c4ad52c88 100644 } } -@@ -4081,7 +4141,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, +@@ -4081,7 +4150,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, struct flow *flow, static void compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, const struct xlate_bond_recirc *xr, bool check_stp, @@ -89648,7 +121985,7 @@ index 4407f9c97a..3c4ad52c88 100644 { const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port); struct flow_wildcards *wc = ctx->wc; -@@ -4111,6 +4171,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4111,6 +4180,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (xport->pt_mode == NETDEV_PT_LEGACY_L3) { flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE, ntohs(flow->dl_type)); @@ -89659,7 +121996,7 @@ index 4407f9c97a..3c4ad52c88 100644 } } -@@ -4118,7 +4182,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4118,7 +4191,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (truncate) { xlate_report_error(ctx, "Cannot truncate output to patch port"); } @@ -89668,7 +122005,7 @@ index 4407f9c97a..3c4ad52c88 100644 return; } -@@ -4203,7 +4267,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, +@@ -4203,7 +4276,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, xr->recirc_id); } else if (is_native_tunnel) { /* Output to native tunnel port. */ @@ -89678,7 +122015,7 @@ index 4407f9c97a..3c4ad52c88 100644 flow->tunnel = flow_tnl; /* Restore tunnel metadata */ } else if (terminate_native_tunnel(ctx, flow, wc, -@@ -4796,7 +4861,7 @@ put_controller_user_action(struct xlate_ctx *ctx, +@@ -4796,7 +4870,7 @@ put_controller_user_action(struct xlate_ctx *ctx, ctx->xin->flow.in_port.ofp_port); uint32_t pid = dpif_port_get_pid(ctx->xbridge->dpif, odp_port); odp_put_userspace_action(pid, &cookie, sizeof cookie, ODPP_NONE, @@ -89687,7 +122024,7 @@ index 4407f9c97a..3c4ad52c88 100644 } static void -@@ -6123,11 +6188,32 @@ static void +@@ -6123,11 +6197,32 @@ static void compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, bool is_last_action) { @@ -89723,7 +122060,7 @@ index 4407f9c97a..3c4ad52c88 100644 /* Ensure that any prior actions are applied before composing the new * conntrack action. */ xlate_commit_actions(ctx); -@@ -6139,11 +6225,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, +@@ -6139,11 +6234,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, do_xlate_actions(ofc->actions, ofpact_ct_get_action_len(ofc), ctx, is_last_action, false); @@ -89735,7 +122072,7 @@ index 4407f9c97a..3c4ad52c88 100644 ct_offset = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CT); if (ofc->flags & NX_CT_F_COMMIT) { -@@ -6278,6 +6359,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6278,6 +6368,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, * then ctx->exit would be true. Reset to false so that we can * do flow translation for 'IF_LESS_EQUAL' case. finish_freezing() * would have taken care of Undoing the changes done for freeze. */ @@ -89743,7 +122080,7 @@ index 4407f9c97a..3c4ad52c88 100644 ctx->exit = false; offset_attr = nl_msg_start_nested( -@@ -6302,7 +6384,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, +@@ -6302,7 +6393,7 @@ xlate_check_pkt_larger(struct xlate_ctx *ctx, ctx->was_mpls = old_was_mpls; ctx->conntracked = old_conntracked; ctx->xin->flow = old_flow; @@ -89752,7 +122089,7 @@ index 4407f9c97a..3c4ad52c88 100644 } static void -@@ -6680,13 +6762,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6680,13 +6771,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, return; } @@ -89768,7 +122105,7 @@ index 4407f9c97a..3c4ad52c88 100644 if (ctx->error) { break; -@@ -6694,7 +6777,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -6694,7 +6786,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, recirc_for_mpls(a, ctx); @@ -89777,7 +122114,7 @@ index 4407f9c97a..3c4ad52c88 100644 /* Check if need to store the remaining actions for later * execution. */ if (ctx->freezing) { -@@ -7067,7 +7150,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7067,7 +7159,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CT_CLEAR: @@ -89788,7 +122125,7 @@ index 4407f9c97a..3c4ad52c88 100644 break; case OFPACT_NAT: -@@ -7085,17 +7170,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, +@@ -7085,17 +7179,18 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_CHECK_PKT_LARGER: { @@ -89812,7 +122149,7 @@ index 4407f9c97a..3c4ad52c88 100644 break; } } -@@ -7519,7 +7605,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7519,7 +7614,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) /* Restore pipeline metadata. May change flow's in_port and other * metadata to the values that existed when freezing was triggered. */ @@ -89822,7 +122159,7 @@ index 4407f9c97a..3c4ad52c88 100644 /* Restore stack, if any. */ if (state->stack) { -@@ -7557,6 +7644,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7557,6 +7653,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -89835,7 +122172,7 @@ index 4407f9c97a..3c4ad52c88 100644 /* Tunnel metadata in udpif format must be normalized before translation. */ if (flow->tunnel.flags & FLOW_TNL_F_UDPIF) { const struct tun_table *tun_tab = ofproto_get_tun_tab( -@@ -7571,14 +7664,10 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7571,14 +7673,10 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) ctx.error = XLATE_INVALID_TUNNEL_METADATA; goto exit; } @@ -91970,7 +124307,7 @@ index 8aec6bbac1..ba55566926 100644 from collections import Sequence, MutableSequence from functools import wraps diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py -index 020291d486..5a17cbd001 100644 +index 020291d486..829a12998b 100644 --- a/python/ovs/db/idl.py +++ b/python/ovs/db/idl.py @@ -12,6 +12,7 @@ @@ -92160,7 +124497,17 @@ index 020291d486..5a17cbd001 100644 def __check_server_db(self): """Returns True if this is a valid server database, False otherwise.""" -@@ -1458,6 +1470,11 @@ class Transaction(object): +@@ -999,7 +1011,8 @@ class Row(object): + return "{table}({data})".format( + table=self._table.name, + data=", ".join("{col}={val}".format(col=c, val=getattr(self, c)) +- for c in sorted(self._table.columns))) ++ for c in sorted(self._table.columns) ++ if hasattr(self, c))) + + def __getattr__(self, column_name): + assert self._changes is not None +@@ -1458,6 +1471,11 @@ class Transaction(object): if self != self.idl.txn: return self._status @@ -92172,7 +124519,7 @@ index 020291d486..5a17cbd001 100644 # If we need a lock but don't have it, give up quickly. if self.idl.lock_name and not self.idl.has_lock: self._status = Transaction.NOT_LOCKED -@@ -1567,10 +1584,9 @@ class Transaction(object): +@@ -1567,10 +1585,9 @@ class Transaction(object): for col, val in row._mutations['_inserts'].items(): column = row._table.columns[col] if column.type.is_map(): @@ -93239,10 +125586,107 @@ index 4893280a99..a0487341c9 100644 bad_action 'fin_timeout(foo=bar)' "invalid key 'foo' in 'fin_timeout' argument" diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index ff1cc93707..272fef8009 100644 +index ff1cc93707..c23f1ba891 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at -@@ -4534,6 +4534,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr +@@ -119,6 +119,22 @@ AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3]) + OVS_VSWITCHD_STOP + AT_CLEANUP + ++# SEND_TCP_BOND_PKTS([p_name], [p_ofport], [packet_len]) ++# ++# Sends 256 packets to port 'p_name' with different TCP destination ports. ++m4_define([SEND_TCP_BOND_PKTS], ++ [ ++ len_cmd="" ++ if test -n "$3"; then ++ len_cmd=" --len $3" ++ fi ++ for i in `seq 0 255`; do ++ pkt="in_port($2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:01:00),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=$i),tcp_flags(ack)" ++ ovs-appctl netdev-dummy/receive $1 $pkt$len_cmd ++ done ++ ] ++) ++ + AT_SETUP([ofproto-dpif - balance-tcp bonding]) + # Create br0 with interfaces bond0(p1, p2, p3) and p7, + # and br1 with interfaces bond1(p4, p5, p6) and p8. +@@ -171,6 +187,73 @@ AT_CHECK([test `grep in_port.6 br1_flows.txt |wc -l` -gt 24]) + OVS_VSWITCHD_STOP() + AT_CLEANUP + ++dnl Regression test for a deadlock / double lock on post-recirculation rule ++dnl updates while processing PACKET_OUT. ++AT_SETUP([ofproto-dpif - balance-tcp bonding rule updates on packet-out]) ++dnl Create br0 with interfaces bond0(p1, p2) and p5, ++dnl and br1 with interfaces bond1(p3, p4) and p6. ++dnl bond0 <-> bond1 ++OVS_VSWITCHD_START( ++ [add-bond br0 bond0 p1 p2 bond_mode=balance-tcp lacp=active dnl ++ other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 -- dnl ++ set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 mtu_request=65535 -- dnl ++ set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 mtu_request=65535 -- dnl ++ add-port br0 p5 -- set interface p5 ofport_request=5 type=dummy mtu_request=65535 -- dnl ++ add-br br1 -- dnl ++ set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- dnl ++ set bridge br1 datapath-type=dummy other-config:datapath-id=1234 dnl ++ fail-mode=secure -- dnl ++ add-bond br1 bond1 p3 p4 bond_mode=balance-tcp lacp=active dnl ++ other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 -- dnl ++ set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 mtu_request=65535 -- dnl ++ set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 mtu_request=65535 -- dnl ++ add-port br1 p6 -- set interface p6 ofport_request=6 type=dummy mtu_request=65535 --]) ++AT_CHECK([ovs-appctl vlog/set bond:dbg]) ++AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK ++]) ++AT_CHECK([ovs-ofctl add-flow br0 action=normal]) ++AT_CHECK([ovs-ofctl add-flow br1 action=normal]) ++OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"]) ++ ++ovs-appctl time/stop ++ovs-appctl time/warp 2000 200 ++ ++dnl Send some traffic to distribute all the hashes between ports. ++AT_CHECK([SEND_TCP_BOND_PKTS([p5], [5], [65500])]) ++ ++dnl Wait for rebalancing for per-hash stats accounting. ++ovs-appctl time/warp 1000 100 ++ ++dnl Check that p2 handles some hashes. ++ovs-appctl bond/show > bond1.txt ++AT_CHECK([sed -n '/slave p2/,/^$/p' bond1.txt | grep 'hash'], [0], [ignore]) ++ ++dnl Pause revalidators to be sure that they do not update flows while ++dnl the bonding configuration chnages. ++ovs-appctl revalidator/pause ++ ++dnl Move p2 down to trigger update of bonding post-recirculation rules by ++dnl forcing move of all the hashes to p1. ++AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 down], 0, [OK ++]) ++ ++dnl Send PACKET_OUT that may lead to flow updates since the bonding ++dnl configuration changed. ++packet=ffffffffffff00102030405008004500001c00000000401100000a000002ffffffff0035111100080000 ++AT_CHECK([ovs-ofctl packet-out br0 "in_port=p5 packet=$packet actions=resubmit(,0)"]) ++ ++dnl Resume revalidators. ++ovs-appctl revalidator/resume ++ovs-appctl revalidator/wait ++ ++ovs-appctl time/warp 200 100 ++dnl Check that all hashes moved form p2 and OVS is still working. ++ovs-appctl bond/show > bond2.txt ++AT_CHECK([sed -n '/slave p2/,/^$/p' bond2.txt | grep 'hash'], [1], [ignore]) ++ ++OVS_VSWITCHD_STOP() ++AT_CLEANUP ++ + # Makes sure recirculation does not change the way packet is handled. + AT_SETUP([ofproto-dpif - balance-tcp bonding, different recirc flow ]) + OVS_VSWITCHD_START( +@@ -4534,6 +4617,54 @@ recirc_id(0),in_port(90),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=6,fr OVS_VSWITCHD_STOP AT_CLEANUP @@ -93297,7 +125741,7 @@ index ff1cc93707..272fef8009 100644 AT_SETUP([ofproto-dpif - exit]) OVS_VSWITCHD_START add_of_ports br0 1 2 3 10 11 12 13 14 -@@ -5171,6 +5219,65 @@ AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 2 +@@ -5171,6 +5302,65 @@ AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 2 OVS_VSWITCHD_STOP AT_CLEANUP @@ -93363,7 +125807,7 @@ index ff1cc93707..272fef8009 100644 AT_SETUP([ofproto-dpif - debug_slow action]) OVS_VSWITCHD_START -@@ -7067,13 +7174,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the +@@ -7067,13 +7257,28 @@ dnl configure bridge IPFIX and ensure that sample action generation works at the dnl datapath level. AT_SETUP([ofproto-dpif - Bridge IPFIX sanity check]) OVS_VSWITCHD_START @@ -93394,7 +125838,7 @@ index ff1cc93707..272fef8009 100644 dnl Send some packets that should be sampled. for i in `seq 1 3`; do AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800)']) -@@ -7083,6 +7205,28 @@ flow-dump from the main thread: +@@ -7083,6 +7288,28 @@ flow-dump from the main thread: packets:2, bytes:68, used:0.001s, actions:userspace(pid=0,ipfix(output_port=4294967295)) ]) @@ -93423,7 +125867,7 @@ index ff1cc93707..272fef8009 100644 AT_CHECK([ovs-appctl revalidator/purge]) dnl dnl Add a slowpath meter. The userspace action should be metered. -@@ -8134,6 +8278,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout], +@@ -8134,6 +8361,34 @@ AT_CHECK([sed -n 's/=[[0-9]][[0-9]]\(\.[[0-9]][[0-9]]*\)\{0,1\}s/=?s/p' stdout], OVS_VSWITCHD_STOP AT_CLEANUP @@ -93458,7 +125902,7 @@ index ff1cc93707..272fef8009 100644 dnl ---------------------------------------------------------------------- AT_BANNER([ofproto-dpif -- megaflows]) -@@ -8632,6 +8804,29 @@ recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth(dst=50:54:00:00:00:0c),eth_ty +@@ -8632,6 +8887,29 @@ recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth(dst=50:54:00:00:00:0c),eth_ty OVS_VSWITCHD_STOP AT_CLEANUP @@ -93488,7 +125932,7 @@ index ff1cc93707..272fef8009 100644 m4_define([OFPROTO_DPIF_MEGAFLOW_DISABLED], [AT_SETUP([ofproto-dpif megaflow - disabled$1]) OVS_VSWITCHD_START([], [], [], [m4_if([$1], [], [], [--dummy-numa="0,0,0,0,1,1,1,1"])]) -@@ -9215,6 +9410,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): +@@ -9215,6 +9493,26 @@ OFPST_TABLE reply (OF1.3) (xid=0x2): OVS_VSWITCHD_STOP AT_CLEANUP @@ -93515,7 +125959,7 @@ index ff1cc93707..272fef8009 100644 AT_SETUP([ofproto-dpif - ICMPv6]) OVS_VSWITCHD_START add_of_ports br0 1 -@@ -10537,6 +10752,87 @@ dnl +@@ -10537,6 +10835,87 @@ dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=2 (via action) data_len=106 (unbuffered) udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1 udp_csum:553 ]) @@ -93603,7 +126047,7 @@ index ff1cc93707..272fef8009 100644 OVS_VSWITCHD_STOP AT_CLEANUP -@@ -10807,6 +11103,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no +@@ -10807,6 +11186,23 @@ Megaflow: recirc_id=0x3,eth,ip,in_port=1,nw_frag=no Datapath actions: 4 ]) @@ -96858,7 +129302,7 @@ index d7854a1df3..32a77392c6 100755 # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/test-list.c b/tests/test-list.c -index 6f1fb059bc..648e02a5e2 100644 +index 6f1fb059bc..d1dbde30a7 100644 --- a/tests/test-list.c +++ b/tests/test-list.c @@ -61,7 +61,7 @@ check_list(struct ovs_list *list, const int values[], size_t n) @@ -96879,7 +129323,16 @@ index 6f1fb059bc..648e02a5e2 100644 assert(i == n); assert(ovs_list_is_empty(list) == !n); -@@ -135,6 +135,13 @@ test_list_for_each_safe(void) +@@ -106,6 +106,8 @@ test_list_construction(void) + int values[MAX_ELEMS]; + struct ovs_list list; + ++ memset(elements, 0, sizeof elements); ++ memset(values, 0, sizeof values); + make_list(&list, elements, values, n); + check_list(&list, values, n); + } +@@ -135,6 +137,13 @@ test_list_for_each_safe(void) values_idx = 0; n_remaining = n; LIST_FOR_EACH_SAFE (e, next, node, &list) { @@ -96893,7 +129346,7 @@ index 6f1fb059bc..648e02a5e2 100644 assert(i < n); if (pattern & (1ul << i)) { ovs_list_remove(&e->node); -@@ -148,7 +155,8 @@ test_list_for_each_safe(void) +@@ -148,7 +157,8 @@ test_list_for_each_safe(void) i++; } assert(i == n); diff --git a/SOURCES/ppc_64-power8-linuxapp-gcc-config b/SOURCES/ppc_64-power8-linuxapp-gcc-config index 042c372..882f0b7 100644 --- a/SOURCES/ppc_64-power8-linuxapp-gcc-config +++ b/SOURCES/ppc_64-power8-linuxapp-gcc-config @@ -1,4 +1,4 @@ -# -*- cfg-sha: f8eb57e7e75a69bb59051bd6f87b77c54bfda5320d8d3a2aaffa94b14d254b18 +# -*- cfg-sha: b505e679a032cef9a7902e6ba5cd29eab5177f21d2ea36962c21e6245854fc52 # SPDX-License-Identifier: BSD-3-Clause # Copyright (C) IBM Corporation 2014. # SPDX-License-Identifier: BSD-3-Clause @@ -10,7 +10,7 @@ CONFIG_RTE_VER_PREFIX="DPDK" # Version information completed when this file is processed for a build CONFIG_RTE_VER_YEAR=19 CONFIG_RTE_VER_MONTH=11 -CONFIG_RTE_VER_MINOR=7 +CONFIG_RTE_VER_MINOR=13 CONFIG_RTE_VER_SUFFIX="" CONFIG_RTE_VER_RELEASE=99 # RTE_EXEC_ENV values are the directories in mk/exec-env/ diff --git a/SOURCES/x86_64-native-linuxapp-gcc-config b/SOURCES/x86_64-native-linuxapp-gcc-config index a19dba6..55f521b 100644 --- a/SOURCES/x86_64-native-linuxapp-gcc-config +++ b/SOURCES/x86_64-native-linuxapp-gcc-config @@ -1,4 +1,4 @@ -# -*- cfg-sha: 133e4d11e86f77e37ed4efd835ccd4f8c81eb1e7ac828474be873cf0bc4126c6 +# -*- cfg-sha: 50ad352778b1c4f4cf16577310f84f691f571bb9041a49d4c2099034d2f57a0b # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2010-2014 Intel Corporation # SPDX-License-Identifier: BSD-3-Clause @@ -10,7 +10,7 @@ CONFIG_RTE_VER_PREFIX="DPDK" # Version information completed when this file is processed for a build CONFIG_RTE_VER_YEAR=19 CONFIG_RTE_VER_MONTH=11 -CONFIG_RTE_VER_MINOR=7 +CONFIG_RTE_VER_MINOR=13 CONFIG_RTE_VER_SUFFIX="" CONFIG_RTE_VER_RELEASE=99 # RTE_EXEC_ENV values are the directories in mk/exec-env/ diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index f08d3e1..51262de 100644 --- a/SPECS/openvswitch2.13.spec +++ b/SPECS/openvswitch2.13.spec @@ -59,7 +59,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.13.0 -Release: 198%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 201%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -715,6 +715,921 @@ exit 0 %endif %changelog +* Mon Sep 19 2022 Open vSwitch CI - 2.13.0-201 +- Merging upstream branch-2.13 [RH git: 9e3e7fe271] + Commit list: + 8535912ace python: idl: Fix idl.Row.__str__ method. + 32c71f8ad3 bond: Avoid deadlock while updating post recirculation rules. + 952303faa9 ofproto-dpif-upcall: Add debug commands to pause/resume revalidators. + 18c8fe97a7 test-list: Fix false-positive build failure with GCC 12. + b22219757a cirrus: Upgrade to FreeBSD 13.1 image. + + +* Tue Sep 06 2022 Timothy Redaelli - 2.13.0-200 +- redhat: Update dpdk config files for 19.11.13 [RH git: b827f8753b] + + +* Tue Sep 06 2022 Timothy Redaelli - 2.13.0-199 +- Merging 104f5e8eb8 version: 19.11.13 [RH git: f14606b7ff] + Commit list: + 104f5e8eb8 version: 19.11.13 + e73049ea26 vhost: fix header spanned across more than two descriptors + 5b3c25e6ee vhost: discard too small descriptor chains + 8b090f2664 net/mlx5: fix Rx queue recovery mechanism + 8059a2db94 version: 19.11.13-rc3 + 19ba437a13 Revert "net/iavf: fix Rx queue interrupt setting" + 5fecb551f0 version: 19.11.13-rc2 + 0558621ba0 net/ice: fix meson build error with gcc11.2 + f0bda10005 ethdev: fix RSS update when RSS is disabled + 6e9e78dbbd eal/freebsd: fix use of newer cpuset macros + b43f266f89 app/testpmd: fix multicast address pool leak + 64fb4a3640 net/iavf: net/iavf: fix mbuf release in multi-process + cc3e9347e0 net/iavf: fix Rx queue interrupt setting + fd52b77927 net/bonding: fix stopping non-active slaves + 8c695fafcb app/testpmd: fix supported RSS offload display + e304fa8fae app/testpmd: fix bonding slave devices not released + 8528169394 app/testpmd: fix port status of bonding slave device + a1686282b9 net/cxgbe: fix Tx queue stuck with mbuf chain coalescing + fec5d8436c examples/vhost: fix retry logic on Rx path + 65dd3bfca5 net/virtio-user: fix socket non-blocking mode + 41a4096ce3 Revert "net/mlx5: fix RSS expansion scheme for GRE header" + d4c20de6c0 version: 19.11.13-rc1 + 7d19e74129 net/netvsc: fix vmbus device reference in multi-process + d39349320e net/netvsc: fix calculation of checksums based on mbuf flag + d8cf14f383 vdpa/ifc/base: fix null pointer dereference + 44bd653285 examples/link_status_interrupt: fix stats refresh rate + fe4e6ce7bf net/nfp: fix disabling VLAN stripping + 63da0f8f3a raw/ifpga: unregister interrupt on close + 17ce1feb63 raw/ifpga: remove virtual devices on close + 2d061b0f22 net/mlx5: fix LRO validation in Rx setup + 39ffe62735 app/testpmd: perform SW IP checksum for GRO/GSO packets + 52e449c888 config: fix C++ cross compiler for ARM + 47978fa148 kni: fix build + 3d3bcdcee4 service: fix lingering active status + 7c4c4a4adc vhost: add some trailing newline in log messages + 48e451fe40 net/vhost: fix deadlock on vring state change + 288097da2b eventdev/eth_tx: fix queue delete + 5f21992197 doc: fix grammar and formatting in compressdev guide + 02686ad4e9 crypto/qat: fix DOCSIS crash + b5d8c94a05 examples/fips_validation: handle empty payload + 9ea7a5a2cf test/crypto: fix SNOW3G vector IV format + f2a1d83ee7 test/crypto: fix ZUC vector IV format + 614f12684b test/crypto: fix authentication IV for ZUC SGL + ccdd69c5dd net/bnxt: cleanup MTU setting + 6986cbb030 net/bnxt: allow Tx only or Rx only + a0d39201ac examples/distributor: fix distributor on Rx core + 91e1eb689b test: check memory allocation for CRC + 8caef8fee3 test/hash: fix out of bound access + ca63816371 net/qede: fix build with GCC 12 + 07d9cd4f91 net/octeontx: fix port close + 69b3923225 malloc: fix allocation of almost hugepage size + 05166062e7 vhost/crypto: fix descriptor processing + 9a6f9e3487 vhost/crypto: fix build with GCC 12 + bf77b580a9 vhost: fix missing enqueue pseudo-header calculation + faaab06d11 app/testpmd: revert MAC update in checksum forwarding + 5b7455b8fa net/nfp: fix initialization + bde6cacb5a net/hns3: remove duplicate definition + 530bf55366 test/bonding: fix RSS test when disable RSS + 4ca26f407d net/bonding: fix RSS inconsistency between ports + ad8183f3cb eventdev/eth_tx: fix adapter creation + d0fff9500a test/crypto: fix cipher offset for ZUC + ae21e9dac0 crypto/scheduler: fix queue pair in scheduler failover + 0d5d346bef test/ipsec: fix build with GCC 12 + ad09a49f19 common/cpt: fix build with GCC 12 + 3ba04d598f eal/x86: drop export of internal alignment macro + 777f8832c6 vdpa/ifc: fix build with GCC 12 + b4c2dfe34b net/ice: fix build with GCC 12 + 1093a40bd8 kni: use dedicated function to set MAC address + 051010a32b kni: use dedicated function to set random MAC address + 3ed306d014 bus/fslmc: fix VFIO setup + 2c86293fd2 net/iavf: increase reset complete wait count + 876ff3ffd9 net/iavf: fix queue start exception handling + 9b6b361ea7 net/ice/base: fix getting sched node from ID type + 2ed9b68967 net/ixgbe: add option for link up check on pin SDP3 + 104eedad56 kni: fix build with Linux 5.18 + ac099749a9 examples/vhost: fix crash when no VMDq + 4a9b088ed4 net/bnxt: fix compatibility with some old firmwares + 8abcce84f2 net/memif: fix overwriting of head segment + 84ee8673e5 net/bonding: fix mbuf fast free usage + 1e64fc63b5 ethdev: prohibit polling stopped queue + ae3d483239 app/testpmd: fix metering and policing command for RFC4115 + 0d9db81311 app/testpmd: replace hardcoded min mbuf number with macro + 5894d7acdc net/mvpp2: fix xstats get return if xstats is null + d00e51a7d1 net/ipn3ke: fix xstats get return if xstats is null + 02922dbbf2 net/hns3: fix xstats get return if xstats is null + 530d754e63 ethdev: clarify null location case in xstats get + fa9bd2129a app/testpmd: remove useless pointer checks + 57ae04724a drivers/crypto: fix warnings for OpenSSL version + e78ce8dd23 test/crypto: fix null check for ZUC authentication + 386ada62c2 examples/ipsec-secgw: fix promiscuous mode option + f616893e2a devtools: fix null test for NUMA systems + ec69d48924 rib: fix traversal with /32 route + c807a4cd6d acl: fix rules with 8-byte field size + c4b081a060 test: avoid hang if queues are full and Tx fails + f584d5fb26 eal/x86: fix unaligned access for small memcpy + 0e67983b1e net/bnxt: fix freeing VNIC filters + 66aae5fff0 net/bnxt: recheck FW readiness if in reset process + fd3e0ac14c net/bnxt: remove unused macro + ee3e5f1825 app/testpmd: check statistics query before printing + 385c7b6b3b net/dpaa: fix event queue detach + 5189c8ebb8 vhost: fix missing virtqueue lock protection + a09c7ed8a2 net/vhost: fix TSO feature default disablement + c7926bd5b5 net/vhost: fix access to freed memory + 41922761ef net/cxgbe: fix port ID in Rx mbuf + b1355507e2 net/bonding: fix RSS key config with extended key length + 43f2d3abe8 net/nfp: remove unneeded header inclusion + ea3fb95adc examples/l2fwd-crypto: fix stats refresh rate + 85d6c18a82 common/dpaax: fix short MAC-I IV calculation for ZUC + dcc0986eba crypto/dpaa2_sec: fix operation status for simple FD + cf5c06e209 crypto/dpaa_sec: fix secondary process probing + 003f602e62 crypto/dpaa2_sec: fix buffer pool ID check + 69e05f69da crypto/dpaa_sec: fix digest size + a2e44b157e eal: fix C++ include for device event and DMA + 6933433fea mem: skip attaching external memory in secondary process + f921474814 test/table: fix buffer overflow on lpm entry + fa44459ab3 net/mlx5: fix GTP handling in header modify action + 3901ebc402 net/mlx5: fix Tx when inlining is impossible + 2b9663aec4 examples/bond: fix invalid use of trylock + 2a645b955c eal/windows: fix data race when creating threads + 684d89c311 net/hns3: fix insecure way to query MAC statistics + acc9aea1e2 net/mlx5: fix mark enabling for Rx + a29c7a79c8 net/mlx5: fix MPRQ stride devargs adjustment + 27aac56207 net/mlx5: improve stride parameter names + 517553cc63 net/mlx5: add minimum WQE size for striding RQ + 4cfd0b287f version: 19.11.12 + 63c4b639c7 Revert "common/qat: fix queue pairs number" + 5a80d2f2ac pmdinfogen: fix compilation with Clang 3.4.2 on CentOS 7 + e94bd824db net/mlx5: fix netlink header path + d28dc9adb8 net/cxgbe: remove useless address check + f17a5eb33a net/bnxt: fix a typo introduced in backport + c511bb7787 version: 19.11.12-rc1 + 1566e521c3 cryptodev: add backward-compatible enum + ce19f07729 raw/ifpga: fix build with optimization + f9b9d26a69 cryptodev: fix clang C++ include + 8174ed2b2f compressdev: fix missing space in log macro + 66be196f77 eal/freebsd: add missing C++ include guards + d3847ac2c5 examples/l3fwd: fix buffer overflow in Tx + 61f29e7073 app/testpmd: fix show RSS RETA on Windows + b7979d39ef vhost: fix FD leak with inflight messages + aef547884b vhost: fix queue number check when setting inflight FD + 1f6e3407fb vhost: add missing c++ guards + 1cc48c513e ethdev: add missing C++ guards + a044eef12f eal: fix missing C++ guards + f927630e22 net/mlx5: fix NIC egress flow mismatch in switchdev mode + 0906b984ff net/mlx5: fix initial link status detection + edea6144b4 net/mlx5: fix link status change detection + 7bd18f45ed common/mlx5: add Netlink event helpers + 7a6fec928a raw/ifpga: fix monitor thread + d074ec715d raw/ifpga: fix interrupt handle allocation + 5822e6d07c net/af_xdp: ensure socket is deleted on Rx queue setup error + 21da1f705c net/mlx5: fix modify port action validation + 1ad09cf616 ethdev: fix doxygen comments for device info struct + c224b27258 examples/flow_classify: fix failure message + 29f79c5405 examples/distributor: reduce Tx queue number to 1 + e980bd3f16 app/pdump: abort on multi-core capture limit + 4e71915c99 raw/ifpga: fix variable initialization in probing + 33dfe70b32 net/mlx5: fix matcher priority with ICMP or ICMPv6 + 61110e21bb doc: fix typos and punctuation in flow API guide + 5243c1dd8e net/ixgbe: fix FSP check for X550EM devices + b66b96e0fe net/hns3: increase time waiting for PF reset completion + d7dd823ceb net/hns3: fix VF RSS TC mode entry + c367ca25ba net/hns3: fix RSS TC mode entry + bf1670a94c net/hns3: remove duplicate macro definition + 166408ae98 compressdev: fix socket ID type + c8a4d2d543 app/compress-perf: fix number of queue pairs to setup + ee0bd3baf7 app/compress-perf: fix socket ID type during init + 07459d98d2 kni: fix freeing order in device release + 1566ae455c eal/linux: fix illegal memory access in uevent handler + 1af997fdb0 distributor: fix potential overflow + 9facdc7965 test/efd: fix sockets mask size + ab746fecf9 app/testpmd: fix build without drivers + f0deb3f51e doc: replace broken links in mlx guides + 9d74f3ab28 doc: remove obsolete vector Tx explanations from mlx5 guide + 1e9ddbec02 net/ena: fix checksum flag for L4 + d1492dfd82 net/ena: fix meta descriptor DF flag setup + 41d1a8d6c4 net/ena: skip timer if reset is triggered + 2ffbbf4e57 net/ena: remove unused offload variables + c3510f9435 net/ena: remove unused enumeration + 1716c2f16a net/af_xdp: add missing trailing newline in logs + 1e68fe334f vhost: fix unsafe vring addresses modifications + 5748cf43bb app/testpmd: check starting port is not in bonding + 8c4cc35028 net/ixgbe: reset security context pointer on close + 9cbe350522 net/nfb: fix multicast/promiscuous mode switching + 2294078fe8 net/nfb: fix array indexes in deinit functions + c641b9a173 crypto/virtio: fix out-of-bounds access + 0810491770 examples/l2fwd-crypto: fix port mask overflow + 22cb63b10d doc: fix FIPS guide + e8422022f2 cryptodev: fix RSA key type name + 322dd30298 ethdev: fix cast for C++ compatibility + cf53c73176 kni: add missing C++ guards + 5d5711a19a eventdev: add missing C++ guards + 49abae5009 compressdev: add missing C++ guards + 68be7b2bae acl: add missing C++ guards + c7b95a425e telemetry: add missing C++ guards + c9f51a980e eventdev/eth_tx: fix queue add error code + a9b0d05644 net/bnxt: fix xstats names query overrun + 28a5003e9b net/bnxt: get maximum supported multicast filters count + 619e8d0b32 net/bnxt: fix handling of VF configuration change + 1850bbf5e1 net/bnxt: fix memzone allocation per VNIC + 6b61dd7c13 net/bnxt: restore RSS configuration after reset recovery + cab22ce839 net/bnxt: fix multicast address set + d9a0a323e9 net/bnxt: cap maximum number of unicast MAC addresses + bbe528c0a6 net/bnxt: fix queue stop operation + fbb34a9344 drivers: remove warning with Meson 0.59 + dda6d6aeb0 build: fix warnings when running external commands + a6aef21b01 build: remove deprecated Meson functions + 0c4178ebe6 eal: fix C++ include + 2bab6dfe4c eventdev: fix C++ include + 2292802064 doc: add dependency on examples for API doxygen + 37e6856e3f raw/ntb: clear all valid doorbell bits on init + dc34c5a920 compress/octeontx: fix null pointer dereference + 8b3ab4586f net/mlx5: fix committed bucket size + 55f2ea35c7 net/iavf: count continuous DD bits for Arm + f7faec39ae net/sfc: demand Tx fast free offload on EF10 simple datapath + 5b759d85bd net/sfc: do not push fast free offload to default TxQ config + a30a7dba88 net/memif: remove pointer deference before null check + dcae278345 vfio: cleanup the multiprocess sync handle + e24d07f803 ipc: end multiprocess thread during cleanup + 0a8fdfb70e test/mbuf: fix mbuf data content check + f0bd885fcb vhost: fix C++ include + b85a9bff6a table: fix C++ include + adda8aa04b ipsec: fix C++ include + 6578183ebd stack: fix stubs header export + 81decddb44 app/testpmd: fix bonding mode set + 2e48567d11 net/bonding: fix reference count on mbufs + 98417a7b4f net/bonding: fix promiscuous and allmulticast state + 9ec546fff4 net/ixgbe: check filter init failure + 04768eab27 net/hns3: fix RSS key with null + f18c3d166a net/hns3: fix max packet size rollback in PF + 613423a3ad net/dpaa2: remove useless C++ include guard + 08349a7b9b net/cxgbe: remove useless C++ include guard + f01ea4e120 bus/dpaa: fix C++ include guard + 04e3a108e7 test/mem: fix error check + b737263dae ring: fix error code when creating ring + 685c1a1e68 doc: fix KNI PMD name typo + 7eb7d8589b kni: fix ioctl signature + 921ec4a84b build: fix warning about using -Wextra flag + 7e275590e5 net/mlx5: reject jump to root table + 9a6321719c net/virtio-user: check FD flags getting failure + 3c97e0b5fc vdpa/ifc: fix log info mismatch + 58f8e7b7a8 net/virtio: fix Tx queue 0 overriden by queue 128 + ed0cc85213 net/hns3: fix using enum as boolean + 21e65fa8ec net/bonding: fix RSS with early configure + c39fd98e6f net/memif: remove unnecessary Rx interrupt stub + 2d59bc708b raw/ifpga/base: fix port feature ID + 4eb2c96733 net/bnxt: handle ring cleanup in case of error + 5381edac9f net/ice: fix link up when starting device + 30c9deb946 raw/ifpga/base: fix SPI transaction + 177049c3d1 net/sfc: validate queue span when parsing flow action RSS + 6f93f1756f net/nfp: remove useless range checks + 6edb22f2d8 net/mlx5: fix maximum packet headers size for TSO + 161c85a44e net/cxgbe: fix dangling pointer by mailbox access rework + a6dd7ffb5d app/testpmd: fix dereference before null check + f4a9c37bef net/bonding: fix mode type mismatch + 5b11370592 net/bnxt: fix xstats query + 21d32d5973 net/ixgbe: add vector Rx parameter check + 692ac5fb54 devtools: fix comment detection in forbidden token check + 1e884c7a68 eal/linux: log hugepage create errors with filename + 47065be226 bus/ifpga: remove useless check while browsing devices + 904776ab83 maintainers: update for stable branches + a489d32bfe config/ppc: fix build with GCC >= 10 + 4b0a43dcaf net/ice: build failure with make and GCC > 11 + 48d18f507a net/hns3: unregister MP action on close for secondary + 21f145ed52 net/hns3: fix multi-process action register and unregister + 98389f055c net/hns3: fix secondary process reference count + 2f88c39702 net/hns3: fix residual MAC after setting default MAC + 87ed66bd94 Release Notes: fix headers of 19.11.10 and 19.11.11 + 878c1a4d79 version: 19.11.11 + 1002b7e366 net/ice: build failure with make and clang < 13 + dbe5215ec7 net/i40e: build failure with make and clang < 13 + 1ead13fe23 net/ixgbe: build failure with make and clang < 13 + 9007725658 version: 19.11.11-rc2 + e247b323cf contigmem: update for FreeBSD 13 + f3068d1619 eal/freebsd: update CPU macro for FreeBSD 13 + 30585e9c4b eal/freebsd: fix incorrect variable name + e99e9d1c16 kni: update kernel API to set random MAC address + f5b3f1a47f cryptodev: fix stringop-overflow build failure with gcc 10 + 2ce84bf86d igb_uio: fix build for switch fall through + fab80885e7 net/ixgbe: build failure with make and clang 13 + acd0a2d2d7 net/ice: build failure with make and clang 13 + cc089e955b net/i40e: build failure with make and clang 13 + d43fa3e198 kni: fix build for SLES15-SP3 (Make) + f32335f082 ethdev: fix typos + e5075011b5 net/nfp: remove unused message length + 928100dd6d version: 19.11.11-rc1 + ee4ce5a574 app/testpmd: fix DCB in VT configuration + f1b0f46e06 net/i40e: fix forward outer IPv6 VXLAN + d7b0ee816a net/virtio: fix indirect descriptor reconnection + 6cc10ec90a doc: capitalise PMD + 49c2d565b2 fix PMD wording + 7f8ad3916a net/mlx5: fix GRE flow item matching + 80e6144404 net/mlx5: fix GRE protocol type translation + 19fc8799b8 Revert "net/ena: trigger reset on Tx prepare failure" + 0d24bd8034 net/ena: advertise scattered Rx capability + 04beaa85c0 net/ena: fix per-queue offload capabilities + 25f93ce73e net/ena: fix offload capabilities verification + d772f58505 net/bnxt: fix VLAN indication in Rx mbuf + f6a319ad81 net/bnxt: check FW capability for VLAN offloads + f20fd985b1 net/mlx5: fix Altivec Rx + 03b29e4c2d net/mlx5: fix GENEVE and VXLAN-GPE flow item matching + 17f73e7cd6 net/mlx5: fix GENEVE protocol type translation + 43ba10dde2 net/mlx5: fix VXLAN-GPE next protocol translation + 7b96050c47 test/crypto: fix unnecessary stats retrieval + 0454374e9a net/ixgbe: fix port initialization if MTU config fails + e2690a4c9b net/af_packet: fix ignoring full ring on Tx + 11c34d523a test/func_reentrancy: free memzones after test + 0034895340 net/i40e: fix risk in descriptor read in scalar Rx + 8f3f08c70a net/i40e: fix risk in descriptor read in NEON Rx + 11260b6b3e net/bnxt: fix Rx next consumer index in mbuf alloc fail + 6d5f21678e app/testpmd: fix packet burst spreading stats + 9ab39169ea net/ice: fix memzone leak on queue re-configure + 83226af504 net/ice: fix memzone leak after device init failure + c06b4e46c9 doc: fix typo in coding style + d544d3a924 remove repeated 'the' in the code + 86e6d758ac app/testpmd: fix hexadecimal parser with odd length + e495c937fd net/mlx4: fix empty Ethernet spec with VLAN + b2543bbdc3 net/mlx5: fix metadata and meter split shared tag + d0d1c1ebf8 doc: remove repeated repeated words + 264243ffe3 examples/ptpclient: fix delay request message + bfee2c85d6 doc: strip build artefacts for examples file list + 667dfb1e82 mbuf: fix dump of dynamic fields and flags + 71476c8a77 drivers/crypto: fix IPsec TTL decrement option + 49fdbb9a22 net/mlx5: fix MPLS tunnel outer layer overwrite + bb085aa7c1 net/failsafe: fix secondary process probe + 3f65b61010 net/mlx5: fix RSS expansion scheme for GRE header + 7f9c3453bc examples/ntb: fix build dependency + 55a6cfdc96 fix spelling in comments and doxygen + 2f782b75e8 examples/multi_process: fix Rx packets distribution + c98edab429 examples/l3fwd-power: fix early shutdown + ffd8f8c733 common/cpt: fix KASUMI input length + 3cf7745c4f test/crypto: fix data lengths + 6bf2029993 test/crypto: skip plain text compare for null cipher + 91f6ce93be eventdev/eth_tx: fix queue delete logic + 43442efcf4 examples/performance-thread: remove unused hits count + 78665353d6 test/distributor: remove unused counter + 36e063bd82 net/vmxnet3: fix build with clang 13 + fd9fd79a69 net/qede/base: remove unused message size + 571c9e53fa net/liquidio: remove unused counter + 0f5f1767a1 event/sw: remove unused inflight events count + 8b0fbea116 bus/fslmc: remove unused device count + 962fa4d5b4 net/hinic/base: remove some unused variables + 6b92949a90 test/red: fix typo in test description + df4b9cae88 doc: describe timestamp limitations for mlx5 + e3f1ad1116 net/mlx5: fix RETA update without stopping device + 3cc36e068b power: fix build with clang 13 + d783e54ad8 app/testpmd: remove unused header file + eba0dc7763 net/hns3: simplify queue DMA address arithmetic + ced22e5b52 interrupt: fix request notifier interrupt processing + 4c105c785c vfio: fix FreeBSD documentation + 8bcb2f4852 vfio: fix FreeBSD clear group stub + ed7ba18720 kni: check error code of allmulticast mode switch + d3ccaea9fd ethdev: fix crash on owner delete + d2b406a1da common/qat: fix queue pairs number + 50f8c29091 examples/fips_validation: fix device start + 1bac9e7b29 crypto/qat: fix uncleared cookies after operation + 5fd855c5dd crypto/qat: fix status in RSA decryption + b3f9982494 net/ice: save rule on switch filter creation + 0dfb8b4a26 net/enic: avoid error message when no advanced filtering + 710a081d81 net/bnxt: fix firmware version query + 698e296cd7 net/i40e: fix 32-bit build + 2fb2e78780 net/mlx5: fix RSS RETA update + 9fbe544f67 app/testpmd: fix RSS type display + 54e7183791 app/testpmd: fix RSS key length + 480955dbb4 mem: fix dynamic hugepage mapping in container + 13b9c2b5f5 eal/linux: fix uevent message parsing + 6c135cfbe7 eal/linux: remove unused variable for socket memory + 2ce7e45bf9 eal: fix device iterator when no bus is selected + 478db9fdd0 examples/performance-thread: fix build with ASan + 7c712c5106 test: fix ring PMD initialisation + 8029c08666 rib: fix IPv6 depth mask + b34c6b4503 lpm6: fix buffer overflow + 8275a9c639 hash: fix Doxygen comment of Toeplitz file + 7cc6083020 eal: reset lcore task callback and argument + 545b8e9ee5 eal/x86: avoid cast-align warning in memcpy functions + 6c88235a91 mbuf: avoid cast-align warning in data offset macro + 2cbe5b75db net: avoid cast-align warning in VLAN insert function + e856790c5f doc: fix default mempool option in guides + 6c8f6b72f2 kni: fix build for SLES15-SP3 + b154202754 test/event: fix timer adapter creation test + 7715355458 ethdev: fix PCI device release in secondary process + 27c4b8065e vhost: add sanity check on inflight last index + fb117f17e2 bpf: allow self-xor operation + 6ed91bcc60 eventdev/eth_rx: fix WRR buffer overrun + 12426ec54b app/eventdev: fix terminal colour after control-c exit + 9f2a1bcfe2 app/testpmd: fix access to DSCP table entries + e3285b3e8e net: fix aliasing in checksum computation + ae332e0f3b doc: fix emulated device names in e1000 guide + 84d8ca0358 app/testpmd: fix hex string parser in flow commands + eaa0d764d2 net/softnic: fix useless address check + 72dd222080 net/enic: fix filter mode detection + e67b39e429 net/i40e/base: fix using checksum before check + 8406d53dc9 net/i40e/base: fix potentially uninitialized variables + b483ed523e net/i40e/base: fix function name in comments + 69d0ba62c5 net/i40e/base: fix AOC media type + 813fffccb3 net/i40e/base: fix update link data for X722 + f2c2ed3570 net/i40e/base: fix PF reset + acd346a95d net/i40e/base: fix PHY identifiers for 2.5G and 5G adapters + 4d26daff81 net/ixgbe: fix queue release + 3f91a5c85b net/i40e: fix Rx packet statistics + 8eb9be9f82 app/testpmd: retain all original dev conf when config DCB + 238751b4f5 net/bonding: fix RSS key length + cc4a61ee31 net/bonding: fix dedicated queue mode in vector burst + 6dbdbe50b1 net/af_xdp: disable secondary process support + 0f30d115c5 test/bpf: fix undefined behavior with clang + 037204dc83 app/crypto-perf: fix AAD template copy overrun + 2ff1b965f5 mbuf: enforce no option for dynamic fields and flags + c43649313a test/atomic: fix 128-bit atomic test with many cores + 92df2aeaa1 mbuf: fix typo in comment + 1f3a6bf923 eal/freebsd: ignore in-memory option + 30edb6e693 bus/vmbus: fix ring buffer mapping in secondary process + 2c85290e65 eal/x86: fix some CPU extended features definitions + 1bb03e0139 test/service: fix some comment + 03cbc1d238 test/event_crypto: fix event crypto metadata write + 6882449642 examples/fips_validation: remove unused allocation + 0b9f46c0b7 net: fix checksum API documentation + a5811ad841 net/hns3: fix input parameters of MAC functions + e40ae0091c ethdev: fix xstats by ID API documentation + 7440bbb945 common/dpaax: fix physical address conversion + 1132c3fa61 test/latency: fix loop boundary + 6586da24bf bus/vmbus: fix leak on device scan + 4ca7fab3b0 net/mlx5: fix flow tables double release + c3dd66c29a net/bnxt: fix tunnel port accounting + 20c6894eed net/bnxt: fix memzone free for Tx and Rx rings + fdfed7e0ab net/bnxt: fix Tx queue startup state + 9d661128f4 net/bnxt: fix function driver register/unregister + 18d35ae547 common/iavf: fix ARQ resource leak + 70146f4f24 vhost: clean IOTLB cache on vring stop + c1e7394cc9 test/mem: fix memory autotests on FreeBSD + 33708f0d77 eal/freebsd: lock memory device to prevent conflicts + 6cf6872c05 efd: allow more CPU sockets in table creation + 6cd9c8890b bitrate: fix calculation to match API description + 88d15937b1 bitrate: fix registration to match API description + 701d4730ef ring: fix Doxygen comment of internal function + 331267709a net/memif: fix chained mbuf determination + 9228c06157 test/compress: fix buffer overflow + fd91b76420 stack: fix reload head when pop fails + fc80aaf9ff doc: fix numbers power of 2 in LPM6 guide + a7be123dcb net/iavf: fix Rx queue buffer size alignment + c0773b56c2 net/i40e/base: fix resource leakage + a0422d6ce7 net/iavf: fix mbuf leak + 1a6d098383 net/i40e: fix device startup resource release + ba9d67f359 net/i40e: fix mbuf leak + 0b0a33dc3a net/octeontx2: fix MTU when PTP is enabled + 8c58b366d1 vhost: log socket path on adding connection + 7bd82b66f0 net/virtio-user: fix Rx interrupts with multi-queue + d7a91388de net/virtio: avoid unneeded link interrupt configuration + 9fa5eea192 net/virtio: fix mbuf count on Rx queue setup + f07a95e2a9 examples/service_cores: fix lcore count check + 72a15cbd51 net/qede: fix minsize build + 6d3cd4152b net/ixgbe: fix mbuf leak + eb965c7d46 net/ixgbe: fix MAC resource leak + 17aff3d975 net/ixgbe: fix queue resource leak + 61e898b734 net/ixgbe: fix hash handle leak + a9c743e399 net/pcap: fix resource leakage on port probe + 306226d765 net/axgbe: fix unreleased lock in I2C transfer + 06ccbd7393 net/bnxt: fix double allocation of ring groups + 843921a929 net/bnxt: fix ring group free + 80d02f329d net/ixgbe: fix Rx multicast statistics after reset + 01b2a53e25 net/iavf: fix overflow in maximum packet length config + 568ce330c2 net/nfp: fix minimum descriptor sizes + abd1775ebd common/dpaax/caamflib: fix IV for short MAC-I in SNOW3G + b7bcb4e6a9 crypto/openssl: fix CCM processing 0 length source + 55f892fa8e config/ppc: ignore GCC 11 psabi warnings + 4990929c60 eal/ppc: ignore GCC 10 stringop-overflow warnings + f534d15329 app/testpmd: fix dump of Tx offload flags + 82785ded07 app/testpmd: fix check without outer checksum + 92f8daa19f app/testpmd: fix Tx retry in flowgen engine + 0466fd0ddb net/ice/base: fix typo in comment + b83e5a9c5c drivers/net: fix vector Rx comments + a5aaa4d87b drivers/net: fix typo in vector Rx comment + eec17bcf6b examples/performance-thread: fix build with clang 12.0.1 + 910f2fa408 test/power: fix CPU frequency when turbo enabled + f81d60e607 net/i40e: support 25G AOC/ACC cables + 0c9d4cddd2 version: 19.11.10 + bff2ef03a1 version: 19.11.10-rc2 + 00b9eee77c telemetry: fix race in telemetry control thread creation + 18f2b1ef5a vhost: utilize dynamic memory allocator + 179f2a3a8a version: 19.11.10-rc1 + 33b20879e3 net/virtio: fix refill order in packed ring datapath + 17969099c9 net/bnxt: fix missing barriers in completion handling + 5dec2a3de6 net/bnxt: fix ring and context memory allocation + f64b38cc8b net/bnxt: fix Rx burst size constraint + bb9cbb3f9c common/mlx5: use new port query API if available + 32a26ef159 net/mlx5: fix RoCE LAG bond device probing + 60a61324b1 net/mlx5: fix switchdev mode recognition + 063e827a32 common/mlx5: fix compatibility with OFED port query API + 21adec5590 app/testpmd: fix offloads for newly attached port + 02681ecc88 net/bnxt: clear cached statistics + 90419a312e net/bnxt: workaround spurious zero stats in Thor + 21778b315b net/bnxt: detect bad opaque in Rx completion + 2240adc427 net/bnxt: invoke device removal event on recovery failure + 4b806b7150 net/bnxt: remove unnecessary comment + a4eb287436 net/bnxt: fix auto-negotiation on Whitney+ + 130bad7727 net/ice: fix default RSS key generation + 0bc0b06bd3 net/i40e: fix multi-process shared data + a5bbc7882f net/mlx5: workaround drop action with old kernel + 182044e8c6 net/mlx5: limit implicit MPLS RSS expansion over GRE + ec7666076e net/mlx5: limit inner RSS expansion for MPLS + eaf27a75fa net/mlx5: fix MPLS RSS expansion + 1511823a74 net/mlx5: fix RSS flow item expansion for GRE key + 67e632a828 doc: fix spelling + ec80e2c0d5 net/octeontx2: fix default MCAM allocation size + 7565eeadf8 net/mlx5: fix representor interrupt handler + 900f1bbba7 bus: clarify log for non-NUMA-aware devices + 74b617cf81 eventdev: fix event port setup in tx adapter + 10615715f0 net/mlx5: fix IPIP multi-tunnel validation + 91867d8536 net/ena: trigger reset on Tx prepare failure + d6c7536f67 net/ena: enable multi-segment in Tx offload flags + 617b42ab3a net/mlx5: fix incorrect r/w lock usage in DMA unmap + ec55004ff1 app/testpmd: fix IPv4 checksum + 82d14a6458 doc: announce common prefix for ethdev + 8859b50254 crypto/octeontx: fix freeing after device release + 5dafebed55 cryptodev: fix freeing after device release + 190ab3d632 app/testpmd: fix Tx checksum calculation for tunnel + a64b7d5c52 net/softnic: fix memory leak as profile is freed + 24f55e1fa6 net/iavf: fix Tx threshold check + 3b5666b33c vhost: fix crash on reconnect + 685f060cd0 net/virtio: report maximum MTU in device info + e5a5f74805 app/testpmd: fix MAC address after port reset + 3ef1ce58c4 app/testpmd: fix help string for port reset + 19f7e6188d net/sfc: fix MAC stats update for stopped device + 37aa48f73e net/sfc: fix xstats query by unsorted list of IDs + d896f4fa36 net/sfc: fix xstats query by ID according to ethdev + e032128534 net/sfc: fix reading adapter state without locking + 151eeab935 net/sfc: fix MAC stats lock in xstats query by ID + eefa99e073 bus/dpaa: fix freeing in FMAN interface destructor + 677835f0e6 net/hinic/base: fix LRO + e398a73084 net/hinic: increase protection of the VLAN + 7a3ff6a730 net/hns3: fix Tx prepare after stop + 0ca1f67604 net/hns3: fix filter parsing comment + 400d62592e net/mlx5: fix Rx/Tx queue checks + 4a8e9207e5 net/mlx5: fix overflow in mempool argument + 87226495a9 test/crypto: fix mempool size for session-less + 14cfe4fbbf distributor: fix 128-bit write alignment + 71801fa379 net/ice/base: revert change of first profile mask + 93cb3e07e3 net/bnxt: fix nested lock during bonding + 3d30086c7b net/mvpp2: fix configured state dependency + d15f6a821b net/mvpp2: fix port speed overflow + 66ea88ff7c net/mlx5: fix typo in vectorized Rx comments + 60319d8a1b net/mlx5: remove redundant operations in NEON Rx + 10aa7ac64c net/softnic: fix connection memory leak + 0ca90c0419 net/bonding: check flow setting + 4ca54efc6c net/bonding: fix error message on flow verify + 1910073862 net/virtio: fix aarch32 build + bc7ff3f494 net/octeontx/base: fix debug build with clang + 875f2ff81f net/ixgbe: fix flow entry access after freeing + 612f6dafc4 net/i40e: fix descriptor scan on Arm + 00bba2d5eb net/ice: fix memzone leak when firmware is missing + b3cc9cc86d net/mlx5: remove unsupported flow item MPLS over IP + 1323532367 net/mlx5: fix match MPLS over GRE with key + a334fa1276 doc: add limitation for ConnectX-4 with L2 in mlx5 guide + c88235f886 net/bnxt: fix Rx interrupt setting + 0426b5875a net/bnxt: fix scalar Tx completion handling + 5abf2cb598 net/bnxt: fix Tx descriptor status implementation + 191b305c37 net/bnxt: fix typo in log message + d825711517 net/bnxt: cleanup code + f68c7e3468 power: fix namespace for internal struct + 2f1dcda6f7 ipc: stop mp control thread on cleanup + 9e5158e6c3 crypto/mvsam: fix options parsing + 2f38ee9eb5 crypto/mvsam: fix session data reset + b5d6216854 crypto/mvsam: fix capabilities + 4a77637fe9 crypto/mvsam: fix AES-GCM session parameters + d21025f95f test/crypto: fix typo in ESN case + 24f7690ba8 test/crypto: fix typo in AES case + 5657e24c45 test/crypto: fix mbuf reset after null check + 4310f369fb app/crypto-perf: fix out-of-place mempool allocation + 77e3c987f3 crypto/qat: fix Arm build with special memcpy + 8995aab00f app/testpmd: change port link speed without stopping all + 611d787899 ethdev: fix doc of flow action + a70576d706 net/pfe: remove unnecessary null check + 0aee3b98f4 net/hns3: fix VLAN strip log + 779b8527ce net/hns3: fix delay for waiting to stop Rx/Tx + ba81e4b317 net/hns3: increase VF reset retry maximum + 9e9fa80269 drivers/net: fix memzone allocations for DMA memory + 004151c375 mempool/octeontx2: fix shift calculation + eb35473b23 vhost: fix missing guest pages table NUMA realloc + 354836674a vhost: fix missing memory table NUMA realloc + 75d705fba9 net/ice/base: fix first profile mask + bc88f4ccfe net/octeontx2: use runtime LSO format indices + 65a9e807b3 net/octeontx2: fix flow creation limit on CN98xx + fc6e2aa74a test/mbuf: fix virtual address conversion + 4deebdea16 app/test: fix IPv6 header initialization + 479de25364 common/mlx5: fix Netlink port name padding in probing + 7e5dd0be04 tests/eal: fix memory leak + cb40436841 rib: fix max depth IPv6 lookup + 0c6d3c0f8d flow_classify: fix leaking rules on delete + d4cd1ffd33 kni: fix crash on userspace VA for segmented packets + 4b9355f4d0 kni: fix mbuf allocation for kernel side use + a8400e9443 vhost/crypto: check request pointer before dereference + 4406ca174c devtools: fix file listing in maintainers check + 848d502d03 doc: fix default burst size in testpmd + e818762474 net/iavf: fix RSS key access out of bound + 97f233a7dc net/bnxt: improve probing log message + 831b94f05d net/bnxt: fix check for PTP support in FW + 024de73171 net/bnxt: use common function to free VNIC resource + f6e2a4d566 net/bnxt: set flow error after tunnel redirection free + ec9a4839b5 net/bnxt: fix error handling in VNIC prepare + e3f51b8a46 net/bnxt: remove unnecessary code + efb741b14d net/bnxt: set flow error when free filter not available + 3e3ef06de5 net/bnxt: fix error messages in VNIC prepare + 839b753bfc net/bnxt: check access to possible null pointer + c7fc0792f6 bitmap: fix buffer overrun in bitmap init + a3d97ddaea version: 19.11.9 + 538b13525a version: 19.11.9-rc4 + 61e8a382cf net/mlx5: fix flow split combined with counter + 67880d27c6 drivers/crypto: fix build with -fno-common + 2381cba05b ethdev: fix redundant flow after RSS expansion + e5f56f22a8 version: 19.11.9-rc3 + 34438f96fb eal/windows: add cleanup function stub + f6a3c19b14 test/cmdline: silence clang 12 warning + 640dec22b7 test: fix build with GCC 11 + 27eb84d0cd net/memif: fix Tx bps statistics for zero-copy + 8671136504 common/sfc_efx/base: limit reported MCDI response length + 43fd40175a net/hns3: fix DCB reconfiguration + 0ace7116f8 net/hns3: remove meaningless packet buffer rollback + a93f977dc0 net/hns3: fix requested FC mode rollback + 5c78bf88aa net/mlx5: fix leak when configured repeatedly + bb7601591b net/mlx4: fix leak when configured repeatedly + 0c3ad62e9e test/crypto: fix build with GCC 11 + cf4cc7e6c4 test: fix division by zero + 84c4822ef4 examples/l3fwd-power: fix empty poll thresholds + 57a0b62dc4 test/table: fix build with GCC 11 + c3761e40de test/power: fix turbo test + 4664acc0f5 test/power: fix low frequency test when turbo enabled + bad1135b3c test/power: add turbo mode to frequency check + 647d1039fe test/power: fix CPU frequency check + 62717ed0e0 test: check flow classifier creation + 93825f29b0 examples/skeleton: fix NUMA check of port and core + f10ba4eba8 examples/l2fwd-cat: fix NUMA check of port and core + 16632a29f3 examples/flow_classify: fix NUMA check of port and core + 3ef4bb9cf8 examples/rxtx_callbacks: fix port ID format specifier + 02d8cd1aef app/crypto-perf: check memory allocation + c19da5ea08 crypto/qat: fix null authentication request + d176e9e77d net/mlx5: fix secondary process initialization ordering + 8b700cbb8c net/mlx4: fix secondary process initialization ordering + 5ad81654a0 net/tap: fix build with GCC 11 + cabcb9e71d net/ice/base: fix build with GCC 11 + d1a3991251 net/bnx2x: fix build with GCC 11 + aecd308c09 net/bnx2x: fix build with GCC 11 + 24c9081923 net/i40e: fix VF RSS configuration + 950f65a5a7 net/ice: fix VSI array out of bounds access + 3cda8f66ab net/iavf: fix Tx context descriptor + 69d191654f net/hns3: fix ordering in secondary process initialization + cb46f4c8f1 net/hns3: fix secondary process request start/stop Rx/Tx + 357f95df19 net/hns3: fix querying flow director counter for out param + 50160966a5 net/hns3: clear hash map on flow director clear + 041ad333d3 net/hns3: return error on PCI config write failure + 417a6b2af4 net/nfp: fix reporting of RSS capabilities + 072f1be82f net/ena: remove endian swap functions + 0731d405e9 net/ena/base: fix type conversions by explicit casting + 0019c2b028 net/ena: switch memcpy to optimized version + 8640d6ca2e net/ice/base: fix memory allocation wrapper + a619f6351f app/eventdev: fix lcore parsing skipping last core + d0d274a3eb event/dpaa2: remove unused macros + ae9f70495f power: fix sanity checks for guest channel read + 5f49a5b80a test/timer: check memzone allocation + 075ddf5387 examples/timer: fix time interval + 0bc04a9e43 ipc: use monotonic clock + 6285f76a75 raw/skeleton: add missing check after setting attribute + de29f33d90 bus/fslmc: remove unused debug macro + d1610c3b79 Revert "kni: fix compilation on SLES15-SP3" + 74ad940af8 app/testpmd: fix NVGRE encap configuration + bb144e7a1c version: 19.11.9-rc2 + fdc039f518 crypto/dpaa_sec: affine the thread portal affinity + a762c60a02 net/bnxt: fix ring count calculation for Thor + a2fb1f4aaf net/bnxt: reset filter indices on free + e584c527e9 net/bnxt: fix Rx descriptor status + 4027913f2c net/mlx5: fix drop action for Direct Rules/Verbs + 0b8f4f0462 eal: fix hang in control thread creation + 555da24882 eal: fix race in control thread creation + 15d8f64d18 version: 19.11.9-rc1 + de7bca5de2 kni: fix compilation on SLES15-SP3 + 92f9c9eb0b drivers/net: check process type in close operation + 2c99a86005 vfio: fix stdbool usage without include + 11c12b2cf0 eal/windows: fix default thread priority + 2dbf2606c0 net/hns3: fix handling link update + 12e49b5846 net/hns3: fix processing Tx offload flags + c6d57a2342 net/hns3: fix HW buffer size on MTU update + b7ac27d751 net/bnxt: fix xstats get + 55b177e226 net/bnxt: fix PTP support for Thor + e32b3efb03 net/bnxt: fix VF info allocation + 1f6e7af0a7 net/bnxt: fix timesync when PTP is not supported + 051dac308c net/bnxt: fix memory allocation for command response + 268646f36e net/bnxt: fix firmware fatal error handling + 0851647152 net/bnxt: fix double free in port start failure + 7bf99811cb net/bnxt: drop unused attribute + 3d47665e9a net/bnxt: fix build failures after merging patches + c1a766c4a6 net/virtio: fix interrupt unregistering for listening socket + 8679bdcfad doc: fix build with Sphinx 4 + 6834973cdf crypto/dpaa2_sec: fix close and uninit functions + e68de00ea7 test/crypto: fix auth-cipher compare length in OOP + 6c674445eb compress/qat: enable compression on GEN3 + 90274c3b30 common/qat: increase IM buffer size for GEN3 + c718bb5c40 app/bbdev: fix HARQ error messages + 6ce09b5c0d eal: fix service core list parsing + ee91d12e90 ipc: check malloc sync reply result + bf9f52b503 raw/ntb: check memory allocations + b1292c3add raw/ntb: check SPAD user index + 6fb38c5e88 net/bnxt: prevent device access in error state + 1b0c5ea4be net/bnxt: check PCI config read + 8fc04810c8 net/bnxt: fix mismatched type comparison in MAC restore + ef39a1f5ae net/bnxt: fix single PF per port check + 9c5569b74d net/bnxt: fix dynamic VNIC count + bc5fbee26c net/bnxt: fix Rx timestamp when FIFO pending bit is set + 6f2c34ddfb net/bnxt: refactor multi-queue Rx configuration + 31a1f37a9c net/virtio: fix vectorized Rx queue rearm + 8d38fea103 test/distributor: fix burst flush on worker quit + c4c133e44c test/distributor: fix worker notification in burst mode + 5205b453a0 ethdev: add missing buses in device iterator + 1b6ccfa09e net/hns3: remove unused VMDq code + b4958eafe0 net/i40e: fix primary MAC type when starting port + 9f6f0698c5 net/iavf: fix primary MAC type when starting port + 7baf297f0c common/iavf: use pad byte to specify MAC type + 77554d0367 net/hns3: remove unused macros + 1e5a7f2500 net/hns3: log time delta in decimal format + e2c69bbeb0 app/testpmd: fix DCB re-configuration + aae830768e app/testpmd: fix DCB forwarding configuration + 0122b41ea6 app/testpmd: fix forward lcores number for DCB + 78e19a6e33 net/tap: check ioctl on restore + 8b36bb0c84 net/mlx5: fix probing device in legacy bonding mode + 5d22718850 net/mlx4: fix buffer leakage on device close + b0038ab926 net/mlx5: remove drop queue function prototypes + 7f161f270f net/bnxt: use prefix on global function + 31ddfaf293 net/bnxt: remove unused function parameters + 34b8f954eb net/bnxt: remove unnecessary forward declarations + 3a7f947674 vhost: fix queue initialization + 0ba631c96b net/e1000: fix flow error message object + 4847b1f570 net/iavf: fix VF to PF command failure handling + bc7383fdbe net/ice: fix fast mbuf freeing + 20489ecb45 net/i40e: remove redundant VSI check in Tx queue setup + be8e65d488 net/i40e: fix negative VEB index + f911129f01 net/bonding: fix socket ID check + 51d0a23649 app/testpmd: fix segment number check + 9ce41b9142 net/hns3: fix typos on comments + 38a311aed8 net/tap: fix interrupt vector array size + 96ea6ed3ed app/testpmd: fix max queue number for Tx offloads + dfbaff67f3 test/kni: check init result + 23fe0ea4f3 test/kni: fix a comment + 2713a81e09 net/bonding: fix leak on remove + 17a606a119 net/hns3: remove unused mailbox macro and struct + e60f3508f9 net/hns3: fix mailbox error message + 60f578e334 net/kni: check init result + 5146e817e3 doc: fix multiport syntax in nfp guide + bc34d76127 power: save original ACPI governor always + a981724dd5 bpf: fix JSLT validation + afc5a394a4 eventdev: fix memory leakage on thread creation failure + 8271d55d94 eventdev: remove redundant thread name setting + b9b0989cad app/eventdev: fix overflow in lcore list parsing + ca9bd286cf test/mempool: fix object initializer + 9ac7bce7b9 mbuf: check shared memory before dumping dynamic space + 050961b8e8 eal/arm64: fix platform register bit + 618ad3e1e0 config/ppc: reduce number of cores and NUMA nodes + 2a80db5159 stack: allow lock-free only on relevant architectures + 4914551f6f doc: fix names of UIO drivers + 260f59fc4d net/e1000/base: fix timeout for shadow RAM write + a32f3e4ddd net/ice: fix disabling promiscuous mode + 71faa46e8e net/hns3: remove unused macro + 2a07c5e85b net/bnxt: fix health check alarm cancellation + 22190e37fc net/bonding: fix adding itself as its slave + 1393f059f7 net/hns3: fix VMDq mode check + 83f938a4dd net/hns3: fix DCB mode check + 5306e73271 net/hns3: remove unused macros + 54b77c9b0c doc: fix HiSilicon copyright syntax + 132399e0a0 examples/ethtool: remove unused parsing + e3e01fe44c examples: add eal cleanup to examples + a8ef7fa9ca test/power: round CPU frequency to check + a8e508f63c test/power: add delay before checking CPU frequency + 8de5391352 test/bpf: fix error message + d7ba846866 common/dpaax: fix possible null pointer access + 421a48e2dd test: check thread creation + c2a2b419d5 test/cmdline: fix inputs array + f28c08dbb1 examples/l3fwd: fix LPM IPv6 subnets + 1d4063311b examples/ptpclient: remove wrong comment + 8dea0ebb2d vfio: fix duplicated user mem map + 0893647891 eventdev: fix case to initiate crypto adapter service + 7675b13535 net/iavf: fix lack of MAC type when set MAC address + b44b687e79 net/i40e: fix lack of MAC type when set MAC address + 459c865d7a net/hns3: fix flow control mode + d9c0ea8409 ethdev: update flow item GTP QFI definition + 4c1990d14e app/testpmd: fix bitmap of link speeds when force speed + fdf412dcc9 net/ixgbe: fix Rx errors statistics for UDP checksum + 9b3e0bd6dc net/mlx4: fix RSS action with null hash key + 1b25f3ab53 net/ice: fix illegal access when removing MAC filter + c33f75c9ea net/e1000: fix max Rx packet size + 16d33d0c95 test: fix TCP header initialization + 4da6f5da89 crypto/qat: fix offset for out-of-place scatter-gather + 9e42a591af examples/l2fwd-crypto: fix packet length while decryption + e71945e7cd examples/l2fwd-crypto: skip masked devices + b37a9322f1 eal: add C++ include guard for reciprocal header + b5dd868cb4 license: fix typos + 9415e84969 event/octeontx2: fix device reconfigure for single slot + 4f672e14dd test/event: fix timeout accuracy + 57d7299334 net/hns3: delete redundant blank line + 3ee68e0cdc net/hns3: support get device version when dump register + f13f923be9 net/hns3: fix VF mailbox head field + 3eef3419ba net/hns3: fix flow counter value + 1bd2e16378 net/hns3: fix flow control exception + 4edc5ba916 net/hns3: fix rollback after setting PVID failure + 704683e6b4 net/hns3: fix FLR miss detection + 40b42b59f5 ethdev: validate input in EEPROM info + 22b28a3a96 ethdev: validate input in register info + c5c6a6758b ethdev: validate input in module EEPROM dump + 52541216a4 vhost: fix initialization of temporary header + 70c0ca3e2f net/bnxt: fix configuring LRO + 65fff5c304 net/e1000: fix Rx error counter for bad length + 9437d72a27 net/ena: fix releasing Tx ring mbufs + 27e1ab8496 net/hns3: update HiSilicon copyright syntax + a24066b557 net/hns3: fix MTU config complexity + 6048de8672 app: fix exit messages + 9692bccd48 test: proceed if timer subsystem already initialized + 2af983586e service: clean references to removed symbol + d4ac20b679 mem: fix freeing segments in --huge-unlink mode + 7fe5c9da11 power: do not skip saving original P-state governor + c2c3fb7fa5 doc: fix sphinx rtd theme import in GHA + 1d513f3e6d examples/vhost_crypto: remove unused short option + e2e3023141 vhost: fix batch dequeue potential buffer overflow + 5dd10355ee vhost: fix packed ring potential buffer overflow + ce06835ea0 vhost: fix split ring potential buffer overflow + 68e2d263d0 examples/vhost: check memory table query + fd68efb26d vdpa/ifc: check PCI config read + e6016563b0 net/ixgbe: fix RSS RETA being reset after port start + fbe7e9e243 net/iavf: fix TSO max segment size + 1023276149 net/i40e: announce request queue capability in PF + 4e26e24f7b net/i40e: fix parsing packet type for NEON + 95f643efba app/testpmd: fix Tx/Rx descriptor query error log + 3be4c6f38e net/hinic: fix crash in secondary process + e0632c72b5 net/mlx5: support RSS expansion for IPv6 GRE + ed829aa3a4 net/ice/base: fix memory allocation for MAC addresses + 893fe89587 net/i40e: fix input set field mask + 476a832aec net/qede: accept bigger RSS table + 850645fad2 net/qede: reduce log verbosity + 31be764e1d net/bnxt: fix handling of null flow mask + 4137df30b4 net/bnxt: fix Tx length hint threshold + d0ee1a953f net/bnxt: fix Rx buffer posting + ceed94c38a net/bnxt: fix link state operations + fee9960eff net/bnxt: fix RSS context cleanup + 8ccce55b4f net/bnxt: fix PCI write check + f0d834811c net/bnxt: fix Tx timestamp init + 6707a2eac2 net/ark: refactor Rx buffer recovery + 09143a5b30 net/ark: update packet director initial state + 4c79a1d2a2 test: fix autotest handling of skipped tests + f9d88ca63a examples/packet_ordering: fix port configuration + 2d05ab32ec examples/bbdev: fix header include for musl + 1ce3f050a1 app/testpmd: fix build with musl + bf14527add net/cxgbe: remove use of uint type + 6f31c9f0b0 bus/dpaa: fix build with musl + 497d9b791a bus/dpaa: fix 64-bit arch detection + d0e66cabf7 common/dpaax/caamflib: fix build with musl + 4859c47729 build: detect execinfo library on Linux + 5cbbd68143 buildtools: fix build with busybox + 4574f511de eal: fix comment of OS-specific header files + 1128a708e5 net/mlx5: fix Rx metadata leftovers + 52fc00866d net/ice: check some functions return + 0dc6e28e29 net/bnxt: fix Rx and Tx timestamps + 8a6b661637 net/bnxt: fix HWRM and FW incompatibility handling + 9c844a580e net/bnxt: fix device readiness check + 127f365700 net/bnxt: fix FW readiness check during recovery + 973b51e6c4 net/bnxt: fix queues per VNIC + 1bdbc5a97a net/bnxt: fix VNIC configuration + 70faac0beb net/bnxt: remove unused macro + e635578ac9 net: fix comment in IPv6 header + 52aff457cc log/linux: make default output stderr + 8c90f92df9 build: exclude meson files from examples installation + fe02843553 net/octeontx2: fix VLAN filter + 705ff17cb9 net/mlx5: fix Rx segmented packets on mbuf starvation + 686c9f7038 net/i40e: fix IPv4 fragment offload + d22f5401be net/i40evf: fix packet loss for X722 + 4e317accb6 net/ice/base: cleanup filter list on error + fa91bf2609 net/ice/base: fix payload indicator on ptype + bde5bcff0c net/e1000: remove MTU setting limitation + 63ca0b5e42 net/ice: fix VLAN filter with PF + d9ad55ab08 net/bonding: fix LACP system address check + f6c8378f65 net/bnxt: fix Rx queue count + 17d0997e87 net/pcap: fix format string + aeb4b92e66 net/af_xdp: fix error handling during Rx queue setup + 26cc939ea4 app/testpmd: remove unnecessary UDP tunnel check + 804ee2a09e net/dpaa2: fix getting link status + c791263546 bus/dpaa: fix statistics reading + 210267915e bus/fslmc: fix random portal hangs with qbman 5.0 + a025ec46fa net/mlx5: fix metadata item validation for ingress flows + 9fc8ad9a6c net/failsafe: report minimum and maximum MTU + e43e3fb745 net/failsafe: fix RSS hash offload reporting + d1c428a983 fbarray: fix log message on truncation error + 291ecb3d2f vfio: fix API description + 634e6699e6 power: remove duplicated symbols from map file + fd3a70f1b2 vfio: fix DMA mapping granularity for IOVA as VA + b92fd56073 vfio: do not merge contiguous areas + 78bc278461 version: 19.11.8 + 6a1b35022c version: 19.11.8-rc1 + 878f397439 Regenerate meson.build changes required due to reverts + 8efff892d5 Revert "Revert "Revert "devtools: test static linkage with pkg-config""" + edcf84c174 Revert "Revert "Revert "build: always link whole DPDK static libraries""" + f06399136e Revert "Revert "Revert "build/pkg-config: move pkg-config file creation""" + 9b7941ee90 Revert "Revert "Revert "build/pkg-config: output drivers first for static build""" + f593dc36c3 Revert "Revert "Revert "build/pkg-config: improve static linking flags""" + ebdf52b302 Revert "Revert "Revert "build/pkg-config: prevent overlinking""" + + * Wed Aug 31 2022 Open vSwitch CI - 2.13.0-198 - Merging upstream branch-2.13 [RH git: 2f5d2b0cc8] Commit list: