#include "ice_dcf_ethdev.h"
#include "ice_rxtx.h"
+#define DCF_NUM_MACADDR_MAX 64
+
+static int dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw,
+ struct rte_ether_addr *mc_addrs,
+ uint32_t mc_addrs_num, bool add);
+
static int
ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *udp_tunnel);
static int
ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev);
+struct rte_ice_dcf_xstats_name_off {
+ char name[RTE_ETH_XSTATS_NAME_SIZE];
+ unsigned int offset;
+};
+
+static const struct rte_ice_dcf_xstats_name_off rte_ice_dcf_stats_strings[] = {
+ {"rx_bytes", offsetof(struct ice_dcf_eth_stats, rx_bytes)},
+ {"rx_unicast_packets", offsetof(struct ice_dcf_eth_stats, rx_unicast)},
+ {"rx_multicast_packets", offsetof(struct ice_dcf_eth_stats, rx_multicast)},
+ {"rx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, rx_broadcast)},
+ {"rx_dropped_packets", offsetof(struct ice_dcf_eth_stats, rx_discards)},
+ {"rx_unknown_protocol_packets", offsetof(struct ice_dcf_eth_stats,
+ rx_unknown_protocol)},
+ {"tx_bytes", offsetof(struct ice_dcf_eth_stats, tx_bytes)},
+ {"tx_unicast_packets", offsetof(struct ice_dcf_eth_stats, tx_unicast)},
+ {"tx_multicast_packets", offsetof(struct ice_dcf_eth_stats, tx_multicast)},
+ {"tx_broadcast_packets", offsetof(struct ice_dcf_eth_stats, tx_broadcast)},
+ {"tx_dropped_packets", offsetof(struct ice_dcf_eth_stats, tx_discards)},
+ {"tx_error_packets", offsetof(struct ice_dcf_eth_stats, tx_errors)},
+};
+
+#define ICE_DCF_NB_XSTATS (sizeof(rte_ice_dcf_stats_strings) / \
+ sizeof(rte_ice_dcf_stats_strings[0]))
+
static uint16_t
ice_dcf_recv_pkts(__rte_unused void *rx_queue,
__rte_unused struct rte_mbuf **bufs,
return ret;
}
- ret = ice_dcf_add_del_all_mac_addr(hw, true);
+ ret = ice_dcf_add_del_all_mac_addr(hw, hw->eth_dev->data->mac_addrs,
+ true, VIRTCHNL_ETHER_ADDR_PRIMARY);
if (ret) {
PMD_DRV_LOG(ERR, "Failed to add mac addr");
return ret;
}
+ if (dcf_ad->mc_addrs_num) {
+ /* flush previous addresses */
+ ret = dcf_add_del_mc_addr_list(hw, dcf_ad->mc_addrs,
+ dcf_ad->mc_addrs_num, true);
+ if (ret)
+ return ret;
+ }
+
+
dev->data->dev_link.link_status = RTE_ETH_LINK_UP;
return 0;
rte_intr_efd_disable(intr_handle);
rte_intr_vec_list_free(intr_handle);
- ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw, false);
+ ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw,
+ dcf_ad->real_hw.eth_dev->data->mac_addrs,
+ false, VIRTCHNL_ETHER_ADDR_PRIMARY);
+
+ if (dcf_ad->mc_addrs_num)
+ /* flush previous addresses */
+ (void)dcf_add_del_mc_addr_list(&dcf_ad->real_hw,
+ dcf_ad->mc_addrs,
+ dcf_ad->mc_addrs_num, false);
+
dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
ad->pf.adapter_stopped = 1;
hw->tm_conf.committed = false;
struct ice_dcf_adapter *adapter = dev->data->dev_private;
struct ice_dcf_hw *hw = &adapter->real_hw;
- dev_info->max_mac_addrs = 1;
+ dev_info->max_mac_addrs = DCF_NUM_MACADDR_MAX;
dev_info->max_rx_queues = hw->vsi_res->num_queue_pairs;
dev_info->max_tx_queues = hw->vsi_res->num_queue_pairs;
dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN;
dev_info->reta_size = hw->vf_res->rss_lut_size;
dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL;
dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
+ dev_info->max_mtu = dev_info->max_rx_pktlen - ICE_ETH_OVERHEAD;
+ dev_info->min_mtu = RTE_ETHER_MIN_MTU;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
}
static int
-ice_dcf_dev_promiscuous_enable(__rte_unused struct rte_eth_dev *dev)
+dcf_config_promisc(struct ice_dcf_adapter *adapter,
+ bool enable_unicast,
+ bool enable_multicast)
{
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ struct virtchnl_promisc_info promisc;
+ struct dcf_virtchnl_cmd args;
+ int err;
+
+ promisc.flags = 0;
+ promisc.vsi_id = hw->vsi_res->vsi_id;
+
+ if (enable_unicast)
+ promisc.flags |= FLAG_VF_UNICAST_PROMISC;
+
+ if (enable_multicast)
+ promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
+ args.req_msg = (uint8_t *)&promisc;
+ args.req_msglen = sizeof(promisc);
+
+ err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (err) {
+ PMD_DRV_LOG(ERR,
+ "fail to execute command VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE");
+ return err;
+ }
+
+ adapter->promisc_unicast_enabled = enable_unicast;
+ adapter->promisc_multicast_enabled = enable_multicast;
return 0;
}
+static int
+ice_dcf_dev_promiscuous_enable(__rte_unused struct rte_eth_dev *dev)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+
+ if (adapter->promisc_unicast_enabled) {
+ PMD_DRV_LOG(INFO, "promiscuous has been enabled");
+ return 0;
+ }
+
+ return dcf_config_promisc(adapter, true,
+ adapter->promisc_multicast_enabled);
+}
+
static int
ice_dcf_dev_promiscuous_disable(__rte_unused struct rte_eth_dev *dev)
{
- return 0;
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+
+ if (!adapter->promisc_unicast_enabled) {
+ PMD_DRV_LOG(INFO, "promiscuous has been disabled");
+ return 0;
+ }
+
+ return dcf_config_promisc(adapter, false,
+ adapter->promisc_multicast_enabled);
}
static int
ice_dcf_dev_allmulticast_enable(__rte_unused struct rte_eth_dev *dev)
{
- return 0;
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+
+ if (adapter->promisc_multicast_enabled) {
+ PMD_DRV_LOG(INFO, "allmulticast has been enabled");
+ return 0;
+ }
+
+ return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled,
+ true);
}
static int
ice_dcf_dev_allmulticast_disable(__rte_unused struct rte_eth_dev *dev)
{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+
+ if (!adapter->promisc_multicast_enabled) {
+ PMD_DRV_LOG(INFO, "allmulticast has been disabled");
+ return 0;
+ }
+
+ return dcf_config_promisc(adapter, adapter->promisc_unicast_enabled,
+ false);
+}
+
+static int
+dcf_dev_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
+ __rte_unused uint32_t index,
+ __rte_unused uint32_t pool)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ int err;
+
+ if (rte_is_zero_ether_addr(addr)) {
+ PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
+ return -EINVAL;
+ }
+
+ err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, true,
+ VIRTCHNL_ETHER_ADDR_EXTRA);
+ if (err) {
+ PMD_DRV_LOG(ERR, "fail to add MAC address");
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+dcf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct rte_ether_addr *addr = &dev->data->mac_addrs[index];
+ int err;
+
+ err = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, addr, false,
+ VIRTCHNL_ETHER_ADDR_EXTRA);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to remove MAC address");
+}
+
+static int
+dcf_add_del_mc_addr_list(struct ice_dcf_hw *hw,
+ struct rte_ether_addr *mc_addrs,
+ uint32_t mc_addrs_num, bool add)
+{
+ struct virtchnl_ether_addr_list *list;
+ struct dcf_virtchnl_cmd args;
+ uint32_t i;
+ int len, err = 0;
+
+ len = sizeof(struct virtchnl_ether_addr_list);
+ len += sizeof(struct virtchnl_ether_addr) * mc_addrs_num;
+
+ list = rte_zmalloc(NULL, len, 0);
+ if (!list) {
+ PMD_DRV_LOG(ERR, "fail to allocate memory");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < mc_addrs_num; i++) {
+ memcpy(list->list[i].addr, mc_addrs[i].addr_bytes,
+ sizeof(list->list[i].addr));
+ list->list[i].type = VIRTCHNL_ETHER_ADDR_EXTRA;
+ }
+
+ list->vsi_id = hw->vsi_res->vsi_id;
+ list->num_elements = mc_addrs_num;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = add ? VIRTCHNL_OP_ADD_ETH_ADDR :
+ VIRTCHNL_OP_DEL_ETH_ADDR;
+ args.req_msg = (uint8_t *)list;
+ args.req_msglen = len;
+ err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_ETHER_ADDRESS" :
+ "OP_DEL_ETHER_ADDRESS");
+ rte_free(list);
+ return err;
+}
+
+static int
+dcf_set_mc_addr_list(struct rte_eth_dev *dev,
+ struct rte_ether_addr *mc_addrs,
+ uint32_t mc_addrs_num)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ uint32_t i;
+ int ret;
+
+
+ if (mc_addrs_num > DCF_NUM_MACADDR_MAX) {
+ PMD_DRV_LOG(ERR,
+ "can't add more than a limited number (%u) of addresses.",
+ (uint32_t)DCF_NUM_MACADDR_MAX);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < mc_addrs_num; i++) {
+ if (!rte_is_multicast_ether_addr(&mc_addrs[i])) {
+ const uint8_t *mac = mc_addrs[i].addr_bytes;
+
+ PMD_DRV_LOG(ERR,
+ "Invalid mac: %02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4],
+ mac[5]);
+ return -EINVAL;
+ }
+ }
+
+ if (adapter->mc_addrs_num) {
+ /* flush previous addresses */
+ ret = dcf_add_del_mc_addr_list(hw, adapter->mc_addrs,
+ adapter->mc_addrs_num, false);
+ if (ret)
+ return ret;
+ }
+ if (!mc_addrs_num) {
+ adapter->mc_addrs_num = 0;
+ return 0;
+ }
+
+ /* add new ones */
+ ret = dcf_add_del_mc_addr_list(hw, mc_addrs, mc_addrs_num, true);
+ if (ret) {
+ /* if adding mac address list fails, should add the
+ * previous addresses back.
+ */
+ if (adapter->mc_addrs_num)
+ (void)dcf_add_del_mc_addr_list(hw, adapter->mc_addrs,
+ adapter->mc_addrs_num,
+ true);
+ return ret;
+ }
+ adapter->mc_addrs_num = mc_addrs_num;
+ memcpy(adapter->mc_addrs,
+ mc_addrs, mc_addrs_num * sizeof(*mc_addrs));
+
+ return 0;
+}
+
+static int
+dcf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+ struct rte_ether_addr *mac_addr)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ struct rte_ether_addr *old_addr;
+ int ret;
+
+ old_addr = hw->eth_dev->data->mac_addrs;
+ if (rte_is_same_ether_addr(old_addr, mac_addr))
+ return 0;
+
+ ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, old_addr, false,
+ VIRTCHNL_ETHER_ADDR_PRIMARY);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Fail to delete old MAC:"
+ " %02X:%02X:%02X:%02X:%02X:%02X",
+ old_addr->addr_bytes[0],
+ old_addr->addr_bytes[1],
+ old_addr->addr_bytes[2],
+ old_addr->addr_bytes[3],
+ old_addr->addr_bytes[4],
+ old_addr->addr_bytes[5]);
+
+ ret = ice_dcf_add_del_all_mac_addr(&adapter->real_hw, mac_addr, true,
+ VIRTCHNL_ETHER_ADDR_PRIMARY);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Fail to add new MAC:"
+ " %02X:%02X:%02X:%02X:%02X:%02X",
+ mac_addr->addr_bytes[0],
+ mac_addr->addr_bytes[1],
+ mac_addr->addr_bytes[2],
+ mac_addr->addr_bytes[3],
+ mac_addr->addr_bytes[4],
+ mac_addr->addr_bytes[5]);
+
+ if (ret)
+ return -EIO;
+
+ rte_ether_addr_copy(mac_addr, hw->eth_dev->data->mac_addrs);
+ return 0;
+}
+
+static int
+dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
+{
+ struct virtchnl_vlan_supported_caps *supported_caps =
+ &hw->vlan_v2_caps.filtering.filtering_support;
+ struct virtchnl_vlan *vlan_setting;
+ struct virtchnl_vlan_filter_list_v2 vlan_filter;
+ struct dcf_virtchnl_cmd args;
+ uint32_t filtering_caps;
+ int err;
+
+ if (supported_caps->outer) {
+ filtering_caps = supported_caps->outer;
+ vlan_setting = &vlan_filter.filters[0].outer;
+ } else {
+ filtering_caps = supported_caps->inner;
+ vlan_setting = &vlan_filter.filters[0].inner;
+ }
+
+ if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100))
+ return -ENOTSUP;
+
+ memset(&vlan_filter, 0, sizeof(vlan_filter));
+ vlan_filter.vport_id = hw->vsi_res->vsi_id;
+ vlan_filter.num_elements = 1;
+ vlan_setting->tpid = RTE_ETHER_TYPE_VLAN;
+ vlan_setting->tci = vlanid;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
+ args.req_msg = (uint8_t *)&vlan_filter;
+ args.req_msglen = sizeof(vlan_filter);
+ err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_VLAN_V2" : "OP_DEL_VLAN_V2");
+
+ return err;
+}
+
+static int
+dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add)
+{
+ struct virtchnl_vlan_filter_list *vlan_list;
+ uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
+ sizeof(uint16_t)];
+ struct dcf_virtchnl_cmd args;
+ int err;
+
+ vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
+ vlan_list->vsi_id = hw->vsi_res->vsi_id;
+ vlan_list->num_elements = 1;
+ vlan_list->vlan_id[0] = vlanid;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
+ args.req_msg = cmd_buffer;
+ args.req_msglen = sizeof(cmd_buffer);
+ err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_VLAN" : "OP_DEL_VLAN");
+
+ return err;
+}
+
+static int
+dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
+{
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ int err;
+
+ if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+ err = dcf_add_del_vlan_v2(hw, vlan_id, on);
+ if (err)
+ return -EIO;
+ return 0;
+ }
+
+ if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+ return -ENOTSUP;
+
+ err = dcf_add_del_vlan(hw, vlan_id, on);
+ if (err)
+ return -EIO;
+ return 0;
+}
+
+static void
+dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable)
+{
+ struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ uint32_t i, j;
+ uint64_t ids;
+
+ for (i = 0; i < RTE_DIM(vfc->ids); i++) {
+ if (vfc->ids[i] == 0)
+ continue;
+
+ ids = vfc->ids[i];
+ for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
+ if (ids & 1)
+ dcf_add_del_vlan_v2(hw, 64 * i + j, enable);
+ }
+ }
+}
+
+static int
+dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable)
+{
+ struct virtchnl_vlan_supported_caps *stripping_caps =
+ &hw->vlan_v2_caps.offloads.stripping_support;
+ struct virtchnl_vlan_setting vlan_strip;
+ struct dcf_virtchnl_cmd args;
+ uint32_t *ethertype;
+ int ret;
+
+ if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+ (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE))
+ ethertype = &vlan_strip.outer_ethertype_setting;
+ else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) &&
+ (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE))
+ ethertype = &vlan_strip.inner_ethertype_setting;
+ else
+ return -ENOTSUP;
+
+ memset(&vlan_strip, 0, sizeof(vlan_strip));
+ vlan_strip.vport_id = hw->vsi_res->vsi_id;
+ *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 :
+ VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
+ args.req_msg = (uint8_t *)&vlan_strip;
+ args.req_msglen = sizeof(vlan_strip);
+ ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (ret)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" :
+ "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
+
+ return ret;
+}
+
+static int
+dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask)
+{
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ bool enable;
+ int err;
+
+ if (mask & RTE_ETH_VLAN_FILTER_MASK) {
+ enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
+
+ dcf_iterate_vlan_filters_v2(dev, enable);
+ }
+
+ if (mask & RTE_ETH_VLAN_STRIP_MASK) {
+ enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
+
+ err = dcf_config_vlan_strip_v2(hw, enable);
+ /* If not support, the stripping is already disabled by PF */
+ if (err == -ENOTSUP && !enable)
+ err = 0;
+ if (err)
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+dcf_enable_vlan_strip(struct ice_dcf_hw *hw)
+{
+ struct dcf_virtchnl_cmd args;
+ int ret;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
+ ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (ret)
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_ENABLE_VLAN_STRIPPING");
+
+ return ret;
+}
+
+static int
+dcf_disable_vlan_strip(struct ice_dcf_hw *hw)
+{
+ struct dcf_virtchnl_cmd args;
+ int ret;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
+ ret = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (ret)
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_DISABLE_VLAN_STRIPPING");
+
+ return ret;
+}
+
+static int
+dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+ struct ice_dcf_adapter *adapter = dev->data->dev_private;
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ int err;
+
+ if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
+ return dcf_dev_vlan_offload_set_v2(dev, mask);
+
+ if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+ return -ENOTSUP;
+
+ /* Vlan stripping setting */
+ if (mask & RTE_ETH_VLAN_STRIP_MASK) {
+ /* Enable or disable VLAN stripping */
+ if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
+ err = dcf_enable_vlan_strip(hw);
+ else
+ err = dcf_disable_vlan_strip(hw);
+
+ if (err)
+ return -EIO;
+ }
return 0;
}
return 0;
}
+static int ice_dcf_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit)
+{
+ unsigned int i;
+
+ if (xstats_names != NULL)
+ for (i = 0; i < ICE_DCF_NB_XSTATS; i++) {
+ snprintf(xstats_names[i].name,
+ sizeof(xstats_names[i].name),
+ "%s", rte_ice_dcf_stats_strings[i].name);
+ }
+ return ICE_DCF_NB_XSTATS;
+}
+
+static int ice_dcf_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats, unsigned int n)
+{
+ int ret;
+ unsigned int i;
+ struct ice_dcf_adapter *adapter =
+ ICE_DCF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct ice_dcf_hw *hw = &adapter->real_hw;
+ struct virtchnl_eth_stats *postats = &hw->eth_stats_offset;
+ struct virtchnl_eth_stats pnstats;
+
+ if (n < ICE_DCF_NB_XSTATS)
+ return ICE_DCF_NB_XSTATS;
+
+ ret = ice_dcf_query_stats(hw, &pnstats);
+ if (ret != 0)
+ return 0;
+
+ if (!xstats)
+ return 0;
+
+ ice_dcf_update_stats(postats, &pnstats);
+
+ /* loop over xstats array and values from pstats */
+ for (i = 0; i < ICE_DCF_NB_XSTATS; i++) {
+ xstats[i].id = i;
+ xstats[i].value = *(uint64_t *)(((char *)&pnstats) +
+ rte_ice_dcf_stats_strings[i].offset);
+ }
+
+ return ICE_DCF_NB_XSTATS;
+}
+
static void
ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)
{
.tx_queue_start = ice_dcf_tx_queue_start,
.rx_queue_stop = ice_dcf_rx_queue_stop,
.tx_queue_stop = ice_dcf_tx_queue_stop,
+ .rxq_info_get = ice_rxq_info_get,
+ .txq_info_get = ice_txq_info_get,
+ .get_monitor_addr = ice_get_monitor_addr,
.link_update = ice_dcf_link_update,
.stats_get = ice_dcf_stats_get,
.stats_reset = ice_dcf_stats_reset,
+ .xstats_get = ice_dcf_xstats_get,
+ .xstats_get_names = ice_dcf_xstats_get_names,
+ .xstats_reset = ice_dcf_stats_reset,
.promiscuous_enable = ice_dcf_dev_promiscuous_enable,
.promiscuous_disable = ice_dcf_dev_promiscuous_disable,
.allmulticast_enable = ice_dcf_dev_allmulticast_enable,
.allmulticast_disable = ice_dcf_dev_allmulticast_disable,
+ .mac_addr_add = dcf_dev_add_mac_addr,
+ .mac_addr_remove = dcf_dev_del_mac_addr,
+ .set_mc_addr_list = dcf_set_mc_addr_list,
+ .mac_addr_set = dcf_dev_set_default_mac_addr,
+ .vlan_filter_set = dcf_dev_vlan_filter_set,
+ .vlan_offload_set = dcf_dev_vlan_offload_set,
.flow_ops_get = ice_dcf_dev_flow_ops_get,
.udp_tunnel_port_add = ice_dcf_dev_udp_tunnel_port_add,
.udp_tunnel_port_del = ice_dcf_dev_udp_tunnel_port_del,
return -1;
}
+ dcf_config_promisc(adapter, false, false);
return 0;
}