net/hns3: support flow director
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index 074b3e8..922371c 100644 (file)
@@ -71,8 +71,6 @@
 #define TAP_IOV_DEFAULT_MAX 1024
 
 static int tap_devices_count;
-static struct rte_vdev_driver pmd_tap_drv;
-static struct rte_vdev_driver pmd_tun_drv;
 
 static const char *valid_arguments[] = {
        ETH_TAP_IFACE_ARG,
@@ -917,7 +915,7 @@ tap_dev_speed_capa(void)
        return capa;
 }
 
-static void
+static int
 tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
        struct pmd_internals *internals = dev->data->dev_private;
@@ -941,6 +939,8 @@ tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
         * functions together and not in partial combinations
         */
        dev_info->flow_type_rss_offloads = ~TAP_RSS_HF_MASK;
+
+       return 0;
 }
 
 static int
@@ -970,10 +970,9 @@ tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats)
 
        for (i = 0; i < imax; i++) {
                tap_stats->q_opackets[i] = pmd->txq[i].stats.opackets;
-               tap_stats->q_errors[i] = pmd->txq[i].stats.errs;
                tap_stats->q_obytes[i] = pmd->txq[i].stats.obytes;
                tx_total += tap_stats->q_opackets[i];
-               tx_err_total += tap_stats->q_errors[i];
+               tx_err_total += pmd->txq[i].stats.errs;
                tx_bytes_total += tap_stats->q_obytes[i];
        }
 
@@ -987,7 +986,7 @@ tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats)
        return 0;
 }
 
-static void
+static int
 tap_stats_reset(struct rte_eth_dev *dev)
 {
        int i;
@@ -1003,6 +1002,8 @@ tap_stats_reset(struct rte_eth_dev *dev)
                pmd->txq[i].stats.errs = 0;
                pmd->txq[i].stats.obytes = 0;
        }
+
+       return 0;
 }
 
 static void
@@ -1101,52 +1102,116 @@ tap_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
        return 0;
 }
 
-static void
+static int
 tap_promisc_enable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *pmd = dev->data->dev_private;
        struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
+       int ret;
+
+       ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+       if (ret != 0)
+               return ret;
 
-       dev->data->promiscuous = 1;
-       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
-       if (pmd->remote_if_index && !pmd->flow_isolate)
-               tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
+       if (pmd->remote_if_index && !pmd->flow_isolate) {
+               dev->data->promiscuous = 1;
+               ret = tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
+               if (ret != 0) {
+                       /* Rollback promisc flag */
+                       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+                       /*
+                        * rte_eth_dev_promiscuous_enable() rollback
+                        * dev->data->promiscuous in the case of failure.
+                        */
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
-static void
+static int
 tap_promisc_disable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *pmd = dev->data->dev_private;
        struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
+       int ret;
 
-       dev->data->promiscuous = 0;
-       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
-       if (pmd->remote_if_index && !pmd->flow_isolate)
-               tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
+       ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+       if (ret != 0)
+               return ret;
+
+       if (pmd->remote_if_index && !pmd->flow_isolate) {
+               dev->data->promiscuous = 0;
+               ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
+               if (ret != 0) {
+                       /* Rollback promisc flag */
+                       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+                       /*
+                        * rte_eth_dev_promiscuous_disable() rollback
+                        * dev->data->promiscuous in the case of failure.
+                        */
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
-static void
+static int
 tap_allmulti_enable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *pmd = dev->data->dev_private;
        struct ifreq ifr = { .ifr_flags = IFF_ALLMULTI };
+       int ret;
+
+       ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+       if (ret != 0)
+               return ret;
+
+       if (pmd->remote_if_index && !pmd->flow_isolate) {
+               dev->data->all_multicast = 1;
+               ret = tap_flow_implicit_create(pmd, TAP_REMOTE_ALLMULTI);
+               if (ret != 0) {
+                       /* Rollback allmulti flag */
+                       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+                       /*
+                        * rte_eth_dev_allmulticast_enable() rollback
+                        * dev->data->all_multicast in the case of failure.
+                        */
+                       return ret;
+               }
+       }
 
-       dev->data->all_multicast = 1;
-       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
-       if (pmd->remote_if_index && !pmd->flow_isolate)
-               tap_flow_implicit_create(pmd, TAP_REMOTE_ALLMULTI);
+       return 0;
 }
 
-static void
+static int
 tap_allmulti_disable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *pmd = dev->data->dev_private;
        struct ifreq ifr = { .ifr_flags = IFF_ALLMULTI };
+       int ret;
 
-       dev->data->all_multicast = 0;
-       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
-       if (pmd->remote_if_index && !pmd->flow_isolate)
-               tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
+       ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+       if (ret != 0)
+               return ret;
+
+       if (pmd->remote_if_index && !pmd->flow_isolate) {
+               dev->data->all_multicast = 0;
+               ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
+               if (ret != 0) {
+                       /* Rollback allmulti flag */
+                       tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+                       /*
+                        * rte_eth_dev_allmulticast_disable() rollback
+                        * dev->data->all_multicast in the case of failure.
+                        */
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
 static int
@@ -2287,7 +2352,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
        /* Register IPC feed callback */
        if (!tap_devices_count) {
                ret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues);
-               if (ret < 0) {
+               if (ret < 0 && rte_errno != ENOTSUP) {
                        TAP_LOG(ERR, "tap: Failed to register IPC callback: %s",
                                strerror(rte_errno));
                        goto leave;