+static void
+cmd_config_speed_all_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_speed_all *res = parsed_result;
+ uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
+ uint16_t link_duplex = 0;
+ portid_t pid;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->value1, "10"))
+ link_speed = ETH_LINK_SPEED_10;
+ else if (!strcmp(res->value1, "100"))
+ link_speed = ETH_LINK_SPEED_100;
+ else if (!strcmp(res->value1, "1000"))
+ link_speed = ETH_LINK_SPEED_1000;
+ else if (!strcmp(res->value1, "10000"))
+ link_speed = ETH_LINK_SPEED_10000;
+ else if (!strcmp(res->value1, "auto"))
+ link_speed = ETH_LINK_SPEED_AUTONEG;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ if (!strcmp(res->value2, "half"))
+ link_duplex = ETH_LINK_HALF_DUPLEX;
+ else if (!strcmp(res->value2, "full"))
+ link_duplex = ETH_LINK_FULL_DUPLEX;
+ else if (!strcmp(res->value2, "auto"))
+ link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ for (pid = 0; pid < nb_ports; pid++) {
+ ports[pid].dev_conf.link_speed = link_speed;
+ ports[pid].dev_conf.link_duplex = link_duplex;
+ }
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_speed_all_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, port, "port");
+cmdline_parse_token_string_t cmd_config_speed_all_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_speed_all_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, all, "all");
+cmdline_parse_token_string_t cmd_config_speed_all_item1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
+cmdline_parse_token_string_t cmd_config_speed_all_value1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
+ "10#100#1000#10000#auto");
+cmdline_parse_token_string_t cmd_config_speed_all_item2 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
+cmdline_parse_token_string_t cmd_config_speed_all_value2 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
+ "half#full#auto");
+
+cmdline_parse_inst_t cmd_config_speed_all = {
+ .f = cmd_config_speed_all_parsed,
+ .data = NULL,
+ .help_str = "port config all speed 10|100|1000|10000|auto duplex "
+ "half|full|auto",
+ .tokens = {
+ (void *)&cmd_config_speed_all_port,
+ (void *)&cmd_config_speed_all_keyword,
+ (void *)&cmd_config_speed_all_all,
+ (void *)&cmd_config_speed_all_item1,
+ (void *)&cmd_config_speed_all_value1,
+ (void *)&cmd_config_speed_all_item2,
+ (void *)&cmd_config_speed_all_value2,
+ NULL,
+ },
+};
+
+/* *** configure speed for specific port *** */
+struct cmd_config_speed_specific {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ uint8_t id;
+ cmdline_fixed_string_t item1;
+ cmdline_fixed_string_t item2;
+ cmdline_fixed_string_t value1;
+ cmdline_fixed_string_t value2;
+};
+
+static void
+cmd_config_speed_specific_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_speed_specific *res = parsed_result;
+ uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
+ uint16_t link_duplex = 0;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (res->id >= nb_ports) {
+ printf("Port id %d must be less than %d\n", res->id, nb_ports);
+ return;
+ }
+
+ if (!strcmp(res->value1, "10"))
+ link_speed = ETH_LINK_SPEED_10;
+ else if (!strcmp(res->value1, "100"))
+ link_speed = ETH_LINK_SPEED_100;
+ else if (!strcmp(res->value1, "1000"))
+ link_speed = ETH_LINK_SPEED_1000;
+ else if (!strcmp(res->value1, "10000"))
+ link_speed = ETH_LINK_SPEED_10000;
+ else if (!strcmp(res->value1, "auto"))
+ link_speed = ETH_LINK_SPEED_AUTONEG;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ if (!strcmp(res->value2, "half"))
+ link_duplex = ETH_LINK_HALF_DUPLEX;
+ else if (!strcmp(res->value2, "full"))
+ link_duplex = ETH_LINK_FULL_DUPLEX;
+ else if (!strcmp(res->value2, "auto"))
+ link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ ports[res->id].dev_conf.link_speed = link_speed;
+ ports[res->id].dev_conf.link_duplex = link_duplex;
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+
+cmdline_parse_token_string_t cmd_config_speed_specific_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, port,
+ "port");
+cmdline_parse_token_string_t cmd_config_speed_specific_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, keyword,
+ "config");
+cmdline_parse_token_num_t cmd_config_speed_specific_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, id, UINT8);
+cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item1,
+ "speed");
+cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
+ "10#100#1000#10000#auto");
+cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
+ "duplex");
+cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
+ "half#full#auto");
+
+cmdline_parse_inst_t cmd_config_speed_specific = {
+ .f = cmd_config_speed_specific_parsed,
+ .data = NULL,
+ .help_str = "port config X speed 10|100|1000|10000|auto duplex "
+ "half|full|auto",
+ .tokens = {
+ (void *)&cmd_config_speed_specific_port,
+ (void *)&cmd_config_speed_specific_keyword,
+ (void *)&cmd_config_speed_specific_id,
+ (void *)&cmd_config_speed_specific_item1,
+ (void *)&cmd_config_speed_specific_value1,
+ (void *)&cmd_config_speed_specific_item2,
+ (void *)&cmd_config_speed_specific_value2,
+ NULL,
+ },
+};
+
+/* *** configure txq/rxq, txd/rxd *** */
+struct cmd_config_rx_tx {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint16_t value;
+};
+
+static void
+cmd_config_rx_tx_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rx_tx *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "rxq")) {
+ if (res->value <= 0) {
+ printf("rxq %d invalid - must be > 0\n", res->value);
+ return;
+ }
+ nb_rxq = res->value;
+ }
+ else if (!strcmp(res->name, "txq")) {
+ if (res->value <= 0) {
+ printf("txq %d invalid - must be > 0\n", res->value);
+ return;
+ }
+ nb_txq = res->value;
+ }
+ else if (!strcmp(res->name, "rxd")) {
+ if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
+ printf("rxd %d invalid - must be > 0 && <= %d\n",
+ res->value, RTE_TEST_RX_DESC_MAX);
+ return;
+ }
+ nb_rxd = res->value;
+ } else if (!strcmp(res->name, "txd")) {
+ if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
+ printf("txd %d invalid - must be > 0 && <= %d\n",
+ res->value, RTE_TEST_TX_DESC_MAX);
+ return;
+ }
+ nb_txd = res->value;
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_rx_tx_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, port, "port");
+cmdline_parse_token_string_t cmd_config_rx_tx_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, keyword, "config");
+cmdline_parse_token_string_t cmd_config_rx_tx_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, all, "all");
+cmdline_parse_token_string_t cmd_config_rx_tx_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, name,
+ "rxq#txq#rxd#txd");
+cmdline_parse_token_num_t cmd_config_rx_tx_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rx_tx, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_rx_tx = {
+ .f = cmd_config_rx_tx_parsed,
+ .data = NULL,
+ .help_str = "port config all rxq|txq|rxd|txd value",
+ .tokens = {
+ (void *)&cmd_config_rx_tx_port,
+ (void *)&cmd_config_rx_tx_keyword,
+ (void *)&cmd_config_rx_tx_all,
+ (void *)&cmd_config_rx_tx_name,
+ (void *)&cmd_config_rx_tx_value,
+ NULL,
+ },
+};
+
+/* *** config max packet length *** */
+struct cmd_config_max_pkt_len_result {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint32_t value;
+};
+
+static void
+cmd_config_max_pkt_len_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_max_pkt_len_result *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "max-pkt-len")) {
+ if (res->value < ETHER_MIN_LEN) {
+ printf("max-pkt-len can not be less than %d\n",
+ ETHER_MIN_LEN);
+ return;
+ }
+ if (res->value == rx_mode.max_rx_pkt_len)
+ return;
+
+ rx_mode.max_rx_pkt_len = res->value;
+ if (res->value > ETHER_MAX_LEN)
+ rx_mode.jumbo_frame = 1;
+ else
+ rx_mode.jumbo_frame = 0;
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
+ "port");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
+ "all");
+cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
+ "max-pkt-len");
+cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
+ UINT32);
+
+cmdline_parse_inst_t cmd_config_max_pkt_len = {
+ .f = cmd_config_max_pkt_len_parsed,
+ .data = NULL,
+ .help_str = "port config all max-pkt-len value",
+ .tokens = {
+ (void *)&cmd_config_max_pkt_len_port,
+ (void *)&cmd_config_max_pkt_len_keyword,
+ (void *)&cmd_config_max_pkt_len_all,
+ (void *)&cmd_config_max_pkt_len_name,
+ (void *)&cmd_config_max_pkt_len_value,
+ NULL,
+ },
+};
+
+/* *** configure rx mode *** */
+struct cmd_config_rx_mode_flag {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t value;
+};
+
+static void
+cmd_config_rx_mode_flag_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rx_mode_flag *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "crc-strip")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_strip_crc = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_strip_crc = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "rx-cksum")) {
+ if (!strcmp(res->value, "on"))
+ rx_mode.hw_ip_checksum = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_mode.hw_ip_checksum = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "hw-vlan")) {
+ if (!strcmp(res->value, "on")) {
+ rx_mode.hw_vlan_filter = 1;
+ rx_mode.hw_vlan_strip = 1;
+ }
+ else if (!strcmp(res->value, "off")) {
+ rx_mode.hw_vlan_filter = 0;
+ rx_mode.hw_vlan_strip = 0;
+ }
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else if (!strcmp(res->name, "drop-en")) {
+ if (!strcmp(res->value, "on"))
+ rx_drop_en = 1;
+ else if (!strcmp(res->value, "off"))
+ rx_drop_en = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
+ "crc-strip#rx-cksum#hw-vlan");
+cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
+ "on#off");
+
+cmdline_parse_inst_t cmd_config_rx_mode_flag = {
+ .f = cmd_config_rx_mode_flag_parsed,
+ .data = NULL,
+ .help_str = "port config all crc-strip|rx-cksum|hw-vlan on|off",
+ .tokens = {
+ (void *)&cmd_config_rx_mode_flag_port,
+ (void *)&cmd_config_rx_mode_flag_keyword,
+ (void *)&cmd_config_rx_mode_flag_all,
+ (void *)&cmd_config_rx_mode_flag_name,
+ (void *)&cmd_config_rx_mode_flag_value,
+ NULL,
+ },
+};
+
+/* *** configure rss *** */
+struct cmd_config_rss {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t value;
+};
+
+static void
+cmd_config_rss_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rss *res = parsed_result;
+ struct rte_eth_rss_conf rss_conf;
+ uint8_t i;
+
+ if (!strcmp(res->value, "ip"))
+ rss_conf.rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6;
+ else if (!strcmp(res->value, "udp"))
+ rss_conf.rss_hf = ETH_RSS_IPV4_UDP | ETH_RSS_IPV6_UDP;
+ else if (!strcmp(res->value, "none"))
+ rss_conf.rss_hf = 0;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+ rss_conf.rss_key = NULL;
+ for (i = 0; i < rte_eth_dev_count(); i++)
+ rte_eth_dev_rss_hash_update(i, &rss_conf);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
+cmdline_parse_token_string_t cmd_config_rss_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "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, "ip#udp#none");
+
+cmdline_parse_inst_t cmd_config_rss = {
+ .f = cmd_config_rss_parsed,
+ .data = NULL,
+ .help_str = "port config all rss ip|udp|none",
+ .tokens = {
+ (void *)&cmd_config_rss_port,
+ (void *)&cmd_config_rss_keyword,
+ (void *)&cmd_config_rss_all,
+ (void *)&cmd_config_rss_name,
+ (void *)&cmd_config_rss_value,
+ NULL,
+ },
+};
+
+/* *** configure rss hash key *** */
+struct cmd_config_rss_hash_key {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss_hash_key;
+ cmdline_fixed_string_t key;
+};
+
+#define RSS_HASH_KEY_LENGTH 40
+static uint8_t
+hexa_digit_to_value(char hexa_digit)
+{
+ if ((hexa_digit >= '0') && (hexa_digit <= '9'))
+ return (uint8_t) (hexa_digit - '0');
+ if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
+ return (uint8_t) ((hexa_digit - 'a') + 10);
+ if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
+ return (uint8_t) ((hexa_digit - 'A') + 10);
+ /* Invalid hexa digit */
+ return 0xFF;
+}
+
+static uint8_t
+parse_and_check_key_hexa_digit(char *key, int idx)
+{
+ uint8_t hexa_v;
+
+ hexa_v = hexa_digit_to_value(key[idx]);
+ if (hexa_v == 0xFF)
+ printf("invalid key: character %c at position %d is not a "
+ "valid hexa digit\n", key[idx], idx);
+ return hexa_v;
+}
+
+static void
+cmd_config_rss_hash_key_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_rss_hash_key *res = parsed_result;
+ uint8_t hash_key[RSS_HASH_KEY_LENGTH];
+ uint8_t xdgt0;
+ uint8_t xdgt1;
+ int i;
+
+ /* Check the length of the RSS hash key */
+ if (strlen(res->key) != (RSS_HASH_KEY_LENGTH * 2)) {
+ printf("key length: %d invalid - key must be a string of %d"
+ "hexa-decimal numbers\n", (int) strlen(res->key),
+ RSS_HASH_KEY_LENGTH * 2);
+ return;
+ }
+ /* Translate RSS hash key into binary representation */
+ for (i = 0; i < RSS_HASH_KEY_LENGTH; 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;
+ hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
+ }
+ port_rss_hash_key_update(res->port_id, hash_key);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
+ "config");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
+ rss_hash_key, "rss-hash-key");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
+
+cmdline_parse_inst_t cmd_config_rss_hash_key = {
+ .f = cmd_config_rss_hash_key_parsed,
+ .data = NULL,
+ .help_str = "port config X rss-hash-key 80 hexa digits",
+ .tokens = {
+ (void *)&cmd_config_rss_hash_key_port,
+ (void *)&cmd_config_rss_hash_key_config,
+ (void *)&cmd_config_rss_hash_key_port_id,
+ (void *)&cmd_config_rss_hash_key_rss_hash_key,
+ (void *)&cmd_config_rss_hash_key_value,
+ NULL,
+ },
+};
+
+/* *** Configure RSS RETA *** */
+struct cmd_config_rss_reta {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ uint8_t port_id;
+ cmdline_fixed_string_t name;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static int
+parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)
+{
+ int i;
+ unsigned size;
+ uint8_t hash_index;
+ uint8_t nb_queue;
+ char s[256];
+ const char *p, *p0 = str;
+ char *end;
+ enum fieldnames {
+ FLD_HASH_INDEX = 0,
+ FLD_QUEUE,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+
+ while ((p = strchr(p0,'(')) != NULL) {
+ ++p;
+ if((p0 = strchr(p,')')) == NULL)
+ return -1;
+
+ size = p0 - p;
+ if(size >= sizeof(s))
+ return -1;
+
+ rte_snprintf(s, sizeof(s), "%.*s", size, p);
+ if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
+ return -1;
+ for (i = 0; i < _NUM_FLD; i++) {
+ errno = 0;
+ int_fld[i] = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+ return -1;
+ }
+
+ hash_index = (uint8_t)int_fld[FLD_HASH_INDEX];
+ nb_queue = (uint8_t)int_fld[FLD_QUEUE];
+
+ if (hash_index >= ETH_RSS_RETA_NUM_ENTRIES) {
+ printf("Invalid RETA hash index=%d",hash_index);
+ return -1;
+ }
+
+ if (hash_index < ETH_RSS_RETA_NUM_ENTRIES/2)
+ reta_conf->mask_lo |= (1ULL << hash_index);
+ else
+ reta_conf->mask_hi |= (1ULL << (hash_index - ETH_RSS_RETA_NUM_ENTRIES/2));
+
+ reta_conf->reta[hash_index] = nb_queue;
+ }
+
+ return 0;
+}
+
+static void
+cmd_set_rss_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret;
+ struct rte_eth_rss_reta reta_conf;
+ struct cmd_config_rss_reta *res = parsed_result;
+
+ memset(&reta_conf,0,sizeof(struct rte_eth_rss_reta));
+ if (!strcmp(res->list_name, "reta")) {
+ if (parse_reta_config(res->list_of_items, &reta_conf)) {
+ printf("Invalid RSS Redirection Table config entered\n");
+ return;
+ }
+ ret = rte_eth_dev_rss_reta_update(res->port_id, &reta_conf);
+ if (ret != 0)
+ printf("Bad redirection table parameter, return code = %d \n",ret);
+ }
+}
+
+cmdline_parse_token_string_t cmd_config_rss_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
+cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_reta_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
+cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
+ NULL);
+cmdline_parse_inst_t cmd_config_rss_reta = {
+ .f = cmd_set_rss_reta_parsed,
+ .data = NULL,
+ .help_str = "port config X rss reta (hash,queue)[,(hash,queue)]",
+ .tokens = {
+ (void *)&cmd_config_rss_reta_port,
+ (void *)&cmd_config_rss_reta_keyword,
+ (void *)&cmd_config_rss_reta_port_id,
+ (void *)&cmd_config_rss_reta_name,
+ (void *)&cmd_config_rss_reta_list_name,
+ (void *)&cmd_config_rss_reta_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SHOW PORT RETA INFO *** */
+struct cmd_showport_reta {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss;
+ cmdline_fixed_string_t reta;
+ uint64_t mask_lo;
+ uint64_t mask_hi;
+};
+
+static void cmd_showport_reta_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_showport_reta *res = parsed_result;
+ struct rte_eth_rss_reta reta_conf;
+
+ if ((res->mask_lo == 0) && (res->mask_hi == 0)) {
+ printf("Invalid RSS Redirection Table config entered\n");
+ return;
+ }
+
+ reta_conf.mask_lo = res->mask_lo;
+ reta_conf.mask_hi = res->mask_hi;
+
+ port_rss_reta_info(res->port_id,&reta_conf);
+}
+
+cmdline_parse_token_string_t cmd_showport_reta_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, show, "show");
+cmdline_parse_token_string_t cmd_showport_reta_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, port, "port");
+cmdline_parse_token_num_t cmd_showport_reta_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_reta_rss =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
+cmdline_parse_token_string_t cmd_showport_reta_reta =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
+cmdline_parse_token_num_t cmd_showport_reta_mask_lo =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta,mask_lo,UINT64);
+cmdline_parse_token_num_t cmd_showport_reta_mask_hi =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_reta,mask_hi,UINT64);
+
+cmdline_parse_inst_t cmd_showport_reta = {
+ .f = cmd_showport_reta_parsed,
+ .data = NULL,
+ .help_str = "show port X rss reta mask_lo mask_hi (X = port number)\n\
+ (mask_lo and mask_hi is UINT64)",
+ .tokens = {
+ (void *)&cmd_showport_reta_show,
+ (void *)&cmd_showport_reta_port,
+ (void *)&cmd_showport_reta_port_id,
+ (void *)&cmd_showport_reta_rss,
+ (void *)&cmd_showport_reta_reta,
+ (void *)&cmd_showport_reta_mask_lo,
+ (void *)&cmd_showport_reta_mask_hi,
+ NULL,
+ },
+};
+
+/* *** Show RSS hash configuration *** */
+struct cmd_showport_rss_hash {
+ cmdline_fixed_string_t show;
+ cmdline_fixed_string_t port;
+ uint8_t port_id;
+ cmdline_fixed_string_t rss_hash;
+ cmdline_fixed_string_t key; /* optional argument */
+};
+
+static void cmd_showport_rss_hash_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *show_rss_key)
+{
+ struct cmd_showport_rss_hash *res = parsed_result;
+
+ port_rss_hash_conf_show(res->port_id, show_rss_key != NULL);
+}
+
+cmdline_parse_token_string_t cmd_showport_rss_hash_show =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
+cmdline_parse_token_string_t cmd_showport_rss_hash_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
+cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
+ "rss-hash");
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
+ TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
+
+cmdline_parse_inst_t cmd_showport_rss_hash = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = NULL,
+ .help_str = "show port X rss-hash (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ NULL,
+ },
+};
+
+cmdline_parse_inst_t cmd_showport_rss_hash_key = {
+ .f = cmd_showport_rss_hash_parsed,
+ .data = (void *)1,
+ .help_str = "show port X rss-hash key (X = port number)\n",
+ .tokens = {
+ (void *)&cmd_showport_rss_hash_show,
+ (void *)&cmd_showport_rss_hash_port,
+ (void *)&cmd_showport_rss_hash_port_id,
+ (void *)&cmd_showport_rss_hash_rss_hash,
+ (void *)&cmd_showport_rss_hash_rss_key,
+ NULL,
+ },
+};
+
+/* *** Configure DCB *** */
+struct cmd_config_dcb {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t config;
+ uint8_t port_id;
+ cmdline_fixed_string_t dcb;
+ cmdline_fixed_string_t vt;
+ cmdline_fixed_string_t vt_en;
+ uint8_t num_tcs;
+ cmdline_fixed_string_t pfc;
+ cmdline_fixed_string_t pfc_en;
+};
+
+static void
+cmd_config_dcb_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_dcb *res = parsed_result;
+ struct dcb_config dcb_conf;
+ 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;
+ }
+
+ dcb_conf.num_tcs = (enum rte_eth_nb_tcs) res->num_tcs;
+ if ((dcb_conf.num_tcs != ETH_4_TCS) && (dcb_conf.num_tcs != ETH_8_TCS)){
+ printf("The invalid number of traffic class,only 4 or 8 allowed\n");
+ return;
+ }
+
+ /* DCB in VT mode */
+ if (!strncmp(res->vt_en, "on",2))
+ dcb_conf.dcb_mode = DCB_VT_ENABLED;
+ else
+ dcb_conf.dcb_mode = DCB_ENABLED;
+
+ if (!strncmp(res->pfc_en, "on",2)) {
+ dcb_conf.pfc_en = 1;
+ }
+ else
+ dcb_conf.pfc_en = 0;
+
+ if (init_port_dcb_config(port_id,&dcb_conf) != 0) {
+ printf("Cannot initialize network ports\n");
+ return;
+ }
+
+ cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_dcb_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
+cmdline_parse_token_string_t cmd_config_dcb_config =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
+cmdline_parse_token_num_t cmd_config_dcb_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_dcb =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
+cmdline_parse_token_string_t cmd_config_dcb_vt =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
+cmdline_parse_token_string_t cmd_config_dcb_vt_en =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
+cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
+cmdline_parse_token_string_t cmd_config_dcb_pfc=
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
+cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
+
+cmdline_parse_inst_t cmd_config_dcb = {
+ .f = cmd_config_dcb_parsed,
+ .data = NULL,
+ .help_str = "port config port-id dcb vt on|off nb-tcs pfc on|off",
+ .tokens = {
+ (void *)&cmd_config_dcb_port,
+ (void *)&cmd_config_dcb_config,
+ (void *)&cmd_config_dcb_port_id,
+ (void *)&cmd_config_dcb_dcb,
+ (void *)&cmd_config_dcb_vt,
+ (void *)&cmd_config_dcb_vt_en,
+ (void *)&cmd_config_dcb_num_tcs,
+ (void *)&cmd_config_dcb_pfc,
+ (void *)&cmd_config_dcb_pfc_en,
+ NULL,
+ },
+};
+
+/* *** configure number of packets per burst *** */
+struct cmd_config_burst {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint16_t value;
+};
+
+static void
+cmd_config_burst_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_burst *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "burst")) {
+ if (res->value < 1 || res->value > MAX_PKT_BURST) {
+ printf("burst must be >= 1 && <= %d\n", MAX_PKT_BURST);
+ return;
+ }
+ nb_pkt_per_burst = res->value;
+ } else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_burst_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
+cmdline_parse_token_string_t cmd_config_burst_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
+cmdline_parse_token_string_t cmd_config_burst_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
+cmdline_parse_token_string_t cmd_config_burst_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
+cmdline_parse_token_num_t cmd_config_burst_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_burst = {
+ .f = cmd_config_burst_parsed,
+ .data = NULL,
+ .help_str = "port config all burst value",
+ .tokens = {
+ (void *)&cmd_config_burst_port,
+ (void *)&cmd_config_burst_keyword,
+ (void *)&cmd_config_burst_all,
+ (void *)&cmd_config_burst_name,
+ (void *)&cmd_config_burst_value,
+ NULL,
+ },
+};
+
+/* *** configure rx/tx queues *** */
+struct cmd_config_thresh {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint8_t value;
+};
+
+static void
+cmd_config_thresh_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_thresh *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "txpt"))
+ tx_thresh.pthresh = res->value;
+ else if(!strcmp(res->name, "txht"))
+ tx_thresh.hthresh = res->value;
+ else if(!strcmp(res->name, "txwt"))
+ tx_thresh.wthresh = res->value;
+ else if(!strcmp(res->name, "rxpt"))
+ rx_thresh.pthresh = res->value;
+ else if(!strcmp(res->name, "rxht"))
+ rx_thresh.hthresh = res->value;
+ else if(!strcmp(res->name, "rxwt"))
+ rx_thresh.wthresh = res->value;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_thresh_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
+cmdline_parse_token_string_t cmd_config_thresh_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
+cmdline_parse_token_string_t cmd_config_thresh_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
+cmdline_parse_token_string_t cmd_config_thresh_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
+ "txpt#txht#txwt#rxpt#rxht#rxwt");
+cmdline_parse_token_num_t cmd_config_thresh_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, UINT8);
+
+cmdline_parse_inst_t cmd_config_thresh = {
+ .f = cmd_config_thresh_parsed,
+ .data = NULL,
+ .help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt value",
+ .tokens = {
+ (void *)&cmd_config_thresh_port,
+ (void *)&cmd_config_thresh_keyword,
+ (void *)&cmd_config_thresh_all,
+ (void *)&cmd_config_thresh_name,
+ (void *)&cmd_config_thresh_value,
+ NULL,
+ },
+};
+
+/* *** configure free/rs threshold *** */
+struct cmd_config_threshold {
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t keyword;
+ cmdline_fixed_string_t all;
+ cmdline_fixed_string_t name;
+ uint16_t value;
+};
+
+static void
+cmd_config_threshold_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_config_threshold *res = parsed_result;
+
+ if (!all_ports_stopped()) {
+ printf("Please stop all ports first\n");
+ return;
+ }
+
+ if (!strcmp(res->name, "txfreet"))
+ tx_free_thresh = res->value;
+ else if (!strcmp(res->name, "txrst"))
+ tx_rs_thresh = res->value;
+ else if (!strcmp(res->name, "rxfreet"))
+ rx_free_thresh = res->value;
+ else {
+ printf("Unknown parameter\n");
+ return;
+ }
+
+ init_port_config();
+
+ cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_config_threshold_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
+cmdline_parse_token_string_t cmd_config_threshold_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
+ "config");
+cmdline_parse_token_string_t cmd_config_threshold_all =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
+cmdline_parse_token_string_t cmd_config_threshold_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
+ "txfreet#txrst#rxfreet");
+cmdline_parse_token_num_t cmd_config_threshold_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, UINT16);
+
+cmdline_parse_inst_t cmd_config_threshold = {
+ .f = cmd_config_threshold_parsed,
+ .data = NULL,
+ .help_str = "port config all txfreet|txrst|rxfreet value",
+ .tokens = {
+ (void *)&cmd_config_threshold_port,
+ (void *)&cmd_config_threshold_keyword,
+ (void *)&cmd_config_threshold_all,
+ (void *)&cmd_config_threshold_name,
+ (void *)&cmd_config_threshold_value,
+ NULL,
+ },
+};
+
+/* *** stop *** */
+struct cmd_stop_result {
+ cmdline_fixed_string_t stop;
+};
+
+static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ stop_packet_forwarding();
+}
+
+cmdline_parse_token_string_t cmd_stop_stop =
+ TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
+
+cmdline_parse_inst_t cmd_stop = {
+ .f = cmd_stop_parsed,
+ .data = NULL,
+ .help_str = "stop - stop packet forwarding",
+ .tokens = {
+ (void *)&cmd_stop_stop,
+ NULL,
+ },
+};
+
+/* *** SET CORELIST and PORTLIST CONFIGURATION *** */
+
+static unsigned int
+parse_item_list(char* str, const char* item_name, unsigned int max_items,
+ unsigned int *parsed_items, int check_unique_values)
+{
+ unsigned int nb_item;
+ unsigned int value;
+ unsigned int i;
+ unsigned int j;
+ int value_ok;
+ char c;
+
+ /*
+ * First parse all items in the list and store their value.
+ */
+ value = 0;
+ nb_item = 0;
+ value_ok = 0;
+ for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
+ c = str[i];
+ if ((c >= '0') && (c <= '9')) {
+ value = (unsigned int) (value * 10 + (c - '0'));
+ value_ok = 1;
+ continue;
+ }
+ if (c != ',') {
+ printf("character %c is not a decimal digit\n", c);
+ return (0);
+ }
+ if (! value_ok) {
+ printf("No valid value before comma\n");
+ return (0);
+ }
+ if (nb_item < max_items) {
+ parsed_items[nb_item] = value;
+ value_ok = 0;
+ value = 0;
+ }
+ nb_item++;
+ }
+ if (nb_item >= max_items) {
+ printf("Number of %s = %u > %u (maximum items)\n",
+ item_name, nb_item + 1, max_items);
+ return (0);
+ }
+ parsed_items[nb_item++] = value;
+ if (! check_unique_values)
+ return (nb_item);
+
+ /*
+ * Then, check that all values in the list are differents.
+ * No optimization here...
+ */
+ for (i = 0; i < nb_item; i++) {
+ for (j = i + 1; j < nb_item; j++) {
+ if (parsed_items[j] == parsed_items[i]) {
+ printf("duplicated %s %u at index %u and %u\n",
+ item_name, parsed_items[i], i, j);
+ return (0);
+ }
+ }
+ }
+ return (nb_item);
+}
+
+struct cmd_set_list_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t list_name;
+ cmdline_fixed_string_t list_of_items;
+};
+
+static void cmd_set_list_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_list_result *res;
+ union {
+ unsigned int lcorelist[RTE_MAX_LCORE];
+ unsigned int portlist[RTE_MAX_ETHPORTS];
+ } parsed_items;
+ unsigned int nb_item;
+
+ res = parsed_result;
+ if (!strcmp(res->list_name, "corelist")) {
+ nb_item = parse_item_list(res->list_of_items, "core",
+ RTE_MAX_LCORE,
+ parsed_items.lcorelist, 1);
+ if (nb_item > 0)
+ set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
+ return;
+ }
+ if (!strcmp(res->list_name, "portlist")) {
+ nb_item = parse_item_list(res->list_of_items, "port",
+ RTE_MAX_ETHPORTS,
+ parsed_items.portlist, 1);
+ if (nb_item > 0)
+ set_fwd_ports_list(parsed_items.portlist, nb_item);
+ }
+}
+
+cmdline_parse_token_string_t cmd_set_list_keyword =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
+ "set");
+cmdline_parse_token_string_t cmd_set_list_name =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
+ "corelist#portlist");
+cmdline_parse_token_string_t cmd_set_list_of_items =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
+ NULL);
+
+cmdline_parse_inst_t cmd_set_fwd_list = {
+ .f = cmd_set_list_parsed,
+ .data = NULL,
+ .help_str = "set corelist|portlist x[,y]*",
+ .tokens = {
+ (void *)&cmd_set_list_keyword,
+ (void *)&cmd_set_list_name,
+ (void *)&cmd_set_list_of_items,
+ NULL,
+ },
+};
+
+/* *** SET COREMASK and PORTMASK CONFIGURATION *** */
+
+struct cmd_setmask_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t mask;
+ uint64_t hexavalue;
+};
+
+static void cmd_set_mask_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_setmask_result *res = parsed_result;
+
+ if (!strcmp(res->mask, "coremask"))
+ set_fwd_lcores_mask(res->hexavalue);
+ else if (!strcmp(res->mask, "portmask"))
+ set_fwd_ports_mask(res->hexavalue);
+}
+
+cmdline_parse_token_string_t cmd_setmask_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
+cmdline_parse_token_string_t cmd_setmask_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
+ "coremask#portmask");
+cmdline_parse_token_num_t cmd_setmask_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
+
+cmdline_parse_inst_t cmd_set_fwd_mask = {
+ .f = cmd_set_mask_parsed,
+ .data = NULL,
+ .help_str = "set coremask|portmask hexadecimal value",
+ .tokens = {
+ (void *)&cmd_setmask_set,
+ (void *)&cmd_setmask_mask,
+ (void *)&cmd_setmask_value,
+ NULL,
+ },
+};
+
+/*
+ * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
+ */
+struct cmd_set_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t what;
+ uint16_t value;
+};
+
+static void cmd_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_result *res = parsed_result;
+ if (!strcmp(res->what, "nbport"))
+ set_fwd_ports_number(res->value);
+ else if (!strcmp(res->what, "nbcore"))
+ set_fwd_lcores_number(res->value);
+ else if (!strcmp(res->what, "burst"))
+ set_nb_pkt_per_burst(res->value);
+ else if (!strcmp(res->what, "verbose"))
+ set_verbose_level(res->value);
+}
+
+cmdline_parse_token_string_t cmd_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
+cmdline_parse_token_string_t cmd_set_what =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
+ "nbport#nbcore#burst#verbose");
+cmdline_parse_token_num_t cmd_set_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
+
+cmdline_parse_inst_t cmd_set_numbers = {
+ .f = cmd_set_parsed,
+ .data = NULL,
+ .help_str = "set nbport|nbcore|burst|verbose value",
+ .tokens = {
+ (void *)&cmd_set_set,
+ (void *)&cmd_set_what,
+ (void *)&cmd_set_value,
+ NULL,
+ },
+};
+
+/* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
+
+struct cmd_set_txpkts_result {
+ cmdline_fixed_string_t cmd_keyword;
+ cmdline_fixed_string_t txpkts;