From 35ff31985618d7445e6df37bbe4b3554aa4abb71 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 13:13:54 +0100 Subject: [PATCH] Fix igb link detection with xenomai --- devices/igb/igb-4.4-ethercat.h | 2 ++ devices/igb/igb-5.10-ethercat.h | 2 ++ devices/igb/igb-5.14-ethercat.h | 2 ++ devices/igb/igb-5.15-ethercat.h | 2 ++ devices/igb/igb-6.1-ethercat.h | 2 ++ devices/igb/igb_main-4.4-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.10-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.14-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.15-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-6.1-ethercat.c | 24 +++++++++++++++++++----- 10 files changed, 105 insertions(+), 25 deletions(-) diff --git a/devices/igb/igb-4.4-ethercat.h b/devices/igb/igb-4.4-ethercat.h index 05f41ddd..846e2c81 100644 --- a/devices/igb/igb-4.4-ethercat.h +++ b/devices/igb/igb-4.4-ethercat.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -474,6 +475,7 @@ struct igb_adapter { /* EtherCAT device variables */ ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; #define IGB_FLAG_HAS_MSI (1 << 0) diff --git a/devices/igb/igb-5.10-ethercat.h b/devices/igb/igb-5.10-ethercat.h index 3fbfcad0..6bfdc364 100644 --- a/devices/igb/igb-5.10-ethercat.h +++ b/devices/igb/igb-5.10-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -671,6 +672,7 @@ struct igb_adapter { /* EtherCAT device variables */ ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; /* flags controlling PTP/1588 function */ diff --git a/devices/igb/igb-5.14-ethercat.h b/devices/igb/igb-5.14-ethercat.h index 8c634215..59392816 100644 --- a/devices/igb/igb-5.14-ethercat.h +++ b/devices/igb/igb-5.14-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -671,6 +672,7 @@ struct igb_adapter { /* EtherCAT device variables */ ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; /* flags controlling PTP/1588 function */ diff --git a/devices/igb/igb-5.15-ethercat.h b/devices/igb/igb-5.15-ethercat.h index 2e82cc6f..02c798fe 100644 --- a/devices/igb/igb-5.15-ethercat.h +++ b/devices/igb/igb-5.15-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -671,6 +672,7 @@ struct igb_adapter { /* EtherCAT device variables */ ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; /* flags controlling PTP/1588 function */ diff --git a/devices/igb/igb-6.1-ethercat.h b/devices/igb/igb-6.1-ethercat.h index 78b9125a..dbdf917d 100644 --- a/devices/igb/igb-6.1-ethercat.h +++ b/devices/igb/igb-6.1-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -673,6 +674,7 @@ struct igb_adapter { /* EtherCAT device variables */ ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; /* flags controlling PTP/1588 function */ diff --git a/devices/igb/igb_main-4.4-ethercat.c b/devices/igb/igb_main-4.4-ethercat.c index 22c22b6f..0d89fde9 100644 --- a/devices/igb/igb_main-4.4-ethercat.c +++ b/devices/igb/igb_main-4.4-ethercat.c @@ -2126,6 +2126,14 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_features_check = passthru_features_check, }; +static void ec_kick_watchdog(struct irq_work *work) +{ + struct igb_adapter *adapter = + container_of(work, struct igb_adapter, ec_watchdog_kicker); + + schedule_work(&adapter->watchdog_task); +} + /** * ec_poll - EtherCAT poll routine * @netdev: net device structure @@ -2140,12 +2148,8 @@ void ec_poll(struct net_device *netdev) int budget = 64; if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { - struct e1000_hw *hw = &adapter->hw; - bool link; - hw->mac.get_link_status = true; - link = igb_has_link(adapter); - ecdev_set_link(adapter->ecdev, link); adapter->ec_watchdog_jiffies = jiffies; + irq_work_queue(&adapter->ec_watchdog_kicker); } for (i = 0; i < adapter->num_q_vectors; i++) { @@ -2605,6 +2609,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); if (adapter->ecdev) { + init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); err = ecdev_open(adapter->ecdev); if (err) { ecdev_withdraw(adapter->ecdev); @@ -2868,6 +2873,7 @@ static void igb_remove(struct pci_dev *pdev) if (adapter->ecdev) { ecdev_close(adapter->ecdev); + irq_work_sync(&adapter->ec_watchdog_kicker); ecdev_withdraw(adapter->ecdev); } @@ -4336,8 +4342,16 @@ static void igb_watchdog_task(struct work_struct *work) int i; u32 connsw; + if (adapter->ecdev) + hw->mac.get_link_status = true; + link = igb_has_link(adapter); + if (adapter->ecdev) { + ecdev_set_link(adapter->ecdev, link); + return; + } + if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) { if (time_after(jiffies, (adapter->link_check_timeout + HZ))) adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; diff --git a/devices/igb/igb_main-5.10-ethercat.c b/devices/igb/igb_main-5.10-ethercat.c index 0b5dab47..719a03d4 100644 --- a/devices/igb/igb_main-5.10-ethercat.c +++ b/devices/igb/igb_main-5.10-ethercat.c @@ -3045,6 +3045,14 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_xdp_xmit = igb_xdp_xmit, }; +static void ec_kick_watchdog(struct irq_work *work) +{ + struct igb_adapter *adapter = + container_of(work, struct igb_adapter, ec_watchdog_kicker); + + schedule_work(&adapter->watchdog_task); +} + /** * ec_poll - EtherCAT poll routine * @netdev: net device structure @@ -3059,12 +3067,8 @@ void ec_poll(struct net_device *netdev) int budget = 64; if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { - struct e1000_hw *hw = &adapter->hw; - bool link; - hw->mac.get_link_status = true; - link = igb_has_link(adapter); - ecdev_set_link(adapter->ecdev, link); adapter->ec_watchdog_jiffies = jiffies; + irq_work_queue(&adapter->ec_watchdog_kicker); } for (i = 0; i < adapter->num_q_vectors; i++) { @@ -3560,6 +3564,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); if (adapter->ecdev) { + init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); err = ecdev_open(adapter->ecdev); if (err) { ecdev_withdraw(adapter->ecdev); @@ -3864,6 +3869,7 @@ static void igb_remove(struct pci_dev *pdev) if (adapter->ecdev) { ecdev_close(adapter->ecdev); + irq_work_sync(&adapter->ec_watchdog_kicker); ecdev_withdraw(adapter->ecdev); } @@ -5525,8 +5531,16 @@ static void igb_watchdog_task(struct work_struct *work) u32 connsw; u16 phy_data, retry_count = 20; + if (adapter->ecdev) + hw->mac.get_link_status = true; + link = igb_has_link(adapter); + if (adapter->ecdev) { + ecdev_set_link(adapter->ecdev, link); + return; + } + if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) { if (time_after(jiffies, (adapter->link_check_timeout + HZ))) adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; diff --git a/devices/igb/igb_main-5.14-ethercat.c b/devices/igb/igb_main-5.14-ethercat.c index 29c5656c..483642c6 100644 --- a/devices/igb/igb_main-5.14-ethercat.c +++ b/devices/igb/igb_main-5.14-ethercat.c @@ -3055,6 +3055,14 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_xdp_xmit = igb_xdp_xmit, }; +static void ec_kick_watchdog(struct irq_work *work) +{ + struct igb_adapter *adapter = + container_of(work, struct igb_adapter, ec_watchdog_kicker); + + schedule_work(&adapter->watchdog_task); +} + /** * ec_poll - EtherCAT poll routine * @netdev: net device structure @@ -3069,12 +3077,8 @@ void ec_poll(struct net_device *netdev) int budget = 64; if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { - struct e1000_hw *hw = &adapter->hw; - bool link; - hw->mac.get_link_status = true; - link = igb_has_link(adapter); - ecdev_set_link(adapter->ecdev, link); adapter->ec_watchdog_jiffies = jiffies; + irq_work_queue(&adapter->ec_watchdog_kicker); } for (i = 0; i < adapter->num_q_vectors; i++) { @@ -3570,6 +3574,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); if (adapter->ecdev) { + init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); err = ecdev_open(adapter->ecdev); if (err) { ecdev_withdraw(adapter->ecdev); @@ -3874,6 +3879,7 @@ static void igb_remove(struct pci_dev *pdev) if (adapter->ecdev) { ecdev_close(adapter->ecdev); + irq_work_sync(&adapter->ec_watchdog_kicker); ecdev_withdraw(adapter->ecdev); } @@ -5535,8 +5541,16 @@ static void igb_watchdog_task(struct work_struct *work) u32 connsw; u16 phy_data, retry_count = 20; + if (adapter->ecdev) + hw->mac.get_link_status = true; + link = igb_has_link(adapter); + if (adapter->ecdev) { + ecdev_set_link(adapter->ecdev, link); + return; + } + if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) { if (time_after(jiffies, (adapter->link_check_timeout + HZ))) adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; diff --git a/devices/igb/igb_main-5.15-ethercat.c b/devices/igb/igb_main-5.15-ethercat.c index 2e93f4be..4d3703a5 100644 --- a/devices/igb/igb_main-5.15-ethercat.c +++ b/devices/igb/igb_main-5.15-ethercat.c @@ -3044,6 +3044,14 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_xdp_xmit = igb_xdp_xmit, }; +static void ec_kick_watchdog(struct irq_work *work) +{ + struct igb_adapter *adapter = + container_of(work, struct igb_adapter, ec_watchdog_kicker); + + schedule_work(&adapter->watchdog_task); +} + /** * ec_poll - EtherCAT poll routine * @netdev: net device structure @@ -3058,12 +3066,8 @@ void ec_poll(struct net_device *netdev) int budget = 64; if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { - struct e1000_hw *hw = &adapter->hw; - bool link; - hw->mac.get_link_status = true; - link = igb_has_link(adapter); - ecdev_set_link(adapter->ecdev, link); adapter->ec_watchdog_jiffies = jiffies; + irq_work_queue(&adapter->ec_watchdog_kicker); } for (i = 0; i < adapter->num_q_vectors; i++) { @@ -3559,6 +3563,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); if (adapter->ecdev) { + init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); err = ecdev_open(adapter->ecdev); if (err) { ecdev_withdraw(adapter->ecdev); @@ -3863,6 +3868,7 @@ static void igb_remove(struct pci_dev *pdev) if (adapter->ecdev) { ecdev_close(adapter->ecdev); + irq_work_sync(&adapter->ec_watchdog_kicker); ecdev_withdraw(adapter->ecdev); } @@ -5533,8 +5539,16 @@ static void igb_watchdog_task(struct work_struct *work) u32 connsw; u16 phy_data, retry_count = 20; + if (adapter->ecdev) + hw->mac.get_link_status = true; + link = igb_has_link(adapter); + if (adapter->ecdev) { + ecdev_set_link(adapter->ecdev, link); + return; + } + if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) { if (time_after(jiffies, (adapter->link_check_timeout + HZ))) adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; diff --git a/devices/igb/igb_main-6.1-ethercat.c b/devices/igb/igb_main-6.1-ethercat.c index 13b860ce..8c1c1165 100644 --- a/devices/igb/igb_main-6.1-ethercat.c +++ b/devices/igb/igb_main-6.1-ethercat.c @@ -3070,6 +3070,14 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_xdp_xmit = igb_xdp_xmit, }; +static void ec_kick_watchdog(struct irq_work *work) +{ + struct igb_adapter *adapter = + container_of(work, struct igb_adapter, ec_watchdog_kicker); + + schedule_work(&adapter->watchdog_task); +} + /** * ec_poll - EtherCAT poll routine * @netdev: net device structure @@ -3084,12 +3092,8 @@ void ec_poll(struct net_device *netdev) int budget = 64; if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { - struct e1000_hw *hw = &adapter->hw; - bool link; - hw->mac.get_link_status = true; - link = igb_has_link(adapter); - ecdev_set_link(adapter->ecdev, link); adapter->ec_watchdog_jiffies = jiffies; + irq_work_queue(&adapter->ec_watchdog_kicker); } for (i = 0; i < adapter->num_q_vectors; i++) { @@ -3578,6 +3582,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); if (adapter->ecdev) { + init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); err = ecdev_open(adapter->ecdev); if (err) { ecdev_withdraw(adapter->ecdev); @@ -3890,6 +3895,7 @@ static void igb_remove(struct pci_dev *pdev) if (adapter->ecdev) { ecdev_close(adapter->ecdev); + irq_work_sync(&adapter->ec_watchdog_kicker); ecdev_withdraw(adapter->ecdev); } @@ -5566,8 +5572,16 @@ static void igb_watchdog_task(struct work_struct *work) u32 connsw; u16 phy_data, retry_count = 20; + if (adapter->ecdev) + hw->mac.get_link_status = true; + link = igb_has_link(adapter); + if (adapter->ecdev) { + ecdev_set_link(adapter->ecdev, link); + return; + } + if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) { if (time_after(jiffies, (adapter->link_check_timeout + HZ))) adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;