[PATCH 2/3] ixgbe: move periodic link service work into separate function
Jeff Daly
jeffd at silicom-usa.com
Thu May 19 19:43:24 CEST 2022
The link update originally direct coded into the periodic service thread
and is made separate in preparation for additional SFP handling code.
Signed-off-by: Jeff Daly <jeffd at silicom-usa.com>
Inspired-by: Stephen Douthit <stephend at silicom-usa.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 99 ++++++++++++++++++++++----------
drivers/net/ixgbe/ixgbe_ethdev.h | 1 +
2 files changed, 71 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 81b15ad28212..f1694ef76b14 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4131,48 +4131,89 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
return ret_val;
}
-static void *
-ixgbe_dev_setup_link_thread_handler(void *param)
+static void
+ixgbe_link_service(struct rte_eth_dev *dev)
{
- struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
- u32 speed, start, ticks, service_ms;
+ bool link_up, autoneg = false, have_int = false;
+ u32 speed;
s32 err;
- bool link_up, autoneg = false;
- pthread_detach(pthread_self());
+ /* Test if we have a LSC interrupt for this platform, if not we need to
+ * manually check the link register since IXGBE_FLAG_NEED_LINK_CONFIG
+ * will never be set in the interrupt handler
+ */
+#ifndef RTE_EXEC_ENV_FREEBSD
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ if (rte_intr_allow_others(intr_handle)) {
+ /* check if LSC interrupt is enabled */
+ if (dev->data->dev_conf.intr_conf.lsc)
+ have_int = true;
+ }
+#endif /* #ifdef RTE_EXEC_ENV_FREEBSD */
- while (1) {
- service_ms = 100;
- if (intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG) {
- speed = hw->phy.autoneg_advertised;
+ /* Skip if we still need to setup an SFP, or if no link config requested
+ */
+ if ((intr->flags & IXGBE_FLAG_NEED_SFP_SETUP) ||
+ (!(intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG) && have_int))
+ return;
+
+ if (!have_int && !(intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG)) {
+ err = ixgbe_check_link(hw, &speed, &link_up, 0);
+ if (!err && !link_up) {
+ intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+ PMD_DRV_LOG(DEBUG, "Link down, no LSC, set NEED_LINK_CONFIG\n");
+ } else {
+ return;
+ }
+ }
+
+ speed = hw->phy.autoneg_advertised;
+ if (!speed)
+ ixgbe_get_link_capabilities(hw, &speed, &autoneg);
- if (!speed)
- ixgbe_get_link_capabilities(hw, &speed, &autoneg);
+ err = ixgbe_setup_link(hw, speed, true);
+ if (err) {
+ PMD_DRV_LOG(ERR, "ixgbe_setup_link failed %d\n", err);
+ return;
+ }
- err = ixgbe_setup_link(hw, speed, true);
+ intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+}
- if (err == IXGBE_SUCCESS)
- err = ixgbe_check_link(hw, &speed, &link_up, 0);
+static void *
+ixgbe_dev_setup_link_thread_handler(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ u32 speed, start, ticks, service_ms;
+ s32 err;
+ bool link_up = false;
- /* Run the service thread handler more frequently when link is
- * down to reduce link up latency (every 200ms vs 1s)
- *
- * Use a number of smaller sleeps to decrease exit latency when
- * ixgbe_dev_stop() wants this thread to join
- */
- if (err == IXGBE_SUCCESS && link_up) {
- service_ms = 2000;
- intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
- }
+ pthread_detach(pthread_self());
- if (!ixgbe_dev_link_update(dev, 0)) {
- ixgbe_dev_link_status_print(dev);
- rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
- }
+ while (1) {
+ ixgbe_link_service(dev);
+
+ if (!ixgbe_dev_link_update(dev, 0)) {
+ ixgbe_dev_link_status_print(dev);
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
+ /* Run the service thread handler more frequently when link is
+ * down to reduce link up latency (every 200ms vs 1s)
+ *
+ * Use a number of smaller sleeps to decrease exit latency when
+ * ixgbe_dev_stop() wants this thread to join
+ */
+
+ err = ixgbe_check_link(hw, &speed, &link_up, 0);
+ if (err == IXGBE_SUCCESS && link_up)
+ service_ms = 2000;
+ else
+ service_ms = 100;
/* Call msec_delay in a loop with several smaller sleeps to
* provide periodic thread cancellation points
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 69e0e82a5b1a..f61706c9eae6 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -29,6 +29,7 @@
#define IXGBE_FLAG_PHY_INTERRUPT (uint32_t)(1 << 2)
#define IXGBE_FLAG_MACSEC (uint32_t)(1 << 3)
#define IXGBE_FLAG_NEED_LINK_CONFIG (uint32_t)(1 << 4)
+#define IXGBE_FLAG_NEED_SFP_SETUP (uint32_t)(1 << 5)
/*
* Defines that were not part of ixgbe_type.h as they are not used by the
--
2.25.1
More information about the dev
mailing list