X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcmdline.c;h=c61c3a00779c1cffc741ebc6ee839401843b79a7;hb=503f9e8b42562b923e73e908be6ba69964f1f1e7;hp=f527b635183dcdf110550b4ac59edc8970f5a95a;hpb=aeca06df4ef7609982cf586f0c58fc6f1d8867f8;p=dpdk.git diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index f527b63518..c61c3a0077 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -172,7 +172,7 @@ static void cmd_help_long_parsed(void *parsed_result, " statistics.\n\n" "quit\n" - " Quit to prompt in Linux and reboot on Baremetal.\n\n" + " Quit to prompt.\n\n" ); } @@ -316,19 +316,27 @@ static void cmd_help_long_parsed(void *parsed_result, " Disable hardware insertion of a VLAN header in" " packets sent on a port.\n\n" - "tx_checksum set (mask) (port_id)\n" - " Enable hardware insertion of checksum offload with" - " the 8-bit mask, 0~0xff, in packets sent on a port.\n" - " bit 0 - insert ip checksum offload if set\n" - " bit 1 - insert udp checksum offload if set\n" - " bit 2 - insert tcp checksum offload if set\n" - " bit 3 - insert sctp checksum offload if set\n" - " bit 4 - insert inner ip checksum offload if set\n" - " bit 5 - insert inner udp checksum offload if set\n" - " bit 6 - insert inner tcp checksum offload if set\n" - " bit 7 - insert inner sctp checksum offload if set\n" + "tx_cksum set (ip|udp|tcp|sctp|vxlan) (hw|sw) (port_id)\n" + " Select hardware or software calculation of the" + " checksum with when transmitting a packet using the" + " csum forward engine.\n" + " ip|udp|tcp|sctp always concern the inner layer.\n" + " vxlan concerns the outer IP and UDP layer (in" + " case the packet is recognized as a vxlan packet by" + " the forward engine)\n" " Please check the NIC datasheet for HW limits.\n\n" + "tx_checksum show (port_id)\n" + " Display tx checksum offload configuration\n\n" + + "tso set (segsize) (portid)\n" + " Enable TCP Segmentation Offload in csum forward" + " engine.\n" + " Please check the NIC datasheet for HW limits.\n\n" + + "tso show (portid)" + " Display the status of TCP Segmentation Offload.\n\n" + "set fwd (%s)\n" " Set packet forwarding mode.\n\n" @@ -728,6 +736,10 @@ static void cmd_help_long_parsed(void *parsed_result, " flow (ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)" " (mask)\n" " Configure mask of flex payload.\n\n" + + "flow_director_flex_payload (port_id)" + " (l2|l3|l4) (config)\n" + " Configure flex payload selection.\n\n" ); } } @@ -2851,48 +2863,213 @@ cmdline_parse_inst_t cmd_tx_vlan_reset = { /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */ -struct cmd_tx_cksum_set_result { +struct cmd_tx_cksum_result { cmdline_fixed_string_t tx_cksum; - cmdline_fixed_string_t set; - uint8_t cksum_mask; + cmdline_fixed_string_t mode; + cmdline_fixed_string_t proto; + cmdline_fixed_string_t hwsw; uint8_t port_id; }; static void -cmd_tx_cksum_set_parsed(void *parsed_result, +cmd_tx_cksum_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { - struct cmd_tx_cksum_set_result *res = parsed_result; + struct cmd_tx_cksum_result *res = parsed_result; + int hw = 0; + uint16_t ol_flags, mask = 0; + struct rte_eth_dev_info dev_info; + + if (port_id_is_invalid(res->port_id)) { + printf("invalid port %d\n", res->port_id); + return; + } - tx_cksum_set(res->port_id, res->cksum_mask); + if (!strcmp(res->mode, "set")) { + + if (!strcmp(res->hwsw, "hw")) + hw = 1; + + if (!strcmp(res->proto, "ip")) { + mask = TESTPMD_TX_OFFLOAD_IP_CKSUM; + } else if (!strcmp(res->proto, "udp")) { + mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM; + } else if (!strcmp(res->proto, "tcp")) { + mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM; + } else if (!strcmp(res->proto, "sctp")) { + mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM; + } else if (!strcmp(res->proto, "vxlan")) { + mask = TESTPMD_TX_OFFLOAD_VXLAN_CKSUM; + } + + if (hw) + ports[res->port_id].tx_ol_flags |= mask; + else + ports[res->port_id].tx_ol_flags &= (~mask); + } + + ol_flags = ports[res->port_id].tx_ol_flags; + printf("IP checksum offload is %s\n", + (ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw"); + printf("UDP checksum offload is %s\n", + (ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw"); + printf("TCP checksum offload is %s\n", + (ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw"); + printf("SCTP checksum offload is %s\n", + (ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw"); + printf("VxLAN checksum offload is %s\n", + (ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) ? "hw" : "sw"); + + /* display warnings if configuration is not supported by the NIC */ + rte_eth_dev_info_get(res->port_id, &dev_info); + if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) && + (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) { + printf("Warning: hardware IP checksum enabled but not " + "supported by port %d\n", res->port_id); + } + if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) && + (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) { + printf("Warning: hardware UDP checksum enabled but not " + "supported by port %d\n", res->port_id); + } + if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) && + (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) { + printf("Warning: hardware TCP checksum enabled but not " + "supported by port %d\n", res->port_id); + } + if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) && + (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) { + printf("Warning: hardware SCTP checksum enabled but not " + "supported by port %d\n", res->port_id); + } } -cmdline_parse_token_string_t cmd_tx_cksum_set_tx_cksum = - TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result, +cmdline_parse_token_string_t cmd_tx_cksum_tx_cksum = + TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result, tx_cksum, "tx_checksum"); -cmdline_parse_token_string_t cmd_tx_cksum_set_set = - TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result, - set, "set"); -cmdline_parse_token_num_t cmd_tx_cksum_set_cksum_mask = - TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result, - cksum_mask, UINT8); -cmdline_parse_token_num_t cmd_tx_cksum_set_portid = - TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result, +cmdline_parse_token_string_t cmd_tx_cksum_mode = + TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result, + mode, "set"); +cmdline_parse_token_string_t cmd_tx_cksum_proto = + TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result, + proto, "ip#tcp#udp#sctp#vxlan"); +cmdline_parse_token_string_t cmd_tx_cksum_hwsw = + TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result, + hwsw, "hw#sw"); +cmdline_parse_token_num_t cmd_tx_cksum_portid = + TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_result, port_id, UINT8); cmdline_parse_inst_t cmd_tx_cksum_set = { - .f = cmd_tx_cksum_set_parsed, + .f = cmd_tx_cksum_parsed, .data = NULL, - .help_str = "enable hardware insertion of L3/L4checksum with a given " - "mask in packets sent on a port, the bit mapping is given as, Bit 0 for ip, " - "Bit 1 for UDP, Bit 2 for TCP, Bit 3 for SCTP, Bit 4 for inner ip, " - "Bit 5 for inner UDP, Bit 6 for inner TCP, Bit 7 for inner SCTP", + .help_str = "enable/disable hardware calculation of L3/L4 checksum when " + "using csum forward engine: tx_cksum set ip|tcp|udp|sctp|vxlan hw|sw ", .tokens = { - (void *)&cmd_tx_cksum_set_tx_cksum, - (void *)&cmd_tx_cksum_set_set, - (void *)&cmd_tx_cksum_set_cksum_mask, - (void *)&cmd_tx_cksum_set_portid, + (void *)&cmd_tx_cksum_tx_cksum, + (void *)&cmd_tx_cksum_mode, + (void *)&cmd_tx_cksum_proto, + (void *)&cmd_tx_cksum_hwsw, + (void *)&cmd_tx_cksum_portid, + NULL, + }, +}; + +cmdline_parse_token_string_t cmd_tx_cksum_mode_show = + TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result, + mode, "show"); + +cmdline_parse_inst_t cmd_tx_cksum_show = { + .f = cmd_tx_cksum_parsed, + .data = NULL, + .help_str = "show checksum offload configuration: tx_cksum show ", + .tokens = { + (void *)&cmd_tx_cksum_tx_cksum, + (void *)&cmd_tx_cksum_mode_show, + (void *)&cmd_tx_cksum_portid, + NULL, + }, +}; + +/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */ +struct cmd_tso_set_result { + cmdline_fixed_string_t tso; + cmdline_fixed_string_t mode; + uint16_t tso_segsz; + uint8_t port_id; +}; + +static void +cmd_tso_set_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tso_set_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + + if (port_id_is_invalid(res->port_id)) + return; + + if (!strcmp(res->mode, "set")) + ports[res->port_id].tso_segsz = res->tso_segsz; + + if (ports[res->port_id].tso_segsz == 0) + printf("TSO is disabled\n"); + else + printf("TSO segment size is %d\n", + ports[res->port_id].tso_segsz); + + /* display warnings if configuration is not supported by the NIC */ + rte_eth_dev_info_get(res->port_id, &dev_info); + if ((ports[res->port_id].tso_segsz != 0) && + (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) { + printf("Warning: TSO enabled but not " + "supported by port %d\n", res->port_id); + } +} + +cmdline_parse_token_string_t cmd_tso_set_tso = + TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result, + tso, "tso"); +cmdline_parse_token_string_t cmd_tso_set_mode = + TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result, + mode, "set"); +cmdline_parse_token_num_t cmd_tso_set_tso_segsz = + TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result, + tso_segsz, UINT16); +cmdline_parse_token_num_t cmd_tso_set_portid = + TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result, + port_id, UINT8); + +cmdline_parse_inst_t cmd_tso_set = { + .f = cmd_tso_set_parsed, + .data = NULL, + .help_str = "Set TSO segment size for csum engine (0 to disable): " + "tso set ", + .tokens = { + (void *)&cmd_tso_set_tso, + (void *)&cmd_tso_set_mode, + (void *)&cmd_tso_set_tso_segsz, + (void *)&cmd_tso_set_portid, + NULL, + }, +}; + +cmdline_parse_token_string_t cmd_tso_show_mode = + TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result, + mode, "show"); + + +cmdline_parse_inst_t cmd_tso_show = { + .f = cmd_tso_set_parsed, + .data = NULL, + .help_str = "Show TSO segment size for csum engine: " + "tso show ", + .tokens = { + (void *)&cmd_tso_set_tso, + (void *)&cmd_tso_show_mode, + (void *)&cmd_tso_set_portid, NULL, }, }; @@ -3755,7 +3932,7 @@ static void cmd_create_bonded_device_parsed(void *parsed_result, /* Update number of ports */ nb_ports = rte_eth_dev_count(); - reconfig(port_id); + reconfig(port_id, res->socket); rte_eth_promiscuous_enable(port_id); } @@ -8405,6 +8582,121 @@ cmdline_parse_inst_t cmd_set_flow_director_flex_mask = { }, }; +/* *** deal with flow director flexible payload configuration *** */ +struct cmd_flow_director_flexpayload_result { + cmdline_fixed_string_t flow_director_flexpayload; + uint8_t port_id; + cmdline_fixed_string_t payload_layer; + cmdline_fixed_string_t payload_cfg; +}; + +static inline int +parse_offsets(const char *q_arg, uint16_t *offsets, uint16_t max_num) +{ + char s[256]; + const char *p, *p0 = q_arg; + char *end; + unsigned long int_fld; + char *str_fld[max_num]; + int i; + unsigned size; + int ret = -1; + + p = strchr(p0, '('); + if (p == NULL) + return -1; + ++p; + p0 = strchr(p, ')'); + if (p0 == NULL) + return -1; + + size = p0 - p; + if (size >= sizeof(s)) + return -1; + + snprintf(s, sizeof(s), "%.*s", size, p); + ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ','); + if (ret < 0 || ret > max_num) + return -1; + for (i = 0; i < ret; i++) { + errno = 0; + int_fld = strtoul(str_fld[i], &end, 0); + if (errno != 0 || *end != '\0' || int_fld > UINT16_MAX) + return -1; + offsets[i] = (uint16_t)int_fld; + } + return ret; +} + +static void +cmd_flow_director_flxpld_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_flow_director_flexpayload_result *res = parsed_result; + struct rte_eth_flex_payload_cfg flex_cfg; + struct rte_port *port; + int ret = 0; + + if (res->port_id > nb_ports) { + printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + return; + } + + port = &ports[res->port_id]; + /** Check if the port is not started **/ + if (port->port_status != RTE_PORT_STOPPED) { + printf("Please stop port %d first\n", res->port_id); + return; + } + + memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg)); + + if (!strcmp(res->payload_layer, "l2")) + flex_cfg.type = RTE_ETH_L2_PAYLOAD; + else if (!strcmp(res->payload_layer, "l3")) + flex_cfg.type = RTE_ETH_L3_PAYLOAD; + else if (!strcmp(res->payload_layer, "l4")) + flex_cfg.type = RTE_ETH_L4_PAYLOAD; + + ret = parse_offsets(res->payload_cfg, flex_cfg.src_offset, + RTE_ETH_FDIR_MAX_FLEXLEN); + if (ret < 0) { + printf("error: Cannot parse flex payload input.\n"); + return; + } + + fdir_set_flex_payload(res->port_id, &flex_cfg); + cmd_reconfig_device_queue(res->port_id, 1, 0); +} + +cmdline_parse_token_string_t cmd_flow_director_flexpayload = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result, + flow_director_flexpayload, + "flow_director_flex_payload"); +cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flexpayload_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result, + payload_layer, "l2#l3#l4"); +cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg = + TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result, + payload_cfg, NULL); + +cmdline_parse_inst_t cmd_set_flow_director_flex_payload = { + .f = cmd_flow_director_flxpld_parsed, + .data = NULL, + .help_str = "set flow director's flex payload on NIC", + .tokens = { + (void *)&cmd_flow_director_flexpayload, + (void *)&cmd_flow_director_flexpayload_port_id, + (void *)&cmd_flow_director_flexpayload_payload_layer, + (void *)&cmd_flow_director_flexpayload_payload_cfg, + NULL, + }, +}; + /* ******************************************************************************** */ /* list of instructions */ @@ -8457,6 +8749,9 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid, (cmdline_parse_inst_t *)&cmd_tx_cksum_set, + (cmdline_parse_inst_t *)&cmd_tx_cksum_show, + (cmdline_parse_inst_t *)&cmd_tso_set, + (cmdline_parse_inst_t *)&cmd_tso_show, (cmdline_parse_inst_t *)&cmd_link_flow_control_set, (cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx, (cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx, @@ -8540,6 +8835,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director, (cmdline_parse_inst_t *)&cmd_flush_flow_director, (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask, + (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload, NULL, };