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);
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;
+}
}
FOREACH_SUBDEV(sdev, i, dev) {
int rmv_interrupt = 0;
+ int lsc_interrupt = 0;
+ int lsc_enabled;
if (sdev->state != DEV_PROBED)
continue;
} 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),
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)
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 */