X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcmdline.c;h=cdde5a16b014cc5df5897d84098565f96bf00c96;hb=69293c7762a0dbb3c28f5e93be00aaa49b52cb48;hp=f768b6b152046791c623ad956588febd9d1e6245;hpb=5ac3502ed1bec3a976d5a3c45e58344dc88cc0c4;p=dpdk.git diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index f768b6b152..cdde5a16b0 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -76,6 +75,7 @@ #include #include #include +#include #include #include @@ -87,10 +87,17 @@ #include #ifdef RTE_LIBRTE_PMD_BOND #include +#include #endif #ifdef RTE_LIBRTE_IXGBE_PMD #include #endif +#ifdef RTE_LIBRTE_I40E_PMD +#include +#endif +#ifdef RTE_LIBRTE_BNXT_PMD +#include +#endif #include "testpmd.h" static struct cmdline *testpmd_cl; @@ -183,7 +190,7 @@ static void cmd_help_long_parsed(void *parsed_result, "Display:\n" "--------\n\n" - "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n" + "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc|cap) (port_id|all)\n" " Display information for port_id, or all.\n\n" "show port X rss reta (size) (mask0,mask1,...)\n" @@ -211,6 +218,22 @@ static void cmd_help_long_parsed(void *parsed_result, "read txd (port_id) (queue_id) (txd_id)\n" " Display a TX descriptor of a port TX queue.\n\n" + + "ddp get list (port_id)\n" + " Get ddp profile info list\n\n" + + "ddp get info (profile_path)\n" + " Get ddp profile information.\n\n" + + "show vf stats (port_id) (vf_id)\n" + " Display a VF's statistics.\n\n" + + "clear vf stats (port_id) (vf_id)\n" + " Reset a VF's statistics.\n\n" + + "show port (port_id) pctype mapping\n" + " Get flow ptype to pctype mapping on a port\n\n" + ); } @@ -263,7 +286,6 @@ static void cmd_help_long_parsed(void *parsed_result, "set portlist (x[,y]*)\n" " Set the list of forwarding ports.\n\n" -#ifdef RTE_LIBRTE_IXGBE_PMD "set tx loopback (port_id) (on|off)\n" " Enable or disable tx loopback.\n\n" @@ -275,7 +297,21 @@ static void cmd_help_long_parsed(void *parsed_result, "set vf mac antispoof (port_id) (vf_id) (on|off).\n" " Set MAC antispoof for a VF from the PF.\n\n" -#endif + + "set macsec offload (port_id) on encrypt (on|off) replay-protect (on|off)\n" + " Enable MACsec offload.\n\n" + + "set macsec offload (port_id) off\n" + " Disable MACsec offload.\n\n" + + "set macsec sc (tx|rx) (port_id) (mac) (pi)\n" + " Configure MACsec secure connection (SC).\n\n" + + "set macsec sa (tx|rx) (port_id) (idx) (an) (pn) (key)\n" + " Configure MACsec secure association (SA).\n\n" + + "set vf broadcast (port_id) (vf_id) (on|off)\n" + " Set VF broadcast for a VF from the PF.\n\n" "vlan set strip (on|off) (port_id)\n" " Set the VLAN strip on a port.\n\n" @@ -283,7 +319,6 @@ static void cmd_help_long_parsed(void *parsed_result, "vlan set stripq (on|off) (port_id,queue_id)\n" " Set the VLAN strip for a queue on a port.\n\n" -#ifdef RTE_LIBRTE_IXGBE_PMD "set vf vlan stripq (port_id) (vf_id) (on|off)\n" " Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n" @@ -292,7 +327,24 @@ static void cmd_help_long_parsed(void *parsed_result, "set vf vlan antispoof (port_id) (vf_id) (on|off)\n" " Set VLAN antispoof for a VF from the PF.\n\n" -#endif + + "set vf vlan tag (port_id) (vf_id) (on|off)\n" + " Set VLAN tag for a VF from the PF.\n\n" + + "set vf tx max-bandwidth (port_id) (vf_id) (bandwidth)\n" + " Set a VF's max bandwidth(Mbps).\n\n" + + "set vf tc tx min-bandwidth (port_id) (vf_id) (bw1, bw2, ...)\n" + " Set all TCs' min bandwidth(%%) on a VF.\n\n" + + "set vf tc tx max-bandwidth (port_id) (vf_id) (tc_no) (bandwidth)\n" + " Set a TC's max bandwidth(Mbps) on a VF.\n\n" + + "set tx strict-link-priority (port_id) (tc_bitmap)\n" + " Set some TCs' strict link priority mode on a physical port.\n\n" + + "set tc tx min-bandwidth (port_id) (bw1, bw2, ...)\n" + " Set all TCs' min bandwidth(%%) for all PF and VFs.\n\n" "vlan set filter (on|off) (port_id)\n" " Set the VLAN filter on a port.\n\n" @@ -375,6 +427,14 @@ static void cmd_help_long_parsed(void *parsed_result, "tso show (portid)" " Display the status of TCP Segmentation Offload.\n\n" + "gro (on|off) (port_id)" + " Enable or disable Generic Receive Offload in" + " csum forwarding engine.\n\n" + + "gro set (max_flow_num) (max_item_num_per_flow) (port_id)\n" + " Set max flow number and max packet number per-flow" + " for GRO.\n\n" + "set fwd (%s)\n" " Set packet forwarding mode.\n\n" @@ -384,13 +444,14 @@ static void cmd_help_long_parsed(void *parsed_result, "mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)\n" " Remove a MAC address from port_id.\n\n" + "mac_addr set (port_id) (XX:XX:XX:XX:XX:XX)\n" + " Set the default MAC address for port_id.\n\n" + "mac_addr add port (port_id) vf (vf_id) (mac_address)\n" " Add a MAC address for a VF on the port.\n\n" -#ifdef RTE_LIBRTE_IXGBE_PMD "set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n" " Set the MAC address for a VF from the PF.\n\n" -#endif "set port (port_id) uta (mac_address|all) (on|off)\n" " Add/Remove a or all unicast hash filter(s)" @@ -402,6 +463,12 @@ static void cmd_help_long_parsed(void *parsed_result, "set allmulti (port_id|all) (on|off)\n" " Set the allmulti mode on port_id, or all.\n\n" + "set vf promisc (port_id) (vf_id) (on|off)\n" + " Set unicast promiscuous mode for a VF from the PF.\n\n" + + "set vf allmulti (port_id) (vf_id) (on|off)\n" + " Set multicast promiscuous mode for a VF from the PF.\n\n" + "set flow_ctrl rx (on|off) tx (on|off) (high_water)" " (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd" " (on|off) autoneg (on|off) (port_id)\n" @@ -471,7 +538,6 @@ static void cmd_help_long_parsed(void *parsed_result, " Flush (default) or don't flush RX streams before" " forwarding. Mainly used with PCAP drivers.\n\n" - #ifdef RTE_NIC_BYPASS "set bypass mode (normal|bypass|isolate) (port_id)\n" " Set the bypass mode for the lowest port on bypass enabled" " NIC.\n\n" @@ -494,7 +560,7 @@ static void cmd_help_long_parsed(void *parsed_result, "show bypass config (port_id)\n" " Show the bypass configuration for a bypass enabled NIC" " using the lowest port on the NIC.\n\n" -#endif + #ifdef RTE_LIBRTE_PMD_BOND "create bonded device (mode) (socket)\n" " Create a new bonded device with specific bonding mode and socket.\n\n" @@ -517,11 +583,18 @@ static void cmd_help_long_parsed(void *parsed_result, "set bonding mac_addr (port_id) (address)\n" " Set the MAC address of a bonded device.\n\n" + "set bonding mode IEEE802.3AD aggregator policy (port_id) (agg_name)" + " Set Aggregation mode for IEEE802.3AD (mode 4)" + "set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n" " Set the transmit balance policy for bonded device running in balance mode.\n\n" "set bonding mon_period (port_id) (value)\n" " Set the bonding link status monitoring polling period in ms.\n\n" + + "set bonding lacp dedicated_queues (enable|disable)\n" + " Enable/disable dedicated queues for LACP control traffic.\n\n" + #endif "set link-up port (port_id)\n" " Set link up for a port.\n\n" @@ -550,6 +623,24 @@ static void cmd_help_long_parsed(void *parsed_result, "E-tag set filter del e-tag-id (value) port (port_id)\n" " Delete an E-tag forwarding filter on a port\n\n" + "ddp add (port_id) (profile_path[,output_path])\n" + " Load a profile package on a port\n\n" + + "ddp del (port_id) (profile_path)\n" + " Delete a profile package from a port\n\n" + + "ptype mapping get (port_id) (valid_only)\n" + " Get ptype mapping on a port\n\n" + + "ptype mapping replace (port_id) (target) (mask) (pky_type)\n" + " Replace target with the pkt_type in ptype mapping\n\n" + + "ptype mapping reset (port_id)\n" + " Reset ptype mapping on a port\n\n" + + "ptype mapping update (port_id) (hw_ptype) (sw_ptype)\n" + " Update a ptype mapping item on a port\n\n" + , list_pkt_forwarding_modes() ); } @@ -594,7 +685,8 @@ static void cmd_help_long_parsed(void *parsed_result, " Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en" " for ports.\n\n" - "port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n" + "port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|" + "geneve|nvgre|none|)\n" " Set the RSS mode.\n\n" "port config port-id rss reta (hash,queue)[,(hash,queue)]\n" @@ -629,6 +721,13 @@ static void cmd_help_long_parsed(void *parsed_result, "port config (port_id|all) l2-tunnel E-tag" " (enable|disable)\n" " Enable/disable the E-tag support.\n\n" + + "port config (port_id) pctype mapping reset\n" + " Reset flow type to pctype mapping on a port\n\n" + + "port config (port_id) pctype mapping update" + " (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n" + " Update a flow type to pctype mapping item on a port\n\n" ); } @@ -791,8 +890,8 @@ static void cmd_help_long_parsed(void *parsed_result, "set_hash_input_set (port_id) (ipv4|ipv4-frag|" "ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|" "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|" - "l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|" - "dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|" + "l2_payload|) (ovlan|ivlan|src-ipv4|dst-ipv4|" + "src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|" "ipv6-next-header|udp-src-port|udp-dst-port|" "tcp-src-port|tcp-dst-port|sctp-src-port|" "sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|" @@ -837,6 +936,10 @@ static void cmd_help_long_parsed(void *parsed_result, "flow list {port_id} [group {group_id}] [...]\n" " List existing flow rules sorted by priority," " filtered by group identifiers.\n\n" + + "flow isolate {port_id} {boolean}\n" + " Restrict ingress traffic to the defined" + " flow rules\n\n" ); } } @@ -881,6 +984,8 @@ static void cmd_operate_port_parsed(void *parsed_result, stop_port(RTE_PORT_ALL); else if (!strcmp(res->name, "close")) close_port(RTE_PORT_ALL); + else if (!strcmp(res->name, "reset")) + reset_port(RTE_PORT_ALL); else printf("Unknown parameter\n"); } @@ -890,14 +995,14 @@ cmdline_parse_token_string_t cmd_operate_port_all_cmd = "port"); cmdline_parse_token_string_t cmd_operate_port_all_port = TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, name, - "start#stop#close"); + "start#stop#close#reset"); cmdline_parse_token_string_t cmd_operate_port_all_all = TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, value, "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 all ports", + .help_str = "port start|stop|close all: Start/Stop/Close/Reset all ports", .tokens = { (void *)&cmd_operate_port_all_cmd, (void *)&cmd_operate_port_all_port, @@ -925,6 +1030,8 @@ static void cmd_operate_specific_port_parsed(void *parsed_result, stop_port(res->value); else if (!strcmp(res->name, "close")) close_port(res->value); + else if (!strcmp(res->name, "reset")) + reset_port(res->value); else printf("Unknown parameter\n"); } @@ -934,7 +1041,7 @@ cmdline_parse_token_string_t cmd_operate_specific_port_cmd = keyword, "port"); cmdline_parse_token_string_t cmd_operate_specific_port_port = TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result, - name, "start#stop#close"); + name, "start#stop#close#reset"); cmdline_parse_token_num_t cmd_operate_specific_port_id = TOKEN_NUM_INITIALIZER(struct cmd_operate_specific_port_result, value, UINT8); @@ -942,7 +1049,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 port_id", + .help_str = "port start|stop|close : Start/Stop/Close/Reset port_id", .tokens = { (void *)&cmd_operate_specific_port_cmd, (void *)&cmd_operate_specific_port_port, @@ -1114,7 +1221,7 @@ cmd_config_speed_all_parsed(void *parsed_result, &link_speed) < 0) return; - FOREACH_PORT(pid, ports) { + RTE_ETH_FOREACH_DEV(pid) { ports[pid].dev_conf.link_speeds = link_speed; } @@ -1625,6 +1732,9 @@ cmd_config_rss_parsed(void *parsed_result, rss_conf.rss_hf = ETH_RSS_NVGRE; else if (!strcmp(res->value, "none")) rss_conf.rss_hf = 0; + else if (isdigit(res->value[0]) && atoi(res->value) > 0 && + atoi(res->value) < 64) + rss_conf.rss_hf = 1ULL << atoi(res->value); else { printf("Unknown parameter\n"); return; @@ -1648,14 +1758,13 @@ cmdline_parse_token_string_t cmd_config_rss_all = cmdline_parse_token_string_t cmd_config_rss_name = TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss"); cmdline_parse_token_string_t cmd_config_rss_value = - TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, - "all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none"); + TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL); cmdline_parse_inst_t cmd_config_rss = { .f = cmd_config_rss_parsed, .data = NULL, .help_str = "port config all rss " - "all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none", + "all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none|", .tokens = { (void *)&cmd_config_rss_port, (void *)&cmd_config_rss_keyword, @@ -2035,7 +2144,9 @@ showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf, char s[256]; char *end; char *str_fld[8]; - uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE; + uint16_t i; + uint16_t num = (nb_entries + RTE_RETA_GROUP_SIZE - 1) / + RTE_RETA_GROUP_SIZE; int ret; p = strchr(p0, '('); @@ -3756,6 +3867,120 @@ cmdline_parse_inst_t cmd_tunnel_tso_show = { }, }; +/* *** SET GRO FOR A PORT *** */ +struct cmd_gro_result { + cmdline_fixed_string_t cmd_keyword; + cmdline_fixed_string_t mode; + uint8_t port_id; +}; + +static void +cmd_enable_gro_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_gro_result *res; + + res = parsed_result; + setup_gro(res->mode, res->port_id); +} + +cmdline_parse_token_string_t cmd_gro_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_gro_result, + cmd_keyword, "gro"); +cmdline_parse_token_string_t cmd_gro_mode = + TOKEN_STRING_INITIALIZER(struct cmd_gro_result, + mode, "on#off"); +cmdline_parse_token_num_t cmd_gro_pid = + TOKEN_NUM_INITIALIZER(struct cmd_gro_result, + port_id, UINT8); + +cmdline_parse_inst_t cmd_enable_gro = { + .f = cmd_enable_gro_parsed, + .data = NULL, + .help_str = "gro (on|off) (port_id)", + .tokens = { + (void *)&cmd_gro_keyword, + (void *)&cmd_gro_mode, + (void *)&cmd_gro_pid, + NULL, + }, +}; + +/* *** SET MAX FLOW NUMBER AND ITEM NUM PER FLOW FOR GRO *** */ +struct cmd_gro_set_result { + cmdline_fixed_string_t gro; + cmdline_fixed_string_t mode; + uint16_t flow_num; + uint16_t item_num_per_flow; + uint8_t port_id; +}; + +static void +cmd_gro_set_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_gro_set_result *res = parsed_result; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + if (test_done == 0) { + printf("Before set GRO flow_num and item_num_per_flow," + " please stop forwarding first\n"); + return; + } + + if (!strcmp(res->mode, "set")) { + if (res->flow_num == 0) + printf("Invalid flow number. Revert to default value:" + " %u.\n", GRO_DEFAULT_FLOW_NUM); + else + gro_ports[res->port_id].param.max_flow_num = + res->flow_num; + + if (res->item_num_per_flow == 0) + printf("Invalid item number per-flow. Revert" + " to default value:%u.\n", + GRO_DEFAULT_ITEM_NUM_PER_FLOW); + else + gro_ports[res->port_id].param.max_item_per_flow = + res->item_num_per_flow; + } +} + +cmdline_parse_token_string_t cmd_gro_set_gro = + TOKEN_STRING_INITIALIZER(struct cmd_gro_set_result, + gro, "gro"); +cmdline_parse_token_string_t cmd_gro_set_mode = + TOKEN_STRING_INITIALIZER(struct cmd_gro_set_result, + mode, "set"); +cmdline_parse_token_num_t cmd_gro_set_flow_num = + TOKEN_NUM_INITIALIZER(struct cmd_gro_set_result, + flow_num, UINT16); +cmdline_parse_token_num_t cmd_gro_set_item_num_per_flow = + TOKEN_NUM_INITIALIZER(struct cmd_gro_set_result, + item_num_per_flow, UINT16); +cmdline_parse_token_num_t cmd_gro_set_portid = + TOKEN_NUM_INITIALIZER(struct cmd_gro_set_result, + port_id, UINT8); + +cmdline_parse_inst_t cmd_gro_set = { + .f = cmd_gro_set_parsed, + .data = NULL, + .help_str = "gro set " + ": set max flow number and max packet number per-flow " + "for GRO", + .tokens = { + (void *)&cmd_gro_set_gro, + (void *)&cmd_gro_set_mode, + (void *)&cmd_gro_set_flow_num, + (void *)&cmd_gro_set_item_num_per_flow, + (void *)&cmd_gro_set_portid, + NULL, + }, +}; + /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */ struct cmd_set_flush_rx { cmdline_fixed_string_t set; @@ -3835,7 +4060,6 @@ cmdline_parse_inst_t cmd_set_link_check = { }, }; -#ifdef RTE_NIC_BYPASS /* *** SET NIC BYPASS MODE *** */ struct cmd_set_bypass_mode_result { cmdline_fixed_string_t set; @@ -3852,19 +4076,23 @@ cmd_set_bypass_mode_parsed(void *parsed_result, { struct cmd_set_bypass_mode_result *res = parsed_result; portid_t port_id = res->port_id; - uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL; + int32_t rc = -EINVAL; + +#if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS + uint32_t bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_NORMAL; if (!strcmp(res->value, "bypass")) - bypass_mode = RTE_BYPASS_MODE_BYPASS; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_BYPASS; else if (!strcmp(res->value, "isolate")) - bypass_mode = RTE_BYPASS_MODE_ISOLATE; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_ISOLATE; else - bypass_mode = RTE_BYPASS_MODE_NORMAL; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_NORMAL; /* Set the bypass mode for the relevant port. */ - if (0 != rte_eth_dev_bypass_state_set(port_id, &bypass_mode)) { + rc = rte_pmd_ixgbe_bypass_state_set(port_id, &bypass_mode); +#endif + if (rc != 0) printf("\t Failed to set bypass mode for port = %d.\n", port_id); - } } cmdline_parse_token_string_t cmd_setbypass_mode_set = @@ -3914,51 +4142,57 @@ cmd_set_bypass_event_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { - int32_t rc; + int32_t rc = -EINVAL; struct cmd_set_bypass_event_result *res = parsed_result; portid_t port_id = res->port_id; - uint32_t bypass_event = RTE_BYPASS_EVENT_NONE; - uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL; + +#if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS + uint32_t bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_NONE; + uint32_t bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_NORMAL; if (!strcmp(res->event_value, "timeout")) - bypass_event = RTE_BYPASS_EVENT_TIMEOUT; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_TIMEOUT; else if (!strcmp(res->event_value, "os_on")) - bypass_event = RTE_BYPASS_EVENT_OS_ON; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_OS_ON; else if (!strcmp(res->event_value, "os_off")) - bypass_event = RTE_BYPASS_EVENT_OS_OFF; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_OS_OFF; else if (!strcmp(res->event_value, "power_on")) - bypass_event = RTE_BYPASS_EVENT_POWER_ON; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_POWER_ON; else if (!strcmp(res->event_value, "power_off")) - bypass_event = RTE_BYPASS_EVENT_POWER_OFF; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_POWER_OFF; else - bypass_event = RTE_BYPASS_EVENT_NONE; + bypass_event = RTE_PMD_IXGBE_BYPASS_EVENT_NONE; if (!strcmp(res->mode_value, "bypass")) - bypass_mode = RTE_BYPASS_MODE_BYPASS; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_BYPASS; else if (!strcmp(res->mode_value, "isolate")) - bypass_mode = RTE_BYPASS_MODE_ISOLATE; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_ISOLATE; else - bypass_mode = RTE_BYPASS_MODE_NORMAL; + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_NORMAL; /* Set the watchdog timeout. */ - if (bypass_event == RTE_BYPASS_EVENT_TIMEOUT) { + if (bypass_event == RTE_PMD_IXGBE_BYPASS_EVENT_TIMEOUT) { rc = -EINVAL; - if (!RTE_BYPASS_TMT_VALID(bypass_timeout) || - (rc = rte_eth_dev_wd_timeout_store(port_id, - bypass_timeout)) != 0) { + if (RTE_PMD_IXGBE_BYPASS_TMT_VALID(bypass_timeout)) { + rc = rte_pmd_ixgbe_bypass_wd_timeout_store(port_id, + bypass_timeout); + } + if (rc != 0) { printf("Failed to set timeout value %u " - "for port %d, errto code: %d.\n", - bypass_timeout, port_id, rc); + "for port %d, errto code: %d.\n", + bypass_timeout, port_id, rc); } } /* Set the bypass event to transition to bypass mode. */ - if (0 != rte_eth_dev_bypass_event_store(port_id, - bypass_event, bypass_mode)) { - printf("\t Failed to set bypass event for port = %d.\n", port_id); - } + rc = rte_pmd_ixgbe_bypass_event_store(port_id, bypass_event, + bypass_mode); +#endif + if (rc != 0) + printf("\t Failed to set bypass event for port = %d.\n", + port_id); } cmdline_parse_token_string_t cmd_setbypass_event_set = @@ -4015,24 +4249,26 @@ cmd_set_bypass_timeout_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { - struct cmd_set_bypass_timeout_result *res = parsed_result; + __rte_unused struct cmd_set_bypass_timeout_result *res = parsed_result; +#if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS if (!strcmp(res->value, "1.5")) - bypass_timeout = RTE_BYPASS_TMT_1_5_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_1_5_SEC; else if (!strcmp(res->value, "2")) - bypass_timeout = RTE_BYPASS_TMT_2_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_2_SEC; else if (!strcmp(res->value, "3")) - bypass_timeout = RTE_BYPASS_TMT_3_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_3_SEC; else if (!strcmp(res->value, "4")) - bypass_timeout = RTE_BYPASS_TMT_4_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_4_SEC; else if (!strcmp(res->value, "8")) - bypass_timeout = RTE_BYPASS_TMT_8_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_8_SEC; else if (!strcmp(res->value, "16")) - bypass_timeout = RTE_BYPASS_TMT_16_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_16_SEC; else if (!strcmp(res->value, "32")) - bypass_timeout = RTE_BYPASS_TMT_32_SEC; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_32_SEC; else - bypass_timeout = RTE_BYPASS_TMT_OFF; + bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF; +#endif } cmdline_parse_token_string_t cmd_setbypass_timeout_set = @@ -4076,17 +4312,19 @@ cmd_show_bypass_config_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_show_bypass_config_result *res = parsed_result; + portid_t port_id = res->port_id; + int rc = -EINVAL; +#if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS uint32_t event_mode; uint32_t bypass_mode; - portid_t port_id = res->port_id; uint32_t timeout = bypass_timeout; int i; - static const char * const timeouts[RTE_BYPASS_TMT_NUM] = + static const char * const timeouts[RTE_PMD_IXGBE_BYPASS_TMT_NUM] = {"off", "1.5", "2", "3", "4", "8", "16", "32"}; - static const char * const modes[RTE_BYPASS_MODE_NUM] = + static const char * const modes[RTE_PMD_IXGBE_BYPASS_MODE_NUM] = {"UNKNOWN", "normal", "bypass", "isolate"}; - static const char * const events[RTE_BYPASS_EVENT_NUM] = { + static const char * const events[RTE_PMD_IXGBE_BYPASS_EVENT_NUM] = { "NONE", "OS/board on", "power supply on", @@ -4096,37 +4334,41 @@ cmd_show_bypass_config_parsed(void *parsed_result, int num_events = (sizeof events) / (sizeof events[0]); /* Display the bypass mode.*/ - if (0 != rte_eth_dev_bypass_state_show(port_id, &bypass_mode)) { + if (rte_pmd_ixgbe_bypass_state_show(port_id, &bypass_mode) != 0) { printf("\tFailed to get bypass mode for port = %d\n", port_id); return; } else { - if (!RTE_BYPASS_MODE_VALID(bypass_mode)) - bypass_mode = RTE_BYPASS_MODE_NONE; + if (!RTE_PMD_IXGBE_BYPASS_MODE_VALID(bypass_mode)) + bypass_mode = RTE_PMD_IXGBE_BYPASS_MODE_NONE; printf("\tbypass mode = %s\n", modes[bypass_mode]); } /* Display the bypass timeout.*/ - if (!RTE_BYPASS_TMT_VALID(timeout)) - timeout = RTE_BYPASS_TMT_OFF; + if (!RTE_PMD_IXGBE_BYPASS_TMT_VALID(timeout)) + timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF; printf("\tbypass timeout = %s\n", timeouts[timeout]); /* Display the bypass events and associated modes. */ - for (i = RTE_BYPASS_EVENT_START; i < num_events; i++) { + for (i = RTE_PMD_IXGBE_BYPASS_EVENT_START; i < num_events; i++) { - if (0 != rte_eth_dev_bypass_event_show(port_id, i, &event_mode)) { + if (rte_pmd_ixgbe_bypass_event_show(port_id, i, &event_mode)) { printf("\tFailed to get bypass mode for event = %s\n", events[i]); } else { - if (!RTE_BYPASS_MODE_VALID(event_mode)) - event_mode = RTE_BYPASS_MODE_NONE; + if (!RTE_PMD_IXGBE_BYPASS_MODE_VALID(event_mode)) + event_mode = RTE_PMD_IXGBE_BYPASS_MODE_NONE; printf("\tbypass event: %-16s = %s\n", events[i], modes[event_mode]); } } +#endif + if (rc != 0) + printf("\tFailed to get bypass configuration for port = %d\n", + port_id); } cmdline_parse_token_string_t cmd_showbypass_config_show = @@ -4155,7 +4397,6 @@ cmdline_parse_inst_t cmd_show_bypass_config = { NULL, }, }; -#endif #ifdef RTE_LIBRTE_PMD_BOND /* *** SET BONDING MODE *** */ @@ -4210,6 +4451,85 @@ cmdline_parse_inst_t cmd_set_bonding_mode = { } }; +/* *** SET BONDING SLOW_QUEUE SW/HW *** */ +struct cmd_set_bonding_lacp_dedicated_queues_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t bonding; + cmdline_fixed_string_t lacp; + cmdline_fixed_string_t dedicated_queues; + uint8_t port_id; + cmdline_fixed_string_t mode; +}; + +static void cmd_set_bonding_lacp_dedicated_queues_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_bonding_lacp_dedicated_queues_result *res = parsed_result; + portid_t port_id = res->port_id; + struct rte_port *port; + + port = &ports[port_id]; + + /** Check if the port is not started **/ + if (port->port_status != RTE_PORT_STOPPED) { + printf("Please stop port %d first\n", port_id); + return; + } + + if (!strcmp(res->mode, "enable")) { + if (rte_eth_bond_8023ad_dedicated_queues_enable(port_id) == 0) + printf("Dedicate queues for LACP control packets" + " enabled\n"); + else + printf("Enabling dedicate queues for LACP control " + "packets on port %d failed\n", port_id); + } else if (!strcmp(res->mode, "disable")) { + if (rte_eth_bond_8023ad_dedicated_queues_disable(port_id) == 0) + printf("Dedicated queues for LACP control packets " + "disabled\n"); + else + printf("Disabling dedicated queues for LACP control " + "traffic on port %d failed\n", port_id); + } +} + +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_set = +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + set, "set"); +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_bonding = +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + bonding, "bonding"); +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_lacp = +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + lacp, "lacp"); +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_dedicated_queues = +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + dedicated_queues, "dedicated_queues"); +cmdline_parse_token_num_t cmd_setbonding_lacp_dedicated_queues_port_id = +TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_setbonding_lacp_dedicated_queues_mode = +TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_lacp_dedicated_queues_result, + mode, "enable#disable"); + +cmdline_parse_inst_t cmd_set_lacp_dedicated_queues = { + .f = cmd_set_bonding_lacp_dedicated_queues_parsed, + .help_str = "set bonding lacp dedicated_queues " + "enable|disable: " + "Enable/disable dedicated queues for LACP control traffic for port_id", + .data = NULL, + .tokens = { + (void *)&cmd_setbonding_lacp_dedicated_queues_set, + (void *)&cmd_setbonding_lacp_dedicated_queues_bonding, + (void *)&cmd_setbonding_lacp_dedicated_queues_lacp, + (void *)&cmd_setbonding_lacp_dedicated_queues_dedicated_queues, + (void *)&cmd_setbonding_lacp_dedicated_queues_port_id, + (void *)&cmd_setbonding_lacp_dedicated_queues_mode, + NULL + } +}; + /* *** SET BALANCE XMIT POLICY *** */ struct cmd_set_bonding_balance_xmit_policy_result { cmdline_fixed_string_t set; @@ -4290,7 +4610,7 @@ static void cmd_show_bonding_config_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_show_bonding_config_result *res = parsed_result; - int bonding_mode; + int bonding_mode, agg_mode; uint8_t slaves[RTE_MAX_ETHPORTS]; int num_slaves, num_active_slaves; int primary_id; @@ -4331,6 +4651,23 @@ static void cmd_show_bonding_config_parsed(void *parsed_result, } } + if (bonding_mode == BONDING_MODE_8023AD) { + agg_mode = rte_eth_bond_8023ad_agg_selection_get(port_id); + printf("\tIEEE802.3AD Aggregator Mode: "); + switch (agg_mode) { + case AGG_BANDWIDTH: + printf("bandwidth"); + break; + case AGG_STABLE: + printf("stable"); + break; + case AGG_COUNT: + printf("count"); + break; + } + printf("\n"); + } + num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS); if (num_slaves < 0) { @@ -4477,7 +4814,7 @@ static void cmd_add_bonding_slave_parsed(void *parsed_result, portid_t master_port_id = res->port_id; portid_t slave_port_id = res->slave_id; - /* Set the primary slave for a bonded device. */ + /* add the slave for a bonded device. */ if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) { printf("\t Failed to add slave %d to master port = %d.\n", slave_port_id, master_port_id); @@ -4535,7 +4872,7 @@ static void cmd_remove_bonding_slave_parsed(void *parsed_result, portid_t master_port_id = res->port_id; portid_t slave_port_id = res->slave_id; - /* Set the primary slave for a bonded device. */ + /* remove the slave from a bonded device. */ if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) { printf("\t Failed to remove slave %d from master port = %d.\n", slave_port_id, master_port_id); @@ -4600,7 +4937,7 @@ static void cmd_create_bonded_device_parsed(void *parsed_result, return; } - snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bond_testpmd_%d", + snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bonding_testpmd_%d", bond_dev_num++); /* Create a new bonded device. */ @@ -4616,7 +4953,6 @@ static void cmd_create_bonded_device_parsed(void *parsed_result, nb_ports = rte_eth_dev_count(); reconfig(port_id, res->socket); rte_eth_promiscuous_enable(port_id); - ports[port_id].enabled = 1; } } @@ -4764,6 +5100,77 @@ cmdline_parse_inst_t cmd_set_bond_mon_period = { } }; + + +struct cmd_set_bonding_agg_mode_policy_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t bonding; + cmdline_fixed_string_t agg_mode; + uint8_t port_num; + cmdline_fixed_string_t policy; +}; + + +static void +cmd_set_bonding_agg_mode(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_bonding_agg_mode_policy_result *res = parsed_result; + uint8_t policy = AGG_BANDWIDTH; + + if (res->port_num >= nb_ports) { + printf("Port id %d must be less than %d\n", + res->port_num, nb_ports); + return; + } + + if (!strcmp(res->policy, "bandwidth")) + policy = AGG_BANDWIDTH; + else if (!strcmp(res->policy, "stable")) + policy = AGG_STABLE; + else if (!strcmp(res->policy, "count")) + policy = AGG_COUNT; + + rte_eth_bond_8023ad_agg_selection_set(res->port_num, policy); +} + + +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_bonding = + TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, + bonding, "bonding"); + +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_agg_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, + agg_mode, "agg_mode"); + +cmdline_parse_token_num_t cmd_set_bonding_agg_mode_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_agg_mode_policy_result, + port_num, UINT8); + +cmdline_parse_token_string_t cmd_set_bonding_agg_mode_policy_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_bonding_balance_xmit_policy_result, + policy, "stable#bandwidth#count"); + +cmdline_parse_inst_t cmd_set_bonding_agg_mode_policy = { + .f = cmd_set_bonding_agg_mode, + .data = (void *) 0, + .help_str = "set bonding mode IEEE802.3AD aggregator policy ", + .tokens = { + (void *)&cmd_set_bonding_agg_mode_set, + (void *)&cmd_set_bonding_agg_mode_bonding, + (void *)&cmd_set_bonding_agg_mode_agg_mode, + (void *)&cmd_set_bonding_agg_mode_portnum, + (void *)&cmd_set_bonding_agg_mode_policy_string, + NULL + } +}; + + #endif /* RTE_LIBRTE_PMD_BOND */ /* *** SET FORWARDING MODE *** */ @@ -4975,7 +5382,7 @@ static void cmd_set_promisc_mode_parsed(void *parsed_result, /* all ports */ if (allports) { - FOREACH_PORT(i, ports) { + RTE_ETH_FOREACH_DEV(i) { if (enable) rte_eth_promiscuous_enable(i); else @@ -5055,7 +5462,7 @@ static void cmd_set_allmulti_mode_parsed(void *parsed_result, /* all ports */ if (allports) { - FOREACH_PORT(i, ports) { + RTE_ETH_FOREACH_DEV(i) { if (enable) rte_eth_allmulticast_enable(i); else @@ -5418,7 +5825,7 @@ cmd_link_flow_ctrl_set_parsed(void *parsed_result, printf("bad flow contrl parameter, return code = %d \n", ret); } -/* *** SETUP ETHERNET PIRORITY FLOW CONTROL *** */ +/* *** SETUP ETHERNET PRIORITY FLOW CONTROL *** */ struct cmd_priority_flow_ctrl_set_result { cmdline_fixed_string_t set; cmdline_fixed_string_t pfc_ctrl; @@ -5789,29 +6196,32 @@ static void cmd_showportall_parsed(void *parsed_result, struct cmd_showportall_result *res = parsed_result; if (!strcmp(res->show, "clear")) { if (!strcmp(res->what, "stats")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) nic_stats_clear(i); else if (!strcmp(res->what, "xstats")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) nic_xstats_clear(i); } else if (!strcmp(res->what, "info")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) port_infos_display(i); else if (!strcmp(res->what, "stats")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) nic_stats_display(i); else if (!strcmp(res->what, "xstats")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) nic_xstats_display(i); else if (!strcmp(res->what, "fdir")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) fdir_get_infos(i); else if (!strcmp(res->what, "stat_qmap")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) nic_stats_mapping_display(i); else if (!strcmp(res->what, "dcb_tc")) - FOREACH_PORT(i, ports) + RTE_ETH_FOREACH_DEV(i) port_dcb_info_display(i); + else if (!strcmp(res->what, "cap")) + RTE_ETH_FOREACH_DEV(i) + port_offload_cap_display(i); } cmdline_parse_token_string_t cmd_showportall_show = @@ -5821,13 +6231,14 @@ cmdline_parse_token_string_t cmd_showportall_port = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port"); cmdline_parse_token_string_t cmd_showportall_what = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what, - "info#stats#xstats#fdir#stat_qmap#dcb_tc"); + "info#stats#xstats#fdir#stat_qmap#dcb_tc#cap"); cmdline_parse_token_string_t cmd_showportall_all = TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all"); cmdline_parse_inst_t cmd_showportall = { .f = cmd_showportall_parsed, .data = NULL, - .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all", + .help_str = "show|clear port " + "info|stats|xstats|fdir|stat_qmap|dcb_tc|cap all", .tokens = { (void *)&cmd_showportall_show, (void *)&cmd_showportall_port, @@ -5867,6 +6278,8 @@ static void cmd_showport_parsed(void *parsed_result, nic_stats_mapping_display(res->portnum); else if (!strcmp(res->what, "dcb_tc")) port_dcb_info_display(res->portnum); + else if (!strcmp(res->what, "cap")) + port_offload_cap_display(res->portnum); } cmdline_parse_token_string_t cmd_showport_show = @@ -5876,14 +6289,15 @@ cmdline_parse_token_string_t cmd_showport_port = TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port"); cmdline_parse_token_string_t cmd_showport_what = TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what, - "info#stats#xstats#fdir#stat_qmap#dcb_tc"); + "info#stats#xstats#fdir#stat_qmap#dcb_tc#cap"); cmdline_parse_token_num_t cmd_showport_portnum = TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8); cmdline_parse_inst_t cmd_showport = { .f = cmd_showport_parsed, .data = NULL, - .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc " + .help_str = "show|clear port " + "info|stats|xstats|fdir|stat_qmap|dcb_tc|cap " "", .tokens = { (void *)&cmd_showport_show, @@ -6324,6 +6738,9 @@ static void cmd_mac_addr_parsed(void *parsed_result, if (strcmp(res->what, "add") == 0) ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0); + else if (strcmp(res->what, "set") == 0) + ret = rte_eth_dev_default_mac_addr_set(res->port_num, + &res->address); else ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address); @@ -6338,7 +6755,7 @@ cmdline_parse_token_string_t cmd_mac_addr_cmd = "mac_addr"); cmdline_parse_token_string_t cmd_mac_addr_what = TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what, - "add#remove"); + "add#remove#set"); cmdline_parse_token_num_t cmd_mac_addr_portnum = TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8); cmdline_parse_token_etheraddr_t cmd_mac_addr_addr = @@ -6347,8 +6764,8 @@ cmdline_parse_token_etheraddr_t cmd_mac_addr_addr = cmdline_parse_inst_t cmd_mac_addr = { .f = cmd_mac_addr_parsed, .data = (void *)0, - .help_str = "mac_addr add|remove : " - "Add/Remove MAC address on port_id", + .help_str = "mac_addr add|remove|set : " + "Add/Remove/Set MAC address on port_id", .tokens = { (void *)&cmd_mac_addr_cmd, (void *)&cmd_mac_addr_what, @@ -6561,7 +6978,7 @@ cmd_set_vf_macvlan_parsed(void *parsed_result, memset(&filter, 0, sizeof(struct rte_eth_mac_filter)); - (void)rte_memcpy(&filter.mac_addr, &res->address, ETHER_ADDR_LEN); + rte_memcpy(&filter.mac_addr, &res->address, ETHER_ADDR_LEN); /* set VF MAC filter */ filter.is_vf = 1; @@ -6720,7 +7137,7 @@ cmd_set_vf_rxmode_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { - int ret; + int ret = -ENOTSUP; uint16_t rx_mode = 0; struct cmd_set_vf_rxmode *res = parsed_result; @@ -6736,7 +7153,16 @@ cmd_set_vf_rxmode_parsed(void *parsed_result, rx_mode |= ETH_VMDQ_ACCEPT_MULTICAST; } - ret = rte_eth_dev_set_vf_rxmode(res->port_id,res->vf_id,rx_mode,(uint8_t)is_on); +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id, + rx_mode, (uint8_t)is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_rxmode(res->port_id, res->vf_id, + rx_mode, (uint8_t)is_on); +#endif if (ret < 0) printf("bad VF receive mode parameter, return code = %d \n", ret); @@ -6801,11 +7227,22 @@ static void cmd_vf_mac_addr_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_vf_mac_addr_result *res = parsed_result; - int ret = 0; + int ret = -ENOTSUP; + + if (strcmp(res->what, "add") != 0) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_add_vf_mac_addr(res->port_num, res->vf_num, + &res->address); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_mac_addr_add(res->port_num, &res->address, + res->vf_num); +#endif - if (strcmp(res->what, "add") == 0) - ret = rte_eth_dev_mac_addr_add(res->port_num, - &res->address, res->vf_num); if(ret < 0) printf("vf_mac_addr_cmd error: (%s)\n", strerror(-ret)); @@ -6867,11 +7304,42 @@ cmd_vf_rx_vlan_filter_parsed(void *parsed_result, __attribute__((unused)) void *data) { struct cmd_vf_rx_vlan_filter *res = parsed_result; + int ret = -ENOTSUP; - if (!strcmp(res->what, "add")) - set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 1); - else - set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 0); + __rte_unused int is_add = (strcmp(res->what, "add") == 0) ? 1 : 0; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_vlan_filter(res->port_id, + res->vlan_id, res->vf_mask, is_add); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_vlan_filter(res->port_id, + res->vlan_id, res->vf_mask, is_add); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_vlan_filter(res->port_id, + res->vlan_id, res->vf_mask, is_add); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vlan_id %d or vf_mask %"PRIu64"\n", + res->vlan_id, res->vf_mask); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented or supported\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } } cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_rx_vlan = @@ -7435,7 +7903,7 @@ cmdline_parse_inst_t cmd_set_mirror_mask = { }, }; -/* *** CONFIGURE VM MIRROR UDLINK/DOWNLINK RULE *** */ +/* *** CONFIGURE VM MIRROR UPLINK/DOWNLINK RULE *** */ struct cmd_set_mirror_link_result { cmdline_fixed_string_t set; cmdline_fixed_string_t port; @@ -7611,6 +8079,8 @@ static void cmd_dump_parsed(void *parsed_result, rte_mempool_list_dump(stdout); else if (!strcmp(res->dump, "dump_devargs")) rte_eal_devargs_dump(stdout); + else if (!strcmp(res->dump, "dump_log_types")) + rte_log_dump(stdout); } cmdline_parse_token_string_t cmd_dump_dump = @@ -7620,7 +8090,8 @@ cmdline_parse_token_string_t cmd_dump_dump = "dump_struct_sizes#" "dump_ring#" "dump_mempool#" - "dump_devargs"); + "dump_devargs#" + "dump_log_types"); cmdline_parse_inst_t cmd_dump = { .f = cmd_dump_parsed, /* function to call */ @@ -8381,7 +8852,7 @@ cmd_ethertype_filter_parsed(void *parsed_result, memset(&filter, 0, sizeof(filter)); if (!strcmp(res->mac, "mac_addr")) { filter.flags |= RTE_ETHTYPE_FLAGS_MAC; - (void)rte_memcpy(&filter.mac_addr, &res->mac_addr, + rte_memcpy(&filter.mac_addr, &res->mac_addr, sizeof(struct ether_addr)); } if (!strcmp(res->drop, "drop")) @@ -8534,6 +9005,10 @@ str2flowtype(char *string) if (!strcmp(flowtype_str[i].str, string)) return flowtype_str[i].type; } + + if (isdigit(string[0]) && atoi(string) > 0 && atoi(string) < 64) + return (uint16_t)atoi(string); + return RTE_ETH_FLOW_UNKNOWN; } @@ -8570,7 +9045,7 @@ do { \ #define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \ do { \ if ((ip_addr).family == AF_INET6) \ - (void)rte_memcpy(&(ip), \ + rte_memcpy(&(ip), \ &((ip_addr).addr.ipv6), \ sizeof(struct in6_addr)); \ else { \ @@ -8630,6 +9105,7 @@ cmd_flow_director_filter_parsed(void *parsed_result, case RTE_ETH_FLOW_FRAG_IPV4: case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: entry.input.flow.ip4_flow.proto = res->proto_value; + /* fall-through */ case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: IPV4_ADDR_TO_UINT(res->ip_dst, @@ -8662,6 +9138,7 @@ cmd_flow_director_filter_parsed(void *parsed_result, case RTE_ETH_FLOW_FRAG_IPV6: case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: entry.input.flow.ipv6_flow.proto = res->proto_value; + /* fall-through */ case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: IPV6_ADDR_TO_ARRAY(res->ip_dst, @@ -8700,12 +9177,12 @@ cmd_flow_director_filter_parsed(void *parsed_result, } if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) - (void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr, + rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr, &res->mac_addr, sizeof(struct ether_addr)); if (fdir_conf.mode == RTE_FDIR_MODE_PERFECT_TUNNEL) { - (void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr, + rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr, &res->mac_addr, sizeof(struct ether_addr)); entry.input.flow.tunnel_flow.tunnel_type = @@ -8714,7 +9191,7 @@ cmd_flow_director_filter_parsed(void *parsed_result, rte_cpu_to_be_32(res->tunnel_id_value); } - (void)rte_memcpy(entry.input.flow_ext.flexbytes, + rte_memcpy(entry.input.flow_ext.flexbytes, flexbytes, RTE_ETH_FDIR_MAX_FLEXLEN); @@ -9412,7 +9889,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result, memset(&port->dev_conf.fdir_conf.flex_conf.flex_mask[i], 0, sizeof(struct rte_eth_fdir_flex_mask)); port->dev_conf.fdir_conf.flex_conf.nb_flexmasks = 1; - (void)rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0], + rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0], &flex_mask, sizeof(struct rte_eth_fdir_flex_mask)); cmd_reconfig_device_queue(res->port_id, 1, 1); @@ -10008,9 +10485,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id = port_id, UINT8); cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type = TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result, - flow_type, - "ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#" - "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload"); + flow_type, NULL); cmdline_parse_token_string_t cmd_set_hash_input_set_field = TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result, inset_field, @@ -10029,7 +10504,7 @@ cmdline_parse_inst_t cmd_set_hash_input_set = { .data = NULL, .help_str = "set_hash_input_set " "ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|" - "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload " + "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload| " "ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|" "ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|" "tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|" @@ -10253,7 +10728,7 @@ cmd_config_l2_tunnel_eth_type_all_parsed entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type); entry.ether_type = res->eth_type_val; - FOREACH_PORT(pid, ports) { + RTE_ETH_FOREACH_DEV(pid) { rte_eth_dev_l2_tunnel_eth_type_conf(pid, &entry); } } @@ -10369,7 +10844,7 @@ cmd_config_l2_tunnel_en_dis_all_parsed( else en = 0; - FOREACH_PORT(pid, ports) { + RTE_ETH_FOREACH_DEV(pid) { rte_eth_dev_l2_tunnel_offload_set(pid, &entry, ETH_L2_TUNNEL_ENABLE_MASK, @@ -10831,7 +11306,6 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = { NULL, }, }; -#ifdef RTE_LIBRTE_IXGBE_PMD /* vf vlan anti spoof configuration */ @@ -10883,11 +11357,29 @@ cmd_set_vf_vlan_anti_spoof_parsed( __attribute__((unused)) void *data) { struct cmd_vf_vlan_anti_spoof_result *res = parsed_result; - int ret = 0; - int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_vlan_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_vlan_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif - ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, - is_on); switch (ret) { case 0: break; @@ -10897,6 +11389,9 @@ cmd_set_vf_vlan_anti_spoof_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -10968,20 +11463,41 @@ cmd_set_vf_mac_anti_spoof_parsed( __attribute__((unused)) void *data) { struct cmd_vf_mac_anti_spoof_result *res = parsed_result; - int ret; - int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + int ret = -ENOTSUP; - ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id, - is_on); - switch (ret) { - case 0: - break; - case -EINVAL: - printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on); - break; - case -ENODEV: - printf("invalid port_id %d\n", res->port_id); - break; + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_mac_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_mac_anti_spoof(res->port_id, + res->vf_id, is_on); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11053,10 +11569,29 @@ cmd_set_vf_vlan_stripq_parsed( __attribute__((unused)) void *data) { struct cmd_vf_vlan_stripq_result *res = parsed_result; - int ret = 0; - int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_vlan_stripq(res->port_id, + res->vf_id, is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_vlan_stripq(res->port_id, + res->vf_id, is_on); +#endif - ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on); switch (ret) { case 0: break; @@ -11066,6 +11601,9 @@ cmd_set_vf_vlan_stripq_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11137,9 +11675,27 @@ cmd_set_vf_vlan_insert_parsed( __attribute__((unused)) void *data) { struct cmd_vf_vlan_insert_result *res = parsed_result; - int ret; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, + res->vlan_id); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id, + res->vlan_id); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_vlan_insert(res->port_id, res->vf_id, + res->vlan_id); +#endif - ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, res->vlan_id); switch (ret) { case 0: break; @@ -11149,6 +11705,9 @@ cmd_set_vf_vlan_insert_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11210,10 +11769,26 @@ cmd_set_tx_loopback_parsed( __attribute__((unused)) void *data) { struct cmd_tx_loopback_result *res = parsed_result; - int ret; - int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_tx_loopback(res->port_id, is_on); +#endif - ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on); switch (ret) { case 0: break; @@ -11223,6 +11798,9 @@ cmd_set_tx_loopback_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11287,10 +11865,20 @@ cmd_set_all_queues_drop_en_parsed( __attribute__((unused)) void *data) { struct cmd_all_queues_drop_en_result *res = parsed_result; - int ret = 0; + int ret = -ENOTSUP; int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; - ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on); + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_all_queues_drop_en(res->port_id, is_on); +#endif switch (ret) { case 0: break; @@ -11300,6 +11888,9 @@ cmd_set_all_queues_drop_en_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11370,11 +11961,16 @@ cmd_set_vf_split_drop_en_parsed( __attribute__((unused)) void *data) { struct cmd_vf_split_drop_en_result *res = parsed_result; - int ret; + int ret = -ENOTSUP; int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res->vf_id, is_on); +#endif switch (ret) { case 0: break; @@ -11384,6 +11980,9 @@ cmd_set_vf_split_drop_en_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("not supported on port %d\n", res->port_id); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11455,10 +12054,27 @@ cmd_set_vf_mac_addr_parsed( __attribute__((unused)) void *data) { struct cmd_set_vf_mac_addr_result *res = parsed_result; - int ret; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id, + &res->mac_addr); +#endif +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_mac_addr(res->port_id, res->vf_id, + &res->mac_addr); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_mac_addr(res->port_id, res->vf_id, + &res->mac_addr); +#endif - ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id, - &res->mac_addr); switch (ret) { case 0: break; @@ -11468,6 +12084,9 @@ cmd_set_vf_mac_addr_parsed( case -ENODEV: printf("invalid port_id %d\n", res->port_id); break; + case -ENOTSUP: + printf("function not implemented\n"); + break; default: printf("programming error: (%s)\n", strerror(-ret)); } @@ -11488,71 +12107,2588 @@ cmdline_parse_inst_t cmd_set_vf_mac_addr = { NULL, }, }; + +/* MACsec configuration */ + +/* Common result structure for MACsec offload enable */ +struct cmd_macsec_offload_on_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t macsec; + cmdline_fixed_string_t offload; + uint8_t port_id; + cmdline_fixed_string_t on; + cmdline_fixed_string_t encrypt; + cmdline_fixed_string_t en_on_off; + cmdline_fixed_string_t replay_protect; + cmdline_fixed_string_t rp_on_off; +}; + +/* Common CLI fields for MACsec offload disable */ +cmdline_parse_token_string_t cmd_macsec_offload_on_set = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + set, "set"); +cmdline_parse_token_string_t cmd_macsec_offload_on_macsec = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + macsec, "macsec"); +cmdline_parse_token_string_t cmd_macsec_offload_on_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + offload, "offload"); +cmdline_parse_token_num_t cmd_macsec_offload_on_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_offload_on_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_macsec_offload_on_on = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + on, "on"); +cmdline_parse_token_string_t cmd_macsec_offload_on_encrypt = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + encrypt, "encrypt"); +cmdline_parse_token_string_t cmd_macsec_offload_on_en_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + en_on_off, "on#off"); +cmdline_parse_token_string_t cmd_macsec_offload_on_replay_protect = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + replay_protect, "replay-protect"); +cmdline_parse_token_string_t cmd_macsec_offload_on_rp_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_on_result, + rp_on_off, "on#off"); + +static void +cmd_set_macsec_offload_on_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_macsec_offload_on_result *res = parsed_result; + int ret = -ENOTSUP; + portid_t port_id = res->port_id; + int en = (strcmp(res->en_on_off, "on") == 0) ? 1 : 0; + int rp = (strcmp(res->rp_on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_MACSEC; +#ifdef RTE_LIBRTE_IXGBE_PMD + ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp); #endif + RTE_SET_USED(en); + RTE_SET_USED(rp); -/* ******************************************************************************** */ + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", port_id); + break; + case -ENOTSUP: + printf("not supported on port %d\n", port_id); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} -/* list of instructions */ -cmdline_parse_ctx_t main_ctx[] = { - (cmdline_parse_inst_t *)&cmd_help_brief, - (cmdline_parse_inst_t *)&cmd_help_long, - (cmdline_parse_inst_t *)&cmd_quit, - (cmdline_parse_inst_t *)&cmd_showport, - (cmdline_parse_inst_t *)&cmd_showqueue, - (cmdline_parse_inst_t *)&cmd_showportall, - (cmdline_parse_inst_t *)&cmd_showcfg, - (cmdline_parse_inst_t *)&cmd_start, - (cmdline_parse_inst_t *)&cmd_start_tx_first, - (cmdline_parse_inst_t *)&cmd_start_tx_first_n, - (cmdline_parse_inst_t *)&cmd_set_link_up, - (cmdline_parse_inst_t *)&cmd_set_link_down, - (cmdline_parse_inst_t *)&cmd_reset, - (cmdline_parse_inst_t *)&cmd_set_numbers, - (cmdline_parse_inst_t *)&cmd_set_txpkts, - (cmdline_parse_inst_t *)&cmd_set_txsplit, - (cmdline_parse_inst_t *)&cmd_set_fwd_list, - (cmdline_parse_inst_t *)&cmd_set_fwd_mask, - (cmdline_parse_inst_t *)&cmd_set_fwd_mode, - (cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode, - (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry, - (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one, - (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all, - (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one, - (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all, - (cmdline_parse_inst_t *)&cmd_set_flush_rx, - (cmdline_parse_inst_t *)&cmd_set_link_check, -#ifdef RTE_NIC_BYPASS - (cmdline_parse_inst_t *)&cmd_set_bypass_mode, - (cmdline_parse_inst_t *)&cmd_set_bypass_event, - (cmdline_parse_inst_t *)&cmd_set_bypass_timeout, - (cmdline_parse_inst_t *)&cmd_show_bypass_config, +cmdline_parse_inst_t cmd_set_macsec_offload_on = { + .f = cmd_set_macsec_offload_on_parsed, + .data = NULL, + .help_str = "set macsec offload on " + "encrypt on|off replay-protect on|off", + .tokens = { + (void *)&cmd_macsec_offload_on_set, + (void *)&cmd_macsec_offload_on_macsec, + (void *)&cmd_macsec_offload_on_offload, + (void *)&cmd_macsec_offload_on_port_id, + (void *)&cmd_macsec_offload_on_on, + (void *)&cmd_macsec_offload_on_encrypt, + (void *)&cmd_macsec_offload_on_en_on_off, + (void *)&cmd_macsec_offload_on_replay_protect, + (void *)&cmd_macsec_offload_on_rp_on_off, + NULL, + }, +}; + +/* Common result structure for MACsec offload disable */ +struct cmd_macsec_offload_off_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t macsec; + cmdline_fixed_string_t offload; + uint8_t port_id; + cmdline_fixed_string_t off; +}; + +/* Common CLI fields for MACsec offload disable */ +cmdline_parse_token_string_t cmd_macsec_offload_off_set = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_off_result, + set, "set"); +cmdline_parse_token_string_t cmd_macsec_offload_off_macsec = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_off_result, + macsec, "macsec"); +cmdline_parse_token_string_t cmd_macsec_offload_off_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_off_result, + offload, "offload"); +cmdline_parse_token_num_t cmd_macsec_offload_off_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_offload_off_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_macsec_offload_off_off = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_offload_off_result, + off, "off"); + +static void +cmd_set_macsec_offload_off_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_macsec_offload_off_result *res = parsed_result; + int ret = -ENOTSUP; + portid_t port_id = res->port_id; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_MACSEC; +#ifdef RTE_LIBRTE_IXGBE_PMD + ret = rte_pmd_ixgbe_macsec_disable(port_id); #endif -#ifdef RTE_LIBRTE_PMD_BOND - (cmdline_parse_inst_t *) &cmd_set_bonding_mode, - (cmdline_parse_inst_t *) &cmd_show_bonding_config, - (cmdline_parse_inst_t *) &cmd_set_bonding_primary, - (cmdline_parse_inst_t *) &cmd_add_bonding_slave, - (cmdline_parse_inst_t *) &cmd_remove_bonding_slave, - (cmdline_parse_inst_t *) &cmd_create_bonded_device, - (cmdline_parse_inst_t *) &cmd_set_bond_mac_addr, - (cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy, - (cmdline_parse_inst_t *) &cmd_set_bond_mon_period, + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", port_id); + break; + case -ENOTSUP: + printf("not supported on port %d\n", port_id); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_macsec_offload_off = { + .f = cmd_set_macsec_offload_off_parsed, + .data = NULL, + .help_str = "set macsec offload off", + .tokens = { + (void *)&cmd_macsec_offload_off_set, + (void *)&cmd_macsec_offload_off_macsec, + (void *)&cmd_macsec_offload_off_offload, + (void *)&cmd_macsec_offload_off_port_id, + (void *)&cmd_macsec_offload_off_off, + NULL, + }, +}; + +/* Common result structure for MACsec secure connection configure */ +struct cmd_macsec_sc_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t macsec; + cmdline_fixed_string_t sc; + cmdline_fixed_string_t tx_rx; + uint8_t port_id; + struct ether_addr mac; + uint16_t pi; +}; + +/* Common CLI fields for MACsec secure connection configure */ +cmdline_parse_token_string_t cmd_macsec_sc_set = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sc_result, + set, "set"); +cmdline_parse_token_string_t cmd_macsec_sc_macsec = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sc_result, + macsec, "macsec"); +cmdline_parse_token_string_t cmd_macsec_sc_sc = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sc_result, + sc, "sc"); +cmdline_parse_token_string_t cmd_macsec_sc_tx_rx = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sc_result, + tx_rx, "tx#rx"); +cmdline_parse_token_num_t cmd_macsec_sc_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sc_result, + port_id, UINT8); +cmdline_parse_token_etheraddr_t cmd_macsec_sc_mac = + TOKEN_ETHERADDR_INITIALIZER + (struct cmd_macsec_sc_result, + mac); +cmdline_parse_token_num_t cmd_macsec_sc_pi = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sc_result, + pi, UINT16); + +static void +cmd_set_macsec_sc_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_macsec_sc_result *res = parsed_result; + int ret = -ENOTSUP; + int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0; + +#ifdef RTE_LIBRTE_IXGBE_PMD + ret = is_tx ? + rte_pmd_ixgbe_macsec_config_txsc(res->port_id, + res->mac.addr_bytes) : + rte_pmd_ixgbe_macsec_config_rxsc(res->port_id, + res->mac.addr_bytes, res->pi); #endif - (cmdline_parse_inst_t *)&cmd_vlan_offload, - (cmdline_parse_inst_t *)&cmd_vlan_tpid, - (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all, - (cmdline_parse_inst_t *)&cmd_rx_vlan_filter, - (cmdline_parse_inst_t *)&cmd_tx_vlan_set, - (cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq, - (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, - (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid, - (cmdline_parse_inst_t *)&cmd_csum_set, + RTE_SET_USED(is_tx); + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("not supported on port %d\n", res->port_id); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_macsec_sc = { + .f = cmd_set_macsec_sc_parsed, + .data = NULL, + .help_str = "set macsec sc tx|rx ", + .tokens = { + (void *)&cmd_macsec_sc_set, + (void *)&cmd_macsec_sc_macsec, + (void *)&cmd_macsec_sc_sc, + (void *)&cmd_macsec_sc_tx_rx, + (void *)&cmd_macsec_sc_port_id, + (void *)&cmd_macsec_sc_mac, + (void *)&cmd_macsec_sc_pi, + NULL, + }, +}; + +/* Common result structure for MACsec secure connection configure */ +struct cmd_macsec_sa_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t macsec; + cmdline_fixed_string_t sa; + cmdline_fixed_string_t tx_rx; + uint8_t port_id; + uint8_t idx; + uint8_t an; + uint32_t pn; + cmdline_fixed_string_t key; +}; + +/* Common CLI fields for MACsec secure connection configure */ +cmdline_parse_token_string_t cmd_macsec_sa_set = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sa_result, + set, "set"); +cmdline_parse_token_string_t cmd_macsec_sa_macsec = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sa_result, + macsec, "macsec"); +cmdline_parse_token_string_t cmd_macsec_sa_sa = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sa_result, + sa, "sa"); +cmdline_parse_token_string_t cmd_macsec_sa_tx_rx = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sa_result, + tx_rx, "tx#rx"); +cmdline_parse_token_num_t cmd_macsec_sa_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sa_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_macsec_sa_idx = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sa_result, + idx, UINT8); +cmdline_parse_token_num_t cmd_macsec_sa_an = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sa_result, + an, UINT8); +cmdline_parse_token_num_t cmd_macsec_sa_pn = + TOKEN_NUM_INITIALIZER + (struct cmd_macsec_sa_result, + pn, UINT32); +cmdline_parse_token_string_t cmd_macsec_sa_key = + TOKEN_STRING_INITIALIZER + (struct cmd_macsec_sa_result, + key, NULL); + +static void +cmd_set_macsec_sa_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_macsec_sa_result *res = parsed_result; + int ret = -ENOTSUP; + int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0; + uint8_t key[16] = { 0 }; + uint8_t xdgt0; + uint8_t xdgt1; + int key_len; + int i; + + key_len = strlen(res->key) / 2; + if (key_len > 16) + key_len = 16; + + for (i = 0; i < key_len; i++) { + xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2)); + if (xdgt0 == 0xFF) + return; + xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1); + if (xdgt1 == 0xFF) + return; + key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1); + } + +#ifdef RTE_LIBRTE_IXGBE_PMD + ret = is_tx ? + rte_pmd_ixgbe_macsec_select_txsa(res->port_id, + res->idx, res->an, res->pn, key) : + rte_pmd_ixgbe_macsec_select_rxsa(res->port_id, + res->idx, res->an, res->pn, key); +#endif + RTE_SET_USED(is_tx); + RTE_SET_USED(key); + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid idx %d or an %d\n", res->idx, res->an); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("not supported on port %d\n", res->port_id); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_macsec_sa = { + .f = cmd_set_macsec_sa_parsed, + .data = NULL, + .help_str = "set macsec sa tx|rx ", + .tokens = { + (void *)&cmd_macsec_sa_set, + (void *)&cmd_macsec_sa_macsec, + (void *)&cmd_macsec_sa_sa, + (void *)&cmd_macsec_sa_tx_rx, + (void *)&cmd_macsec_sa_port_id, + (void *)&cmd_macsec_sa_idx, + (void *)&cmd_macsec_sa_an, + (void *)&cmd_macsec_sa_pn, + (void *)&cmd_macsec_sa_key, + NULL, + }, +}; + +/* VF unicast promiscuous mode configuration */ + +/* Common result structure for VF unicast promiscuous mode */ +struct cmd_vf_promisc_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t promisc; + uint8_t port_id; + uint32_t vf_id; + cmdline_fixed_string_t on_off; +}; + +/* Common CLI fields for VF unicast promiscuous mode enable disable */ +cmdline_parse_token_string_t cmd_vf_promisc_set = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_promisc_result, + set, "set"); +cmdline_parse_token_string_t cmd_vf_promisc_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_promisc_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_vf_promisc_promisc = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_promisc_result, + promisc, "promisc"); +cmdline_parse_token_num_t cmd_vf_promisc_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_promisc_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_vf_promisc_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_promisc_result, + vf_id, UINT32); +cmdline_parse_token_string_t cmd_vf_promisc_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_promisc_result, + on_off, "on#off"); + +static void +cmd_set_vf_promisc_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_promisc_result *res = parsed_result; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_unicast_promisc(res->port_id, + res->vf_id, is_on); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d\n", res->vf_id); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_vf_promisc = { + .f = cmd_set_vf_promisc_parsed, + .data = NULL, + .help_str = "set vf promisc on|off: " + "Set unicast promiscuous mode for a VF from the PF", + .tokens = { + (void *)&cmd_vf_promisc_set, + (void *)&cmd_vf_promisc_vf, + (void *)&cmd_vf_promisc_promisc, + (void *)&cmd_vf_promisc_port_id, + (void *)&cmd_vf_promisc_vf_id, + (void *)&cmd_vf_promisc_on_off, + NULL, + }, +}; + +/* VF multicast promiscuous mode configuration */ + +/* Common result structure for VF multicast promiscuous mode */ +struct cmd_vf_allmulti_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t allmulti; + uint8_t port_id; + uint32_t vf_id; + cmdline_fixed_string_t on_off; +}; + +/* Common CLI fields for VF multicast promiscuous mode enable disable */ +cmdline_parse_token_string_t cmd_vf_allmulti_set = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_allmulti_result, + set, "set"); +cmdline_parse_token_string_t cmd_vf_allmulti_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_allmulti_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_vf_allmulti_allmulti = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_allmulti_result, + allmulti, "allmulti"); +cmdline_parse_token_num_t cmd_vf_allmulti_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_allmulti_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_vf_allmulti_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_allmulti_result, + vf_id, UINT32); +cmdline_parse_token_string_t cmd_vf_allmulti_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_allmulti_result, + on_off, "on#off"); + +static void +cmd_set_vf_allmulti_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_allmulti_result *res = parsed_result; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_multicast_promisc(res->port_id, + res->vf_id, is_on); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d\n", res->vf_id); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_vf_allmulti = { + .f = cmd_set_vf_allmulti_parsed, + .data = NULL, + .help_str = "set vf allmulti on|off: " + "Set multicast promiscuous mode for a VF from the PF", + .tokens = { + (void *)&cmd_vf_allmulti_set, + (void *)&cmd_vf_allmulti_vf, + (void *)&cmd_vf_allmulti_allmulti, + (void *)&cmd_vf_allmulti_port_id, + (void *)&cmd_vf_allmulti_vf_id, + (void *)&cmd_vf_allmulti_on_off, + NULL, + }, +}; + +/* vf broadcast mode configuration */ + +/* Common result structure for vf broadcast */ +struct cmd_set_vf_broadcast_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t broadcast; + uint8_t port_id; + uint16_t vf_id; + cmdline_fixed_string_t on_off; +}; + +/* Common CLI fields for vf broadcast enable disable */ +cmdline_parse_token_string_t cmd_set_vf_broadcast_set = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_broadcast_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_vf_broadcast_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_broadcast_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_set_vf_broadcast_broadcast = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_broadcast_result, + broadcast, "broadcast"); +cmdline_parse_token_num_t cmd_set_vf_broadcast_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_set_vf_broadcast_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_set_vf_broadcast_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_set_vf_broadcast_result, + vf_id, UINT16); +cmdline_parse_token_string_t cmd_set_vf_broadcast_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_broadcast_result, + on_off, "on#off"); + +static void +cmd_set_vf_broadcast_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_vf_broadcast_result *res = parsed_result; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_broadcast(res->port_id, + res->vf_id, is_on); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_vf_broadcast = { + .f = cmd_set_vf_broadcast_parsed, + .data = NULL, + .help_str = "set vf broadcast on|off", + .tokens = { + (void *)&cmd_set_vf_broadcast_set, + (void *)&cmd_set_vf_broadcast_vf, + (void *)&cmd_set_vf_broadcast_broadcast, + (void *)&cmd_set_vf_broadcast_port_id, + (void *)&cmd_set_vf_broadcast_vf_id, + (void *)&cmd_set_vf_broadcast_on_off, + NULL, + }, +}; + +/* vf vlan tag configuration */ + +/* Common result structure for vf vlan tag */ +struct cmd_set_vf_vlan_tag_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t vlan; + cmdline_fixed_string_t tag; + uint8_t port_id; + uint16_t vf_id; + cmdline_fixed_string_t on_off; +}; + +/* Common CLI fields for vf vlan tag enable disable */ +cmdline_parse_token_string_t cmd_set_vf_vlan_tag_set = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + set, "set"); +cmdline_parse_token_string_t cmd_set_vf_vlan_tag_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_set_vf_vlan_tag_vlan = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + vlan, "vlan"); +cmdline_parse_token_string_t cmd_set_vf_vlan_tag_tag = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + tag, "tag"); +cmdline_parse_token_num_t cmd_set_vf_vlan_tag_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_set_vf_vlan_tag_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + vf_id, UINT16); +cmdline_parse_token_string_t cmd_set_vf_vlan_tag_on_off = + TOKEN_STRING_INITIALIZER + (struct cmd_set_vf_vlan_tag_result, + on_off, "on#off"); + +static void +cmd_set_vf_vlan_tag_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_vf_vlan_tag_result *res = parsed_result; + int ret = -ENOTSUP; + + __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_vlan_tag(res->port_id, + res->vf_id, is_on); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_set_vf_vlan_tag = { + .f = cmd_set_vf_vlan_tag_parsed, + .data = NULL, + .help_str = "set vf vlan tag on|off", + .tokens = { + (void *)&cmd_set_vf_vlan_tag_set, + (void *)&cmd_set_vf_vlan_tag_vf, + (void *)&cmd_set_vf_vlan_tag_vlan, + (void *)&cmd_set_vf_vlan_tag_tag, + (void *)&cmd_set_vf_vlan_tag_port_id, + (void *)&cmd_set_vf_vlan_tag_vf_id, + (void *)&cmd_set_vf_vlan_tag_on_off, + NULL, + }, +}; + +/* Common definition of VF and TC TX bandwidth configuration */ +struct cmd_vf_tc_bw_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t tc; + cmdline_fixed_string_t tx; + cmdline_fixed_string_t min_bw; + cmdline_fixed_string_t max_bw; + cmdline_fixed_string_t strict_link_prio; + uint8_t port_id; + uint16_t vf_id; + uint8_t tc_no; + uint32_t bw; + cmdline_fixed_string_t bw_list; + uint8_t tc_map; +}; + +cmdline_parse_token_string_t cmd_vf_tc_bw_set = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + set, "set"); +cmdline_parse_token_string_t cmd_vf_tc_bw_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_vf_tc_bw_tc = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + tc, "tc"); +cmdline_parse_token_string_t cmd_vf_tc_bw_tx = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + tx, "tx"); +cmdline_parse_token_string_t cmd_vf_tc_bw_strict_link_prio = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + strict_link_prio, "strict-link-priority"); +cmdline_parse_token_string_t cmd_vf_tc_bw_min_bw = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + min_bw, "min-bandwidth"); +cmdline_parse_token_string_t cmd_vf_tc_bw_max_bw = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + max_bw, "max-bandwidth"); +cmdline_parse_token_num_t cmd_vf_tc_bw_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_tc_bw_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_vf_tc_bw_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_tc_bw_result, + vf_id, UINT16); +cmdline_parse_token_num_t cmd_vf_tc_bw_tc_no = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_tc_bw_result, + tc_no, UINT8); +cmdline_parse_token_num_t cmd_vf_tc_bw_bw = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_tc_bw_result, + bw, UINT32); +cmdline_parse_token_string_t cmd_vf_tc_bw_bw_list = + TOKEN_STRING_INITIALIZER + (struct cmd_vf_tc_bw_result, + bw_list, NULL); +cmdline_parse_token_num_t cmd_vf_tc_bw_tc_map = + TOKEN_NUM_INITIALIZER + (struct cmd_vf_tc_bw_result, + tc_map, UINT8); + +/* VF max bandwidth setting */ +static void +cmd_vf_max_bw_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_tc_bw_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_max_bw(res->port_id, + res->vf_id, res->bw); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d or bandwidth %d\n", + res->vf_id, res->bw); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_vf_max_bw = { + .f = cmd_vf_max_bw_parsed, + .data = NULL, + .help_str = "set vf tx max-bandwidth ", + .tokens = { + (void *)&cmd_vf_tc_bw_set, + (void *)&cmd_vf_tc_bw_vf, + (void *)&cmd_vf_tc_bw_tx, + (void *)&cmd_vf_tc_bw_max_bw, + (void *)&cmd_vf_tc_bw_port_id, + (void *)&cmd_vf_tc_bw_vf_id, + (void *)&cmd_vf_tc_bw_bw, + NULL, + }, +}; + +static int +vf_tc_min_bw_parse_bw_list(uint8_t *bw_list, + uint8_t *tc_num, + char *str) +{ + uint32_t size; + const char *p, *p0 = str; + char s[256]; + char *end; + char *str_fld[16]; + uint16_t i; + int ret; + + p = strchr(p0, '('); + if (p == NULL) { + printf("The bandwidth-list should be '(bw1, bw2, ...)'\n"); + return -1; + } + p++; + p0 = strchr(p, ')'); + if (p0 == NULL) { + printf("The bandwidth-list should be '(bw1, bw2, ...)'\n"); + return -1; + } + size = p0 - p; + if (size >= sizeof(s)) { + printf("The string size exceeds the internal buffer size\n"); + return -1; + } + snprintf(s, sizeof(s), "%.*s", size, p); + ret = rte_strsplit(s, sizeof(s), str_fld, 16, ','); + if (ret <= 0) { + printf("Failed to get the bandwidth list. "); + return -1; + } + *tc_num = ret; + for (i = 0; i < ret; i++) + bw_list[i] = (uint8_t)strtoul(str_fld[i], &end, 0); + + return 0; +} + +/* TC min bandwidth setting */ +static void +cmd_vf_tc_min_bw_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_tc_bw_result *res = parsed_result; + uint8_t tc_num; + uint8_t bw[16]; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + ret = vf_tc_min_bw_parse_bw_list(bw, &tc_num, res->bw_list); + if (ret) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_tc_bw_alloc(res->port_id, res->vf_id, + tc_num, bw); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d or bandwidth\n", res->vf_id); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_vf_tc_min_bw = { + .f = cmd_vf_tc_min_bw_parsed, + .data = NULL, + .help_str = "set vf tc tx min-bandwidth " + " ", + .tokens = { + (void *)&cmd_vf_tc_bw_set, + (void *)&cmd_vf_tc_bw_vf, + (void *)&cmd_vf_tc_bw_tc, + (void *)&cmd_vf_tc_bw_tx, + (void *)&cmd_vf_tc_bw_min_bw, + (void *)&cmd_vf_tc_bw_port_id, + (void *)&cmd_vf_tc_bw_vf_id, + (void *)&cmd_vf_tc_bw_bw_list, + NULL, + }, +}; + +static void +cmd_tc_min_bw_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_tc_bw_result *res = parsed_result; + struct rte_port *port; + uint8_t tc_num; + uint8_t bw[16]; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + 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; + } + + ret = vf_tc_min_bw_parse_bw_list(bw, &tc_num, res->bw_list); + if (ret) + return; + +#ifdef RTE_LIBRTE_IXGBE_PMD + ret = rte_pmd_ixgbe_set_tc_bw_alloc(res->port_id, tc_num, bw); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid bandwidth\n"); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_tc_min_bw = { + .f = cmd_tc_min_bw_parsed, + .data = NULL, + .help_str = "set tc tx min-bandwidth ", + .tokens = { + (void *)&cmd_vf_tc_bw_set, + (void *)&cmd_vf_tc_bw_tc, + (void *)&cmd_vf_tc_bw_tx, + (void *)&cmd_vf_tc_bw_min_bw, + (void *)&cmd_vf_tc_bw_port_id, + (void *)&cmd_vf_tc_bw_bw_list, + NULL, + }, +}; + +/* TC max bandwidth setting */ +static void +cmd_vf_tc_max_bw_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_tc_bw_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_vf_tc_max_bw(res->port_id, res->vf_id, + res->tc_no, res->bw); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d, tc_no %d or bandwidth %d\n", + res->vf_id, res->tc_no, res->bw); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_vf_tc_max_bw = { + .f = cmd_vf_tc_max_bw_parsed, + .data = NULL, + .help_str = "set vf tc tx max-bandwidth " + " ", + .tokens = { + (void *)&cmd_vf_tc_bw_set, + (void *)&cmd_vf_tc_bw_vf, + (void *)&cmd_vf_tc_bw_tc, + (void *)&cmd_vf_tc_bw_tx, + (void *)&cmd_vf_tc_bw_max_bw, + (void *)&cmd_vf_tc_bw_port_id, + (void *)&cmd_vf_tc_bw_vf_id, + (void *)&cmd_vf_tc_bw_tc_no, + (void *)&cmd_vf_tc_bw_bw, + NULL, + }, +}; + +/* Strict link priority scheduling mode setting */ +static void +cmd_strict_link_prio_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_tc_bw_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_set_tc_strict_prio(res->port_id, res->tc_map); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid tc_bitmap 0x%x\n", res->tc_map); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_strict_link_prio = { + .f = cmd_strict_link_prio_parsed, + .data = NULL, + .help_str = "set tx strict-link-priority ", + .tokens = { + (void *)&cmd_vf_tc_bw_set, + (void *)&cmd_vf_tc_bw_tx, + (void *)&cmd_vf_tc_bw_strict_link_prio, + (void *)&cmd_vf_tc_bw_port_id, + (void *)&cmd_vf_tc_bw_tc_map, + NULL, + }, +}; + +/* Load dynamic device personalization*/ +struct cmd_ddp_add_result { + cmdline_fixed_string_t ddp; + cmdline_fixed_string_t add; + uint8_t port_id; + char filepath[]; +}; + +cmdline_parse_token_string_t cmd_ddp_add_ddp = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, ddp, "ddp"); +cmdline_parse_token_string_t cmd_ddp_add_add = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, add, "add"); +cmdline_parse_token_num_t cmd_ddp_add_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ddp_add_result, port_id, UINT8); +cmdline_parse_token_string_t cmd_ddp_add_filepath = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_add_result, filepath, NULL); + +static void +cmd_ddp_add_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ddp_add_result *res = parsed_result; + uint8_t *buff; + uint32_t size; + char *filepath; + char *file_fld[2]; + int file_num; + int ret = -ENOTSUP; + + if (res->port_id > nb_ports) { + printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + return; + } + + if (!all_ports_stopped()) { + printf("Please stop all ports first\n"); + return; + } + + filepath = strdup(res->filepath); + if (filepath == NULL) { + printf("Failed to allocate memory\n"); + return; + } + file_num = rte_strsplit(filepath, strlen(filepath), file_fld, 2, ','); + + buff = open_ddp_package_file(file_fld[0], &size); + if (!buff) { + free((void *)filepath); + return; + } + +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_process_ddp_package(res->port_id, + buff, size, + RTE_PMD_I40E_PKG_OP_WR_ADD); +#endif + + if (ret == -EEXIST) + printf("Profile has already existed.\n"); + else if (ret < 0) + printf("Failed to load profile.\n"); + else if (file_num == 2) + save_ddp_package_file(file_fld[1], buff, size); + + close_ddp_package_file(buff); + free((void *)filepath); +} + +cmdline_parse_inst_t cmd_ddp_add = { + .f = cmd_ddp_add_parsed, + .data = NULL, + .help_str = "ddp add ", + .tokens = { + (void *)&cmd_ddp_add_ddp, + (void *)&cmd_ddp_add_add, + (void *)&cmd_ddp_add_port_id, + (void *)&cmd_ddp_add_filepath, + NULL, + }, +}; + +/* Delete dynamic device personalization*/ +struct cmd_ddp_del_result { + cmdline_fixed_string_t ddp; + cmdline_fixed_string_t del; + uint8_t port_id; + char filepath[]; +}; + +cmdline_parse_token_string_t cmd_ddp_del_ddp = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, ddp, "ddp"); +cmdline_parse_token_string_t cmd_ddp_del_del = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, del, "del"); +cmdline_parse_token_num_t cmd_ddp_del_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ddp_del_result, port_id, UINT8); +cmdline_parse_token_string_t cmd_ddp_del_filepath = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_del_result, filepath, NULL); + +static void +cmd_ddp_del_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ddp_del_result *res = parsed_result; + uint8_t *buff; + uint32_t size; + int ret = -ENOTSUP; + + if (res->port_id > nb_ports) { + printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + return; + } + + if (!all_ports_stopped()) { + printf("Please stop all ports first\n"); + return; + } + + buff = open_ddp_package_file(res->filepath, &size); + if (!buff) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_process_ddp_package(res->port_id, + buff, size, + RTE_PMD_I40E_PKG_OP_WR_DEL); +#endif + + if (ret == -EACCES) + printf("Profile does not exist.\n"); + else if (ret < 0) + printf("Failed to delete profile.\n"); + + close_ddp_package_file(buff); +} + +cmdline_parse_inst_t cmd_ddp_del = { + .f = cmd_ddp_del_parsed, + .data = NULL, + .help_str = "ddp del ", + .tokens = { + (void *)&cmd_ddp_del_ddp, + (void *)&cmd_ddp_del_del, + (void *)&cmd_ddp_del_port_id, + (void *)&cmd_ddp_del_filepath, + NULL, + }, +}; + +/* Get dynamic device personalization profile info */ +struct cmd_ddp_info_result { + cmdline_fixed_string_t ddp; + cmdline_fixed_string_t get; + cmdline_fixed_string_t info; + char filepath[]; +}; + +cmdline_parse_token_string_t cmd_ddp_info_ddp = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_info_result, ddp, "ddp"); +cmdline_parse_token_string_t cmd_ddp_info_get = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_info_result, get, "get"); +cmdline_parse_token_string_t cmd_ddp_info_info = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_info_result, info, "info"); +cmdline_parse_token_string_t cmd_ddp_info_filepath = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_info_result, filepath, NULL); + +static void +cmd_ddp_info_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ddp_info_result *res = parsed_result; + uint8_t *pkg; + uint32_t pkg_size; + int ret = -ENOTSUP; +#ifdef RTE_LIBRTE_I40E_PMD + uint32_t i, j, n; + uint8_t *buff; + uint32_t buff_size = 0; + struct rte_pmd_i40e_profile_info info; + uint32_t dev_num = 0; + struct rte_pmd_i40e_ddp_device_id *devs; + uint32_t proto_num = 0; + struct rte_pmd_i40e_proto_info *proto; + uint32_t pctype_num = 0; + struct rte_pmd_i40e_ptype_info *pctype; + uint32_t ptype_num = 0; + struct rte_pmd_i40e_ptype_info *ptype; + uint8_t proto_id; + +#endif + + pkg = open_ddp_package_file(res->filepath, &pkg_size); + if (!pkg) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&info, sizeof(info), + RTE_PMD_I40E_PKG_INFO_GLOBAL_HEADER); + if (!ret) { + printf("Global Track id: 0x%x\n", info.track_id); + printf("Global Version: %d.%d.%d.%d\n", + info.version.major, + info.version.minor, + info.version.update, + info.version.draft); + printf("Global Package name: %s\n\n", info.name); + } + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&info, sizeof(info), + RTE_PMD_I40E_PKG_INFO_HEADER); + if (!ret) { + printf("i40e Profile Track id: 0x%x\n", info.track_id); + printf("i40e Profile Version: %d.%d.%d.%d\n", + info.version.major, + info.version.minor, + info.version.update, + info.version.draft); + printf("i40e Profile name: %s\n\n", info.name); + } + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&buff_size, sizeof(buff_size), + RTE_PMD_I40E_PKG_INFO_GLOBAL_NOTES_SIZE); + if (!ret && buff_size) { + buff = (uint8_t *)malloc(buff_size); + if (buff) { + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + buff, buff_size, + RTE_PMD_I40E_PKG_INFO_GLOBAL_NOTES); + if (!ret) + printf("Package Notes:\n%s\n\n", buff); + free(buff); + } + } + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&dev_num, sizeof(dev_num), + RTE_PMD_I40E_PKG_INFO_DEVID_NUM); + if (!ret && dev_num) { + buff_size = dev_num * sizeof(struct rte_pmd_i40e_ddp_device_id); + devs = (struct rte_pmd_i40e_ddp_device_id *)malloc(buff_size); + if (devs) { + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)devs, buff_size, + RTE_PMD_I40E_PKG_INFO_DEVID_LIST); + if (!ret) { + printf("List of supported devices:\n"); + for (i = 0; i < dev_num; i++) { + printf(" %04X:%04X %04X:%04X\n", + devs[i].vendor_dev_id >> 16, + devs[i].vendor_dev_id & 0xFFFF, + devs[i].sub_vendor_dev_id >> 16, + devs[i].sub_vendor_dev_id & 0xFFFF); + } + printf("\n"); + } + free(devs); + } + } + + /* get information about protocols and packet types */ + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&proto_num, sizeof(proto_num), + RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM); + if (ret || !proto_num) + goto no_print_return; + + buff_size = proto_num * sizeof(struct rte_pmd_i40e_proto_info); + proto = (struct rte_pmd_i40e_proto_info *)malloc(buff_size); + if (!proto) + goto no_print_return; + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, (uint8_t *)proto, + buff_size, + RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST); + if (!ret) { + printf("List of used protocols:\n"); + for (i = 0; i < proto_num; i++) + printf(" %2u: %s\n", proto[i].proto_id, + proto[i].name); + printf("\n"); + } + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&pctype_num, sizeof(pctype_num), + RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM); + if (ret || !pctype_num) + goto no_print_pctypes; + + buff_size = pctype_num * sizeof(struct rte_pmd_i40e_ptype_info); + pctype = (struct rte_pmd_i40e_ptype_info *)malloc(buff_size); + if (!pctype) + goto no_print_pctypes; + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, (uint8_t *)pctype, + buff_size, + RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST); + if (ret) { + free(pctype); + goto no_print_pctypes; + } + + printf("List of defined packet classification types:\n"); + for (i = 0; i < pctype_num; i++) { + printf(" %2u:", pctype[i].ptype_id); + for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { + proto_id = pctype[i].protocols[j]; + if (proto_id != RTE_PMD_I40E_PROTO_UNUSED) { + for (n = 0; n < proto_num; n++) { + if (proto[n].proto_id == proto_id) { + printf(" %s", proto[n].name); + break; + } + } + } + } + printf("\n"); + } + printf("\n"); + free(pctype); + +no_print_pctypes: + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, (uint8_t *)&ptype_num, + sizeof(ptype_num), + RTE_PMD_I40E_PKG_INFO_PTYPE_NUM); + if (ret || !ptype_num) + goto no_print_return; + + buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_info); + ptype = (struct rte_pmd_i40e_ptype_info *)malloc(buff_size); + if (!ptype) + goto no_print_return; + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, (uint8_t *)ptype, + buff_size, + RTE_PMD_I40E_PKG_INFO_PTYPE_LIST); + if (ret) { + free(ptype); + goto no_print_return; + } + printf("List of defined packet types:\n"); + for (i = 0; i < ptype_num; i++) { + printf(" %2u:", ptype[i].ptype_id); + for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { + proto_id = ptype[i].protocols[j]; + if (proto_id != RTE_PMD_I40E_PROTO_UNUSED) { + for (n = 0; n < proto_num; n++) { + if (proto[n].proto_id == proto_id) { + printf(" %s", proto[n].name); + break; + } + } + } + } + printf("\n"); + } + free(ptype); + printf("\n"); + + free(proto); + ret = 0; +#endif +no_print_return: + if (ret == -ENOTSUP) + printf("Function not supported in PMD driver\n"); + close_ddp_package_file(pkg); +} + +cmdline_parse_inst_t cmd_ddp_get_info = { + .f = cmd_ddp_info_parsed, + .data = NULL, + .help_str = "ddp get info ", + .tokens = { + (void *)&cmd_ddp_info_ddp, + (void *)&cmd_ddp_info_get, + (void *)&cmd_ddp_info_info, + (void *)&cmd_ddp_info_filepath, + NULL, + }, +}; + +/* Get dynamic device personalization profile info list*/ +#define PROFILE_INFO_SIZE 48 +#define MAX_PROFILE_NUM 16 + +struct cmd_ddp_get_list_result { + cmdline_fixed_string_t ddp; + cmdline_fixed_string_t get; + cmdline_fixed_string_t list; + uint8_t port_id; +}; + +cmdline_parse_token_string_t cmd_ddp_get_list_ddp = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, ddp, "ddp"); +cmdline_parse_token_string_t cmd_ddp_get_list_get = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, get, "get"); +cmdline_parse_token_string_t cmd_ddp_get_list_list = + TOKEN_STRING_INITIALIZER(struct cmd_ddp_get_list_result, list, "list"); +cmdline_parse_token_num_t cmd_ddp_get_list_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ddp_get_list_result, port_id, UINT8); + +static void +cmd_ddp_get_list_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ddp_get_list_result *res = parsed_result; +#ifdef RTE_LIBRTE_I40E_PMD + struct rte_pmd_i40e_profile_list *p_list; + struct rte_pmd_i40e_profile_info *p_info; + uint32_t p_num; + uint32_t size; + uint32_t i; +#endif + int ret = -ENOTSUP; + + if (res->port_id > nb_ports) { + printf("Invalid port, range is [0, %d]\n", nb_ports - 1); + return; + } + +#ifdef RTE_LIBRTE_I40E_PMD + size = PROFILE_INFO_SIZE * MAX_PROFILE_NUM + 4; + p_list = (struct rte_pmd_i40e_profile_list *)malloc(size); + if (!p_list) + printf("%s: Failed to malloc buffer\n", __func__); + + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_get_ddp_list(res->port_id, + (uint8_t *)p_list, size); + + if (!ret) { + p_num = p_list->p_count; + printf("Profile number is: %d\n\n", p_num); + + for (i = 0; i < p_num; i++) { + p_info = &p_list->p_info[i]; + printf("Profile %d:\n", i); + printf("Track id: 0x%x\n", p_info->track_id); + printf("Version: %d.%d.%d.%d\n", + p_info->version.major, + p_info->version.minor, + p_info->version.update, + p_info->version.draft); + printf("Profile name: %s\n\n", p_info->name); + } + } + + free(p_list); +#endif + + if (ret < 0) + printf("Failed to get ddp list\n"); +} + +cmdline_parse_inst_t cmd_ddp_get_list = { + .f = cmd_ddp_get_list_parsed, + .data = NULL, + .help_str = "ddp get list ", + .tokens = { + (void *)&cmd_ddp_get_list_ddp, + (void *)&cmd_ddp_get_list_get, + (void *)&cmd_ddp_get_list_list, + (void *)&cmd_ddp_get_list_port_id, + NULL, + }, +}; + +/* show vf stats */ + +/* Common result structure for show vf stats */ +struct cmd_show_vf_stats_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t stats; + uint8_t port_id; + uint16_t vf_id; +}; + +/* Common CLI fields show vf stats*/ +cmdline_parse_token_string_t cmd_show_vf_stats_show = + TOKEN_STRING_INITIALIZER + (struct cmd_show_vf_stats_result, + show, "show"); +cmdline_parse_token_string_t cmd_show_vf_stats_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_show_vf_stats_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_show_vf_stats_stats = + TOKEN_STRING_INITIALIZER + (struct cmd_show_vf_stats_result, + stats, "stats"); +cmdline_parse_token_num_t cmd_show_vf_stats_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_show_vf_stats_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_show_vf_stats_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_show_vf_stats_result, + vf_id, UINT16); + +static void +cmd_show_vf_stats_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_show_vf_stats_result *res = parsed_result; + struct rte_eth_stats stats; + int ret = -ENOTSUP; + static const char *nic_stats_border = "########################"; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + memset(&stats, 0, sizeof(stats)); + +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_get_vf_stats(res->port_id, + res->vf_id, + &stats); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_get_vf_stats(res->port_id, + res->vf_id, + &stats); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d\n", res->vf_id); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } + + printf("\n %s NIC statistics for port %-2d vf %-2d %s\n", + nic_stats_border, res->port_id, res->vf_id, nic_stats_border); + + printf(" RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes: " + "%-"PRIu64"\n", + stats.ipackets, stats.imissed, stats.ibytes); + printf(" RX-errors: %-"PRIu64"\n", stats.ierrors); + printf(" RX-nombuf: %-10"PRIu64"\n", + stats.rx_nombuf); + printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes: " + "%-"PRIu64"\n", + stats.opackets, stats.oerrors, stats.obytes); + + printf(" %s############################%s\n", + nic_stats_border, nic_stats_border); +} + +cmdline_parse_inst_t cmd_show_vf_stats = { + .f = cmd_show_vf_stats_parsed, + .data = NULL, + .help_str = "show vf stats ", + .tokens = { + (void *)&cmd_show_vf_stats_show, + (void *)&cmd_show_vf_stats_vf, + (void *)&cmd_show_vf_stats_stats, + (void *)&cmd_show_vf_stats_port_id, + (void *)&cmd_show_vf_stats_vf_id, + NULL, + }, +}; + +/* clear vf stats */ + +/* Common result structure for clear vf stats */ +struct cmd_clear_vf_stats_result { + cmdline_fixed_string_t clear; + cmdline_fixed_string_t vf; + cmdline_fixed_string_t stats; + uint8_t port_id; + uint16_t vf_id; +}; + +/* Common CLI fields clear vf stats*/ +cmdline_parse_token_string_t cmd_clear_vf_stats_clear = + TOKEN_STRING_INITIALIZER + (struct cmd_clear_vf_stats_result, + clear, "clear"); +cmdline_parse_token_string_t cmd_clear_vf_stats_vf = + TOKEN_STRING_INITIALIZER + (struct cmd_clear_vf_stats_result, + vf, "vf"); +cmdline_parse_token_string_t cmd_clear_vf_stats_stats = + TOKEN_STRING_INITIALIZER + (struct cmd_clear_vf_stats_result, + stats, "stats"); +cmdline_parse_token_num_t cmd_clear_vf_stats_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_clear_vf_stats_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_clear_vf_stats_vf_id = + TOKEN_NUM_INITIALIZER + (struct cmd_clear_vf_stats_result, + vf_id, UINT16); + +static void +cmd_clear_vf_stats_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_clear_vf_stats_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_reset_vf_stats(res->port_id, + res->vf_id); +#endif +#ifdef RTE_LIBRTE_BNXT_PMD + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_reset_vf_stats(res->port_id, + res->vf_id); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid vf_id %d\n", res->vf_id); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_clear_vf_stats = { + .f = cmd_clear_vf_stats_parsed, + .data = NULL, + .help_str = "clear vf stats ", + .tokens = { + (void *)&cmd_clear_vf_stats_clear, + (void *)&cmd_clear_vf_stats_vf, + (void *)&cmd_clear_vf_stats_stats, + (void *)&cmd_clear_vf_stats_port_id, + (void *)&cmd_clear_vf_stats_vf_id, + NULL, + }, +}; + +/* port config pctype mapping reset */ + +/* Common result structure for port config pctype mapping reset */ +struct cmd_pctype_mapping_reset_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + uint8_t port_id; + cmdline_fixed_string_t pctype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t reset; +}; + +/* Common CLI fields for port config pctype mapping reset*/ +cmdline_parse_token_string_t cmd_pctype_mapping_reset_port = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + port, "port"); +cmdline_parse_token_string_t cmd_pctype_mapping_reset_config = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + config, "config"); +cmdline_parse_token_num_t cmd_pctype_mapping_reset_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_pctype_mapping_reset_pctype = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + pctype, "pctype"); +cmdline_parse_token_string_t cmd_pctype_mapping_reset_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_pctype_mapping_reset_reset = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_reset_result, + reset, "reset"); + +static void +cmd_pctype_mapping_reset_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pctype_mapping_reset_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_flow_type_mapping_reset(res->port_id); +#endif + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_pctype_mapping_reset = { + .f = cmd_pctype_mapping_reset_parsed, + .data = NULL, + .help_str = "port config pctype mapping reset", + .tokens = { + (void *)&cmd_pctype_mapping_reset_port, + (void *)&cmd_pctype_mapping_reset_config, + (void *)&cmd_pctype_mapping_reset_port_id, + (void *)&cmd_pctype_mapping_reset_pctype, + (void *)&cmd_pctype_mapping_reset_mapping, + (void *)&cmd_pctype_mapping_reset_reset, + NULL, + }, +}; + +/* show port pctype mapping */ + +/* Common result structure for show port pctype mapping */ +struct cmd_pctype_mapping_get_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t port; + uint8_t port_id; + cmdline_fixed_string_t pctype; + cmdline_fixed_string_t mapping; +}; + +/* Common CLI fields for pctype mapping get */ +cmdline_parse_token_string_t cmd_pctype_mapping_get_show = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_get_result, + show, "show"); +cmdline_parse_token_string_t cmd_pctype_mapping_get_port = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_get_result, + port, "port"); +cmdline_parse_token_num_t cmd_pctype_mapping_get_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_pctype_mapping_get_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_pctype_mapping_get_pctype = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_get_result, + pctype, "pctype"); +cmdline_parse_token_string_t cmd_pctype_mapping_get_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_get_result, + mapping, "mapping"); + +static void +cmd_pctype_mapping_get_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pctype_mapping_get_result *res = parsed_result; + int ret = -ENOTSUP; +#ifdef RTE_LIBRTE_I40E_PMD + struct rte_pmd_i40e_flow_type_mapping + mapping[RTE_PMD_I40E_FLOW_TYPE_MAX]; + int i, j, first_pctype; +#endif + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_flow_type_mapping_get(res->port_id, mapping); +#endif + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + return; + case -ENOTSUP: + printf("function not implemented\n"); + return; + default: + printf("programming error: (%s)\n", strerror(-ret)); + return; + } + +#ifdef RTE_LIBRTE_I40E_PMD + for (i = 0; i < RTE_PMD_I40E_FLOW_TYPE_MAX; i++) { + if (mapping[i].pctype != 0ULL) { + first_pctype = 1; + + printf("pctype: "); + for (j = 0; j < RTE_PMD_I40E_PCTYPE_MAX; j++) { + if (mapping[i].pctype & (1ULL << j)) { + printf(first_pctype ? + "%02d" : ",%02d", j); + first_pctype = 0; + } + } + printf(" -> flowtype: %02d\n", mapping[i].flow_type); + } + } +#endif +} + +cmdline_parse_inst_t cmd_pctype_mapping_get = { + .f = cmd_pctype_mapping_get_parsed, + .data = NULL, + .help_str = "show port pctype mapping", + .tokens = { + (void *)&cmd_pctype_mapping_get_show, + (void *)&cmd_pctype_mapping_get_port, + (void *)&cmd_pctype_mapping_get_port_id, + (void *)&cmd_pctype_mapping_get_pctype, + (void *)&cmd_pctype_mapping_get_mapping, + NULL, + }, +}; + +/* port config pctype mapping update */ + +/* Common result structure for port config pctype mapping update */ +struct cmd_pctype_mapping_update_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + uint8_t port_id; + cmdline_fixed_string_t pctype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t update; + cmdline_fixed_string_t pctype_list; + uint16_t flow_type; +}; + +/* Common CLI fields for pctype mapping update*/ +cmdline_parse_token_string_t cmd_pctype_mapping_update_port = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + port, "port"); +cmdline_parse_token_string_t cmd_pctype_mapping_update_config = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + config, "config"); +cmdline_parse_token_num_t cmd_pctype_mapping_update_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_pctype_mapping_update_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_pctype_mapping_update_pctype = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + pctype, "pctype"); +cmdline_parse_token_string_t cmd_pctype_mapping_update_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_pctype_mapping_update_update = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + update, "update"); +cmdline_parse_token_string_t cmd_pctype_mapping_update_pc_type = + TOKEN_STRING_INITIALIZER + (struct cmd_pctype_mapping_update_result, + pctype_list, NULL); +cmdline_parse_token_num_t cmd_pctype_mapping_update_flow_type = + TOKEN_NUM_INITIALIZER + (struct cmd_pctype_mapping_update_result, + flow_type, UINT16); + +static void +cmd_pctype_mapping_update_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_pctype_mapping_update_result *res = parsed_result; + int ret = -ENOTSUP; +#ifdef RTE_LIBRTE_I40E_PMD + struct rte_pmd_i40e_flow_type_mapping mapping; + unsigned int i; +#endif + unsigned int nb_item; + unsigned int pctype_list[RTE_PMD_I40E_PCTYPE_MAX]; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + nb_item = parse_item_list(res->pctype_list, "pctypes", + RTE_PMD_I40E_PCTYPE_MAX, pctype_list, 1); + +#ifdef RTE_LIBRTE_I40E_PMD + mapping.flow_type = res->flow_type; + for (i = 0, mapping.pctype = 0ULL; i < nb_item; i++) + mapping.pctype |= (1ULL << pctype_list[i]); + ret = rte_pmd_i40e_flow_type_mapping_update(res->port_id, + &mapping, + 1, + 0); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid pctype or flow type\n"); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_pctype_mapping_update = { + .f = cmd_pctype_mapping_update_parsed, + .data = NULL, + .help_str = "port config pctype mapping update" + " ", + .tokens = { + (void *)&cmd_pctype_mapping_update_port, + (void *)&cmd_pctype_mapping_update_config, + (void *)&cmd_pctype_mapping_update_port_id, + (void *)&cmd_pctype_mapping_update_pctype, + (void *)&cmd_pctype_mapping_update_mapping, + (void *)&cmd_pctype_mapping_update_update, + (void *)&cmd_pctype_mapping_update_pc_type, + (void *)&cmd_pctype_mapping_update_flow_type, + NULL, + }, +}; + +/* ptype mapping get */ + +/* Common result structure for ptype mapping get */ +struct cmd_ptype_mapping_get_result { + cmdline_fixed_string_t ptype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t get; + uint8_t port_id; + uint8_t valid_only; +}; + +/* Common CLI fields for ptype mapping get */ +cmdline_parse_token_string_t cmd_ptype_mapping_get_ptype = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_get_result, + ptype, "ptype"); +cmdline_parse_token_string_t cmd_ptype_mapping_get_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_get_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_ptype_mapping_get_get = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_get_result, + get, "get"); +cmdline_parse_token_num_t cmd_ptype_mapping_get_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_get_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_ptype_mapping_get_valid_only = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_get_result, + valid_only, UINT8); + +static void +cmd_ptype_mapping_get_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ptype_mapping_get_result *res = parsed_result; + int ret = -ENOTSUP; +#ifdef RTE_LIBRTE_I40E_PMD + int max_ptype_num = 256; + struct rte_pmd_i40e_ptype_mapping mapping[max_ptype_num]; + uint16_t count; + int i; +#endif + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_ptype_mapping_get(res->port_id, + mapping, + max_ptype_num, + &count, + res->valid_only); +#endif + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } + +#ifdef RTE_LIBRTE_I40E_PMD + if (!ret) { + for (i = 0; i < count; i++) + printf("%3d\t0x%08x\n", + mapping[i].hw_ptype, mapping[i].sw_ptype); + } +#endif +} + +cmdline_parse_inst_t cmd_ptype_mapping_get = { + .f = cmd_ptype_mapping_get_parsed, + .data = NULL, + .help_str = "ptype mapping get ", + .tokens = { + (void *)&cmd_ptype_mapping_get_ptype, + (void *)&cmd_ptype_mapping_get_mapping, + (void *)&cmd_ptype_mapping_get_get, + (void *)&cmd_ptype_mapping_get_port_id, + (void *)&cmd_ptype_mapping_get_valid_only, + NULL, + }, +}; + +/* ptype mapping replace */ + +/* Common result structure for ptype mapping replace */ +struct cmd_ptype_mapping_replace_result { + cmdline_fixed_string_t ptype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t replace; + uint8_t port_id; + uint32_t target; + uint8_t mask; + uint32_t pkt_type; +}; + +/* Common CLI fields for ptype mapping replace */ +cmdline_parse_token_string_t cmd_ptype_mapping_replace_ptype = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + ptype, "ptype"); +cmdline_parse_token_string_t cmd_ptype_mapping_replace_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_ptype_mapping_replace_replace = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + replace, "replace"); +cmdline_parse_token_num_t cmd_ptype_mapping_replace_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_ptype_mapping_replace_target = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + target, UINT32); +cmdline_parse_token_num_t cmd_ptype_mapping_replace_mask = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + mask, UINT8); +cmdline_parse_token_num_t cmd_ptype_mapping_replace_pkt_type = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_replace_result, + pkt_type, UINT32); + +static void +cmd_ptype_mapping_replace_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ptype_mapping_replace_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_ptype_mapping_replace(res->port_id, + res->target, + res->mask, + res->pkt_type); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid ptype 0x%8x or 0x%8x\n", + res->target, res->pkt_type); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_ptype_mapping_replace = { + .f = cmd_ptype_mapping_replace_parsed, + .data = NULL, + .help_str = + "ptype mapping replace ", + .tokens = { + (void *)&cmd_ptype_mapping_replace_ptype, + (void *)&cmd_ptype_mapping_replace_mapping, + (void *)&cmd_ptype_mapping_replace_replace, + (void *)&cmd_ptype_mapping_replace_port_id, + (void *)&cmd_ptype_mapping_replace_target, + (void *)&cmd_ptype_mapping_replace_mask, + (void *)&cmd_ptype_mapping_replace_pkt_type, + NULL, + }, +}; + +/* ptype mapping reset */ + +/* Common result structure for ptype mapping reset */ +struct cmd_ptype_mapping_reset_result { + cmdline_fixed_string_t ptype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t reset; + uint8_t port_id; +}; + +/* Common CLI fields for ptype mapping reset*/ +cmdline_parse_token_string_t cmd_ptype_mapping_reset_ptype = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_reset_result, + ptype, "ptype"); +cmdline_parse_token_string_t cmd_ptype_mapping_reset_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_reset_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_ptype_mapping_reset_reset = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_reset_result, + reset, "reset"); +cmdline_parse_token_num_t cmd_ptype_mapping_reset_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_reset_result, + port_id, UINT8); + +static void +cmd_ptype_mapping_reset_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ptype_mapping_reset_result *res = parsed_result; + int ret = -ENOTSUP; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + ret = rte_pmd_i40e_ptype_mapping_reset(res->port_id); +#endif + + switch (ret) { + case 0: + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_ptype_mapping_reset = { + .f = cmd_ptype_mapping_reset_parsed, + .data = NULL, + .help_str = "ptype mapping reset ", + .tokens = { + (void *)&cmd_ptype_mapping_reset_ptype, + (void *)&cmd_ptype_mapping_reset_mapping, + (void *)&cmd_ptype_mapping_reset_reset, + (void *)&cmd_ptype_mapping_reset_port_id, + NULL, + }, +}; + +/* ptype mapping update */ + +/* Common result structure for ptype mapping update */ +struct cmd_ptype_mapping_update_result { + cmdline_fixed_string_t ptype; + cmdline_fixed_string_t mapping; + cmdline_fixed_string_t reset; + uint8_t port_id; + uint8_t hw_ptype; + uint32_t sw_ptype; +}; + +/* Common CLI fields for ptype mapping update*/ +cmdline_parse_token_string_t cmd_ptype_mapping_update_ptype = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_update_result, + ptype, "ptype"); +cmdline_parse_token_string_t cmd_ptype_mapping_update_mapping = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_update_result, + mapping, "mapping"); +cmdline_parse_token_string_t cmd_ptype_mapping_update_update = + TOKEN_STRING_INITIALIZER + (struct cmd_ptype_mapping_update_result, + reset, "update"); +cmdline_parse_token_num_t cmd_ptype_mapping_update_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_update_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_ptype_mapping_update_hw_ptype = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_update_result, + hw_ptype, UINT8); +cmdline_parse_token_num_t cmd_ptype_mapping_update_sw_ptype = + TOKEN_NUM_INITIALIZER + (struct cmd_ptype_mapping_update_result, + sw_ptype, UINT32); + +static void +cmd_ptype_mapping_update_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_ptype_mapping_update_result *res = parsed_result; + int ret = -ENOTSUP; +#ifdef RTE_LIBRTE_I40E_PMD + struct rte_pmd_i40e_ptype_mapping mapping; +#endif + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + +#ifdef RTE_LIBRTE_I40E_PMD + mapping.hw_ptype = res->hw_ptype; + mapping.sw_ptype = res->sw_ptype; + ret = rte_pmd_i40e_ptype_mapping_update(res->port_id, + &mapping, + 1, + 0); +#endif + + switch (ret) { + case 0: + break; + case -EINVAL: + printf("invalid ptype 0x%8x\n", res->sw_ptype); + break; + case -ENODEV: + printf("invalid port_id %d\n", res->port_id); + break; + case -ENOTSUP: + printf("function not implemented\n"); + break; + default: + printf("programming error: (%s)\n", strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_ptype_mapping_update = { + .f = cmd_ptype_mapping_update_parsed, + .data = NULL, + .help_str = "ptype mapping update ", + .tokens = { + (void *)&cmd_ptype_mapping_update_ptype, + (void *)&cmd_ptype_mapping_update_mapping, + (void *)&cmd_ptype_mapping_update_update, + (void *)&cmd_ptype_mapping_update_port_id, + (void *)&cmd_ptype_mapping_update_hw_ptype, + (void *)&cmd_ptype_mapping_update_sw_ptype, + NULL, + }, +}; + +/* Common result structure for file commands */ +struct cmd_cmdfile_result { + cmdline_fixed_string_t load; + cmdline_fixed_string_t filename; +}; + +/* Common CLI fields for file commands */ +cmdline_parse_token_string_t cmd_load_cmdfile = + TOKEN_STRING_INITIALIZER(struct cmd_cmdfile_result, load, "load"); +cmdline_parse_token_string_t cmd_load_cmdfile_filename = + TOKEN_STRING_INITIALIZER(struct cmd_cmdfile_result, filename, NULL); + +static void +cmd_load_from_file_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_cmdfile_result *res = parsed_result; + + cmdline_read_from_file(res->filename); +} + +cmdline_parse_inst_t cmd_load_from_file = { + .f = cmd_load_from_file_parsed, + .data = NULL, + .help_str = "load ", + .tokens = { + (void *)&cmd_load_cmdfile, + (void *)&cmd_load_cmdfile_filename, + NULL, + }, +}; + +/* ******************************************************************************** */ + +/* list of instructions */ +cmdline_parse_ctx_t main_ctx[] = { + (cmdline_parse_inst_t *)&cmd_help_brief, + (cmdline_parse_inst_t *)&cmd_help_long, + (cmdline_parse_inst_t *)&cmd_quit, + (cmdline_parse_inst_t *)&cmd_load_from_file, + (cmdline_parse_inst_t *)&cmd_showport, + (cmdline_parse_inst_t *)&cmd_showqueue, + (cmdline_parse_inst_t *)&cmd_showportall, + (cmdline_parse_inst_t *)&cmd_showcfg, + (cmdline_parse_inst_t *)&cmd_start, + (cmdline_parse_inst_t *)&cmd_start_tx_first, + (cmdline_parse_inst_t *)&cmd_start_tx_first_n, + (cmdline_parse_inst_t *)&cmd_set_link_up, + (cmdline_parse_inst_t *)&cmd_set_link_down, + (cmdline_parse_inst_t *)&cmd_reset, + (cmdline_parse_inst_t *)&cmd_set_numbers, + (cmdline_parse_inst_t *)&cmd_set_txpkts, + (cmdline_parse_inst_t *)&cmd_set_txsplit, + (cmdline_parse_inst_t *)&cmd_set_fwd_list, + (cmdline_parse_inst_t *)&cmd_set_fwd_mask, + (cmdline_parse_inst_t *)&cmd_set_fwd_mode, + (cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode, + (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry, + (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one, + (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all, + (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one, + (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all, + (cmdline_parse_inst_t *)&cmd_set_flush_rx, + (cmdline_parse_inst_t *)&cmd_set_link_check, + (cmdline_parse_inst_t *)&cmd_set_bypass_mode, + (cmdline_parse_inst_t *)&cmd_set_bypass_event, + (cmdline_parse_inst_t *)&cmd_set_bypass_timeout, + (cmdline_parse_inst_t *)&cmd_show_bypass_config, +#ifdef RTE_LIBRTE_PMD_BOND + (cmdline_parse_inst_t *) &cmd_set_bonding_mode, + (cmdline_parse_inst_t *) &cmd_show_bonding_config, + (cmdline_parse_inst_t *) &cmd_set_bonding_primary, + (cmdline_parse_inst_t *) &cmd_add_bonding_slave, + (cmdline_parse_inst_t *) &cmd_remove_bonding_slave, + (cmdline_parse_inst_t *) &cmd_create_bonded_device, + (cmdline_parse_inst_t *) &cmd_set_bond_mac_addr, + (cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy, + (cmdline_parse_inst_t *) &cmd_set_bond_mon_period, + (cmdline_parse_inst_t *) &cmd_set_lacp_dedicated_queues, + (cmdline_parse_inst_t *) &cmd_set_bonding_agg_mode_policy, +#endif + (cmdline_parse_inst_t *)&cmd_vlan_offload, + (cmdline_parse_inst_t *)&cmd_vlan_tpid, + (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all, + (cmdline_parse_inst_t *)&cmd_rx_vlan_filter, + (cmdline_parse_inst_t *)&cmd_tx_vlan_set, + (cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq, + (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, + (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid, + (cmdline_parse_inst_t *)&cmd_csum_set, (cmdline_parse_inst_t *)&cmd_csum_show, (cmdline_parse_inst_t *)&cmd_csum_tunnel, (cmdline_parse_inst_t *)&cmd_tso_set, (cmdline_parse_inst_t *)&cmd_tso_show, (cmdline_parse_inst_t *)&cmd_tunnel_tso_set, (cmdline_parse_inst_t *)&cmd_tunnel_tso_show, + (cmdline_parse_inst_t *)&cmd_enable_gro, + (cmdline_parse_inst_t *)&cmd_gro_set, (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, @@ -11592,15 +14728,11 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_config_burst, (cmdline_parse_inst_t *)&cmd_config_thresh, (cmdline_parse_inst_t *)&cmd_config_threshold, - (cmdline_parse_inst_t *)&cmd_set_vf_rxmode, (cmdline_parse_inst_t *)&cmd_set_uc_hash_filter, (cmdline_parse_inst_t *)&cmd_set_uc_all_hash_filter, (cmdline_parse_inst_t *)&cmd_vf_mac_addr_filter, (cmdline_parse_inst_t *)&cmd_set_vf_macvlan_filter, - (cmdline_parse_inst_t *)&cmd_set_vf_traffic, - (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter, (cmdline_parse_inst_t *)&cmd_queue_rate_limit, - (cmdline_parse_inst_t *)&cmd_vf_rate_limit, (cmdline_parse_inst_t *)&cmd_tunnel_filter, (cmdline_parse_inst_t *)&cmd_tunnel_udp_config, (cmdline_parse_inst_t *)&cmd_global_config, @@ -11647,7 +14779,6 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis, (cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add, (cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del, -#ifdef RTE_LIBRTE_IXGBE_PMD (cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof, (cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof, (cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq, @@ -11655,11 +14786,62 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_set_tx_loopback, (cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en, (cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en, + (cmdline_parse_inst_t *)&cmd_set_macsec_offload_on, + (cmdline_parse_inst_t *)&cmd_set_macsec_offload_off, + (cmdline_parse_inst_t *)&cmd_set_macsec_sc, + (cmdline_parse_inst_t *)&cmd_set_macsec_sa, + (cmdline_parse_inst_t *)&cmd_set_vf_traffic, + (cmdline_parse_inst_t *)&cmd_set_vf_rxmode, + (cmdline_parse_inst_t *)&cmd_vf_rate_limit, + (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter, (cmdline_parse_inst_t *)&cmd_set_vf_mac_addr, -#endif + (cmdline_parse_inst_t *)&cmd_set_vf_promisc, + (cmdline_parse_inst_t *)&cmd_set_vf_allmulti, + (cmdline_parse_inst_t *)&cmd_set_vf_broadcast, + (cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag, + (cmdline_parse_inst_t *)&cmd_vf_max_bw, + (cmdline_parse_inst_t *)&cmd_vf_tc_min_bw, + (cmdline_parse_inst_t *)&cmd_vf_tc_max_bw, + (cmdline_parse_inst_t *)&cmd_strict_link_prio, + (cmdline_parse_inst_t *)&cmd_tc_min_bw, + (cmdline_parse_inst_t *)&cmd_ddp_add, + (cmdline_parse_inst_t *)&cmd_ddp_del, + (cmdline_parse_inst_t *)&cmd_ddp_get_list, + (cmdline_parse_inst_t *)&cmd_ddp_get_info, + (cmdline_parse_inst_t *)&cmd_show_vf_stats, + (cmdline_parse_inst_t *)&cmd_clear_vf_stats, + (cmdline_parse_inst_t *)&cmd_ptype_mapping_get, + (cmdline_parse_inst_t *)&cmd_ptype_mapping_replace, + (cmdline_parse_inst_t *)&cmd_ptype_mapping_reset, + (cmdline_parse_inst_t *)&cmd_ptype_mapping_update, + + (cmdline_parse_inst_t *)&cmd_pctype_mapping_get, + (cmdline_parse_inst_t *)&cmd_pctype_mapping_reset, + (cmdline_parse_inst_t *)&cmd_pctype_mapping_update, NULL, }; +/* read cmdline commands from file */ +void +cmdline_read_from_file(const char *filename) +{ + struct cmdline *cl; + + cl = cmdline_file_new(main_ctx, "testpmd> ", filename); + if (cl == NULL) { + printf("Failed to create file based cmdline context: %s\n", + filename); + return; + } + + cmdline_interact(cl); + cmdline_quit(cl); + + cmdline_free(cl); + + printf("Read CLI commands from %s\n", filename); +} + /* prompt function, called from main on MASTER lcore */ void prompt(void) @@ -11688,7 +14870,7 @@ cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue) if (id == (portid_t)RTE_PORT_ALL) { portid_t pid; - FOREACH_PORT(pid, ports) { + RTE_ETH_FOREACH_DEV(pid) { /* check if need_reconfig has been set to 1 */ if (ports[pid].need_reconfig == 0) ports[pid].need_reconfig = dev;