+ tx_conf->tx_rs_thresh, tx_conf->txq_flags);
+}
+
+void
+port_rss_reta_info(portid_t port_id,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t nb_entries)
+{
+ uint16_t i, idx, shift;
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries);
+ if (ret != 0) {
+ printf("Failed to get RSS RETA info, return code = %d\n", ret);
+ return;
+ }
+
+ for (i = 0; i < nb_entries; i++) {
+ idx = i / RTE_RETA_GROUP_SIZE;
+ shift = i % RTE_RETA_GROUP_SIZE;
+ if (!(reta_conf[idx].mask & (1ULL << shift)))
+ continue;
+ printf("RSS RETA configuration: hash index=%u, queue=%u\n",
+ i, reta_conf[idx].reta[shift]);
+ }
+}
+
+/*
+ * Displays the RSS hash functions of a port, and, optionaly, the RSS hash
+ * key of the port.
+ */
+void
+port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
+{
+ struct rss_type_info {
+ char str[32];
+ uint64_t rss_type;
+ };
+ static const struct rss_type_info rss_type_table[] = {
+ {"ipv4", ETH_RSS_IPV4},
+ {"ipv4-frag", ETH_RSS_FRAG_IPV4},
+ {"ipv4-tcp", ETH_RSS_NONFRAG_IPV4_TCP},
+ {"ipv4-udp", ETH_RSS_NONFRAG_IPV4_UDP},
+ {"ipv4-sctp", ETH_RSS_NONFRAG_IPV4_SCTP},
+ {"ipv4-other", ETH_RSS_NONFRAG_IPV4_OTHER},
+ {"ipv6", ETH_RSS_IPV6},
+ {"ipv6-frag", ETH_RSS_FRAG_IPV6},
+ {"ipv6-tcp", ETH_RSS_NONFRAG_IPV6_TCP},
+ {"ipv6-udp", ETH_RSS_NONFRAG_IPV6_UDP},
+ {"ipv6-sctp", ETH_RSS_NONFRAG_IPV6_SCTP},
+ {"ipv6-other", ETH_RSS_NONFRAG_IPV6_OTHER},
+ {"l2-payload", ETH_RSS_L2_PAYLOAD},
+ {"ipv6-ex", ETH_RSS_IPV6_EX},
+ {"ipv6-tcp-ex", ETH_RSS_IPV6_TCP_EX},
+ {"ipv6-udp-ex", ETH_RSS_IPV6_UDP_EX},
+ };
+
+ struct rte_eth_rss_conf rss_conf;
+ uint8_t rss_key[10 * 4];
+ uint64_t rss_hf;
+ uint8_t i;
+ int diag;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+ /* Get RSS hash key if asked to display it */
+ rss_conf.rss_key = (show_rss_key) ? rss_key : NULL;
+ diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+ if (diag != 0) {
+ switch (diag) {
+ case -ENODEV:
+ printf("port index %d invalid\n", port_id);
+ break;
+ case -ENOTSUP:
+ printf("operation not supported by device\n");
+ break;
+ default:
+ printf("operation failed - diag=%d\n", diag);
+ break;
+ }
+ return;
+ }
+ rss_hf = rss_conf.rss_hf;
+ if (rss_hf == 0) {
+ printf("RSS disabled\n");
+ return;
+ }
+ printf("RSS functions:\n ");
+ for (i = 0; i < RTE_DIM(rss_type_table); i++) {
+ if (rss_hf & rss_type_table[i].rss_type)
+ printf("%s ", rss_type_table[i].str);
+ }
+ printf("\n");
+ if (!show_rss_key)
+ return;
+ printf("RSS key:\n");
+ for (i = 0; i < sizeof(rss_key); i++)
+ printf("%02X", rss_key[i]);
+ printf("\n");
+}
+
+void
+port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key)
+{
+ struct rte_eth_rss_conf rss_conf;
+ int diag;
+
+ rss_conf.rss_key = NULL;
+ diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+ if (diag == 0) {
+ rss_conf.rss_key = hash_key;
+ diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf);
+ }
+ if (diag == 0)
+ return;
+
+ switch (diag) {
+ case -ENODEV:
+ printf("port index %d invalid\n", port_id);
+ break;
+ case -ENOTSUP:
+ printf("operation not supported by device\n");
+ break;
+ default:
+ printf("operation failed - diag=%d\n", diag);
+ break;
+ }