net/failsafe: support link status change event
authorGaetan Rivet <gaetan.rivet@6wind.com>
Tue, 18 Jul 2017 12:48:21 +0000 (14:48 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Jul 2017 13:25:43 +0000 (16:25 +0300)
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
doc/guides/nics/features/failsafe.ini
drivers/net/failsafe/failsafe.c
drivers/net/failsafe/failsafe_ether.c
drivers/net/failsafe/failsafe_ops.c
drivers/net/failsafe/failsafe_private.h

index 2e802aa..a42e344 100644 (file)
@@ -5,6 +5,7 @@
 ;
 [Features]
 Link status          = Y
+Link status event    = Y
 MTU update           = Y
 Jumbo frame          = Y
 Promiscuous mode     = Y
index 7628c21..6006bef 100644 (file)
@@ -238,6 +238,7 @@ fs_eth_dev_create(struct rte_vdev_device *vdev)
                mac->addr_bytes[0], mac->addr_bytes[1],
                mac->addr_bytes[2], mac->addr_bytes[3],
                mac->addr_bytes[4], mac->addr_bytes[5]);
+       dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
        return 0;
 free_args:
        failsafe_args_free(dev);
index 359b8c9..d205f61 100644 (file)
@@ -387,3 +387,21 @@ failsafe_eth_rmv_event_callback(uint8_t port_id __rte_unused,
        sdev->remove = 1;
        return 0;
 }
+
+int
+failsafe_eth_lsc_event_callback(uint8_t port_id __rte_unused,
+                               enum rte_eth_event_type event __rte_unused,
+                               void *cb_arg, void *out __rte_unused)
+{
+       struct rte_eth_dev *dev = cb_arg;
+       int ret;
+
+       ret = dev->dev_ops->link_update(dev, 0);
+       /* We must pass on the LSC event */
+       if (ret)
+               return _rte_eth_dev_callback_process(dev,
+                                                    RTE_ETH_EVENT_INTR_LSC,
+                                                    NULL, NULL);
+       else
+               return 0;
+}
index e8edf15..ff9ad15 100644 (file)
@@ -206,6 +206,8 @@ fs_dev_configure(struct rte_eth_dev *dev)
        }
        FOREACH_SUBDEV(sdev, i, dev) {
                int rmv_interrupt = 0;
+               int lsc_interrupt = 0;
+               int lsc_enabled;
 
                if (sdev->state != DEV_PROBED)
                        continue;
@@ -218,6 +220,17 @@ fs_dev_configure(struct rte_eth_dev *dev)
                } else {
                        DEBUG("sub_device %d does not support RMV event", i);
                }
+               lsc_enabled = dev->data->dev_conf.intr_conf.lsc;
+               lsc_interrupt = lsc_enabled &&
+                               (ETH(sdev)->data->dev_flags &
+                                RTE_ETH_DEV_INTR_LSC);
+               if (lsc_interrupt) {
+                       DEBUG("Enabling LSC interrupts for sub_device %d", i);
+                       dev->data->dev_conf.intr_conf.lsc = 1;
+               } else if (lsc_enabled && !lsc_interrupt) {
+                       DEBUG("Disabling LSC interrupts for sub_device %d", i);
+                       dev->data->dev_conf.intr_conf.lsc = 0;
+               }
                DEBUG("Configuring sub-device %d", i);
                sdev->remove = 0;
                ret = rte_eth_dev_configure(PORT_ID(sdev),
@@ -238,6 +251,16 @@ fs_dev_configure(struct rte_eth_dev *dev)
                                     SUB_ID(sdev));
                }
                dev->data->dev_conf.intr_conf.rmv = 0;
+               if (lsc_interrupt) {
+                       ret = rte_eth_dev_callback_register(PORT_ID(sdev),
+                                               RTE_ETH_EVENT_INTR_LSC,
+                                               failsafe_eth_lsc_event_callback,
+                                               dev);
+                       if (ret)
+                               WARN("Failed to register LSC callback for sub_device %d",
+                                    SUB_ID(sdev));
+               }
+               dev->data->dev_conf.intr_conf.lsc = lsc_enabled;
                sdev->state = DEV_ACTIVE;
        }
        if (PRIV(dev)->state < DEV_ACTIVE)
index 80bbc61..2c52d2b 100644 (file)
@@ -179,6 +179,9 @@ void failsafe_dev_remove(struct rte_eth_dev *dev);
 int failsafe_eth_rmv_event_callback(uint8_t port_id,
                                    enum rte_eth_event_type type,
                                    void *arg, void *out);
+int failsafe_eth_lsc_event_callback(uint8_t port_id,
+                                   enum rte_eth_event_type event,
+                                   void *cb_arg, void *out);
 
 /* GLOBALS */