+ *(const void **)arg = &iavf_tm_ops;
+
+ return 0;
+}
+
+static int
+iavf_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct rte_ether_addr *mc_addrs,
+ uint32_t mc_addrs_num)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ int err, ret;
+
+ if (mc_addrs_num > IAVF_NUM_MACADDR_MAX) {
+ PMD_DRV_LOG(ERR,
+ "can't add more than a limited number (%u) of addresses.",
+ (uint32_t)IAVF_NUM_MACADDR_MAX);
+ return -EINVAL;
+ }
+
+ /* flush previous addresses */
+ err = iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+ false);
+ if (err)
+ return err;
+
+ /* add new ones */
+ err = iavf_add_del_mc_addr_list(adapter, mc_addrs, mc_addrs_num, true);
+
+ if (err) {
+ /* if adding mac address list fails, should add the previous
+ * addresses back.
+ */
+ ret = iavf_add_del_mc_addr_list(adapter, vf->mc_addrs,
+ vf->mc_addrs_num, true);
+ if (ret)
+ return ret;
+ } else {
+ vf->mc_addrs_num = mc_addrs_num;
+ memcpy(vf->mc_addrs,
+ mc_addrs, mc_addrs_num * sizeof(*mc_addrs));
+ }
+
+ return err;
+}
+
+static void
+iavf_config_rss_hf(struct iavf_adapter *adapter, uint64_t rss_hf)
+{
+ static const uint64_t map_hena_rss[] = {
+ /* IPv4 */
+ [IAVF_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
+ ETH_RSS_NONFRAG_IPV4_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
+ ETH_RSS_NONFRAG_IPV4_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV4_UDP] =
+ ETH_RSS_NONFRAG_IPV4_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
+ ETH_RSS_NONFRAG_IPV4_TCP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV4_TCP] =
+ ETH_RSS_NONFRAG_IPV4_TCP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+ ETH_RSS_NONFRAG_IPV4_SCTP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+ ETH_RSS_NONFRAG_IPV4_OTHER,
+ [IAVF_FILTER_PCTYPE_FRAG_IPV4] = ETH_RSS_FRAG_IPV4,
+
+ /* IPv6 */
+ [IAVF_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
+ ETH_RSS_NONFRAG_IPV6_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
+ ETH_RSS_NONFRAG_IPV6_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV6_UDP] =
+ ETH_RSS_NONFRAG_IPV6_UDP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
+ ETH_RSS_NONFRAG_IPV6_TCP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV6_TCP] =
+ ETH_RSS_NONFRAG_IPV6_TCP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+ ETH_RSS_NONFRAG_IPV6_SCTP,
+ [IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+ ETH_RSS_NONFRAG_IPV6_OTHER,
+ [IAVF_FILTER_PCTYPE_FRAG_IPV6] = ETH_RSS_FRAG_IPV6,
+
+ /* L2 Payload */
+ [IAVF_FILTER_PCTYPE_L2_PAYLOAD] = ETH_RSS_L2_PAYLOAD
+ };
+
+ const uint64_t ipv4_rss = ETH_RSS_NONFRAG_IPV4_UDP |
+ ETH_RSS_NONFRAG_IPV4_TCP |
+ ETH_RSS_NONFRAG_IPV4_SCTP |
+ ETH_RSS_NONFRAG_IPV4_OTHER |
+ ETH_RSS_FRAG_IPV4;
+
+ const uint64_t ipv6_rss = ETH_RSS_NONFRAG_IPV6_UDP |
+ ETH_RSS_NONFRAG_IPV6_TCP |
+ ETH_RSS_NONFRAG_IPV6_SCTP |
+ ETH_RSS_NONFRAG_IPV6_OTHER |
+ ETH_RSS_FRAG_IPV6;
+
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ uint64_t caps = 0, hena = 0, valid_rss_hf = 0;
+ uint32_t i;
+ int ret;
+
+ ret = iavf_get_hena_caps(adapter, &caps);
+ if (ret) {
+ /**
+ * RSS offload type configuration is not a necessary feature
+ * for VF, so here just print a warning and return.
+ */
+ PMD_DRV_LOG(WARNING,
+ "fail to get RSS offload type caps, ret: %d", ret);
+ return;
+ }
+
+ /**
+ * ETH_RSS_IPV4 and ETH_RSS_IPV6 can be considered as 2
+ * generalizations of all other IPv4 and IPv6 RSS types.