net/e1000: fix max Rx packet size
[dpdk.git] / drivers / net / ice / ice_dcf_ethdev.c
index d46734a..b937cbb 100644 (file)
@@ -5,7 +5,6 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <sys/types.h>
-#include <sys/ioctl.h>
 #include <unistd.h>
 
 #include <rte_interrupts.h>
@@ -14,7 +13,7 @@
 #include <rte_atomic.h>
 #include <rte_eal.h>
 #include <rte_ether.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_pci.h>
 #include <rte_kvargs.h>
 #include <rte_malloc.h>
 #include <rte_memzone.h>
 #include "ice_dcf_ethdev.h"
 #include "ice_rxtx.h"
 
+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_udp_tunnel_port_del(struct rte_eth_dev *dev,
+                               struct rte_eth_udp_tunnel *udp_tunnel);
+
 static uint16_t
 ice_dcf_recv_pkts(__rte_unused void *rx_queue,
                  __rte_unused struct rte_mbuf **bufs,
@@ -601,6 +607,9 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev)
                return 0;
        }
 
+       /* Stop the VF representors for this device */
+       ice_dcf_vf_repr_stop_all(dcf_ad);
+
        ice_dcf_stop_queues(dev);
 
        rte_intr_efd_disable(intr_handle);
@@ -733,31 +742,14 @@ ice_dcf_dev_allmulticast_disable(__rte_unused struct rte_eth_dev *dev)
 }
 
 static int
-ice_dcf_dev_filter_ctrl(struct rte_eth_dev *dev,
-                       enum rte_filter_type filter_type,
-                       enum rte_filter_op filter_op,
-                       void *arg)
+ice_dcf_dev_flow_ops_get(struct rte_eth_dev *dev,
+                        const struct rte_flow_ops **ops)
 {
-       int ret = 0;
-
        if (!dev)
                return -EINVAL;
 
-       switch (filter_type) {
-       case RTE_ETH_FILTER_GENERIC:
-               if (filter_op != RTE_ETH_FILTER_GET)
-                       return -EINVAL;
-               *(const void **)arg = &ice_flow_ops;
-               break;
-
-       default:
-               PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
-                           filter_type);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
+       *ops = &ice_flow_ops;
+       return 0;
 }
 
 #define ICE_DCF_32_BIT_WIDTH (CHAR_BIT * 4)
@@ -849,6 +841,30 @@ ice_dcf_stats_reset(struct rte_eth_dev *dev)
        return 0;
 }
 
+static void
+ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+       if (dcf_adapter->repr_infos) {
+               rte_free(dcf_adapter->repr_infos);
+               dcf_adapter->repr_infos = NULL;
+       }
+}
+
+static int
+ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+       dcf_adapter->repr_infos =
+                       rte_calloc("ice_dcf_rep_info",
+                                  dcf_adapter->real_hw.num_vfs,
+                                  sizeof(dcf_adapter->repr_infos[0]), 0);
+       if (!dcf_adapter->repr_infos) {
+               PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static int
 ice_dcf_dev_close(struct rte_eth_dev *dev)
 {
@@ -857,6 +873,7 @@ ice_dcf_dev_close(struct rte_eth_dev *dev)
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
+       ice_dcf_free_repr_info(adapter);
        ice_dcf_uninit_parent_adapter(dev);
        ice_dcf_uninit_hw(dev, &adapter->real_hw);
 
@@ -870,6 +887,64 @@ ice_dcf_link_update(__rte_unused struct rte_eth_dev *dev,
        return 0;
 }
 
+/* Add UDP tunneling port */
+static int
+ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
+                               struct rte_eth_udp_tunnel *udp_tunnel)
+{
+       struct ice_dcf_adapter *adapter = dev->data->dev_private;
+       struct ice_adapter *parent_adapter = &adapter->parent;
+       struct ice_hw *parent_hw = &parent_adapter->hw;
+       int ret = 0;
+
+       if (!udp_tunnel)
+               return -EINVAL;
+
+       switch (udp_tunnel->prot_type) {
+       case RTE_TUNNEL_TYPE_VXLAN:
+               ret = ice_create_tunnel(parent_hw, TNL_VXLAN,
+                                       udp_tunnel->udp_port);
+               break;
+       case RTE_TUNNEL_TYPE_ECPRI:
+               ret = ice_create_tunnel(parent_hw, TNL_ECPRI,
+                                       udp_tunnel->udp_port);
+               break;
+       default:
+               PMD_DRV_LOG(ERR, "Invalid tunnel type");
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+/* Delete UDP tunneling port */
+static int
+ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
+                               struct rte_eth_udp_tunnel *udp_tunnel)
+{
+       struct ice_dcf_adapter *adapter = dev->data->dev_private;
+       struct ice_adapter *parent_adapter = &adapter->parent;
+       struct ice_hw *parent_hw = &parent_adapter->hw;
+       int ret = 0;
+
+       if (!udp_tunnel)
+               return -EINVAL;
+
+       switch (udp_tunnel->prot_type) {
+       case RTE_TUNNEL_TYPE_VXLAN:
+       case RTE_TUNNEL_TYPE_ECPRI:
+               ret = ice_destroy_tunnel(parent_hw, udp_tunnel->udp_port, 0);
+               break;
+       default:
+               PMD_DRV_LOG(ERR, "Invalid tunnel type");
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
 static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
        .dev_start               = ice_dcf_dev_start,
        .dev_stop                = ice_dcf_dev_stop,
@@ -891,7 +966,9 @@ static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
        .promiscuous_disable     = ice_dcf_dev_promiscuous_disable,
        .allmulticast_enable     = ice_dcf_dev_allmulticast_enable,
        .allmulticast_disable    = ice_dcf_dev_allmulticast_disable,
-       .filter_ctrl             = ice_dcf_dev_filter_ctrl,
+       .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,
 };
 
 static int
@@ -994,27 +1071,34 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
                                            ice_dcf_dev_init);
        if (ret || !eth_da.nb_representor_ports)
                return ret;
+       if (eth_da.type != RTE_ETH_REPRESENTOR_VF)
+               return -ENOTSUP;
 
        dcf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);
        if (dcf_ethdev == NULL)
                return -ENODEV;
 
        dcf_adapter = dcf_ethdev->data->dev_private;
+       ret = ice_dcf_init_repr_info(dcf_adapter);
+       if (ret)
+               return ret;
 
        if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs ||
            eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) {
                PMD_DRV_LOG(ERR, "the number of port representors is too large: %u",
                            eth_da.nb_representor_ports);
+               ice_dcf_free_repr_info(dcf_adapter);
                return -EINVAL;
        }
 
        dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID;
 
-       repr_param.adapter = dcf_adapter;
+       repr_param.dcf_eth_dev = dcf_ethdev;
        repr_param.switch_domain_id = 0;
 
        for (i = 0; i < eth_da.nb_representor_ports; i++) {
                uint16_t vf_id = eth_da.representor_ports[i];
+               struct rte_eth_dev *vf_rep_eth_dev;
 
                if (vf_id >= dcf_adapter->real_hw.num_vfs) {
                        PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)",
@@ -1041,6 +1125,18 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
                                    repr_name);
                        break;
                }
+
+               vf_rep_eth_dev = rte_eth_dev_allocated(repr_name);
+               if (!vf_rep_eth_dev) {
+                       PMD_DRV_LOG(ERR,
+                                   "Failed to find the ethdev for DCF VF representor: %s",
+                                   repr_name);
+                       ret = -ENODEV;
+                       break;
+               }
+
+               dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev;
+               dcf_adapter->num_reprs++;
        }
 
        return ret;