Add following testpmd run-time commands to support test of new Rx offload API: rx_offload get capability <port_id> rx_offload get configuration <port_id> rx_offload enable|disable per_port vlan_strip|ipv4_cksum... <port_id> rx_offload enable|disable per_queue vlan_strip|iipv4_cksum... <port_id> <queue_id>
Above last 2 commands should be run when the port is stopped. Signed-off-by: Wei Dai <wei....@intel.com> --- app/test-pmd/cmdline.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/testpmd.c | 15 +- app/test-pmd/testpmd.h | 1 + 3 files changed, 470 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index d1dc1de..1a08b3d 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -15996,6 +15996,458 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = { }, }; +static const char * const rx_offload_names[] = { + "VLAN_STRIP", + "IPV4_CKSUM", + "UDP_CKSUM", + "TCP_CKSUM", + "TCP_LRO", + "QINQ_STRIP", + "OUTER_IPV4_CKSUM", + "MACSEC_STRIP", + "HEADER_SPLIT", + "VLAN_FILTER", + "VLAN_EXTEND", + "JUMBO_FRAME", + "CRC_STRIP", + "SCATTER", + "TIMESTAMP", + "SECURITY" +}; + +#define MAX_NUM_OF_RX_OFFLOADS \ + ((int)(sizeof(rx_offload_names)/sizeof(rx_offload_names[0]))) + +/* Get Rx offloads capability */ +struct cmd_rx_offload_get_capa_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t capability; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_rx_offload_get_capa_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_rx_offload_get_capa_get = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + get, "get"); +cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + capability, "capability"); +cmdline_parse_token_num_t cmd_rx_offload_get_capa_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + port_id, UINT16); + +static void +cmd_rx_offload_get_capa_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_rx_offload_get_capa_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + uint64_t queue_offloads; + uint64_t port_offloads; + uint64_t mask; + int k; + + rte_eth_dev_info_get(port_id, &dev_info); + queue_offloads = dev_info.rx_queue_offload_capa; + port_offloads = dev_info.rx_offload_capa ^ queue_offloads; + + printf("Rx Offloading Capabilities of port %d :\n", port_id); + printf(" Per Queue :"); + mask = 1; + for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) { + if (queue_offloads & mask) + printf(" %s", rx_offload_names[k]); + mask <<= 1; + } + printf("\n"); + printf(" Per Port :"); + mask = 1; + for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) { + if (port_offloads & mask) + printf(" %s", rx_offload_names[k]); + mask <<= 1; + } + printf("\n\n"); +} + +cmdline_parse_inst_t cmd_rx_offload_get_capa = { + .f = cmd_rx_offload_get_capa_parsed, + .data = NULL, + .help_str = "rx_offload get capability <port_id>", + .tokens = { + (void *)&cmd_rx_offload_get_capa_rx_offload, + (void *)&cmd_rx_offload_get_capa_get, + (void *)&cmd_rx_offload_get_capa_capability, + (void *)&cmd_rx_offload_get_capa_port_id, + NULL, + } +}; + +/* Get Rx offloads configuration */ +struct cmd_rx_offload_get_configuration_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t configuration; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_get = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + get, "get"); +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + configuration, "configuration"); +cmdline_parse_token_num_t cmd_rx_offload_get_configuration_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + port_id, UINT16); + +static void +cmd_rx_offload_get_configuration_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_rx_offload_get_configuration_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + struct rte_port *port = &ports[port_id]; + uint64_t port_offloads; + uint64_t queue_offloads; + uint64_t mask; + uint16_t nb_rx_queues; + int q; + int k; + + printf("Rx Offloading Configuration of port %d :\n", port_id); + + port_offloads = port->dev_conf.rxmode.offloads; + printf(" Port :"); + mask = 1; + for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) { + if (port_offloads & mask) + printf(" %s", rx_offload_names[k]); + mask <<= 1; + } + printf("\n"); + + rte_eth_dev_info_get(port_id, &dev_info); + nb_rx_queues = dev_info.nb_rx_queues; + for (q = 0; q < nb_rx_queues; q++) { + queue_offloads = port->rx_offloads[q]; + printf(" Queue[%2d] :", q); + mask = 1; + for (k = 0; k < MAX_NUM_OF_RX_OFFLOADS; k++) { + if (queue_offloads & mask) + printf(" %s", rx_offload_names[k]); + mask <<= 1; + } + printf("\n"); + } + printf("\n"); +} + +cmdline_parse_inst_t cmd_rx_offload_get_configuration = { + .f = cmd_rx_offload_get_configuration_parsed, + .data = NULL, + .help_str = "rx_offload get configuration <port_id>", + .tokens = { + (void *)&cmd_rx_offload_get_configuration_rx_offload, + (void *)&cmd_rx_offload_get_configuration_get, + (void *)&cmd_rx_offload_get_configuration_configuration, + (void *)&cmd_rx_offload_get_configuration_port_id, + NULL, + } +}; + +/* Enable/Disable a per port offloading */ +struct cmd_config_per_port_rx_offload_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t en_dis; + cmdline_fixed_string_t per_port; + cmdline_fixed_string_t offload; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + per_port, "per_port"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#" + "qinq_strip#outer_ipv4_cksum#macsec_strip#" + "header_split#vlan_filter#vlan_extend#jumbo_frame#" + "crc_strip#scatter#timestamp#security"); +cmdline_parse_token_num_t cmd_config_per_port_rx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + port_id, UINT16); + +static int +config_rx_offload(const char *name, uint64_t *offload, int on) +{ + uint64_t local = *offload; + + if (!strcmp(name, "vlan_strip")) { + if (on) + local |= DEV_RX_OFFLOAD_VLAN_STRIP; + else + local &= ~DEV_RX_OFFLOAD_VLAN_STRIP; + } else if (!strcmp(name, "ipv4_cksum")) { + if (on) + local |= DEV_RX_OFFLOAD_IPV4_CKSUM; + else + local &= ~DEV_RX_OFFLOAD_IPV4_CKSUM; + } else if (!strcmp(name, "udp_cksum")) { + if (on) + local |= DEV_RX_OFFLOAD_UDP_CKSUM; + else + local &= ~DEV_RX_OFFLOAD_UDP_CKSUM; + } else if (!strcmp(name, "tcp_cksum")) { + if (on) + local |= DEV_RX_OFFLOAD_TCP_CKSUM; + else + local &= ~DEV_RX_OFFLOAD_TCP_CKSUM; + } else if (!strcmp(name, "tcp_lro")) { + if (on) + local |= DEV_RX_OFFLOAD_TCP_LRO; + else + local &= ~DEV_RX_OFFLOAD_TCP_LRO; + } else if (!strcmp(name, "qinq_strip")) { + if (on) + local |= DEV_RX_OFFLOAD_QINQ_STRIP; + else + local &= ~DEV_RX_OFFLOAD_QINQ_STRIP; + } else if (!strcmp(name, "outer_ipv4_cksum")) { + if (on) + local |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; + else + local &= ~DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; + } else if (!strcmp(name, "macsec_strip")) { + if (on) + local |= DEV_RX_OFFLOAD_MACSEC_STRIP; + else + local &= ~DEV_RX_OFFLOAD_MACSEC_STRIP; + } else if (!strcmp(name, "header_split")) { + if (on) + local |= DEV_RX_OFFLOAD_HEADER_SPLIT; + else + local &= ~DEV_RX_OFFLOAD_HEADER_SPLIT; + } else if (!strcmp(name, "vlan_filter")) { + if (on) + local |= DEV_RX_OFFLOAD_VLAN_FILTER; + else + local &= ~DEV_RX_OFFLOAD_VLAN_FILTER; + } else if (!strcmp(name, "vlan_extend")) { + if (on) + local |= DEV_RX_OFFLOAD_VLAN_EXTEND; + else + local &= ~DEV_RX_OFFLOAD_VLAN_EXTEND; + } else if (!strcmp(name, "jumbo_frame")) { + if (on) + local |= DEV_RX_OFFLOAD_JUMBO_FRAME; + else + local &= ~DEV_RX_OFFLOAD_JUMBO_FRAME; + } else if (!strcmp(name, "crc_strip")) { + if (on) + local |= DEV_RX_OFFLOAD_CRC_STRIP; + else + local &= ~DEV_RX_OFFLOAD_CRC_STRIP; + } else if (!strcmp(name, "scatter")) { + if (on) + local |= DEV_RX_OFFLOAD_SCATTER; + else + local &= ~DEV_RX_OFFLOAD_SCATTER; + } else if (!strcmp(name, "timestamp")) { + if (on) + local |= DEV_RX_OFFLOAD_TIMESTAMP; + else + local &= ~DEV_RX_OFFLOAD_TIMESTAMP; + } else if (!strcmp(name, "security")) { + if (on) + local |= DEV_RX_OFFLOAD_SECURITY; + else + local &= ~DEV_RX_OFFLOAD_SECURITY; + } else + return -1; + + *offload = local; + return 0; +} + +static void +cmd_config_per_port_rx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_port_rx_offload_result *res = parsed_result; + portid_t port_id = res->port_id; + struct rte_port *port = &ports[port_id]; + int on; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + if (!strcmp(res->en_dis, "enable")) + on = 1; + else if (!strcmp(res->en_dis, "disable")) + on = 0; + else { + printf("Unknown parameter: %s\n", res->en_dis); + return; + } + + if (config_rx_offload(res->offload, + &port->dev_conf.rxmode.offloads, on)) { + printf("Unknown offload name: %s", res->offload); + } +} + +cmdline_parse_inst_t cmd_config_per_port_rx_offload = { + .f = cmd_config_per_port_rx_offload_parsed, + .data = NULL, + .help_str = "rx_offload enable|disable per_port vlan_strip|ipv4_cksum|" + "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|" + "macsec_strip|header_split|vlan_filter|vlan_extend|" + "jumbo_frame|crc_strip|scatter|timestamp|security " + "<port_id>", + .tokens = { + (void *)&cmd_config_per_port_rx_offload_result_rx_offload, + (void *)&cmd_config_per_port_rx_offload_result_en_dis, + (void *)&cmd_config_per_port_rx_offload_result_per_port, + (void *)&cmd_config_per_port_rx_offload_result_offload, + (void *)&cmd_config_per_port_rx_offload_result_port_id, + NULL, + } +}; + +/* Enable/Disable a per queue offloading */ +struct cmd_config_per_queue_rx_offload_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t en_dis; + cmdline_fixed_string_t per_queue; + cmdline_fixed_string_t offload; + portid_t port_id; + uint16_t queue_id; +}; + +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + per_queue, "per_queue"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#" + "qinq_strip#outer_ipv4_cksum#macsec_strip#" + "header_split#vlan_filter#vlan_extend#jumbo_frame#" + "crc_strip#scatter#timestamp#security"); +cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + port_id, UINT16); +cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_queue_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + queue_id, UINT16); + + +static void +cmd_config_per_queue_rx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_queue_rx_offload_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + uint16_t queue_id = res->queue_id; + struct rte_port *port = &ports[port_id]; + int on; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + if (!strcmp(res->en_dis, "enable")) + on = 1; + else if (!strcmp(res->en_dis, "disable")) + on = 0; + else { + printf("Unknown parameter: %s\n", res->en_dis); + return; + } + + rte_eth_dev_info_get(port_id, &dev_info); + if (queue_id >= dev_info.nb_rx_queues) { + printf("Error: input queue_id should be 0 ... " + "%d", dev_info.nb_rx_queues - 1); + return; + } + + if (config_rx_offload(res->offload, + &port->rx_offloads[queue_id], on)) { + printf("Unknown offload name: %s", res->offload); + } +} + +cmdline_parse_inst_t cmd_config_per_queue_rx_offload = { + .f = cmd_config_per_queue_rx_offload_parsed, + .data = NULL, + .help_str = "rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|" + "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|" + "macsec_strip|header_split|vlan_filter|vlan_extend|" + "jumbo_frame|crc_strip|scatter|timestamp|security " + "<port_id> <queue_id>", + .tokens = { + (void *)&cmd_config_per_queue_rx_offload_result_rx_offload, + (void *)&cmd_config_per_queue_rx_offload_result_en_dis, + (void *)&cmd_config_per_queue_rx_offload_result_per_queue, + (void *)&cmd_config_per_queue_rx_offload_result_offload, + (void *)&cmd_config_per_queue_rx_offload_result_port_id, + (void *)&cmd_config_per_queue_rx_offload_result_queue_id, + NULL, + } +}; + /* Common result structure for file commands */ struct cmd_cmdfile_result { cmdline_fixed_string_t load; @@ -16272,6 +16724,10 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_tm_node, (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent, (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit, + (cmdline_parse_inst_t *)&cmd_rx_offload_get_capa, + (cmdline_parse_inst_t *)&cmd_rx_offload_get_configuration, + (cmdline_parse_inst_t *)&cmd_config_per_port_rx_offload, + (cmdline_parse_inst_t *)&cmd_config_per_queue_rx_offload, NULL, }; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 4c0e258..9786bfe 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -656,6 +656,7 @@ init_config(void) uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; struct rte_gro_param gro_param; uint32_t gso_types; + int k; memset(port_per_socket,0,RTE_MAX_NUMA_NODES); @@ -707,6 +708,17 @@ init_config(void) } } + port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads", + sizeof(port->rx_offloads[0]) * + port->dev_info.max_rx_queues, + sizeof(port->rx_offloads[0])); + if (port->rx_offloads == NULL) + rte_exit(EXIT_FAILURE, + "rte_zmalloc(%d port->rx_offload[0]) " + "failed\n", port->dev_info.max_rx_queues); + for (k = 0; k < port->dev_info.max_rx_queues; k++) + port->rx_offloads[k] = port->dev_conf.rxmode.offloads; + /* set flag to initialize port/queue */ port->need_reconfig = 1; port->need_reconfig_queues = 1; @@ -1615,10 +1627,9 @@ start_port(portid_t pid) port->need_reconfig_queues = 1; return -1; } - /* Apply Rx offloads configuration */ - port->rx_conf.offloads = port->dev_conf.rxmode.offloads; /* setup rx queues */ for (qi = 0; qi < nb_rxq; qi++) { + port->rx_conf.offloads = port->rx_offloads[qi]; if ((numa_support) && (rxring_numa[pi] != NUMA_NO_CONFIG)) { struct rte_mempool * mp = diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 153abea..dcad260 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -183,6 +183,7 @@ struct rte_port { uint8_t dcb_flag; /**< enable dcb */ struct rte_eth_rxconf rx_conf; /**< rx configuration */ struct rte_eth_txconf tx_conf; /**< tx configuration */ + uint64_t *rx_offloads; /**< offloads of each Rx queue */ struct 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 */ -- 2.7.5