ethdev: add return value to stats get dev op
[dpdk.git] / drivers / net / failsafe / failsafe_ops.c
index e8edf15..d360965 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)
@@ -559,13 +582,25 @@ fs_link_update(struct rte_eth_dev *dev,
        return -1;
 }
 
-static void
+static int
 fs_stats_get(struct rte_eth_dev *dev,
             struct rte_eth_stats *stats)
 {
-       if (TX_SUBDEV(dev) == NULL)
-               return;
-       rte_eth_stats_get(PORT_ID(TX_SUBDEV(dev)), stats);
+       struct sub_device *sdev;
+       uint8_t i;
+       int ret;
+
+       rte_memcpy(stats, &PRIV(dev)->stats_accumulator, sizeof(*stats));
+       FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+               ret = rte_eth_stats_get(PORT_ID(sdev), &sdev->stats_snapshot);
+               if (ret) {
+                       ERROR("Operation rte_eth_stats_get failed for sub_device %d with error %d",
+                                 i, ret);
+                       return ret;
+               }
+               failsafe_stats_increment(stats, &sdev->stats_snapshot);
+       }
+       return 0;
 }
 
 static void
@@ -574,8 +609,11 @@ fs_stats_reset(struct rte_eth_dev *dev)
        struct sub_device *sdev;
        uint8_t i;
 
-       FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
+       FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
                rte_eth_stats_reset(PORT_ID(sdev));
+               memset(&sdev->stats_snapshot, 0, sizeof(struct rte_eth_stats));
+       }
+       memset(&PRIV(dev)->stats_accumulator, 0, sizeof(struct rte_eth_stats));
 }
 
 /**