Fix igc link detection with xenomai

This commit is contained in:
Bjarne von Horn 2024-02-02 13:24:20 +01:00
parent 35ff319856
commit 34c56eae7d
4 changed files with 42 additions and 12 deletions

View File

@ -5,6 +5,7 @@
#define _IGC_H_
#include "../ecdev.h"
#include <linux/irq_work.h>
#include <linux/kobject.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@ -268,6 +269,7 @@ struct igc_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
void igc_up(struct igc_adapter *adapter);

View File

@ -5,6 +5,7 @@
#define _IGC_H_
#include "../ecdev.h"
#include <linux/irq_work.h>
#include <linux/kobject.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@ -283,6 +284,7 @@ struct igc_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
void igc_up(struct igc_adapter *adapter);

View File

@ -5576,8 +5576,16 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link;
int i;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGC_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
@ -6537,6 +6545,14 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_xsk_wakeup = igc_xsk_wakeup,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igc_adapter *adapter =
container_of(work, struct igc_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -6551,13 +6567,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct igc_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igc_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++) {
@ -6910,6 +6921,7 @@ static int igc_probe(struct pci_dev *pdev,
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);
@ -6976,6 +6988,7 @@ static void igc_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->irq_work);
ecdev_withdraw(adapter->ecdev);
}

View File

@ -5641,8 +5641,16 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link;
int i;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGC_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
@ -6657,6 +6665,14 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_xsk_wakeup = igc_xsk_wakeup,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igc_adapter *adapter =
container_of(work, struct igc_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -6671,13 +6687,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct igc_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igc_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++) {
@ -7050,6 +7061,7 @@ static int igc_probe(struct pci_dev *pdev,
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);
@ -7116,6 +7128,7 @@ static void igc_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->irq_work);
ecdev_withdraw(adapter->ecdev);
}