ethdev: add access to EEPROM
[dpdk.git] / drivers / net / failsafe / failsafe.c
index 2665a39..dc9b0d0 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright 2017 6WIND S.A.
- * Copyright 2017 Mellanox.
+ * Copyright 2017 Mellanox Technologies, Ltd
  */
 
 #include <rte_alarm.h>
@@ -85,16 +85,14 @@ failsafe_hotplug_alarm_cancel(struct rte_eth_dev *dev)
 {
        int ret = 0;
 
-       if (PRIV(dev)->pending_alarm) {
-               rte_errno = 0;
-               rte_eal_alarm_cancel(fs_hotplug_alarm, dev);
-               if (rte_errno) {
-                       ERROR("rte_eal_alarm_cancel failed (errno: %s)",
-                             strerror(rte_errno));
-                       ret = -rte_errno;
-               } else {
-                       PRIV(dev)->pending_alarm = 0;
-               }
+       rte_errno = 0;
+       rte_eal_alarm_cancel(fs_hotplug_alarm, dev);
+       if (rte_errno) {
+               ERROR("rte_eal_alarm_cancel failed (errno: %s)",
+                     strerror(rte_errno));
+               ret = -rte_errno;
+       } else {
+               PRIV(dev)->pending_alarm = 0;
        }
        return ret;
 }
@@ -115,16 +113,45 @@ fs_hotplug_alarm(void *arg)
                        break;
        /* if we have non-probed device */
        if (i != PRIV(dev)->subs_tail) {
+               if (fs_lock(dev, 1) != 0)
+                       goto reinstall;
                ret = failsafe_eth_dev_state_sync(dev);
+               fs_unlock(dev, 1);
                if (ret)
                        ERROR("Unable to synchronize sub_device state");
        }
        failsafe_dev_remove(dev);
+reinstall:
        ret = failsafe_hotplug_alarm_install(dev);
        if (ret)
                ERROR("Unable to set up next alarm");
 }
 
+static int
+fs_mutex_init(struct fs_priv *priv)
+{
+       int ret;
+       pthread_mutexattr_t attr;
+
+       ret = pthread_mutexattr_init(&attr);
+       if (ret) {
+               ERROR("Cannot initiate mutex attributes - %s", strerror(ret));
+               return ret;
+       }
+       /* Allow mutex relocks for the thread holding the mutex. */
+       ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+       if (ret) {
+               ERROR("Cannot set mutex type - %s", strerror(ret));
+               return ret;
+       }
+       ret = pthread_mutex_init(&priv->hotplug_mutex, &attr);
+       if (ret) {
+               ERROR("Cannot initiate mutex - %s", strerror(ret));
+               return ret;
+       }
+       return 0;
+}
+
 static int
 fs_eth_dev_create(struct rte_vdev_device *vdev)
 {
@@ -176,6 +203,9 @@ fs_eth_dev_create(struct rte_vdev_device *vdev)
        snprintf(priv->my_owner.name, sizeof(priv->my_owner.name),
                 FAILSAFE_OWNER_NAME);
        ret = failsafe_eal_init(dev);
+       if (ret)
+               goto free_args;
+       ret = fs_mutex_init(priv);
        if (ret)
                goto free_args;
        ret = failsafe_hotplug_alarm_install(dev);
@@ -252,6 +282,9 @@ fs_rte_eth_free(const char *name)
                ERROR("Error while uninitializing sub-EAL");
        failsafe_args_free(dev);
        fs_sub_device_free(dev);
+       ret = pthread_mutex_destroy(&PRIV(dev)->hotplug_mutex);
+       if (ret)
+               ERROR("Error while destroying hotplug mutex");
        rte_free(PRIV(dev));
        rte_eth_dev_release_port(dev);
        return ret;
@@ -261,10 +294,24 @@ static int
 rte_pmd_failsafe_probe(struct rte_vdev_device *vdev)
 {
        const char *name;
+       struct rte_eth_dev *eth_dev;
 
        name = rte_vdev_device_name(vdev);
        INFO("Initializing " FAILSAFE_DRIVER_NAME " for %s",
                        name);
+
+       if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
+           strlen(rte_vdev_device_args(vdev)) == 0) {
+               eth_dev = rte_eth_dev_attach_secondary(name);
+               if (!eth_dev) {
+                       RTE_LOG(ERR, PMD, "Failed to probe %s\n", name);
+                       return -1;
+               }
+               /* TODO: request info from primary to set up Rx and Tx */
+               eth_dev->dev_ops = &failsafe_ops;
+               return 0;
+       }
+
        return fs_eth_dev_create(vdev);
 }