+ }
+ }
+
+ return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
+}
+
+static int
+ionic_dev_rss_reta_query(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_identity *ident = &adapter->ident;
+ int i, num;
+ uint16_t tbl_sz = rte_le_to_cpu_16(ident->lif.eth.rss_ind_tbl_sz);
+
+ IONIC_PRINT_CALL();
+
+ if (reta_size != tbl_sz) {
+ IONIC_PRINT(ERR, "The size of hash lookup table configured "
+ "(%d) does not match the number hardware can support "
+ "(%d)",
+ reta_size, tbl_sz);
+ return -EINVAL;
+ }
+
+ if (!lif->rss_ind_tbl) {
+ IONIC_PRINT(ERR, "RSS RETA has not been built yet");
+ return -EINVAL;
+ }
+
+ num = reta_size / RTE_RETA_GROUP_SIZE;
+
+ for (i = 0; i < num; i++) {
+ memcpy(reta_conf->reta,
+ &lif->rss_ind_tbl[i * RTE_RETA_GROUP_SIZE],
+ RTE_RETA_GROUP_SIZE);
+ reta_conf++;
+ }
+
+ return 0;
+}
+
+static int
+ionic_dev_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ uint64_t rss_hf = 0;
+
+ IONIC_PRINT_CALL();
+
+ if (!lif->rss_ind_tbl) {
+ IONIC_PRINT(NOTICE, "RSS not enabled");
+ return 0;
+ }
+
+ /* Get key value (if not null, rss_key is 40-byte) */
+ if (rss_conf->rss_key != NULL &&
+ rss_conf->rss_key_len >= IONIC_RSS_HASH_KEY_SIZE)
+ memcpy(rss_conf->rss_key, lif->rss_hash_key,
+ IONIC_RSS_HASH_KEY_SIZE);
+
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV4)
+ rss_hf |= ETH_RSS_IPV4;
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV4_TCP)
+ rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV4_UDP)
+ rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV6)
+ rss_hf |= ETH_RSS_IPV6;
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV6_TCP)
+ rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+ if (lif->rss_types & IONIC_RSS_TYPE_IPV6_UDP)
+ rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+
+ rss_conf->rss_hf = rss_hf;
+
+ return 0;
+}
+
+static int
+ionic_dev_rss_hash_update(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ uint32_t rss_types = 0;
+ uint8_t *key = NULL;
+
+ IONIC_PRINT_CALL();
+
+ if (rss_conf->rss_key)
+ key = rss_conf->rss_key;
+
+ if ((rss_conf->rss_hf & IONIC_ETH_RSS_OFFLOAD_ALL) == 0) {
+ /*
+ * Can't disable rss through hash flags,
+ * if it is enabled by default during init
+ */
+ if (lif->rss_ind_tbl)
+ return -EINVAL;
+ } else {
+ /* Can't enable rss if disabled by default during init */
+ if (!lif->rss_ind_tbl)
+ return -EINVAL;
+
+ if (rss_conf->rss_hf & ETH_RSS_IPV4)
+ rss_types |= IONIC_RSS_TYPE_IPV4;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+ rss_types |= IONIC_RSS_TYPE_IPV4_TCP;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+ rss_types |= IONIC_RSS_TYPE_IPV4_UDP;
+ if (rss_conf->rss_hf & ETH_RSS_IPV6)
+ rss_types |= IONIC_RSS_TYPE_IPV6;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+ rss_types |= IONIC_RSS_TYPE_IPV6_TCP;
+ if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+ rss_types |= IONIC_RSS_TYPE_IPV6_UDP;
+
+ ionic_lif_rss_config(lif, rss_types, key, NULL);
+ }
+
+ return 0;
+}
+
+static int
+ionic_dev_stats_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_stats *stats)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+
+ ionic_lif_get_stats(lif, stats);
+
+ return 0;
+}
+
+static int
+ionic_dev_stats_reset(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+
+ IONIC_PRINT_CALL();
+
+ ionic_lif_reset_stats(lif);
+
+ return 0;
+}
+
+static int
+ionic_dev_xstats_get_names(__rte_unused struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int size)
+{
+ unsigned int i;
+
+ if (xstats_names != NULL) {
+ for (i = 0; i < IONIC_NB_HW_STATS; i++) {
+ snprintf(xstats_names[i].name,
+ sizeof(xstats_names[i].name),
+ "%s", rte_ionic_xstats_strings[i].name);
+ }
+ }
+
+ return IONIC_NB_HW_STATS;
+}
+
+static int
+ionic_dev_xstats_get_names_by_id(struct rte_eth_dev *eth_dev,
+ struct rte_eth_xstat_name *xstats_names, const uint64_t *ids,
+ unsigned int limit)
+{
+ struct rte_eth_xstat_name xstats_names_copy[IONIC_NB_HW_STATS];
+ uint16_t i;
+
+ if (!ids) {
+ if (xstats_names != NULL) {
+ for (i = 0; i < IONIC_NB_HW_STATS; i++) {
+ snprintf(xstats_names[i].name,
+ sizeof(xstats_names[i].name),
+ "%s", rte_ionic_xstats_strings[i].name);