Merge branch 'verify_igb' into devel-1.6

This commit is contained in:
Bjarne von Horn 2024-04-08 14:16:51 +02:00
commit 721b4db1d2
45 changed files with 1167 additions and 912 deletions

View File

@ -66,7 +66,7 @@ AC_ARG_ENABLE([kernel],
;; ;;
no) enablekernel=0 no) enablekernel=0
;; ;;
*) AC_MSG_ERROR([Invalid value for --enable-generic]) *) AC_MSG_ERROR([Invalid value for --enable-kernel])
;; ;;
esac esac
], ],
@ -163,6 +163,37 @@ AC_SUBST(INSTALL_MOD_DIR,[$moddir])
AC_MSG_CHECKING([for Linux modules installation directory]) AC_MSG_CHECKING([for Linux modules installation directory])
AC_MSG_RESULT([$INSTALL_MOD_DIR]) AC_MSG_RESULT([$INSTALL_MOD_DIR])
#-----------------------------------------------------------------------------
# Native driver resource (de)allocation verifying
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to verify native driver resources])
AC_ARG_ENABLE([driver-resource-verifying],
AS_HELP_STRING([--enable-driver-resource-verifying],
[Verify resource (de-)allocation in native drivers]),
[
case "${enableval}" in
yes) enableverifying=1
;;
no) enableverifying=0
;;
*) AC_MSG_ERROR([Invalid value for --enable-driver-resource-verifying])
;;
esac
],
[enableverifying=0]
)
if test "x$enableverifying" = "x1"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AM_CONDITIONAL(ENABLE_DRIVER_RESOURCE_VERIFYING, test "x$enableverifying" = "x1")
AC_SUBST(ENABLE_DRIVER_RESOURCE_VERIFYING,[$enableverifying])
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Generic Ethernet driver # Generic Ethernet driver
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

View File

@ -660,9 +660,18 @@ struct rtl8139_private {
unsigned int regs_len; unsigned int regs_len;
unsigned long fifo_copy_timeout; unsigned long fifo_copy_timeout;
ec_device_t *ecdev; ec_device_t *ecdev_;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct rtl8139_private *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
MODULE_AUTHOR("Florian Pose <fp@igh.de>"); MODULE_AUTHOR("Florian Pose <fp@igh.de>");
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver"); MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -1083,9 +1092,10 @@ static int rtl8139_init_one(struct pci_dev *pdev,
/* dev is fully set up and ready to use now */ /* dev is fully set up and ready to use now */
// offer device to EtherCAT master module // offer device to EtherCAT master module
tp->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); tp->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE);
tp->ecdev_initialized = true;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
pr_debug("about to register device named %s (%p)...\n", pr_debug("about to register device named %s (%p)...\n",
dev->name, dev); dev->name, dev);
i = register_netdev (dev); i = register_netdev (dev);
@ -1158,10 +1168,10 @@ static int rtl8139_init_one(struct pci_dev *pdev,
if (rtl_chip_info[tp->chipset].flags & HasHltClk) if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */ RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
if (tp->ecdev) { if (get_ecdev(tp)) {
i = ecdev_open(tp->ecdev); i = ecdev_open(get_ecdev(tp));
if (i) { if (i) {
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
goto err_out; goto err_out;
} }
} }
@ -1182,9 +1192,9 @@ static void rtl8139_remove_one(struct pci_dev *pdev)
assert (dev != NULL); assert (dev != NULL);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_close(tp->ecdev); ecdev_close(get_ecdev(tp));
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
} }
else { else {
cancel_delayed_work_sync(&tp->thread); cancel_delayed_work_sync(&tp->thread);
@ -1393,7 +1403,7 @@ static int rtl8139_open (struct net_device *dev)
const int irq = tp->pci_dev->irq; const int irq = tp->pci_dev->irq;
int retval; int retval;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev); retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
if (retval) if (retval)
return retval; return retval;
@ -1404,7 +1414,7 @@ static int rtl8139_open (struct net_device *dev)
tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN, tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma, GFP_KERNEL); &tp->rx_ring_dma, GFP_KERNEL);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) { if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
if (!tp->ecdev) { if (!get_ecdev(tp)) {
free_irq(irq, dev); free_irq(irq, dev);
} }
@ -1426,7 +1436,7 @@ static int rtl8139_open (struct net_device *dev)
rtl8139_init_ring (dev); rtl8139_init_ring (dev);
rtl8139_hw_start (dev); rtl8139_hw_start (dev);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netif_start_queue (dev); netif_start_queue (dev);
} }
@ -1437,7 +1447,7 @@ static int rtl8139_open (struct net_device *dev)
irq, RTL_R8 (MediaStatus), irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half"); tp->mii.full_duplex ? "full" : "half");
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rtl8139_start_thread(tp); rtl8139_start_thread(tp);
} }
@ -1449,10 +1459,10 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media)
{ {
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
u16 state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS; u16 state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
ecdev_set_link(tp->ecdev, state ? 1 : 0); ecdev_set_link(get_ecdev(tp), state ? 1 : 0);
} }
else { else {
if (tp->phys[0] >= 0) { if (tp->phys[0] >= 0) {
@ -1523,7 +1533,7 @@ static void rtl8139_hw_start (struct net_device *dev)
if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb))) if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
/* Enable all known interrupts by setting the interrupt mask. */ /* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask); RTL_W16 (IntrMask, rtl8139_intr_mask);
} }
@ -1770,7 +1780,7 @@ static void rtl8139_tx_timeout_task (struct work_struct *work)
if (tmp8 & CmdTxEnb) if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb); RTL_W8 (ChipCmd, CmdRxEnb);
if (tp->ecdev) { if (get_ecdev(tp)) {
rtl8139_tx_clear (tp); rtl8139_tx_clear (tp);
rtl8139_hw_start (dev); rtl8139_hw_start (dev);
} }
@ -1798,7 +1808,7 @@ static void rtl8139_tx_timeout(struct net_device *dev, unsigned int txqueue)
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
tp->watchdog_fired = 1; tp->watchdog_fired = 1;
if (!tp->ecdev && !tp->have_thread) { if (!get_ecdev(tp) && !tp->have_thread) {
INIT_DELAYED_WORK(&tp->thread, rtl8139_thread); INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
schedule_delayed_work(&tp->thread, next_tick); schedule_delayed_work(&tp->thread, next_tick);
} }
@ -1821,18 +1831,18 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
if (len < ETH_ZLEN) if (len < ETH_ZLEN)
memset(tp->tx_buf[entry], 0, ETH_ZLEN); memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]); skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
} else { } else {
if (!tp->ecdev) { if (!get_ecdev(tp)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
if (!tp->ecdev) { if (!get_ecdev(tp)) {
spin_lock_irqsave(&tp->lock, flags); spin_lock_irqsave(&tp->lock, flags);
} }
/* /*
@ -1846,7 +1856,7 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
tp->cur_tx++; tp->cur_tx++;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
netif_stop_queue (dev); netif_stop_queue (dev);
spin_unlock_irqrestore(&tp->lock, flags); spin_unlock_irqrestore(&tp->lock, flags);
@ -1925,7 +1935,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
if (tp->dirty_tx != dirty_tx) { if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx; tp->dirty_tx = dirty_tx;
mb(); mb();
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netif_wake_queue (dev); netif_wake_queue (dev);
} }
} }
@ -2061,7 +2071,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
RTL_R16 (RxBufAddr), RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
while ((tp->ecdev || netif_running(dev)) while ((get_ecdev(tp) || netif_running(dev))
&& received < budget && received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
u32 ring_offset = cur_rx % RX_BUF_LEN; u32 ring_offset = cur_rx % RX_BUF_LEN;
@ -2079,7 +2089,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
else else
pkt_size = rx_size; pkt_size = rx_size;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
if (netif_msg_rx_status(tp)) if (netif_msg_rx_status(tp))
pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x," pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status, " cur %4.4x.\n", dev->name, rx_status,
@ -2151,8 +2161,8 @@ no_early_rx:
} }
keep_pkt: keep_pkt:
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_receive(tp->ecdev, &rx_ring[ring_offset + 4], pkt_size); ecdev_receive(get_ecdev(tp), &rx_ring[ring_offset + 4], pkt_size);
} }
else { else {
/* Malloc up new buffer, compatible with net-2e. */ /* Malloc up new buffer, compatible with net-2e. */
@ -2290,7 +2300,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
int link_changed = 0; /* avoid bogus "uninit" warning */ int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0; int handled = 0;
if (tp->ecdev) { if (get_ecdev(tp)) {
status = RTL_R16 (IntrStatus); status = RTL_R16 (IntrStatus);
} }
else { else {
@ -2308,7 +2318,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
if (unlikely(status == 0xFFFF)) if (unlikely(status == 0xFFFF))
goto out; goto out;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
/* close possible race's with dev_close */ /* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) { if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0); RTL_W16 (IntrMask, 0);
@ -2328,7 +2338,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
/* Receive packets are processed by poll routine. /* Receive packets are processed by poll routine.
If not running start it now. */ If not running start it now. */
if (status & RxAckBits){ if (status & RxAckBits){
if (tp->ecdev) { if (get_ecdev(tp)) {
/* EtherCAT device: Just receive all frames */ /* EtherCAT device: Just receive all frames */
rtl8139_rx(dev, tp, 100); // FIXME rtl8139_rx(dev, tp, 100); // FIXME
} else { } else {
@ -2351,7 +2361,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
RTL_W16 (IntrStatus, TxErr); RTL_W16 (IntrStatus, TxErr);
} }
out: out:
if (!tp->ecdev) { if (!get_ecdev(tp)) {
spin_unlock (&tp->lock); spin_unlock (&tp->lock);
} }
@ -2405,7 +2415,7 @@ static int rtl8139_close (struct net_device *dev)
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags = 0; unsigned long flags = 0;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netif_stop_queue(dev); netif_stop_queue(dev);
napi_disable(&tp->napi); napi_disable(&tp->napi);
@ -2426,7 +2436,7 @@ static int rtl8139_close (struct net_device *dev)
dev->stats.rx_missed_errors += RTL_R32 (RxMissed); dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0); RTL_W32 (RxMissed, 0);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
spin_unlock_irqrestore (&tp->lock, flags); spin_unlock_irqrestore (&tp->lock, flags);
free_irq(tp->pci_dev->irq, dev); free_irq(tp->pci_dev->irq, dev);
@ -2654,7 +2664,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
int rc; int rc;
if (tp->ecdev || !netif_running(dev)) if (get_ecdev(tp) || !netif_running(dev))
return -EINVAL; return -EINVAL;
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
@ -2673,7 +2683,7 @@ rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
unsigned long flags; unsigned long flags;
unsigned int start; unsigned int start;
if (tp->ecdev || netif_running(dev)) { if (get_ecdev(tp) || netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags); spin_lock_irqsave (&tp->lock, flags);
dev->stats.rx_missed_errors += RTL_R32 (RxMissed); dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0); RTL_W32 (RxMissed, 0);
@ -2762,7 +2772,7 @@ static int __maybe_unused rtl8139_suspend(struct device *device)
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags; unsigned long flags;
if (tp->ecdev || !netif_running (dev)) if (get_ecdev(tp) || !netif_running (dev))
return 0; return 0;
netif_device_detach (dev); netif_device_detach (dev);
@ -2787,7 +2797,7 @@ static int __maybe_unused rtl8139_resume(struct device *device)
struct net_device *dev = dev_get_drvdata(device); struct net_device *dev = dev_get_drvdata(device);
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
if (tp->ecdev || !netif_running (dev)) if (get_ecdev(tp) || !netif_running (dev))
return 0; return 0;
rtl8139_init_ring (dev); rtl8139_init_ring (dev);

View File

@ -26,6 +26,11 @@
src := @abs_srcdir@ src := @abs_srcdir@
ccflags-y := -I@abs_top_builddir@ ccflags-y := -I@abs_top_builddir@
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y += -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
REV := $(shell if test -s $(src)/../revision; then \ REV := $(shell if test -s $(src)/../revision; then \
cat $(src)/../revision; \ cat $(src)/../revision; \
else \ else \

View File

@ -646,10 +646,19 @@ struct nic {
__le16 eeprom[256]; __le16 eeprom[256];
spinlock_t mdio_lock; spinlock_t mdio_lock;
const struct firmware *fw; const struct firmware *fw;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct nic *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
static inline void e100_write_flush(struct nic *nic) static inline void e100_write_flush(struct nic *nic)
{ {
/* Flush previous PCI writes through intermediate bridges /* Flush previous PCI writes through intermediate bridges
@ -661,7 +670,7 @@ static void e100_enable_irq(struct nic *nic)
{ {
unsigned long flags; unsigned long flags;
if (nic->ecdev) if (get_ecdev(nic))
return; return;
spin_lock_irqsave(&nic->cmd_lock, flags); spin_lock_irqsave(&nic->cmd_lock, flags);
@ -674,11 +683,11 @@ static void e100_disable_irq(struct nic *nic)
{ {
unsigned long flags = 0; unsigned long flags = 0;
if (!nic->ecdev) if (!nic->ecdev_)
spin_lock_irqsave(&nic->cmd_lock, flags); spin_lock_irqsave(&nic->cmd_lock, flags);
iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi); iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi);
e100_write_flush(nic); e100_write_flush(nic);
if (!nic->ecdev) if (!nic->ecdev_)
spin_unlock_irqrestore(&nic->cmd_lock, flags); spin_unlock_irqrestore(&nic->cmd_lock, flags);
} }
@ -868,7 +877,7 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
unsigned int i; unsigned int i;
int err = 0; int err = 0;
if (!nic->ecdev) if (!get_ecdev(nic))
spin_lock_irqsave(&nic->cmd_lock, flags); spin_lock_irqsave(&nic->cmd_lock, flags);
/* Previous command is accepted when SCB clears */ /* Previous command is accepted when SCB clears */
@ -889,7 +898,7 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
iowrite8(cmd, &nic->csr->scb.cmd_lo); iowrite8(cmd, &nic->csr->scb.cmd_lo);
err_unlock: err_unlock:
if (!nic->ecdev) if (!get_ecdev(nic))
spin_unlock_irqrestore(&nic->cmd_lock, flags); spin_unlock_irqrestore(&nic->cmd_lock, flags);
return err; return err;
@ -902,7 +911,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
unsigned long flags; unsigned long flags;
int err; int err;
if (!nic->ecdev) { if (!get_ecdev(nic)) {
spin_lock_irqsave(&nic->cb_lock, flags); spin_lock_irqsave(&nic->cb_lock, flags);
} }
@ -950,7 +959,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
} }
err_unlock: err_unlock:
if (!nic->ecdev) { if (!get_ecdev(nic)) {
spin_unlock_irqrestore(&nic->cb_lock, flags); spin_unlock_irqrestore(&nic->cb_lock, flags);
} }
@ -984,7 +993,7 @@ static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
* manipulation of the MDI control registers is a multi-step * manipulation of the MDI control registers is a multi-step
* procedure it should be done under lock. * procedure it should be done under lock.
*/ */
if (!nic->ecdev) if (!nic->ecdev_) /* exemption of initialization check */
spin_lock_irqsave(&nic->mdio_lock, flags); spin_lock_irqsave(&nic->mdio_lock, flags);
for (i = 100; i; --i) { for (i = 100; i; --i) {
if (ioread32(&nic->csr->mdi_ctrl) & mdi_ready) if (ioread32(&nic->csr->mdi_ctrl) & mdi_ready)
@ -993,7 +1002,7 @@ static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
} }
if (unlikely(!i)) { if (unlikely(!i)) {
netdev_err(nic->netdev, "e100.mdio_ctrl won't go Ready\n"); netdev_err(nic->netdev, "e100.mdio_ctrl won't go Ready\n");
if (!nic->ecdev) if (!get_ecdev(nic))
spin_unlock_irqrestore(&nic->mdio_lock, flags); spin_unlock_irqrestore(&nic->mdio_lock, flags);
return 0; /* No way to indicate timeout error */ return 0; /* No way to indicate timeout error */
} }
@ -1004,7 +1013,7 @@ static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
if ((data_out = ioread32(&nic->csr->mdi_ctrl)) & mdi_ready) if ((data_out = ioread32(&nic->csr->mdi_ctrl)) & mdi_ready)
break; break;
} }
if (!nic->ecdev) if (!nic->ecdev_)
spin_unlock_irqrestore(&nic->mdio_lock, flags); spin_unlock_irqrestore(&nic->mdio_lock, flags);
netif_printk(nic, hw, KERN_DEBUG, nic->netdev, netif_printk(nic, hw, KERN_DEBUG, nic->netdev,
"%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n", "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
@ -1182,7 +1191,7 @@ static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
config->multicast_all = 0x1; /* 1=accept, 0=no */ config->multicast_all = 0x1; /* 1=accept, 0=no */
/* disable WoL when up */ /* disable WoL when up */
if (nic->ecdev || if (get_ecdev(nic) ||
(netif_running(nic->netdev) || !(nic->flags & wol_magic))) (netif_running(nic->netdev) || !(nic->flags & wol_magic)))
config->magic_packet_disable = 0x1; /* 1=off, 0=on */ config->magic_packet_disable = 0x1; /* 1=off, 0=on */
@ -1748,8 +1757,8 @@ static void e100_watchdog_impl(struct nic *nic)
struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
u32 speed; u32 speed;
if (nic->ecdev) { if (get_ecdev(nic)) {
ecdev_set_link(nic->ecdev, mii_link_ok(&nic->mii) ? 1 : 0); ecdev_set_link(get_ecdev(nic), mii_link_ok(&nic->mii) ? 1 : 0);
return; return;
} }
@ -1862,14 +1871,14 @@ static netdev_tx_t e100_xmit_frame(struct sk_buff *skb,
/* We queued the skb, but now we're out of space. */ /* We queued the skb, but now we're out of space. */
netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev, netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev,
"No space for CB\n"); "No space for CB\n");
if (!nic->ecdev) if (!get_ecdev(nic))
netif_stop_queue(netdev); netif_stop_queue(netdev);
break; break;
case -ENOMEM: case -ENOMEM:
/* This is a hard error - log it. */ /* This is a hard error - log it. */
netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev, netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev,
"Out of Tx resources, returning skb\n"); "Out of Tx resources, returning skb\n");
if (!nic->ecdev) if (!get_ecdev(nic))
netif_stop_queue(netdev); netif_stop_queue(netdev);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -1883,7 +1892,7 @@ static int e100_tx_clean(struct nic *nic)
struct cb *cb; struct cb *cb;
int tx_cleaned = 0; int tx_cleaned = 0;
if (!nic->ecdev) if (!get_ecdev(nic))
spin_lock(&nic->cb_lock); spin_lock(&nic->cb_lock);
/* Clean CBs marked complete */ /* Clean CBs marked complete */
@ -1904,7 +1913,7 @@ static int e100_tx_clean(struct nic *nic)
le32_to_cpu(cb->u.tcb.tbd.buf_addr), le32_to_cpu(cb->u.tcb.tbd.buf_addr),
le16_to_cpu(cb->u.tcb.tbd.size), le16_to_cpu(cb->u.tcb.tbd.size),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (!nic->ecdev) if (!get_ecdev(nic))
dev_kfree_skb_any(cb->skb); dev_kfree_skb_any(cb->skb);
cb->skb = NULL; cb->skb = NULL;
tx_cleaned = 1; tx_cleaned = 1;
@ -1913,7 +1922,7 @@ static int e100_tx_clean(struct nic *nic)
nic->cbs_avail++; nic->cbs_avail++;
} }
if (!nic->ecdev) { if (!get_ecdev(nic)) {
spin_unlock(&nic->cb_lock); spin_unlock(&nic->cb_lock);
/* Recover from running out of Tx resources in xmit_frame */ /* Recover from running out of Tx resources in xmit_frame */
@ -1934,7 +1943,7 @@ static void e100_clean_cbs(struct nic *nic)
le32_to_cpu(cb->u.tcb.tbd.buf_addr), le32_to_cpu(cb->u.tcb.tbd.buf_addr),
le16_to_cpu(cb->u.tcb.tbd.size), le16_to_cpu(cb->u.tcb.tbd.size),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (!nic->ecdev) if (!get_ecdev(nic))
dev_kfree_skb(cb->skb); dev_kfree_skb(cb->skb);
} }
nic->cb_to_clean = nic->cb_to_clean->next; nic->cb_to_clean = nic->cb_to_clean->next;
@ -2089,7 +2098,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
nic->ru_running = RU_SUSPENDED; nic->ru_running = RU_SUSPENDED;
} }
if (!nic->ecdev) { if (!get_ecdev(nic)) {
/* Pull off the RFD and put the actual data (minus eth hdr) */ /* Pull off the RFD and put the actual data (minus eth hdr) */
skb_reserve(skb, sizeof(struct rfd)); skb_reserve(skb, sizeof(struct rfd));
skb_put(skb, actual_size); skb_put(skb, actual_size);
@ -2107,27 +2116,27 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
} }
if (unlikely(!(rfd_status & cb_ok))) { if (unlikely(!(rfd_status & cb_ok))) {
if (!nic->ecdev) { if (!get_ecdev(nic)) {
/* Don't indicate if hardware indicates errors */ /* Don't indicate if hardware indicates errors */
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
} else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + fcs_pad) { } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + fcs_pad) {
/* Don't indicate oversized frames */ /* Don't indicate oversized frames */
nic->rx_over_length_errors++; nic->rx_over_length_errors++;
if (!nic->ecdev) { if (!get_ecdev(nic)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
} else { } else {
process_skb: process_skb:
dev->stats.rx_packets++; dev->stats.rx_packets++;
dev->stats.rx_bytes += (actual_size - fcs_pad); dev->stats.rx_bytes += (actual_size - fcs_pad);
if (nic->ecdev) { if (get_ecdev(nic)) {
ecdev_receive(nic->ecdev, ecdev_receive(get_ecdev(nic),
skb->data + sizeof(struct rfd), actual_size - fcs_pad); skb->data + sizeof(struct rfd), actual_size - fcs_pad);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
if (ecdev_get_link(nic->ecdev)) { if (ecdev_get_link(get_ecdev(nic))) {
nic->ec_watchdog_jiffies = jiffies; nic->ec_watchdog_jiffies = jiffies;
} }
} else { } else {
@ -2137,7 +2146,7 @@ process_skb:
(*work_done)++; (*work_done)++;
} }
if (nic->ecdev) { if (get_ecdev(nic)) {
// make receive frame descriptior usable again // make receive frame descriptior usable again
memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd)); memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd));
rx->dma_addr = dma_map_single(&nic->pdev->dev, skb->data, rx->dma_addr = dma_map_single(&nic->pdev->dev, skb->data,
@ -2191,7 +2200,7 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
old_before_last_rx = nic->rx_to_use->prev->prev; old_before_last_rx = nic->rx_to_use->prev->prev;
old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data; old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data;
if (!nic->ecdev) { if (!get_ecdev(nic)) {
/* Alloc new skbs to refill list */ /* Alloc new skbs to refill list */
for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
if(unlikely(e100_rx_alloc_skb(nic, rx))) if(unlikely(e100_rx_alloc_skb(nic, rx)))
@ -2288,7 +2297,7 @@ static int e100_rx_alloc_list(struct nic *nic)
} }
} }
if (!nic->ecdev) { if (!get_ecdev(nic)) {
/* Set the el-bit on the buffer that is before the last buffer. /* Set the el-bit on the buffer that is before the last buffer.
* This lets us update the next pointer on the last buffer without * This lets us update the next pointer on the last buffer without
* worrying about hardware touching it. * worrying about hardware touching it.
@ -2330,7 +2339,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
if (stat_ack & stat_ack_rnr) if (stat_ack & stat_ack_rnr)
nic->ru_running = RU_SUSPENDED; nic->ru_running = RU_SUSPENDED;
if (!nic->ecdev && likely(napi_schedule_prep(&nic->napi))) { if (!get_ecdev(nic) && likely(napi_schedule_prep(&nic->napi))) {
e100_disable_irq(nic); e100_disable_irq(nic);
__napi_schedule(&nic->napi); __napi_schedule(&nic->napi);
} }
@ -2418,13 +2427,13 @@ static int e100_up(struct nic *nic)
goto err_clean_cbs; goto err_clean_cbs;
e100_set_multicast_list(nic->netdev); e100_set_multicast_list(nic->netdev);
e100_start_receiver(nic, NULL); e100_start_receiver(nic, NULL);
if (!nic->ecdev) { if (!get_ecdev(nic)) {
mod_timer(&nic->watchdog, jiffies); mod_timer(&nic->watchdog, jiffies);
} }
if ((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, if ((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED,
nic->netdev->name, nic->netdev))) nic->netdev->name, nic->netdev)))
goto err_no_irq; goto err_no_irq;
if (!nic->ecdev) { if (!get_ecdev(nic)) {
netif_wake_queue(nic->netdev); netif_wake_queue(nic->netdev);
napi_enable(&nic->napi); napi_enable(&nic->napi);
/* enable ints _after_ enabling poll, preventing a race between /* enable ints _after_ enabling poll, preventing a race between
@ -2434,7 +2443,7 @@ static int e100_up(struct nic *nic)
return 0; return 0;
err_no_irq: err_no_irq:
if (!nic->ecdev) if (!get_ecdev(nic))
del_timer_sync(&nic->watchdog); del_timer_sync(&nic->watchdog);
err_clean_cbs: err_clean_cbs:
e100_clean_cbs(nic); e100_clean_cbs(nic);
@ -2445,14 +2454,14 @@ err_rx_clean_list:
static void e100_down(struct nic *nic) static void e100_down(struct nic *nic)
{ {
if (!nic->ecdev) { if (!get_ecdev(nic)) {
/* wait here for poll to complete */ /* wait here for poll to complete */
napi_disable(&nic->napi); napi_disable(&nic->napi);
netif_stop_queue(nic->netdev); netif_stop_queue(nic->netdev);
} }
e100_hw_reset(nic); e100_hw_reset(nic);
free_irq(nic->pdev->irq, nic->netdev); free_irq(nic->pdev->irq, nic->netdev);
if (!nic->ecdev) { if (!get_ecdev(nic)) {
del_timer_sync(&nic->watchdog); del_timer_sync(&nic->watchdog);
netif_carrier_off(nic->netdev); netif_carrier_off(nic->netdev);
} }
@ -2929,7 +2938,7 @@ static int e100_open(struct net_device *netdev)
struct nic *nic = netdev_priv(netdev); struct nic *nic = netdev_priv(netdev);
int err = 0; int err = 0;
if (!nic->ecdev) if (!get_ecdev(nic))
netif_carrier_off(netdev); netif_carrier_off(netdev);
if ((err = e100_up(nic))) if ((err = e100_up(nic)))
netif_err(nic, ifup, nic->netdev, "Cannot open interface, aborting\n"); netif_err(nic, ifup, nic->netdev, "Cannot open interface, aborting\n");
@ -3089,9 +3098,10 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_pme_active(pdev, false); pci_pme_active(pdev, false);
// offer device to EtherCAT master module // offer device to EtherCAT master module
nic->ecdev = ecdev_offer(netdev, e100_ec_poll, THIS_MODULE); nic->ecdev_ = ecdev_offer(netdev, e100_ec_poll, THIS_MODULE);
nic->ecdev_initialized = true;
if (!nic->ecdev) { if (!get_ecdev(nic)) {
strcpy(netdev->name, "eth%d"); strcpy(netdev->name, "eth%d");
if ((err = register_netdev(netdev))) { if ((err = register_netdev(netdev))) {
netif_err(nic, probe, nic->netdev, netif_err(nic, probe, nic->netdev,
@ -3115,10 +3125,10 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
pdev->irq, netdev->dev_addr); pdev->irq, netdev->dev_addr);
if (nic->ecdev) { if (get_ecdev(nic)) {
err = ecdev_open(nic->ecdev); err = ecdev_open(get_ecdev(nic));
if (err) { if (err) {
ecdev_withdraw(nic->ecdev); ecdev_withdraw(get_ecdev(nic));
goto err_out_free; goto err_out_free;
} }
} }
@ -3146,9 +3156,9 @@ static void e100_remove(struct pci_dev *pdev)
if (netdev) { if (netdev) {
struct nic *nic = netdev_priv(netdev); struct nic *nic = netdev_priv(netdev);
if (nic->ecdev) { if (get_ecdev(nic)) {
ecdev_close(nic->ecdev); ecdev_close(get_ecdev(nic));
ecdev_withdraw(nic->ecdev); ecdev_withdraw(get_ecdev(nic));
} else { } else {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -3263,7 +3273,7 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev); struct nic *nic = netdev_priv(netdev);
if (nic->ecdev) if (get_ecdev(nic))
return -EBUSY; return -EBUSY;
netif_device_detach(netdev); netif_device_detach(netdev);
@ -3290,7 +3300,7 @@ static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev); struct nic *nic = netdev_priv(netdev);
if (nic->ecdev) if (get_ecdev(nic))
return -EBUSY; return -EBUSY;
if (pci_enable_device(pdev)) { if (pci_enable_device(pdev)) {
@ -3323,11 +3333,11 @@ static void e100_io_resume(struct pci_dev *pdev)
/* ack any pending wake events, disable PME */ /* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0); pci_enable_wake(pdev, PCI_D0, 0);
if (!nic->ecdev) if (!get_ecdev(nic))
netif_device_attach(netdev); netif_device_attach(netdev);
if (nic->ecdev || netif_running(netdev)) { if (get_ecdev(nic) || netif_running(netdev)) {
e100_open(netdev); e100_open(netdev);
if (!nic->ecdev) if (!get_ecdev(nic))
mod_timer(&nic->watchdog, jiffies); mod_timer(&nic->watchdog, jiffies);
} }
} }

View File

@ -43,6 +43,10 @@ ifeq (@ENABLE_E1000@,1)
obj-m += ec_e1000.o obj-m += ec_e1000.o
ec_e1000-objs := $(EC_E1000_OBJ) ec_e1000-objs := $(EC_E1000_OBJ)
CFLAGS_e1000_main-@KERNEL_E1000@-ethercat.o = -DREV=$(REV) CFLAGS_e1000_main-@KERNEL_E1000@-ethercat.o = -DREV=$(REV)
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
endif endif
KBUILD_EXTRA_SYMBOLS := \ KBUILD_EXTRA_SYMBOLS := \

View File

@ -303,11 +303,20 @@ struct e1000_adapter {
struct delayed_work fifo_stall_task; struct delayed_work fifo_stall_task;
struct delayed_work phy_info_task; struct delayed_work phy_info_task;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct e1000_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
enum e1000_state_t { enum e1000_state_t {
__E1000_TESTING, __E1000_TESTING,
__E1000_RESETTING, __E1000_RESETTING,

View File

@ -303,11 +303,20 @@ struct e1000_adapter {
struct delayed_work fifo_stall_task; struct delayed_work fifo_stall_task;
struct delayed_work phy_info_task; struct delayed_work phy_info_task;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct e1000_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
enum e1000_state_t { enum e1000_state_t {
__E1000_TESTING, __E1000_TESTING,
__E1000_RESETTING, __E1000_RESETTING,

View File

@ -271,7 +271,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
int irq_flags = IRQF_SHARED; int irq_flags = IRQF_SHARED;
int err; int err;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return 0; return 0;
} }
@ -288,7 +288,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -303,7 +303,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (!adapter->ecdev_) {
return; return;
} }
@ -320,7 +320,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -407,7 +407,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
*/ */
for (i = 0; i < adapter->num_rx_queues; i++) { for (i = 0; i < adapter->num_rx_queues; i++) {
struct e1000_rx_ring *ring = &adapter->rx_ring[i]; struct e1000_rx_ring *ring = &adapter->rx_ring[i];
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* fill rx ring completely! */ /* fill rx ring completely! */
adapter->alloc_rx_buf(adapter, ring, ring->count); adapter->alloc_rx_buf(adapter, ring, ring->count);
} else { } else {
@ -427,7 +427,7 @@ int e1000_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->flags); clear_bit(__E1000_DOWN, &adapter->flags);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -516,13 +516,13 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter)
* still running after the adapter has been turned down. * still running after the adapter has been turned down.
*/ */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->phy_info_task);
cancel_delayed_work_sync(&adapter->fifo_stall_task); cancel_delayed_work_sync(&adapter->fifo_stall_task);
} }
/* Only kill reset task if adapter is not resetting */ /* Only kill reset task if adapter is not resetting */
if (!adapter->ecdev && !test_bit(__E1000_RESETTING, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_RESETTING, &adapter->flags))
cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->reset_task);
} }
@ -537,7 +537,7 @@ void e1000_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */ /* flush and sleep below */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_disable(netdev); netif_tx_disable(netdev);
} }
@ -557,7 +557,7 @@ void e1000_down(struct e1000_adapter *adapter)
* in the hardware until the next IFF_DOWN+IFF_UP cycle. * in the hardware until the next IFF_DOWN+IFF_UP cycle.
*/ */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
napi_disable(&adapter->napi); napi_disable(&adapter->napi);
@ -1012,6 +1012,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
adapter->bars = bars; adapter->bars = bars;
adapter->need_ioport = need_ioport; adapter->need_ioport = need_ioport;
adapter->ecdev_initialized = 0;
hw = &adapter->hw; hw = &adapter->hw;
hw->back = adapter; hw->back = adapter;
@ -1246,12 +1247,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
e1000_reset(adapter); e1000_reset(adapter);
// offer device to EtherCAT master module // offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
} else { } else {
@ -1273,7 +1275,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
((hw->bus_width == e1000_bus_width_64) ? 64 : 32), ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
netdev->dev_addr); netdev->dev_addr);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* carrier off reporting is important to ethtool even BEFORE open */ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
} }
@ -1323,15 +1325,15 @@ static void e1000_remove(struct pci_dev *pdev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
bool disable_dev; bool disable_dev;
if (adapter->ecdev) if (get_ecdev(adapter))
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
e1000_down_and_stop(adapter); e1000_down_and_stop(adapter);
e1000_release_manageability(adapter); e1000_release_manageability(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} else { } else {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -1464,7 +1466,7 @@ int e1000_open(struct net_device *netdev)
/* From here on the code is the same as e1000_up() */ /* From here on the code is the same as e1000_up() */
clear_bit(__E1000_DOWN, &adapter->flags); clear_bit(__E1000_DOWN, &adapter->flags);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -1926,7 +1928,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 rdlen, rctl, rxcsum; u32 rdlen, rctl, rxcsum;
if (!adapter->ecdev && adapter->netdev->mtu > ETH_DATA_LEN) { if (!get_ecdev(adapter) && adapter->netdev->mtu > ETH_DATA_LEN) {
rdlen = adapter->rx_ring[0].count * rdlen = adapter->rx_ring[0].count *
sizeof(struct e1000_rx_desc); sizeof(struct e1000_rx_desc);
adapter->clean_rx = e1000_clean_jumbo_rx_irq; adapter->clean_rx = e1000_clean_jumbo_rx_irq;
@ -2026,7 +2028,7 @@ static void
e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
struct e1000_tx_buffer *buffer_info) struct e1000_tx_buffer *buffer_info)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2236,7 +2238,7 @@ static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
E1000_WRITE_FLUSH(); E1000_WRITE_FLUSH();
mdelay(5); mdelay(5);
if (!adapter->ecdev && netif_running(netdev)) if (!get_ecdev(adapter) && netif_running(netdev))
e1000_clean_all_rx_rings(adapter); e1000_clean_all_rx_rings(adapter);
} }
@ -2259,7 +2261,7 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
/* No need to loop, because 82542 supports only 1 queue */ /* No need to loop, because 82542 supports only 1 queue */
struct e1000_rx_ring *ring = &adapter->rx_ring[0]; struct e1000_rx_ring *ring = &adapter->rx_ring[0];
e1000_configure_rx(adapter); e1000_configure_rx(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* fill rx ring completely! */ /* fill rx ring completely! */
adapter->alloc_rx_buf(adapter, ring, ring->count); adapter->alloc_rx_buf(adapter, ring, ring->count);
} else { } else {
@ -2519,12 +2521,12 @@ static void e1000_watchdog(struct work_struct *work)
u32 link, tctl; u32 link, tctl;
link = e1000_has_link(adapter); link = e1000_has_link(adapter);
if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link) if (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)
goto link_up; goto link_up;
if (link) { if (link) {
if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) || if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) ||
(!adapter->ecdev && !netif_carrier_ok(netdev))) { (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) {
u32 ctrl; u32 ctrl;
/* update snapshot of PHY registers on LSC */ /* update snapshot of PHY registers on LSC */
e1000_get_speed_and_duplex(hw, e1000_get_speed_and_duplex(hw,
@ -2559,8 +2561,8 @@ static void e1000_watchdog(struct work_struct *work)
tctl |= E1000_TCTL_EN; tctl |= E1000_TCTL_EN;
ew32(TCTL, tctl); ew32(TCTL, tctl);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 1); ecdev_set_link(get_ecdev(adapter), 1);
} }
else { else {
netif_carrier_on(netdev); netif_carrier_on(netdev);
@ -2571,15 +2573,15 @@ static void e1000_watchdog(struct work_struct *work)
adapter->smartspeed = 0; adapter->smartspeed = 0;
} }
} else { } else {
if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) {
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
pr_info("%s NIC Link is Down\n", pr_info("%s NIC Link is Down\n",
netdev->name); netdev->name);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -2607,7 +2609,7 @@ link_up:
e1000_update_adaptive(hw); e1000_update_adaptive(hw);
if (!adapter->ecdev && !netif_carrier_ok(netdev)) { if (!get_ecdev(adapter) && !netif_carrier_ok(netdev)) {
if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) { if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* We've lost link, so the controller stops DMA, /* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going * but we've got queued Tx work that's never going
@ -2643,7 +2645,7 @@ link_up:
adapter->detect_tx_hung = true; adapter->detect_tx_hung = true;
/* Reschedule the task */ /* Reschedule the task */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->watchdog_task, 2 * HZ); schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
} }
@ -3164,7 +3166,7 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_tx_ring *tx_ring = adapter->tx_ring; struct e1000_tx_ring *tx_ring = adapter->tx_ring;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -3260,7 +3262,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (!__pskb_pull_tail(skb, pull_size)) { if (!__pskb_pull_tail(skb, pull_size)) {
e_err(drv, "__pskb_pull_tail " e_err(drv, "__pskb_pull_tail "
"failed.\n"); "failed.\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -3311,7 +3313,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (unlikely((hw->mac_type == e1000_82547) && if (unlikely((hw->mac_type == e1000_82547) &&
(e1000_82547_fifo_workaround(adapter, skb)))) { (e1000_82547_fifo_workaround(adapter, skb)))) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
if (!test_bit(__E1000_DOWN, &adapter->flags)) if (!test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->fifo_stall_task, 1); schedule_delayed_work(&adapter->fifo_stall_task, 1);
@ -3329,7 +3331,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
tso = e1000_tso(adapter, tx_ring, skb, protocol); tso = e1000_tso(adapter, tx_ring, skb, protocol);
if (tso < 0) { if (tso < 0) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -3361,7 +3363,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
*/ */
int desc_needed = MAX_SKB_FRAGS + 7; int desc_needed = MAX_SKB_FRAGS + 7;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_sent_queue(netdev, skb->len); netdev_sent_queue(netdev, skb->len);
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
} }
@ -3378,12 +3380,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
/* Make sure there is space in the ring for the next send. */ /* Make sure there is space in the ring for the next send. */
e1000_maybe_stop_tx(netdev, tx_ring, desc_needed); e1000_maybe_stop_tx(netdev, tx_ring, desc_needed);
if (adapter->ecdev || !netdev_xmit_more() || if (get_ecdev(adapter) || !netdev_xmit_more() ||
netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) { netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt); writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt);
} }
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
tx_ring->buffer_info[first].time_stamp = 0; tx_ring->buffer_info[first].time_stamp = 0;
@ -3634,7 +3636,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -3720,7 +3722,7 @@ void e1000_update_stats(struct e1000_adapter *adapter)
if (pci_channel_offline(pdev)) if (pci_channel_offline(pdev))
return; return;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
spin_lock_irqsave(&adapter->stats_lock, flags); spin_lock_irqsave(&adapter->stats_lock, flags);
} }
@ -3851,7 +3853,7 @@ void e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.mgpdc += er32(MGTPDC); adapter->stats.mgpdc += er32(MGTPDC);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
spin_unlock_irqrestore(&adapter->stats_lock, flags); spin_unlock_irqrestore(&adapter->stats_lock, flags);
} }
} }
@ -3900,11 +3902,11 @@ static irqreturn_t e1000_intr(int irq, void *data)
if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
hw->get_link_status = 1; hw->get_link_status = 1;
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->watchdog_task, 1); schedule_delayed_work(&adapter->watchdog_task, 1);
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int i, ec_work_done = 0; int i, ec_work_done = 0;
for (i = 0; i < E1000_MAX_INTR; i++) { for (i = 0; i < E1000_MAX_INTR; i++) {
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring, if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
@ -4022,12 +4024,12 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
*/ */
smp_store_release(&tx_ring->next_to_clean, i); smp_store_release(&tx_ring->next_to_clean, i);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_completed_queue(netdev, pkts_compl, bytes_compl); netdev_completed_queue(netdev, pkts_compl, bytes_compl);
} }
#define TX_WAKE_THRESHOLD 32 #define TX_WAKE_THRESHOLD 32
if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) && if (!get_ecdev(adapter) && unlikely(count && netif_carrier_ok(netdev) &&
E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) { E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
* sees the new next_to_clean. * sees the new next_to_clean.
@ -4041,7 +4043,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
} }
} }
if (!adapter->ecdev && adapter->detect_tx_hung) { if (!get_ecdev(adapter) && adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the /* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i * check with the clearing of time_stamp and movement of i
*/ */
@ -4529,7 +4531,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
length = le16_to_cpu(rx_desc->length); length = le16_to_cpu(rx_desc->length);
data = buffer_info->rxbuf.data; data = buffer_info->rxbuf.data;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
prefetch(data); prefetch(data);
skb = e1000_copybreak(adapter, buffer_info, length, data); skb = e1000_copybreak(adapter, buffer_info, length, data);
if (!skb) { if (!skb) {
@ -4573,7 +4575,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (adapter->discarding) { if (adapter->discarding) {
/* All receives must fit into a single buffer */ /* All receives must fit into a single buffer */
netdev_dbg(netdev, "Receive packet consumed multiple buffers\n"); netdev_dbg(netdev, "Receive packet consumed multiple buffers\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
if (status & E1000_RXD_STAT_EOP) if (status & E1000_RXD_STAT_EOP)
@ -4589,7 +4591,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
} else if (netdev->features & NETIF_F_RXALL) { } else if (netdev->features & NETIF_F_RXALL) {
goto process_skb; goto process_skb;
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
goto next_desc; goto next_desc;
@ -4606,7 +4608,7 @@ process_skb:
*/ */
length -= 4; length -= 4;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (buffer_info->rxbuf.data == NULL) if (buffer_info->rxbuf.data == NULL)
skb_put(skb, length); skb_put(skb, length);
else /* copybreak skb */ else /* copybreak skb */
@ -4619,10 +4621,10 @@ process_skb:
le16_to_cpu(rx_desc->csum), skb); le16_to_cpu(rx_desc->csum), skb);
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma, dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma,
adapter->rx_buffer_len, DMA_FROM_DEVICE); adapter->rx_buffer_len, DMA_FROM_DEVICE);
ecdev_receive(adapter->ecdev, data, length); ecdev_receive(get_ecdev(adapter), data, length);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
@ -4941,7 +4943,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
data->phy_id = hw->phy_addr; data->phy_id = hw->phy_addr;
break; break;
case SIOCGMIIREG: case SIOCGMIIREG:
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EPERM; return -EPERM;
} }
spin_lock_irqsave(&adapter->stats_lock, flags); spin_lock_irqsave(&adapter->stats_lock, flags);
@ -4953,7 +4955,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
spin_unlock_irqrestore(&adapter->stats_lock, flags); spin_unlock_irqrestore(&adapter->stats_lock, flags);
break; break;
case SIOCSMIIREG: case SIOCSMIIREG:
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EPERM; return -EPERM;
} }
if (data->reg_num & ~(0x1F)) if (data->reg_num & ~(0x1F))
@ -5243,7 +5245,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
u32 ctrl, ctrl_ext, rctl, status; u32 ctrl, ctrl_ext, rctl, status;
u32 wufc = adapter->wol; u32 wufc = adapter->wol;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -5339,7 +5341,7 @@ static int __maybe_unused e1000_resume(struct device *dev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 err; u32 err;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -5375,7 +5377,7 @@ static int __maybe_unused e1000_resume(struct device *dev)
if (netif_running(netdev)) if (netif_running(netdev))
e1000_up(adapter); e1000_up(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_device_attach(netdev); netif_device_attach(netdev);
} }

View File

@ -260,7 +260,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
int irq_flags = IRQF_SHARED; int irq_flags = IRQF_SHARED;
int err; int err;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return 0; return 0;
} }
@ -277,7 +277,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -292,7 +292,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (adapter->ecdev_) {
return; return;
} }
@ -309,7 +309,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -396,7 +396,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
*/ */
for (i = 0; i < adapter->num_rx_queues; i++) { for (i = 0; i < adapter->num_rx_queues; i++) {
struct e1000_rx_ring *ring = &adapter->rx_ring[i]; struct e1000_rx_ring *ring = &adapter->rx_ring[i];
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* fill rx ring completely! */ /* fill rx ring completely! */
adapter->alloc_rx_buf(adapter, ring, ring->count); adapter->alloc_rx_buf(adapter, ring, ring->count);
} else { } else {
@ -416,7 +416,7 @@ int e1000_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->flags); clear_bit(__E1000_DOWN, &adapter->flags);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -505,13 +505,13 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter)
* still running after the adapter has been turned down. * still running after the adapter has been turned down.
*/ */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->phy_info_task);
cancel_delayed_work_sync(&adapter->fifo_stall_task); cancel_delayed_work_sync(&adapter->fifo_stall_task);
} }
/* Only kill reset task if adapter is not resetting */ /* Only kill reset task if adapter is not resetting */
if (!adapter->ecdev && !test_bit(__E1000_RESETTING, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_RESETTING, &adapter->flags))
cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->reset_task);
} }
@ -526,7 +526,7 @@ void e1000_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */ /* flush and sleep below */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_disable(netdev); netif_tx_disable(netdev);
} }
@ -546,7 +546,7 @@ void e1000_down(struct e1000_adapter *adapter)
* in the hardware until the next IFF_DOWN+IFF_UP cycle. * in the hardware until the next IFF_DOWN+IFF_UP cycle.
*/ */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
napi_disable(&adapter->napi); napi_disable(&adapter->napi);
@ -1001,6 +1001,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
adapter->bars = bars; adapter->bars = bars;
adapter->need_ioport = need_ioport; adapter->need_ioport = need_ioport;
adapter->ecdev_initialized = 0;
hw = &adapter->hw; hw = &adapter->hw;
hw->back = adapter; hw->back = adapter;
@ -1231,12 +1232,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
e1000_reset(adapter); e1000_reset(adapter);
// offer device to EtherCAT master module // offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
} else { } else {
@ -1258,7 +1260,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
((hw->bus_width == e1000_bus_width_64) ? 64 : 32), ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
netdev->dev_addr); netdev->dev_addr);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* carrier off reporting is important to ethtool even BEFORE open */ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
} }
@ -1308,15 +1310,15 @@ static void e1000_remove(struct pci_dev *pdev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
bool disable_dev; bool disable_dev;
if (adapter->ecdev) if (get_ecdev(adapter))
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
e1000_down_and_stop(adapter); e1000_down_and_stop(adapter);
e1000_release_manageability(adapter); e1000_release_manageability(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} else { } else {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -1449,7 +1451,7 @@ int e1000_open(struct net_device *netdev)
/* From here on the code is the same as e1000_up() */ /* From here on the code is the same as e1000_up() */
clear_bit(__E1000_DOWN, &adapter->flags); clear_bit(__E1000_DOWN, &adapter->flags);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -1911,7 +1913,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 rdlen, rctl, rxcsum; u32 rdlen, rctl, rxcsum;
if (!adapter->ecdev && adapter->netdev->mtu > ETH_DATA_LEN) { if (!get_ecdev(adapter) && adapter->netdev->mtu > ETH_DATA_LEN) {
rdlen = adapter->rx_ring[0].count * rdlen = adapter->rx_ring[0].count *
sizeof(struct e1000_rx_desc); sizeof(struct e1000_rx_desc);
adapter->clean_rx = e1000_clean_jumbo_rx_irq; adapter->clean_rx = e1000_clean_jumbo_rx_irq;
@ -2012,7 +2014,7 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
struct e1000_tx_buffer *buffer_info, struct e1000_tx_buffer *buffer_info,
int budget) int budget)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2222,7 +2224,7 @@ static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
E1000_WRITE_FLUSH(); E1000_WRITE_FLUSH();
mdelay(5); mdelay(5);
if (!adapter->ecdev && netif_running(netdev)) if (!get_ecdev(adapter) && netif_running(netdev))
e1000_clean_all_rx_rings(adapter); e1000_clean_all_rx_rings(adapter);
} }
@ -2245,7 +2247,7 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
/* No need to loop, because 82542 supports only 1 queue */ /* No need to loop, because 82542 supports only 1 queue */
struct e1000_rx_ring *ring = &adapter->rx_ring[0]; struct e1000_rx_ring *ring = &adapter->rx_ring[0];
e1000_configure_rx(adapter); e1000_configure_rx(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* fill rx ring completely! */ /* fill rx ring completely! */
adapter->alloc_rx_buf(adapter, ring, ring->count); adapter->alloc_rx_buf(adapter, ring, ring->count);
} else { } else {
@ -2501,12 +2503,12 @@ static void e1000_watchdog(struct work_struct *work)
u32 link, tctl; u32 link, tctl;
link = e1000_has_link(adapter); link = e1000_has_link(adapter);
if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link) if (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)
goto link_up; goto link_up;
if (link) { if (link) {
if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) || if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) ||
(!adapter->ecdev && !netif_carrier_ok(netdev))) { (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) {
u32 ctrl; u32 ctrl;
/* update snapshot of PHY registers on LSC */ /* update snapshot of PHY registers on LSC */
e1000_get_speed_and_duplex(hw, e1000_get_speed_and_duplex(hw,
@ -2541,8 +2543,8 @@ static void e1000_watchdog(struct work_struct *work)
tctl |= E1000_TCTL_EN; tctl |= E1000_TCTL_EN;
ew32(TCTL, tctl); ew32(TCTL, tctl);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 1); ecdev_set_link(get_ecdev(adapter), 1);
} }
else { else {
netif_carrier_on(netdev); netif_carrier_on(netdev);
@ -2553,15 +2555,15 @@ static void e1000_watchdog(struct work_struct *work)
adapter->smartspeed = 0; adapter->smartspeed = 0;
} }
} else { } else {
if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) {
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
pr_info("%s NIC Link is Down\n", pr_info("%s NIC Link is Down\n",
netdev->name); netdev->name);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -2589,7 +2591,7 @@ link_up:
e1000_update_adaptive(hw); e1000_update_adaptive(hw);
if (!adapter->ecdev && !netif_carrier_ok(netdev)) { if (!get_ecdev(adapter) && !netif_carrier_ok(netdev)) {
if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) { if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* We've lost link, so the controller stops DMA, /* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going * but we've got queued Tx work that's never going
@ -2625,7 +2627,7 @@ link_up:
adapter->detect_tx_hung = true; adapter->detect_tx_hung = true;
/* Reschedule the task */ /* Reschedule the task */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->watchdog_task, 2 * HZ); schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
} }
@ -3146,7 +3148,7 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_tx_ring *tx_ring = adapter->tx_ring; struct e1000_tx_ring *tx_ring = adapter->tx_ring;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -3242,7 +3244,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (!__pskb_pull_tail(skb, pull_size)) { if (!__pskb_pull_tail(skb, pull_size)) {
e_err(drv, "__pskb_pull_tail " e_err(drv, "__pskb_pull_tail "
"failed.\n"); "failed.\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -3293,7 +3295,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
if (unlikely((hw->mac_type == e1000_82547) && if (unlikely((hw->mac_type == e1000_82547) &&
(e1000_82547_fifo_workaround(adapter, skb)))) { (e1000_82547_fifo_workaround(adapter, skb)))) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
if (!test_bit(__E1000_DOWN, &adapter->flags)) if (!test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->fifo_stall_task, 1); schedule_delayed_work(&adapter->fifo_stall_task, 1);
@ -3311,7 +3313,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
tso = e1000_tso(adapter, tx_ring, skb, protocol); tso = e1000_tso(adapter, tx_ring, skb, protocol);
if (tso < 0) { if (tso < 0) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -3343,7 +3345,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
*/ */
int desc_needed = MAX_SKB_FRAGS + 7; int desc_needed = MAX_SKB_FRAGS + 7;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_sent_queue(netdev, skb->len); netdev_sent_queue(netdev, skb->len);
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
} }
@ -3360,12 +3362,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
/* Make sure there is space in the ring for the next send. */ /* Make sure there is space in the ring for the next send. */
e1000_maybe_stop_tx(netdev, tx_ring, desc_needed); e1000_maybe_stop_tx(netdev, tx_ring, desc_needed);
if (adapter->ecdev || !netdev_xmit_more() || if (get_ecdev(adapter) || !netdev_xmit_more() ||
netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) { netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt); writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt);
} }
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
tx_ring->buffer_info[first].time_stamp = 0; tx_ring->buffer_info[first].time_stamp = 0;
@ -3616,7 +3618,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -3702,7 +3704,7 @@ void e1000_update_stats(struct e1000_adapter *adapter)
if (pci_channel_offline(pdev)) if (pci_channel_offline(pdev))
return; return;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
spin_lock_irqsave(&adapter->stats_lock, flags); spin_lock_irqsave(&adapter->stats_lock, flags);
} }
@ -3833,7 +3835,7 @@ void e1000_update_stats(struct e1000_adapter *adapter)
adapter->stats.mgpdc += er32(MGTPDC); adapter->stats.mgpdc += er32(MGTPDC);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
spin_unlock_irqrestore(&adapter->stats_lock, flags); spin_unlock_irqrestore(&adapter->stats_lock, flags);
} }
} }
@ -3882,11 +3884,11 @@ static irqreturn_t e1000_intr(int irq, void *data)
if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
hw->get_link_status = 1; hw->get_link_status = 1;
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->flags))
schedule_delayed_work(&adapter->watchdog_task, 1); schedule_delayed_work(&adapter->watchdog_task, 1);
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int i, ec_work_done = 0; int i, ec_work_done = 0;
for (i = 0; i < E1000_MAX_INTR; i++) { for (i = 0; i < E1000_MAX_INTR; i++) {
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring, if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
@ -4005,12 +4007,12 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
*/ */
smp_store_release(&tx_ring->next_to_clean, i); smp_store_release(&tx_ring->next_to_clean, i);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_completed_queue(netdev, pkts_compl, bytes_compl); netdev_completed_queue(netdev, pkts_compl, bytes_compl);
} }
#define TX_WAKE_THRESHOLD 32 #define TX_WAKE_THRESHOLD 32
if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) && if (!get_ecdev(adapter) && unlikely(count && netif_carrier_ok(netdev) &&
E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) { E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
* sees the new next_to_clean. * sees the new next_to_clean.
@ -4024,7 +4026,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
} }
} }
if (!adapter->ecdev && adapter->detect_tx_hung) { if (!get_ecdev(adapter) && adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the /* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i * check with the clearing of time_stamp and movement of i
*/ */
@ -4512,7 +4514,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
length = le16_to_cpu(rx_desc->length); length = le16_to_cpu(rx_desc->length);
data = buffer_info->rxbuf.data; data = buffer_info->rxbuf.data;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
prefetch(data); prefetch(data);
skb = e1000_copybreak(adapter, buffer_info, length, data); skb = e1000_copybreak(adapter, buffer_info, length, data);
if (!skb) { if (!skb) {
@ -4556,7 +4558,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (adapter->discarding) { if (adapter->discarding) {
/* All receives must fit into a single buffer */ /* All receives must fit into a single buffer */
netdev_dbg(netdev, "Receive packet consumed multiple buffers\n"); netdev_dbg(netdev, "Receive packet consumed multiple buffers\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
if (status & E1000_RXD_STAT_EOP) if (status & E1000_RXD_STAT_EOP)
@ -4572,7 +4574,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
} else if (netdev->features & NETIF_F_RXALL) { } else if (netdev->features & NETIF_F_RXALL) {
goto process_skb; goto process_skb;
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
goto next_desc; goto next_desc;
@ -4589,7 +4591,7 @@ process_skb:
*/ */
length -= 4; length -= 4;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (buffer_info->rxbuf.data == NULL) if (buffer_info->rxbuf.data == NULL)
skb_put(skb, length); skb_put(skb, length);
else /* copybreak skb */ else /* copybreak skb */
@ -4602,10 +4604,10 @@ process_skb:
le16_to_cpu(rx_desc->csum), skb); le16_to_cpu(rx_desc->csum), skb);
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma, dma_sync_single_for_cpu(&adapter->pdev->dev, buffer_info->dma,
adapter->rx_buffer_len, DMA_FROM_DEVICE); adapter->rx_buffer_len, DMA_FROM_DEVICE);
ecdev_receive(adapter->ecdev, data, length); ecdev_receive(get_ecdev(adapter), data, length);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
@ -4924,7 +4926,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
data->phy_id = hw->phy_addr; data->phy_id = hw->phy_addr;
break; break;
case SIOCGMIIREG: case SIOCGMIIREG:
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EPERM; return -EPERM;
} }
spin_lock_irqsave(&adapter->stats_lock, flags); spin_lock_irqsave(&adapter->stats_lock, flags);
@ -4936,7 +4938,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
spin_unlock_irqrestore(&adapter->stats_lock, flags); spin_unlock_irqrestore(&adapter->stats_lock, flags);
break; break;
case SIOCSMIIREG: case SIOCSMIIREG:
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EPERM; return -EPERM;
} }
if (data->reg_num & ~(0x1F)) if (data->reg_num & ~(0x1F))
@ -5226,7 +5228,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
u32 ctrl, ctrl_ext, rctl, status; u32 ctrl, ctrl_ext, rctl, status;
u32 wufc = adapter->wol; u32 wufc = adapter->wol;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -5322,7 +5324,7 @@ static int __maybe_unused e1000_resume(struct device *dev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 err; u32 err;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return -EBUSY; return -EBUSY;
} }
@ -5358,7 +5360,7 @@ static int __maybe_unused e1000_resume(struct device *dev)
if (netif_running(netdev)) if (netif_running(netdev))
e1000_up(adapter); e1000_up(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_device_attach(netdev); netif_device_attach(netdev);
} }

View File

@ -70,6 +70,10 @@ ifeq (@ENABLE_E1000E@,1)
ec_e1000e-objs := $(EC_E1000E_OBJ) ec_e1000e-objs := $(EC_E1000E_OBJ)
CFLAGS_netdev-@KERNEL_E1000E@-ethercat.o = -DREV=$(REV) CFLAGS_netdev-@KERNEL_E1000E@-ethercat.o = -DREV=$(REV)
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
endif endif
KBUILD_EXTRA_SYMBOLS := \ KBUILD_EXTRA_SYMBOLS := \

View File

@ -336,11 +336,20 @@ struct e1000_adapter {
u16 eee_advert; u16 eee_advert;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work watchdog_kicker; struct irq_work watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct e1000_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
struct e1000_info { struct e1000_info {
enum e1000_mac_type mac; enum e1000_mac_type mac;
unsigned int flags; unsigned int flags;

View File

@ -338,11 +338,20 @@ struct e1000_adapter {
u16 eee_advert; u16 eee_advert;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work watchdog_kicker; struct irq_work watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct e1000_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
struct e1000_info { struct e1000_info {
enum e1000_mac_type mac; enum e1000_mac_type mac;
unsigned int flags; unsigned int flags;

View File

@ -45,7 +45,7 @@ char e1000e_driver_name[] = "ec_e1000e";
static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter) static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter)
{ {
#ifdef EC_DISABLE_E1000E_WORKAROUND #ifdef EC_DISABLE_E1000E_WORKAROUND
return !adapter->ecdev && (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA); return !get_ecdev(adapter) && (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA);
#else #else
return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA; return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA;
#endif #endif
@ -959,7 +959,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
skb = buffer_info->skb; skb = buffer_info->skb;
if (!adapter->ecdev) if (!get_ecdev(adapter))
buffer_info->skb = NULL; buffer_info->skb = NULL;
prefetch(skb->data - NET_IP_ALIGN); prefetch(skb->data - NET_IP_ALIGN);
@ -999,7 +999,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
goto next_desc; goto next_desc;
} }
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
!(netdev->features & NETIF_F_RXALL))) { !(netdev->features & NETIF_F_RXALL))) {
/* recycle */ /* recycle */
@ -1026,7 +1026,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
* performance for small packets with large amounts * performance for small packets with large amounts
* of reassembly being done in the stack * of reassembly being done in the stack
*/ */
if (!adapter->ecdev && length < copybreak) { if (!get_ecdev(adapter) && length < copybreak) {
struct sk_buff *new_skb = struct sk_buff *new_skb =
napi_alloc_skb(&adapter->napi, length); napi_alloc_skb(&adapter->napi, length);
if (new_skb) { if (new_skb) {
@ -1050,8 +1050,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1101,7 +1101,7 @@ static void e1000_put_txbuf(struct e1000_ring *tx_ring,
buffer_info->dma = 0; buffer_info->dma = 0;
} }
if (buffer_info->skb) { if (buffer_info->skb) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (drop) if (drop)
dev_kfree_skb_any(buffer_info->skb); dev_kfree_skb_any(buffer_info->skb);
else else
@ -1153,8 +1153,8 @@ static void e1000_print_hw_hang(struct work_struct *work)
} }
/* Real hang detected */ /* Real hang detected */
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_stop_queue(netdev); netif_stop_queue(netdev);
@ -1296,12 +1296,12 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
tx_ring->next_to_clean = i; tx_ring->next_to_clean = i;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_completed_queue(netdev, pkts_compl, bytes_compl); netdev_completed_queue(netdev, pkts_compl, bytes_compl);
} }
#define TX_WAKE_THRESHOLD 32 #define TX_WAKE_THRESHOLD 32
if (!adapter->ecdev && count && netif_carrier_ok(netdev) && if (!get_ecdev(adapter) && count && netif_carrier_ok(netdev) &&
e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
* sees the new next_to_clean. * sees the new next_to_clean.
@ -1315,7 +1315,7 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
} }
} }
if (!adapter->ecdev && adapter->detect_tx_hung) { if (!get_ecdev(adapter) && adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the /* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i * check with the clearing of time_stamp and movement of i
*/ */
@ -1394,7 +1394,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (adapter->flags2 & FLAG2_IS_DISCARDING) { if (adapter->flags2 & FLAG2_IS_DISCARDING) {
e_dbg("Packet Split buffers didn't pick up the full packet\n"); e_dbg("Packet Split buffers didn't pick up the full packet\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
if (staterr & E1000_RXD_STAT_EOP) if (staterr & E1000_RXD_STAT_EOP)
@ -1404,7 +1404,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
!(netdev->features & NETIF_F_RXALL))) { !(netdev->features & NETIF_F_RXALL))) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
goto next_desc; goto next_desc;
@ -1414,7 +1414,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (!length) { if (!length) {
e_dbg("Last part of the packet spanning multiple descriptors\n"); e_dbg("Last part of the packet spanning multiple descriptors\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
goto next_desc; goto next_desc;
@ -1503,8 +1503,8 @@ copydone:
cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
adapter->rx_hdr_split++; adapter->rx_hdr_split++;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1513,7 +1513,7 @@ copydone:
next_desc: next_desc:
rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
if (!adapter->ecdev) buffer_info->skb = NULL; if (!get_ecdev(adapter)) buffer_info->skb = NULL;
/* return some buffers to hardware, one at a time is too slow */ /* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= E1000_RX_BUFFER_WRITE) { if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
@ -1587,7 +1587,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
skb = buffer_info->skb; skb = buffer_info->skb;
if (!adapter->ecdev) if (!get_ecdev(adapter))
buffer_info->skb = NULL; buffer_info->skb = NULL;
++i; ++i;
@ -1613,7 +1613,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
/* recycle both page and skb */ /* recycle both page and skb */
buffer_info->skb = skb; buffer_info->skb = skb;
/* an error means any chain goes out the window too */ /* an error means any chain goes out the window too */
if (!adapter->ecdev && rx_ring->rx_skb_top) if (!get_ecdev(adapter) && rx_ring->rx_skb_top)
dev_kfree_skb_irq(rx_ring->rx_skb_top); dev_kfree_skb_irq(rx_ring->rx_skb_top);
rx_ring->rx_skb_top = NULL; rx_ring->rx_skb_top = NULL;
goto next_desc; goto next_desc;
@ -1686,14 +1686,14 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
total_rx_packets++; total_rx_packets++;
/* eth type trans needs skb->data to point to something */ /* eth type trans needs skb->data to point to something */
if (!adapter->ecdev && !pskb_may_pull(skb, ETH_HLEN)) { if (!get_ecdev(adapter) && !pskb_may_pull(skb, ETH_HLEN)) {
e_err("pskb_may_pull failed.\n"); e_err("pskb_may_pull failed.\n");
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
goto next_desc; goto next_desc;
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1818,7 +1818,7 @@ static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 icr = er32(ICR); u32 icr = er32(ICR);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
e1000_clean_tx_irq(adapter->tx_ring); e1000_clean_tx_irq(adapter->tx_ring);
@ -1892,7 +1892,7 @@ static irqreturn_t e1000_intr(int __always_unused irq, void *data)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 rctl, icr = er32(ICR); u32 rctl, icr = er32(ICR);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
e1000_clean_tx_irq(adapter->tx_ring); e1000_clean_tx_irq(adapter->tx_ring);
@ -1980,7 +1980,7 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
if (icr & E1000_ICR_LSC) { if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1); mod_timer(&adapter->watchdog_timer, jiffies + 1);
} }
@ -2027,7 +2027,7 @@ static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data)
rx_ring->set_itr = 0; rx_ring->set_itr = 0;
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
} else { } else {
@ -2241,7 +2241,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int err; int err;
if (adapter->ecdev) if (get_ecdev(adapter))
return 0; return 0;
if (adapter->msix_entries) { if (adapter->msix_entries) {
@ -2276,7 +2276,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2310,7 +2310,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
ew32(EIAC_82574, 0); ew32(EIAC_82574, 0);
e1e_flush(); e1e_flush();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2332,7 +2332,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->msix_entries) { if (adapter->msix_entries) {
@ -3859,7 +3859,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000e_setup_rss_hash(adapter); e1000e_setup_rss_hash(adapter);
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
e1000_configure_rx(adapter); e1000_configure_rx(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL); adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL);
} else { } else {
adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring),
@ -4322,7 +4322,7 @@ void e1000e_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->state); clear_bit(__E1000_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (adapter->msix_entries) if (adapter->msix_entries)
e1000_configure_msix(adapter); e1000_configure_msix(adapter);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -4375,8 +4375,8 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
*/ */
set_bit(__E1000_DOWN, &adapter->state); set_bit(__E1000_DOWN, &adapter->state);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -4388,7 +4388,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */ /* flush and sleep below */
if (!adapter->ecdev) if (!get_ecdev(adapter))
netif_stop_queue(netdev); netif_stop_queue(netdev);
/* disable transmits in the hardware */ /* disable transmits in the hardware */
@ -4400,7 +4400,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
e1e_flush(); e1e_flush();
usleep_range(10000, 11000); usleep_range(10000, 11000);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
napi_synchronize(&adapter->napi); napi_synchronize(&adapter->napi);
@ -4733,8 +4733,8 @@ int e1000e_open(struct net_device *netdev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
@ -4782,7 +4782,7 @@ int e1000e_open(struct net_device *netdev)
* ignore e1000e MSI messages, which means we need to test our MSI * ignore e1000e MSI messages, which means we need to test our MSI
* interrupt now * interrupt now
*/ */
if (!adapter->ecdev && adapter->int_mode != E1000E_INT_MODE_LEGACY) { if (!get_ecdev(adapter) && adapter->int_mode != E1000E_INT_MODE_LEGACY) {
err = e1000_test_msi(adapter); err = e1000_test_msi(adapter);
if (err) { if (err) {
e_err("Interrupt allocation failed\n"); e_err("Interrupt allocation failed\n");
@ -4793,7 +4793,7 @@ int e1000e_open(struct net_device *netdev)
/* From here on the code is the same as e1000e_up() */ /* From here on the code is the same as e1000e_up() */
clear_bit(__E1000_DOWN, &adapter->state); clear_bit(__E1000_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -4854,7 +4854,7 @@ int e1000e_close(struct net_device *netdev)
netdev_info(netdev, "NIC Link is Down\n"); netdev_info(netdev, "NIC Link is Down\n");
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_disable(&adapter->napi); napi_disable(&adapter->napi);
} }
@ -5329,9 +5329,9 @@ static void e1000_watchdog_task(struct work_struct *work)
return; return;
link = e1000e_has_link(adapter); link = e1000e_has_link(adapter);
if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link) if ((get_ecdev(adapter) && (ecdev_get_link(get_ecdev(adapter))) && link)
|| (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) { || (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Cancel scheduled suspend requests. */ /* Cancel scheduled suspend requests. */
pm_runtime_resume(netdev->dev.parent); pm_runtime_resume(netdev->dev.parent);
} }
@ -5345,8 +5345,8 @@ static void e1000_watchdog_task(struct work_struct *work)
e1000_update_mng_vlan(adapter); e1000_update_mng_vlan(adapter);
if (link) { if (link) {
if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && !netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) {
bool txb2b = true; bool txb2b = true;
/* Cancel scheduled suspend requests. */ /* Cancel scheduled suspend requests. */
@ -5462,27 +5462,27 @@ static void e1000_watchdog_task(struct work_struct *work)
if (phy->ops.cfg_on_link_up) if (phy->ops.cfg_on_link_up)
phy->ops.cfg_on_link_up(hw); phy->ops.cfg_on_link_up(hw);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 1); ecdev_set_link(get_ecdev(adapter), 1);
} }
else { else {
netif_wake_queue(netdev); netif_wake_queue(netdev);
netif_carrier_on(netdev); netif_carrier_on(netdev);
} }
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer, mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ)); round_jiffies(jiffies + 2 * HZ));
} }
} else { } else {
if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) {
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
/* Link status message must follow this format */ /* Link status message must follow this format */
netdev_info(netdev, "NIC Link is Down\n"); netdev_info(netdev, "NIC Link is Down\n");
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -5584,7 +5584,7 @@ link_up:
} }
/* Reset the timer */ /* Reset the timer */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 2 * HZ)); round_jiffies(jiffies + 2 * HZ));
} }
@ -5965,13 +5965,13 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
__be16 protocol = vlan_get_protocol(skb); __be16 protocol = vlan_get_protocol(skb);
if (test_bit(__E1000_DOWN, &adapter->state)) { if (test_bit(__E1000_DOWN, &adapter->state)) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
if (skb->len <= 0) { if (skb->len <= 0) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -6000,7 +6000,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
pull_size = min_t(unsigned int, 4, skb->data_len); pull_size = min_t(unsigned int, 4, skb->data_len);
if (!__pskb_pull_tail(skb, pull_size)) { if (!__pskb_pull_tail(skb, pull_size)) {
e_err("__pskb_pull_tail failed.\n"); e_err("__pskb_pull_tail failed.\n");
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -6026,7 +6026,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
/* need: count + 2 desc gap to keep tail from touching /* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time * head, otherwise try next time
*/ */
if (!adapter->ecdev && e1000_maybe_stop_tx(tx_ring, count + 2)) if (!get_ecdev(adapter) && e1000_maybe_stop_tx(tx_ring, count + 2))
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
if (skb_vlan_tag_present(skb)) { if (skb_vlan_tag_present(skb)) {
@ -6039,7 +6039,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
tso = e1000_tso(tx_ring, skb, protocol); tso = e1000_tso(tx_ring, skb, protocol);
if (tso < 0) { if (tso < 0) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -6081,14 +6081,14 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
netdev_sent_queue(netdev, skb->len); netdev_sent_queue(netdev, skb->len);
e1000_tx_queue(tx_ring, tx_flags, count); e1000_tx_queue(tx_ring, tx_flags, count);
/* Make sure there is space in the ring for the next send. */ /* Make sure there is space in the ring for the next send. */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
e1000_maybe_stop_tx(tx_ring, e1000_maybe_stop_tx(tx_ring,
(MAX_SKB_FRAGS * (MAX_SKB_FRAGS *
DIV_ROUND_UP(PAGE_SIZE, DIV_ROUND_UP(PAGE_SIZE,
adapter->tx_fifo_limit) + 2)); adapter->tx_fifo_limit) + 2));
} }
if (adapter->ecdev || !netdev_xmit_more() || if (get_ecdev(adapter) || !netdev_xmit_more() ||
netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) { netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
if (check_arbiter_wa_flag(adapter)) if (check_arbiter_wa_flag(adapter))
e1000e_update_tdt_wa(tx_ring, e1000e_update_tdt_wa(tx_ring,
@ -6097,7 +6097,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
writel(tx_ring->next_to_use, tx_ring->tail); writel(tx_ring->next_to_use, tx_ring->tail);
} }
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
tx_ring->buffer_info[first].time_stamp = 0; tx_ring->buffer_info[first].time_stamp = 0;
@ -6199,7 +6199,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
/* Jumbo frame support */ /* Jumbo frame support */
@ -7019,7 +7019,7 @@ static int __e1000_resume(struct pci_dev *pdev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u16 aspm_disable_flag = 0; u16 aspm_disable_flag = 0;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
@ -7093,7 +7093,7 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
int rc; int rc;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
e1000e_flush_lpic(pdev); e1000e_flush_lpic(pdev);
@ -7586,6 +7586,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->hw.mac.type = ei->mac; adapter->hw.mac.type = ei->mac;
adapter->max_hw_frame_size = ei->max_hw_frame_size; adapter->max_hw_frame_size = ei->max_hw_frame_size;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
adapter->ecdev_initialized = 0;
mmio_start = pci_resource_start(pdev, 0); mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0); mmio_len = pci_resource_len(pdev, 0);
@ -7816,12 +7817,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (hw->mac.type >= e1000_pch_cnp) if (hw->mac.type >= e1000_pch_cnp)
adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS;
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker); init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -7893,10 +7895,10 @@ static void e1000_remove(struct pci_dev *pdev)
e1000e_ptp_remove(adapter); e1000e_ptp_remove(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->watchdog_kicker); irq_work_sync(&adapter->watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
/* The timers may be rescheduled, so explicitly disable them /* The timers may be rescheduled, so explicitly disable them
@ -7920,7 +7922,7 @@ static void e1000_remove(struct pci_dev *pdev)
} }
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }

View File

@ -34,7 +34,7 @@ char e1000e_driver_name[] = "ec_e1000e";
static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter) static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter)
{ {
#ifdef EC_DISABLE_E1000E_WORKAROUND #ifdef EC_DISABLE_E1000E_WORKAROUND
return !adapter->ecdev && (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA); return !get_ecdev(adapter) && (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA);
#else #else
return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA; return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA;
#endif #endif
@ -949,7 +949,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
skb = buffer_info->skb; skb = buffer_info->skb;
if (!adapter->ecdev) if (!get_ecdev(adapter))
buffer_info->skb = NULL; buffer_info->skb = NULL;
prefetch(skb->data - NET_IP_ALIGN); prefetch(skb->data - NET_IP_ALIGN);
@ -989,7 +989,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
goto next_desc; goto next_desc;
} }
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
!(netdev->features & NETIF_F_RXALL))) { !(netdev->features & NETIF_F_RXALL))) {
/* recycle */ /* recycle */
@ -1016,7 +1016,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
* performance for small packets with large amounts * performance for small packets with large amounts
* of reassembly being done in the stack * of reassembly being done in the stack
*/ */
if (!adapter->ecdev && length < copybreak) { if (!get_ecdev(adapter) && length < copybreak) {
struct sk_buff *new_skb = struct sk_buff *new_skb =
napi_alloc_skb(&adapter->napi, length); napi_alloc_skb(&adapter->napi, length);
if (new_skb) { if (new_skb) {
@ -1040,8 +1040,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1091,7 +1091,7 @@ static void e1000_put_txbuf(struct e1000_ring *tx_ring,
buffer_info->dma = 0; buffer_info->dma = 0;
} }
if (buffer_info->skb) { if (buffer_info->skb) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (drop) if (drop)
dev_kfree_skb_any(buffer_info->skb); dev_kfree_skb_any(buffer_info->skb);
else else
@ -1143,8 +1143,8 @@ static void e1000_print_hw_hang(struct work_struct *work)
} }
/* Real hang detected */ /* Real hang detected */
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_stop_queue(netdev); netif_stop_queue(netdev);
@ -1286,12 +1286,12 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
tx_ring->next_to_clean = i; tx_ring->next_to_clean = i;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_completed_queue(netdev, pkts_compl, bytes_compl); netdev_completed_queue(netdev, pkts_compl, bytes_compl);
} }
#define TX_WAKE_THRESHOLD 32 #define TX_WAKE_THRESHOLD 32
if (!adapter->ecdev && count && netif_carrier_ok(netdev) && if (!get_ecdev(adapter) && count && netif_carrier_ok(netdev) &&
e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
* sees the new next_to_clean. * sees the new next_to_clean.
@ -1305,7 +1305,7 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
} }
} }
if (!adapter->ecdev && adapter->detect_tx_hung) { if (!get_ecdev(adapter) && adapter->detect_tx_hung) {
/* Detect a transmit hang in hardware, this serializes the /* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i * check with the clearing of time_stamp and movement of i
*/ */
@ -1384,7 +1384,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (adapter->flags2 & FLAG2_IS_DISCARDING) { if (adapter->flags2 & FLAG2_IS_DISCARDING) {
e_dbg("Packet Split buffers didn't pick up the full packet\n"); e_dbg("Packet Split buffers didn't pick up the full packet\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
if (staterr & E1000_RXD_STAT_EOP) if (staterr & E1000_RXD_STAT_EOP)
@ -1394,7 +1394,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
!(netdev->features & NETIF_F_RXALL))) { !(netdev->features & NETIF_F_RXALL))) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
goto next_desc; goto next_desc;
@ -1404,7 +1404,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
if (!length) { if (!length) {
e_dbg("Last part of the packet spanning multiple descriptors\n"); e_dbg("Last part of the packet spanning multiple descriptors\n");
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
} }
goto next_desc; goto next_desc;
@ -1493,8 +1493,8 @@ copydone:
cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
adapter->rx_hdr_split++; adapter->rx_hdr_split++;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1503,7 +1503,7 @@ copydone:
next_desc: next_desc:
rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
if (!adapter->ecdev) buffer_info->skb = NULL; if (!get_ecdev(adapter)) buffer_info->skb = NULL;
/* return some buffers to hardware, one at a time is too slow */ /* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= E1000_RX_BUFFER_WRITE) { if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
@ -1577,7 +1577,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
skb = buffer_info->skb; skb = buffer_info->skb;
if (!adapter->ecdev) if (!get_ecdev(adapter))
buffer_info->skb = NULL; buffer_info->skb = NULL;
++i; ++i;
@ -1603,7 +1603,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
/* recycle both page and skb */ /* recycle both page and skb */
buffer_info->skb = skb; buffer_info->skb = skb;
/* an error means any chain goes out the window too */ /* an error means any chain goes out the window too */
if (!adapter->ecdev && rx_ring->rx_skb_top) if (!get_ecdev(adapter) && rx_ring->rx_skb_top)
dev_kfree_skb_irq(rx_ring->rx_skb_top); dev_kfree_skb_irq(rx_ring->rx_skb_top);
rx_ring->rx_skb_top = NULL; rx_ring->rx_skb_top = NULL;
goto next_desc; goto next_desc;
@ -1676,14 +1676,14 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
total_rx_packets++; total_rx_packets++;
/* eth type trans needs skb->data to point to something */ /* eth type trans needs skb->data to point to something */
if (!adapter->ecdev && !pskb_may_pull(skb, ETH_HLEN)) { if (!get_ecdev(adapter) && !pskb_may_pull(skb, ETH_HLEN)) {
e_err("pskb_may_pull failed.\n"); e_err("pskb_may_pull failed.\n");
dev_kfree_skb_irq(skb); dev_kfree_skb_irq(skb);
goto next_desc; goto next_desc;
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_receive(adapter->ecdev, skb->data, length); ecdev_receive(get_ecdev(adapter), skb->data, length);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
} else { } else {
e1000_receive_skb(adapter, netdev, skb, staterr, e1000_receive_skb(adapter, netdev, skb, staterr,
@ -1808,7 +1808,7 @@ static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 icr = er32(ICR); u32 icr = er32(ICR);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
e1000_clean_tx_irq(adapter->tx_ring); e1000_clean_tx_irq(adapter->tx_ring);
@ -1882,7 +1882,7 @@ static irqreturn_t e1000_intr(int __always_unused irq, void *data)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 rctl, icr = er32(ICR); u32 rctl, icr = er32(ICR);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
e1000_clean_tx_irq(adapter->tx_ring); e1000_clean_tx_irq(adapter->tx_ring);
@ -1970,7 +1970,7 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
if (icr & E1000_ICR_LSC) { if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
/* guard against interrupt when we're going down */ /* guard against interrupt when we're going down */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1); mod_timer(&adapter->watchdog_timer, jiffies + 1);
} }
@ -2017,7 +2017,7 @@ static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data)
rx_ring->set_itr = 0; rx_ring->set_itr = 0;
} }
if (adapter->ecdev) { if (get_ecdev(adapter)) {
int ec_work_done = 0; int ec_work_done = 0;
adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100);
} else { } else {
@ -2231,7 +2231,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int err; int err;
if (adapter->ecdev) if (get_ecdev(adapter))
return 0; return 0;
if (adapter->msix_entries) { if (adapter->msix_entries) {
@ -2266,7 +2266,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2300,7 +2300,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
ew32(EIAC_82574, 0); ew32(EIAC_82574, 0);
e1e_flush(); e1e_flush();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return; return;
} }
@ -2322,7 +2322,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->msix_entries) { if (adapter->msix_entries) {
@ -3845,7 +3845,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000e_setup_rss_hash(adapter); e1000e_setup_rss_hash(adapter);
e1000_setup_rctl(adapter); e1000_setup_rctl(adapter);
e1000_configure_rx(adapter); e1000_configure_rx(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL); adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL);
} else { } else {
adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring),
@ -4309,7 +4309,7 @@ void e1000e_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->state); clear_bit(__E1000_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (adapter->msix_entries) if (adapter->msix_entries)
e1000_configure_msix(adapter); e1000_configure_msix(adapter);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -4362,8 +4362,8 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
*/ */
set_bit(__E1000_DOWN, &adapter->state); set_bit(__E1000_DOWN, &adapter->state);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -4375,7 +4375,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */ /* flush and sleep below */
if (!adapter->ecdev) if (!get_ecdev(adapter))
netif_stop_queue(netdev); netif_stop_queue(netdev);
/* disable transmits in the hardware */ /* disable transmits in the hardware */
@ -4387,7 +4387,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset)
e1e_flush(); e1e_flush();
usleep_range(10000, 11000); usleep_range(10000, 11000);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
napi_synchronize(&adapter->napi); napi_synchronize(&adapter->napi);
@ -4720,8 +4720,8 @@ int e1000e_open(struct net_device *netdev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
@ -4769,7 +4769,7 @@ int e1000e_open(struct net_device *netdev)
* ignore e1000e MSI messages, which means we need to test our MSI * ignore e1000e MSI messages, which means we need to test our MSI
* interrupt now * interrupt now
*/ */
if (!adapter->ecdev && adapter->int_mode != E1000E_INT_MODE_LEGACY) { if (!get_ecdev(adapter) && adapter->int_mode != E1000E_INT_MODE_LEGACY) {
err = e1000_test_msi(adapter); err = e1000_test_msi(adapter);
if (err) { if (err) {
e_err("Interrupt allocation failed\n"); e_err("Interrupt allocation failed\n");
@ -4780,7 +4780,7 @@ int e1000e_open(struct net_device *netdev)
/* From here on the code is the same as e1000e_up() */ /* From here on the code is the same as e1000e_up() */
clear_bit(__E1000_DOWN, &adapter->state); clear_bit(__E1000_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_enable(&adapter->napi); napi_enable(&adapter->napi);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
@ -4841,7 +4841,7 @@ int e1000e_close(struct net_device *netdev)
netdev_info(netdev, "NIC Link is Down\n"); netdev_info(netdev, "NIC Link is Down\n");
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_disable(&adapter->napi); napi_disable(&adapter->napi);
} }
@ -5312,9 +5312,9 @@ static void e1000_watchdog_task(struct work_struct *work)
return; return;
link = e1000e_has_link(adapter); link = e1000e_has_link(adapter);
if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link) if ((get_ecdev(adapter) && (ecdev_get_link(get_ecdev(adapter))) && link)
|| (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) { || (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)) {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Cancel scheduled suspend requests. */ /* Cancel scheduled suspend requests. */
pm_runtime_resume(netdev->dev.parent); pm_runtime_resume(netdev->dev.parent);
} }
@ -5328,8 +5328,8 @@ static void e1000_watchdog_task(struct work_struct *work)
e1000_update_mng_vlan(adapter); e1000_update_mng_vlan(adapter);
if (link) { if (link) {
if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && !netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) {
bool txb2b = true; bool txb2b = true;
/* Cancel scheduled suspend requests. */ /* Cancel scheduled suspend requests. */
@ -5420,27 +5420,27 @@ static void e1000_watchdog_task(struct work_struct *work)
if (phy->ops.cfg_on_link_up) if (phy->ops.cfg_on_link_up)
phy->ops.cfg_on_link_up(hw); phy->ops.cfg_on_link_up(hw);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 1); ecdev_set_link(get_ecdev(adapter), 1);
} }
else { else {
netif_wake_queue(netdev); netif_wake_queue(netdev);
netif_carrier_on(netdev); netif_carrier_on(netdev);
} }
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer, mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ)); round_jiffies(jiffies + 2 * HZ));
} }
} else { } else {
if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter)))
|| (!adapter->ecdev && netif_carrier_ok(netdev))) { || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) {
adapter->link_speed = 0; adapter->link_speed = 0;
adapter->link_duplex = 0; adapter->link_duplex = 0;
/* Link status message must follow this format */ /* Link status message must follow this format */
netdev_info(netdev, "NIC Link is Down\n"); netdev_info(netdev, "NIC Link is Down\n");
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -5542,7 +5542,7 @@ link_up:
} }
/* Reset the timer */ /* Reset the timer */
if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state)) if (!get_ecdev(adapter) && !test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 2 * HZ)); round_jiffies(jiffies + 2 * HZ));
} }
@ -5923,13 +5923,13 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
__be16 protocol = vlan_get_protocol(skb); __be16 protocol = vlan_get_protocol(skb);
if (test_bit(__E1000_DOWN, &adapter->state)) { if (test_bit(__E1000_DOWN, &adapter->state)) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
if (skb->len <= 0) { if (skb->len <= 0) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -5958,7 +5958,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
pull_size = min_t(unsigned int, 4, skb->data_len); pull_size = min_t(unsigned int, 4, skb->data_len);
if (!__pskb_pull_tail(skb, pull_size)) { if (!__pskb_pull_tail(skb, pull_size)) {
e_err("__pskb_pull_tail failed.\n"); e_err("__pskb_pull_tail failed.\n");
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -5984,7 +5984,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
/* need: count + 2 desc gap to keep tail from touching /* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time * head, otherwise try next time
*/ */
if (!adapter->ecdev && e1000_maybe_stop_tx(tx_ring, count + 2)) if (!get_ecdev(adapter) && e1000_maybe_stop_tx(tx_ring, count + 2))
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
if (skb_vlan_tag_present(skb)) { if (skb_vlan_tag_present(skb)) {
@ -5997,7 +5997,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
tso = e1000_tso(tx_ring, skb, protocol); tso = e1000_tso(tx_ring, skb, protocol);
if (tso < 0) { if (tso < 0) {
if (!adapter->ecdev) if (!get_ecdev(adapter))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
@ -6039,14 +6039,14 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
netdev_sent_queue(netdev, skb->len); netdev_sent_queue(netdev, skb->len);
e1000_tx_queue(tx_ring, tx_flags, count); e1000_tx_queue(tx_ring, tx_flags, count);
/* Make sure there is space in the ring for the next send. */ /* Make sure there is space in the ring for the next send. */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
e1000_maybe_stop_tx(tx_ring, e1000_maybe_stop_tx(tx_ring,
((MAX_SKB_FRAGS + 1) * ((MAX_SKB_FRAGS + 1) *
DIV_ROUND_UP(PAGE_SIZE, DIV_ROUND_UP(PAGE_SIZE,
adapter->tx_fifo_limit) + 4)); adapter->tx_fifo_limit) + 4));
} }
if (adapter->ecdev || !netdev_xmit_more() || if (get_ecdev(adapter) || !netdev_xmit_more() ||
netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) { netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
if (check_arbiter_wa_flag(adapter)) if (check_arbiter_wa_flag(adapter))
e1000e_update_tdt_wa(tx_ring, e1000e_update_tdt_wa(tx_ring,
@ -6055,7 +6055,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
writel(tx_ring->next_to_use, tx_ring->tail); writel(tx_ring->next_to_use, tx_ring->tail);
} }
} else { } else {
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
tx_ring->buffer_info[first].time_stamp = 0; tx_ring->buffer_info[first].time_stamp = 0;
@ -6157,7 +6157,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
/* Jumbo frame support */ /* Jumbo frame support */
@ -7033,7 +7033,7 @@ static int __e1000_resume(struct pci_dev *pdev)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u16 aspm_disable_flag = 0; u16 aspm_disable_flag = 0;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
@ -7107,7 +7107,7 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
int rc; int rc;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
e1000e_flush_lpic(pdev); e1000e_flush_lpic(pdev);
@ -7594,6 +7594,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->hw.mac.type = ei->mac; adapter->hw.mac.type = ei->mac;
adapter->max_hw_frame_size = ei->max_hw_frame_size; adapter->max_hw_frame_size = ei->max_hw_frame_size;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
adapter->ecdev_initialized = 0;
mmio_start = pci_resource_start(pdev, 0); mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0); mmio_len = pci_resource_len(pdev, 0);
@ -7844,12 +7845,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (hw->mac.type >= e1000_pch_cnp) if (hw->mac.type >= e1000_pch_cnp)
adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS;
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker); init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -7921,10 +7923,10 @@ static void e1000_remove(struct pci_dev *pdev)
e1000e_ptp_remove(adapter); e1000e_ptp_remove(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->watchdog_kicker); irq_work_sync(&adapter->watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
/* The timers may be rescheduled, so explicitly disable them /* The timers may be rescheduled, so explicitly disable them
@ -7948,7 +7950,7 @@ static void e1000_remove(struct pci_dev *pdev)
} }
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }

View File

@ -38,6 +38,10 @@ ifeq (@ENABLE_GENET@,1)
bcmmii-@KERNEL_GENET@-ethercat.o \ bcmmii-@KERNEL_GENET@-ethercat.o \
bcmgenet_wol-@KERNEL_GENET@-ethercat.o bcmgenet_wol-@KERNEL_GENET@-ethercat.o
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
CFLAGS_bcmgenet-@KERNEL_GENET@-ethercat.o = -DREV="\"$(REV)\"" CFLAGS_bcmgenet-@KERNEL_GENET@-ethercat.o = -DREV="\"$(REV)\""
endif endif

View File

@ -1897,7 +1897,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
if (skb) { if (skb) {
pkts_compl++; pkts_compl++;
bytes_compl += GENET_CB(skb)->bytes_sent; bytes_compl += GENET_CB(skb)->bytes_sent;
if (!priv->ecdev) if (!get_ecdev(priv))
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
@ -1914,7 +1914,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
ring->packets += pkts_compl; ring->packets += pkts_compl;
ring->bytes += bytes_compl; ring->bytes += bytes_compl;
if (!priv->ecdev) if (!get_ecdev(priv))
netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue), netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue),
pkts_compl, bytes_compl); pkts_compl, bytes_compl);
@ -1940,7 +1940,7 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget)
unsigned int work_done = 0; unsigned int work_done = 0;
struct netdev_queue *txq; struct netdev_queue *txq;
if (ring->priv->ecdev) if (get_ecdev(ring->priv))
return 0; return 0;
spin_lock(&ring->lock); spin_lock(&ring->lock);
@ -1992,7 +1992,7 @@ static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
/* If 64 byte status block enabled, must make sure skb has /* If 64 byte status block enabled, must make sure skb has
* enough headroom for us to insert 64B status block. * enough headroom for us to insert 64B status block.
*/ */
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
new_skb = skb_realloc_headroom(skb, sizeof(*status)); new_skb = skb_realloc_headroom(skb, sizeof(*status));
if (!new_skb) { if (!new_skb) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
@ -2078,7 +2078,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock(&ring->lock); spin_lock(&ring->lock);
if (ring->free_bds <= (nr_frags + 1)) { if (ring->free_bds <= (nr_frags + 1)) {
if (!priv->ecdev && !netif_tx_queue_stopped(txq)) { if (!get_ecdev(priv) && !netif_tx_queue_stopped(txq)) {
netif_tx_stop_queue(txq); netif_tx_stop_queue(txq);
netdev_err(dev, netdev_err(dev,
"%s: tx ring %d full when queue %d awake\n", "%s: tx ring %d full when queue %d awake\n",
@ -2158,14 +2158,14 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
ring->prod_index += nr_frags + 1; ring->prod_index += nr_frags + 1;
ring->prod_index &= DMA_P_INDEX_MASK; ring->prod_index &= DMA_P_INDEX_MASK;
if (!priv->ecdev) { if (!get_ecdev(priv)) {
netdev_tx_sent_queue(txq, GENET_CB(skb)->bytes_sent); netdev_tx_sent_queue(txq, GENET_CB(skb)->bytes_sent);
if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) if (ring->free_bds <= (MAX_SKB_FRAGS + 1))
netif_tx_stop_queue(txq); netif_tx_stop_queue(txq);
} }
if (priv->ecdev || !netdev_xmit_more() || netif_xmit_stopped(txq)) if (get_ecdev(priv) || !netdev_xmit_more() || netif_xmit_stopped(txq))
/* Packets are ready, update producer index */ /* Packets are ready, update producer index */
bcmgenet_tdma_ring_writel(priv, ring->index, bcmgenet_tdma_ring_writel(priv, ring->index,
ring->prod_index, TDMA_PROD_INDEX); ring->prod_index, TDMA_PROD_INDEX);
@ -2184,7 +2184,7 @@ out_unmap_frags:
bcmgenet_free_tx_cb(kdev, tx_cb_ptr); bcmgenet_free_tx_cb(kdev, tx_cb_ptr);
} }
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb(skb); dev_kfree_skb(skb);
goto out; goto out;
} }
@ -2250,7 +2250,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
unsigned int p_index, mask; unsigned int p_index, mask;
unsigned int discards; unsigned int discards;
if (!priv->ecdev) { if (!get_ecdev(priv)) {
/* Clear status before servicing to reduce spurious interrupts */ /* Clear status before servicing to reduce spurious interrupts */
if (ring->index == DESC_INDEX) { if (ring->index == DESC_INDEX) {
bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_DONE, bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_DONE,
@ -2292,7 +2292,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
__be16 rx_csum; __be16 rx_csum;
cb = &priv->rx_cbs[ring->read_ptr]; cb = &priv->rx_cbs[ring->read_ptr];
if (priv->ecdev) if (get_ecdev(priv))
/* DMA unmap current skb */ /* DMA unmap current skb */
skb = bcmgenet_free_rx_cb(kdev, cb); skb = bcmgenet_free_rx_cb(kdev, cb);
else else
@ -2328,7 +2328,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
netif_err(priv, rx_status, dev, "oversized packet\n"); netif_err(priv, rx_status, dev, "oversized packet\n");
dev->stats.rx_length_errors++; dev->stats.rx_length_errors++;
dev->stats.rx_errors++; dev->stats.rx_errors++;
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
goto next; goto next;
} }
@ -2337,7 +2337,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
netif_err(priv, rx_status, dev, netif_err(priv, rx_status, dev,
"dropping fragmented packet!\n"); "dropping fragmented packet!\n");
ring->errors++; ring->errors++;
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
goto next; goto next;
} }
@ -2359,12 +2359,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
if (dma_flag & DMA_RX_LG) if (dma_flag & DMA_RX_LG)
dev->stats.rx_length_errors++; dev->stats.rx_length_errors++;
dev->stats.rx_errors++; dev->stats.rx_errors++;
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
goto next; goto next;
} /* error packet */ } /* error packet */
if (!priv->ecdev) { if (!get_ecdev(priv)) {
skb_put(skb, len); skb_put(skb, len);
/* remove RSB and hardware 2bytes added for IP alignment */ /* remove RSB and hardware 2bytes added for IP alignment */
@ -2373,7 +2373,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
len -= 66; len -= 66;
if (priv->crc_fwd_en) { if (priv->crc_fwd_en) {
if (!priv->ecdev) if (!get_ecdev(priv))
skb_trim(skb, len - ETH_FCS_LEN); skb_trim(skb, len - ETH_FCS_LEN);
len -= ETH_FCS_LEN; len -= ETH_FCS_LEN;
} }
@ -2387,12 +2387,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
if (dma_flag & DMA_RX_MULT) if (dma_flag & DMA_RX_MULT)
dev->stats.multicast++; dev->stats.multicast++;
if (priv->ecdev) { if (get_ecdev(priv)) {
dma_addr_t mapping; dma_addr_t mapping;
/* skip status block and padding in skb */ /* skip status block and padding in skb */
const unsigned char *data = skb->data + 66; const unsigned char *data = skb->data + 66;
ecdev_receive(priv->ecdev, data, len); ecdev_receive(get_ecdev(priv), data, len);
/* remap skb */ /* remap skb */
mapping = dma_map_single(kdev, skb->data, priv->rx_buf_len, mapping = dma_map_single(kdev, skb->data, priv->rx_buf_len,
@ -2439,7 +2439,7 @@ static int bcmgenet_rx_poll(struct napi_struct *napi, int budget)
struct dim_sample dim_sample = {}; struct dim_sample dim_sample = {};
unsigned int work_done; unsigned int work_done;
if (ring->priv->ecdev) if (get_ecdev(ring->priv))
return 0; return 0;
work_done = bcmgenet_desc_rx(ring, budget); work_done = bcmgenet_desc_rx(ring, budget);
@ -2653,7 +2653,7 @@ static void init_umac(struct bcmgenet_priv *priv)
/* Enable MDIO interrupts on GENET v3+ */ /* Enable MDIO interrupts on GENET v3+ */
if (priv->hw_params->flags & GENET_HAS_MDIO_INTR) { if (priv->hw_params->flags & GENET_HAS_MDIO_INTR) {
int0_enable |= UMAC_IRQ_MDIO_ERROR; int0_enable |= UMAC_IRQ_MDIO_ERROR;
if (!priv->ecdev) if (!get_ecdev(priv))
int0_enable |= UMAC_IRQ_MDIO_DONE; int0_enable |= UMAC_IRQ_MDIO_DONE;
} }
@ -2683,7 +2683,7 @@ static void bcmgenet_init_rx_coalesce(struct bcmgenet_rx_ring *ring)
usecs = ring->rx_coalesce_usecs; usecs = ring->rx_coalesce_usecs;
pkts = ring->rx_max_coalesced_frames; pkts = ring->rx_max_coalesced_frames;
if (ring->priv->ecdev) if (get_ecdev(ring->priv))
return; return;
/* If DIM was enabled, re-apply default parameters */ /* If DIM was enabled, re-apply default parameters */
@ -2752,7 +2752,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
DMA_END_ADDR); DMA_END_ADDR);
/* Initialize Tx NAPI */ /* Initialize Tx NAPI */
if (!priv->ecdev) if (!get_ecdev(priv))
netif_napi_add_tx(priv->dev, &ring->napi, bcmgenet_tx_poll); netif_napi_add_tx(priv->dev, &ring->napi, bcmgenet_tx_poll);
} }
@ -2789,7 +2789,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
bcmgenet_init_rx_coalesce(ring); bcmgenet_init_rx_coalesce(ring);
/* Initialize Rx NAPI */ /* Initialize Rx NAPI */
if (!priv->ecdev) if (!get_ecdev(priv))
netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll); netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll);
bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX);
@ -2820,7 +2820,7 @@ static void bcmgenet_enable_tx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_tx_ring *ring; struct bcmgenet_tx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->tx_queues; ++i) { for (i = 0; i < priv->hw_params->tx_queues; ++i) {
@ -2839,7 +2839,7 @@ static void bcmgenet_disable_tx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_tx_ring *ring; struct bcmgenet_tx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->tx_queues; ++i) { for (i = 0; i < priv->hw_params->tx_queues; ++i) {
@ -2856,7 +2856,7 @@ static void bcmgenet_fini_tx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_tx_ring *ring; struct bcmgenet_tx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->tx_queues; ++i) { for (i = 0; i < priv->hw_params->tx_queues; ++i) {
@ -2942,7 +2942,7 @@ static void bcmgenet_enable_rx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_rx_ring *ring; struct bcmgenet_rx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->rx_queues; ++i) { for (i = 0; i < priv->hw_params->rx_queues; ++i) {
@ -2961,7 +2961,7 @@ static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_rx_ring *ring; struct bcmgenet_rx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->rx_queues; ++i) { for (i = 0; i < priv->hw_params->rx_queues; ++i) {
@ -2980,7 +2980,7 @@ static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv)
unsigned int i; unsigned int i;
struct bcmgenet_rx_ring *ring; struct bcmgenet_rx_ring *ring;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (i = 0; i < priv->hw_params->rx_queues; ++i) { for (i = 0; i < priv->hw_params->rx_queues; ++i) {
@ -3520,7 +3520,7 @@ static int bcmgenet_open(struct net_device *dev)
bcmgenet_netif_start(dev); bcmgenet_netif_start(dev);
if (!priv->ecdev) if (!get_ecdev(priv))
netif_tx_start_all_queues(dev); netif_tx_start_all_queues(dev);
return 0; return 0;
@ -4089,6 +4089,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
} }
priv = netdev_priv(dev); priv = netdev_priv(dev);
priv->ecdev_initialized = false;
priv->irq0 = platform_get_irq(pdev, 0); priv->irq0 = platform_get_irq(pdev, 0);
if (priv->irq0 < 0) { if (priv->irq0 < 0) {
err = priv->irq0; err = priv->irq0;
@ -4245,12 +4246,13 @@ static int bcmgenet_probe(struct platform_device *pdev)
/* Turn off the main clock, WOL clock is handled separately */ /* Turn off the main clock, WOL clock is handled separately */
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
priv->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); priv->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE);
if (priv->ecdev) { priv->ecdev_initialized = true;
err = ecdev_open(priv->ecdev); if (get_ecdev(priv)) {
err = ecdev_open(get_ecdev(priv));
if (err) { if (err) {
ecdev_withdraw(priv->ecdev); ecdev_withdraw(get_ecdev(priv));
priv->ecdev = NULL; priv->ecdev_ = NULL;
bcmgenet_mii_exit(dev); bcmgenet_mii_exit(dev);
goto err; goto err;
} }
@ -4276,10 +4278,10 @@ static int bcmgenet_remove(struct platform_device *pdev)
struct bcmgenet_priv *priv = dev_to_priv(&pdev->dev); struct bcmgenet_priv *priv = dev_to_priv(&pdev->dev);
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_close(priv->ecdev); ecdev_close(get_ecdev(priv));
ecdev_withdraw(priv->ecdev); ecdev_withdraw(get_ecdev(priv));
priv->ecdev = NULL; priv->ecdev_ = NULL;
} else } else
unregister_netdev(priv->dev); unregister_netdev(priv->dev);
bcmgenet_mii_exit(priv->dev); bcmgenet_mii_exit(priv->dev);
@ -4301,8 +4303,8 @@ static int bcmgenet_resume_noirq(struct device *d)
int ret; int ret;
u32 reg; u32 reg;
if (priv->ecdev) if (get_ecdev(priv))
ecdev_open(priv->ecdev); ecdev_open(get_ecdev(priv));
else if (!netif_running(dev)) else if (!netif_running(dev))
return 0; return 0;
@ -4388,8 +4390,8 @@ static int bcmgenet_resume(struct device *d)
bcmgenet_netif_start(dev); bcmgenet_netif_start(dev);
if (priv->ecdev) if (get_ecdev(priv))
ecdev_open(priv->ecdev); ecdev_open(get_ecdev(priv));
else else
netif_device_attach(dev); netif_device_attach(dev);
@ -4407,8 +4409,8 @@ static int bcmgenet_suspend(struct device *d)
struct net_device *dev = dev_get_drvdata(d); struct net_device *dev = dev_get_drvdata(d);
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_close(priv->ecdev); ecdev_close(get_ecdev(priv));
} else { } else {
if (!netif_running(dev)) if (!netif_running(dev))
return 0; return 0;
@ -4433,8 +4435,8 @@ static int bcmgenet_suspend_noirq(struct device *d)
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
int ret = 0; int ret = 0;
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_close(priv->ecdev); ecdev_close(get_ecdev(priv));
} else if (!netif_running(dev)) } else if (!netif_running(dev))
return 0; return 0;

View File

@ -650,9 +650,19 @@ struct bcmgenet_priv {
struct ethtool_eee eee; struct ethtool_eee eee;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct bcmgenet_priv *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
#define GENET_IO_MACRO(name, offset) \ #define GENET_IO_MACRO(name, offset) \
static inline u32 bcmgenet_##name##_readl(struct bcmgenet_priv *priv, \ static inline u32 bcmgenet_##name##_readl(struct bcmgenet_priv *priv, \
u32 off) \ u32 off) \

View File

@ -105,8 +105,8 @@ void bcmgenet_mii_setup(struct net_device *dev)
if (phydev->link) if (phydev->link)
bcmgenet_mac_config(dev); bcmgenet_mac_config(dev);
if (priv->ecdev) if (get_ecdev(priv))
ecdev_set_link(priv->ecdev, phydev->link); ecdev_set_link(get_ecdev(priv), phydev->link);
phy_print_status(phydev); phy_print_status(phydev);
} }

View File

@ -37,6 +37,10 @@ REV := $(shell if test -s $(TOPDIR)/revision; then \
ifeq (@ENABLE_IGB@,1) ifeq (@ENABLE_IGB@,1)
obj-m += ec_igb.o obj-m += ec_igb.o
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
ec_igb-objs := \ ec_igb-objs := \
e1000_82575-@KERNEL_IGB@-ethercat.o \ e1000_82575-@KERNEL_IGB@-ethercat.o \
e1000_i210-@KERNEL_IGB@-ethercat.o \ e1000_i210-@KERNEL_IGB@-ethercat.o \

View File

@ -670,11 +670,20 @@ struct igb_adapter {
struct vf_mac_filter *vf_mac_list; struct vf_mac_filter *vf_mac_list;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igb_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
/* flags controlling PTP/1588 function */ /* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1) #define IGB_PTP_OVERFLOW_CHECK BIT(1)

View File

@ -670,11 +670,20 @@ struct igb_adapter {
struct vf_mac_filter *vf_mac_list; struct vf_mac_filter *vf_mac_list;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igb_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
/* flags controlling PTP/1588 function */ /* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1) #define IGB_PTP_OVERFLOW_CHECK BIT(1)

View File

@ -672,11 +672,20 @@ struct igb_adapter {
spinlock_t vfs_lock; spinlock_t vfs_lock;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igb_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
/* flags controlling PTP/1588 function */ /* flags controlling PTP/1588 function */
#define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_ENABLED BIT(0)
#define IGB_PTP_OVERFLOW_CHECK BIT(1) #define IGB_PTP_OVERFLOW_CHECK BIT(1)

View File

@ -1047,10 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) { netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
}
} }
static void igb_reset_interrupt_capability(struct igb_adapter *adapter) static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
@ -1221,11 +1218,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
if (!q_vector) if (!q_vector)
return -ENOMEM; return -ENOMEM;
if (!adapter->ecdev) { /* initialize NAPI */
/* initialize NAPI */ netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -6430,6 +6425,9 @@ static int igb_poll(struct napi_struct *napi, int budget)
napi); napi);
bool clean_complete = true; bool clean_complete = true;
if (q_vector->adapter->ecdev)
return -EBUSY;
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);

View File

@ -1037,10 +1037,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) { netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
}
} }
static void igb_reset_interrupt_capability(struct igb_adapter *adapter) static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
@ -1219,11 +1216,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
if (!q_vector) if (!q_vector)
return -ENOMEM; return -ENOMEM;
if (!adapter->ecdev) { /* initialize NAPI */
/* initialize NAPI */ netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -7858,6 +7853,9 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (q_vector->adapter->ecdev)
return -EBUSY;
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);

View File

@ -1047,10 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) { netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
}
} }
static void igb_reset_interrupt_capability(struct igb_adapter *adapter) static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
@ -1227,11 +1224,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
if (!q_vector) if (!q_vector)
return -ENOMEM; return -ENOMEM;
if (!adapter->ecdev) { /* initialize NAPI */
/* initialize NAPI */ netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -6506,6 +6501,9 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (q_vector->adapter->ecdev)
return -EBUSY;
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);

View File

@ -1036,9 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
} }
static void igb_reset_interrupt_capability(struct igb_adapter *adapter) static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
@ -1218,10 +1216,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
return -ENOMEM; return -ENOMEM;
/* initialize NAPI */ /* initialize NAPI */
if (!adapter->ecdev) { netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -6491,7 +6487,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->bytecount = skb->len; first->bytecount = skb->len;
first->gso_segs = 1; first->gso_segs = 1;
if (unlikely(!adapter->ecdev && if (unlikely(!adapter->ecdev &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
@ -8133,6 +8129,10 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (q_vector->adapter->ecdev) {
return -EBUSY;
}
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);
@ -8274,7 +8274,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
q_vector->tx.total_bytes += total_bytes; q_vector->tx.total_bytes += total_bytes;
q_vector->tx.total_packets += total_packets; q_vector->tx.total_packets += total_packets;
if (!adapter->ecdev && if (!adapter->ecdev &&
test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
@ -8926,7 +8926,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
total_packets++; total_packets++;
continue; continue;
} }
/* verify the packet layout is correct */ /* verify the packet layout is correct */
if (igb_cleanup_headers(rx_ring, rx_desc, skb)) { if (igb_cleanup_headers(rx_ring, rx_desc, skb)) {
skb = NULL; skb = NULL;

View File

@ -946,7 +946,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int i, err = 0, vector = 0, free_vector = 0; int i, err = 0, vector = 0, free_vector = 0;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return 0; return 0;
} }
@ -1047,8 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
} }
@ -1229,10 +1228,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
return -ENOMEM; return -ENOMEM;
/* initialize NAPI */ /* initialize NAPI */
if (!adapter->ecdev) { netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -1450,7 +1447,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
igb_assign_vector(adapter->q_vector[0], 0); igb_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGB_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGB_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, igb_intr_msi, 0, err = request_irq(pdev->irq, igb_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -1461,7 +1458,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_HAS_MSI; adapter->flags &= ~IGB_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, err = request_irq(pdev->irq, igb_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -1476,7 +1473,7 @@ request_done:
static void igb_free_irq(struct igb_adapter *adapter) static void igb_free_irq(struct igb_adapter *adapter)
{ {
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
int vector = 0, i; int vector = 0, i;
@ -1516,7 +1513,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
wr32(E1000_IMC, ~0); wr32(E1000_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchronizing IRQs */ /* skip synchronizing IRQs */
return; return;
} }
@ -1538,7 +1535,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
@ -2156,7 +2153,7 @@ int igb_up(struct igb_adapter *adapter)
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -2179,7 +2176,7 @@ int igb_up(struct igb_adapter *adapter)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -2213,7 +2210,7 @@ void igb_down(struct igb_adapter *adapter)
igb_nfc_filter_exit(adapter); igb_nfc_filter_exit(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -2231,7 +2228,7 @@ void igb_down(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -2454,7 +2451,7 @@ void igb_reset(struct igb_adapter *adapter)
break; break;
} }
} }
if (!adapter->ecdev && !netif_running(adapter->netdev)) if (!get_ecdev(adapter) && !netif_running(adapter->netdev))
igb_power_down_link(adapter); igb_power_down_link(adapter);
igb_update_mng_vlan(adapter); igb_update_mng_vlan(adapter);
@ -2918,7 +2915,7 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp) static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{ {
struct igb_adapter *adapter = netdev_priv(dev); struct igb_adapter *adapter = netdev_priv(dev);
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
@ -2987,7 +2984,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n,
int nxmit = 0; int nxmit = 0;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
if (unlikely(test_bit(__IGB_DOWN, &adapter->state))) if (unlikely(test_bit(__IGB_DOWN, &adapter->state)))
@ -3289,6 +3286,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter = netdev_priv(netdev); adapter = netdev_priv(netdev);
adapter->netdev = netdev; adapter->netdev = netdev;
adapter->pdev = pdev; adapter->pdev = pdev;
adapter->ecdev_initialized = 0;
hw = &adapter->hw; hw = &adapter->hw;
hw->back = adapter; hw->back = adapter;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
@ -3576,12 +3574,13 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
igb_get_hw_control(adapter); igb_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -3881,10 +3880,10 @@ static void igb_remove(struct pci_dev *pdev)
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -3921,7 +3920,7 @@ static void igb_remove(struct pci_dev *pdev)
igb_disable_sriov(pdev); igb_disable_sriov(pdev);
#endif #endif
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -4164,8 +4163,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
} }
@ -4193,7 +4192,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(adapter->netdev, err = netif_set_real_num_tx_queues(adapter->netdev,
adapter->num_tx_queues); adapter->num_tx_queues);
@ -4209,7 +4208,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
/* From here on the code is the same as igb_up() */ /* From here on the code is the same as igb_up() */
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -4228,14 +4227,14 @@ static int __igb_open(struct net_device *netdev, bool resuming)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = 1; hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -4484,7 +4483,7 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
rx_ring->next_to_clean = 0; rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0; rx_ring->next_to_use = 0;
if (!adapter->ecdev) if (!get_ecdev(adapter))
rx_ring->xdp_prog = adapter->xdp_prog; rx_ring->xdp_prog = adapter->xdp_prog;
/* XDP RX-queue info */ /* XDP RX-queue info */
@ -4795,7 +4794,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
int reg_idx = ring->reg_idx; int reg_idx = ring->reg_idx;
u32 rxdctl = 0; u32 rxdctl = 0;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
MEM_TYPE_PAGE_SHARED, NULL)); MEM_TYPE_PAGE_SHARED, NULL));
@ -4935,7 +4934,7 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
/* Free all the Tx ring sk_buffs */ /* Free all the Tx ring sk_buffs */
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
} }
@ -6206,7 +6205,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -6223,7 +6222,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -6379,7 +6378,7 @@ dma_error:
DMA_TO_DEVICE); DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0); dma_unmap_len_set(tx_buffer, len, 0);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -6497,7 +6496,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->bytecount = skb->len; first->bytecount = skb->len;
first->gso_segs = 1; first->gso_segs = 1;
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
@ -6536,12 +6535,12 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
cleanup_tx_tstamp: cleanup_tx_tstamp:
if (unlikely(!adapter->ecdev && tx_flags & IGB_TX_FLAGS_TSTAMP)) { if (unlikely(!get_ecdev(adapter) && tx_flags & IGB_TX_FLAGS_TSTAMP)) {
dev_kfree_skb_any(adapter->ptp_tx_skb); dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL; adapter->ptp_tx_skb = NULL;
if (adapter->hw.mac.type == e1000_82576) if (adapter->hw.mac.type == e1000_82576)
@ -8139,6 +8138,10 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter)) {
return -EBUSY;
}
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);
@ -8213,7 +8216,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
total_packets += tx_buffer->gso_segs; total_packets += tx_buffer->gso_segs;
/* free the skb */ /* free the skb */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (tx_buffer->type == IGB_TYPE_SKB) if (tx_buffer->type == IGB_TYPE_SKB)
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
else else
@ -8267,7 +8270,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -8280,7 +8283,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
q_vector->tx.total_bytes += total_bytes; q_vector->tx.total_bytes += total_bytes;
q_vector->tx.total_packets += total_packets; q_vector->tx.total_packets += total_packets;
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
@ -8324,7 +8327,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -8866,9 +8869,9 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt);
pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset; pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, pktbuf, size); ecdev_receive(get_ecdev(adapter), pktbuf, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igb_reuse_rx_page(rx_ring, rx_buffer); igb_reuse_rx_page(rx_ring, rx_buffer);
} else { } else {
@ -8931,7 +8934,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
if (igb_is_non_eop(rx_ring, rx_desc)) if (igb_is_non_eop(rx_ring, rx_desc))
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }

View File

@ -935,7 +935,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int i, err = 0, vector = 0, free_vector = 0; int i, err = 0, vector = 0, free_vector = 0;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return 0; return 0;
} }
@ -1036,8 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
} }
@ -1218,10 +1217,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
return -ENOMEM; return -ENOMEM;
/* initialize NAPI */ /* initialize NAPI */
if (!adapter->ecdev) { netif_napi_add(adapter->netdev, &q_vector->napi,
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
igb_poll, 64);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -1439,7 +1436,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
igb_assign_vector(adapter->q_vector[0], 0); igb_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGB_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGB_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, igb_intr_msi, 0, err = request_irq(pdev->irq, igb_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -1450,7 +1447,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_HAS_MSI; adapter->flags &= ~IGB_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, err = request_irq(pdev->irq, igb_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -1465,7 +1462,7 @@ request_done:
static void igb_free_irq(struct igb_adapter *adapter) static void igb_free_irq(struct igb_adapter *adapter)
{ {
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
int vector = 0, i; int vector = 0, i;
@ -1505,7 +1502,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
wr32(E1000_IMC, ~0); wr32(E1000_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchronizing IRQs */ /* skip synchronizing IRQs */
return; return;
} }
@ -1527,7 +1524,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
@ -2145,7 +2142,7 @@ int igb_up(struct igb_adapter *adapter)
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -2168,7 +2165,7 @@ int igb_up(struct igb_adapter *adapter)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -2202,7 +2199,7 @@ void igb_down(struct igb_adapter *adapter)
igb_nfc_filter_exit(adapter); igb_nfc_filter_exit(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -2220,7 +2217,7 @@ void igb_down(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -2443,7 +2440,7 @@ void igb_reset(struct igb_adapter *adapter)
break; break;
} }
} }
if (!adapter->ecdev && !netif_running(adapter->netdev)) if (!get_ecdev(adapter) && !netif_running(adapter->netdev))
igb_power_down_link(adapter); igb_power_down_link(adapter);
igb_update_mng_vlan(adapter); igb_update_mng_vlan(adapter);
@ -2907,7 +2904,7 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp) static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{ {
struct igb_adapter *adapter = netdev_priv(dev); struct igb_adapter *adapter = netdev_priv(dev);
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
@ -2976,7 +2973,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n,
int nxmit = 0; int nxmit = 0;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
if (unlikely(test_bit(__IGB_DOWN, &adapter->state))) if (unlikely(test_bit(__IGB_DOWN, &adapter->state)))
@ -3278,6 +3275,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter = netdev_priv(netdev); adapter = netdev_priv(netdev);
adapter->netdev = netdev; adapter->netdev = netdev;
adapter->pdev = pdev; adapter->pdev = pdev;
adapter->ecdev_initialized = 0;
hw = &adapter->hw; hw = &adapter->hw;
hw->back = adapter; hw->back = adapter;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
@ -3561,12 +3559,13 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
igb_get_hw_control(adapter); igb_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -3866,10 +3865,10 @@ static void igb_remove(struct pci_dev *pdev)
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -3906,7 +3905,7 @@ static void igb_remove(struct pci_dev *pdev)
igb_disable_sriov(pdev); igb_disable_sriov(pdev);
#endif #endif
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -4149,8 +4148,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
} }
@ -4178,7 +4177,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(adapter->netdev, err = netif_set_real_num_tx_queues(adapter->netdev,
adapter->num_tx_queues); adapter->num_tx_queues);
@ -4194,7 +4193,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
/* From here on the code is the same as igb_up() */ /* From here on the code is the same as igb_up() */
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -4213,14 +4212,14 @@ static int __igb_open(struct net_device *netdev, bool resuming)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = 1; hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -4450,7 +4449,7 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
struct device *dev = rx_ring->dev; struct device *dev = rx_ring->dev;
int size, res; int size, res;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* XDP RX-queue info */ /* XDP RX-queue info */
if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
xdp_rxq_info_unreg(&rx_ring->xdp_rxq); xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
@ -4482,7 +4481,7 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
rx_ring->next_to_clean = 0; rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0; rx_ring->next_to_use = 0;
if (!adapter->ecdev) if (!get_ecdev(adapter))
rx_ring->xdp_prog = adapter->xdp_prog; rx_ring->xdp_prog = adapter->xdp_prog;
return 0; return 0;
@ -4789,7 +4788,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
int reg_idx = ring->reg_idx; int reg_idx = ring->reg_idx;
u32 rxdctl = 0; u32 rxdctl = 0;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
MEM_TYPE_PAGE_SHARED, NULL)); MEM_TYPE_PAGE_SHARED, NULL));
@ -4929,7 +4928,7 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
/* Free all the Tx ring sk_buffs */ /* Free all the Tx ring sk_buffs */
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
} }
@ -6196,7 +6195,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -6213,7 +6212,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -6369,7 +6368,7 @@ dma_error:
DMA_TO_DEVICE); DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0); dma_unmap_len_set(tx_buffer, len, 0);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -6487,7 +6486,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->bytecount = skb->len; first->bytecount = skb->len;
first->gso_segs = 1; first->gso_segs = 1;
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
@ -6526,12 +6525,12 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
cleanup_tx_tstamp: cleanup_tx_tstamp:
if (unlikely(!adapter->ecdev && tx_flags & IGB_TX_FLAGS_TSTAMP)) { if (unlikely(!get_ecdev(adapter) && tx_flags & IGB_TX_FLAGS_TSTAMP)) {
dev_kfree_skb_any(adapter->ptp_tx_skb); dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL; adapter->ptp_tx_skb = NULL;
if (adapter->hw.mac.type == e1000_82576) if (adapter->hw.mac.type == e1000_82576)
@ -8129,6 +8128,10 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter)) {
return -EBUSY;
}
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);
@ -8203,7 +8206,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
total_packets += tx_buffer->gso_segs; total_packets += tx_buffer->gso_segs;
/* free the skb */ /* free the skb */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (tx_buffer->type == IGB_TYPE_SKB) if (tx_buffer->type == IGB_TYPE_SKB)
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
else else
@ -8257,7 +8260,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -8270,7 +8273,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
q_vector->tx.total_bytes += total_bytes; q_vector->tx.total_bytes += total_bytes;
q_vector->tx.total_packets += total_packets; q_vector->tx.total_packets += total_packets;
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
@ -8314,7 +8317,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -8852,9 +8855,9 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt);
pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset; pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, pktbuf, size); ecdev_receive(get_ecdev(adapter), pktbuf, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igb_reuse_rx_page(rx_ring, rx_buffer); igb_reuse_rx_page(rx_ring, rx_buffer);
} else { } else {
@ -8917,11 +8920,11 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
if (igb_is_non_eop(rx_ring, rx_desc)) if (igb_is_non_eop(rx_ring, rx_desc))
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }
/* verify the packet layout is correct */ /* verify the packet layout is correct */
if (igb_cleanup_headers(rx_ring, rx_desc, skb)) { if (igb_cleanup_headers(rx_ring, rx_desc, skb)) {
skb = NULL; skb = NULL;

View File

@ -933,7 +933,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int i, err = 0, vector = 0, free_vector = 0; int i, err = 0, vector = 0, free_vector = 0;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
return 0; return 0;
} }
@ -1034,8 +1034,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
if (q_vector->rx.ring) if (q_vector->rx.ring)
adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL; adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
if (!adapter->ecdev) netif_napi_del(&q_vector->napi);
netif_napi_del(&q_vector->napi);
} }
@ -1220,9 +1219,7 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
return -ENOMEM; return -ENOMEM;
/* initialize NAPI */ /* initialize NAPI */
if (!adapter->ecdev) { netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll);
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll);
}
/* tie q_vector and adapter together */ /* tie q_vector and adapter together */
adapter->q_vector[v_idx] = q_vector; adapter->q_vector[v_idx] = q_vector;
@ -1440,7 +1437,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
igb_assign_vector(adapter->q_vector[0], 0); igb_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGB_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGB_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, igb_intr_msi, 0, err = request_irq(pdev->irq, igb_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -1451,7 +1448,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_HAS_MSI; adapter->flags &= ~IGB_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, err = request_irq(pdev->irq, igb_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -1466,7 +1463,7 @@ request_done:
static void igb_free_irq(struct igb_adapter *adapter) static void igb_free_irq(struct igb_adapter *adapter)
{ {
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
int vector = 0, i; int vector = 0, i;
@ -1506,7 +1503,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
wr32(E1000_IMC, ~0); wr32(E1000_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchronizing IRQs */ /* skip synchronizing IRQs */
return; return;
} }
@ -1528,7 +1525,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) if (get_ecdev(adapter))
return; return;
if (adapter->flags & IGB_FLAG_HAS_MSIX) { if (adapter->flags & IGB_FLAG_HAS_MSIX) {
@ -2146,7 +2143,7 @@ int igb_up(struct igb_adapter *adapter)
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -2169,7 +2166,7 @@ int igb_up(struct igb_adapter *adapter)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -2203,7 +2200,7 @@ void igb_down(struct igb_adapter *adapter)
igb_nfc_filter_exit(adapter); igb_nfc_filter_exit(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -2221,7 +2218,7 @@ void igb_down(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -2469,7 +2466,7 @@ void igb_reset(struct igb_adapter *adapter)
break; break;
} }
} }
if (!adapter->ecdev && !netif_running(adapter->netdev)) if (!get_ecdev(adapter) && !netif_running(adapter->netdev))
igb_power_down_link(adapter); igb_power_down_link(adapter);
igb_update_mng_vlan(adapter); igb_update_mng_vlan(adapter);
@ -2933,7 +2930,7 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp) static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{ {
struct igb_adapter *adapter = netdev_priv(dev); struct igb_adapter *adapter = netdev_priv(dev);
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
@ -3002,7 +2999,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n,
int nxmit = 0; int nxmit = 0;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
return -EBUSY; return -EBUSY;
if (unlikely(test_bit(__IGB_DOWN, &adapter->state))) if (unlikely(test_bit(__IGB_DOWN, &adapter->state)))
@ -3298,6 +3295,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter = netdev_priv(netdev); adapter = netdev_priv(netdev);
adapter->netdev = netdev; adapter->netdev = netdev;
adapter->pdev = pdev; adapter->pdev = pdev;
adapter->ecdev_initialized = 0;
hw = &adapter->hw; hw = &adapter->hw;
hw->back = adapter; hw->back = adapter;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
@ -3580,12 +3578,13 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
igb_get_hw_control(adapter); igb_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = 1;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -3893,10 +3892,10 @@ static void igb_remove(struct pci_dev *pdev)
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -3933,7 +3932,7 @@ static void igb_remove(struct pci_dev *pdev)
igb_disable_sriov(pdev); igb_disable_sriov(pdev);
#endif #endif
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -4179,8 +4178,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} else { } else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
} }
@ -4208,7 +4207,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(adapter->netdev, err = netif_set_real_num_tx_queues(adapter->netdev,
adapter->num_tx_queues); adapter->num_tx_queues);
@ -4224,7 +4223,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
/* From here on the code is the same as igb_up() */ /* From here on the code is the same as igb_up() */
clear_bit(__IGB_DOWN, &adapter->state); clear_bit(__IGB_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&(adapter->q_vector[i]->napi)); napi_enable(&(adapter->q_vector[i]->napi));
} }
@ -4243,14 +4242,14 @@ static int __igb_open(struct net_device *netdev, bool resuming)
wr32(E1000_CTRL_EXT, reg_data); wr32(E1000_CTRL_EXT, reg_data);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = 1; hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -4480,7 +4479,7 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
struct device *dev = rx_ring->dev; struct device *dev = rx_ring->dev;
int size, res; int size, res;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* XDP RX-queue info */ /* XDP RX-queue info */
if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
xdp_rxq_info_unreg(&rx_ring->xdp_rxq); xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
@ -4512,7 +4511,7 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
rx_ring->next_to_clean = 0; rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0; rx_ring->next_to_use = 0;
if (!adapter->ecdev) if (!get_ecdev(adapter))
rx_ring->xdp_prog = adapter->xdp_prog; rx_ring->xdp_prog = adapter->xdp_prog;
return 0; return 0;
@ -4819,7 +4818,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
int reg_idx = ring->reg_idx; int reg_idx = ring->reg_idx;
u32 rxdctl = 0; u32 rxdctl = 0;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
MEM_TYPE_PAGE_SHARED, NULL)); MEM_TYPE_PAGE_SHARED, NULL));
@ -4959,7 +4958,7 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
/* Free all the Tx ring sk_buffs or xdp frames */ /* Free all the Tx ring sk_buffs or xdp frames */
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (tx_buffer->type == IGB_TYPE_SKB) if (tx_buffer->type == IGB_TYPE_SKB)
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
else else
@ -6230,7 +6229,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -6247,7 +6246,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -6403,7 +6402,7 @@ dma_error:
DMA_TO_DEVICE); DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0); dma_unmap_len_set(tx_buffer, len, 0);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -6555,7 +6554,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->bytecount = skb->len; first->bytecount = skb->len;
first->gso_segs = 1; first->gso_segs = 1;
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON &&
@ -6594,12 +6593,12 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
cleanup_tx_tstamp: cleanup_tx_tstamp:
if (unlikely(!adapter->ecdev && tx_flags & IGB_TX_FLAGS_TSTAMP)) { if (unlikely(!get_ecdev(adapter) && tx_flags & IGB_TX_FLAGS_TSTAMP)) {
dev_kfree_skb_any(adapter->ptp_tx_skb); dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL; adapter->ptp_tx_skb = NULL;
if (adapter->hw.mac.type == e1000_82576) if (adapter->hw.mac.type == e1000_82576)
@ -8282,6 +8281,10 @@ static int igb_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter)) {
return -EBUSY;
}
#ifdef CONFIG_IGB_DCA #ifdef CONFIG_IGB_DCA
if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_dca(q_vector); igb_update_dca(q_vector);
@ -8356,7 +8359,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
total_packets += tx_buffer->gso_segs; total_packets += tx_buffer->gso_segs;
/* free the skb */ /* free the skb */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
if (tx_buffer->type == IGB_TYPE_SKB) if (tx_buffer->type == IGB_TYPE_SKB)
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
else else
@ -8410,7 +8413,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -8423,7 +8426,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
q_vector->tx.total_bytes += total_bytes; q_vector->tx.total_bytes += total_bytes;
q_vector->tx.total_packets += total_packets; q_vector->tx.total_packets += total_packets;
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
@ -8467,7 +8470,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -9005,9 +9008,9 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt);
pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset; pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, pktbuf, size); ecdev_receive(get_ecdev(adapter), pktbuf, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igb_reuse_rx_page(rx_ring, rx_buffer); igb_reuse_rx_page(rx_ring, rx_buffer);
} else { } else {
@ -9071,7 +9074,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
if (igb_is_non_eop(rx_ring, rx_desc)) if (igb_is_non_eop(rx_ring, rx_desc))
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }

View File

@ -48,6 +48,10 @@ ifeq (@ENABLE_IGC@,1)
igc_ethtool-@KERNEL_IGC@-ethercat.o \ igc_ethtool-@KERNEL_IGC@-ethercat.o \
igc_nvm-@KERNEL_IGC@-ethercat.o igc_nvm-@KERNEL_IGC@-ethercat.o
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
CFLAGS_igc_main-@KERNEL_IGC@-ethercat.o = -DREV=$(REV) CFLAGS_igc_main-@KERNEL_IGC@-ethercat.o = -DREV=$(REV)
endif endif

View File

@ -249,7 +249,7 @@ struct igc_adapter {
static inline ec_device_t *get_ecdev(struct igc_adapter *adapter) static inline ec_device_t *get_ecdev(struct igc_adapter *adapter)
{ {
#if 0 #ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized); WARN_ON(!adapter->ecdev_initialized);
#endif #endif
return adapter->ecdev_; return adapter->ecdev_;

View File

@ -254,11 +254,20 @@ struct igc_adapter {
} perout[IGC_N_PEROUT]; } perout[IGC_N_PEROUT];
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igc_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
void igc_up(struct igc_adapter *adapter); void igc_up(struct igc_adapter *adapter);
void igc_down(struct igc_adapter *adapter); void igc_down(struct igc_adapter *adapter);
int igc_open(struct net_device *netdev); int igc_open(struct net_device *netdev);

View File

@ -267,11 +267,20 @@ struct igc_adapter {
} perout[IGC_N_PEROUT]; } perout[IGC_N_PEROUT];
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igc_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
void igc_up(struct igc_adapter *adapter); void igc_up(struct igc_adapter *adapter);
void igc_down(struct igc_adapter *adapter); void igc_down(struct igc_adapter *adapter);
int igc_open(struct net_device *netdev); int igc_open(struct net_device *netdev);

View File

@ -282,11 +282,20 @@ struct igc_adapter {
} perout[IGC_N_PEROUT]; } perout[IGC_N_PEROUT];
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct igc_adapter *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
void igc_up(struct igc_adapter *adapter); void igc_up(struct igc_adapter *adapter);
void igc_down(struct igc_adapter *adapter); void igc_down(struct igc_adapter *adapter);
int igc_open(struct net_device *netdev); int igc_open(struct net_device *netdev);

View File

@ -4023,6 +4023,9 @@ static int igc_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter))
return -EBUSY;
if (q_vector->tx.ring) if (q_vector->tx.ring)
clean_complete = igc_clean_tx_irq(q_vector, budget); clean_complete = igc_clean_tx_irq(q_vector, budget);

View File

@ -212,7 +212,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
{ {
struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* skb is reused in EtherCAT TX operation */ /* skb is reused in EtherCAT TX operation */
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
} }
@ -1201,7 +1201,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
{ {
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -1215,7 +1215,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -1413,7 +1413,7 @@ dma_error:
if (dma_unmap_len(tx_buffer, len)) if (dma_unmap_len(tx_buffer, len))
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -1584,7 +1584,7 @@ done:
first->bytecount = skb->len; first->bytecount = skb->len;
first->gso_segs = 1; first->gso_segs = 1;
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
/* FIXME: add support for retrieving timestamps from /* FIXME: add support for retrieving timestamps from
* the other timer registers before skipping the * the other timer registers before skipping the
@ -1623,7 +1623,7 @@ done:
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
@ -2568,10 +2568,10 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
total_packets++; total_packets++;
total_bytes += size; total_bytes += size;
} }
else if (adapter->ecdev) { else if (get_ecdev(adapter)) {
unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, va, size); ecdev_receive(get_ecdev(adapter), va, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igc_reuse_rx_page(rx_ring, rx_buffer); igc_reuse_rx_page(rx_ring, rx_buffer);
} }
@ -2600,7 +2600,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }
@ -2913,7 +2913,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
break; break;
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
} }
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
@ -2956,7 +2956,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -2974,7 +2974,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_xdp_xmit_zc(tx_ring); igc_xdp_xmit_zc(tx_ring);
} }
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
@ -3019,7 +3019,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -3989,7 +3989,7 @@ static void igc_configure_msix(struct igc_adapter *adapter)
*/ */
static void igc_irq_enable(struct igc_adapter *adapter) static void igc_irq_enable(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip enabling interrupts */ /* skip enabling interrupts */
return; return;
} }
@ -4032,7 +4032,7 @@ static void igc_irq_disable(struct igc_adapter *adapter)
wr32(IGC_IMC, ~0); wr32(IGC_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchonizing IRQs */ /* skip synchonizing IRQs */
return; return;
} }
@ -4503,6 +4503,9 @@ static int igc_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter))
return -EBUSY;
if (q_vector->tx.ring) if (q_vector->tx.ring)
clean_complete = igc_clean_tx_irq(q_vector, budget); clean_complete = igc_clean_tx_irq(q_vector, budget);
@ -4794,7 +4797,7 @@ void igc_up(struct igc_adapter *adapter)
igc_configure(adapter); igc_configure(adapter);
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -4807,7 +4810,7 @@ void igc_up(struct igc_adapter *adapter)
rd32(IGC_ICR); rd32(IGC_ICR);
igc_irq_enable(adapter); igc_irq_enable(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -5005,7 +5008,7 @@ void igc_down(struct igc_adapter *adapter)
} }
/* set trans_start so we don't get spurious watchdogs during reset */ /* set trans_start so we don't get spurious watchdogs during reset */
netif_trans_update(netdev); netif_trans_update(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -5025,7 +5028,7 @@ void igc_down(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -5384,7 +5387,7 @@ static int igc_request_msix(struct igc_adapter *adapter)
unsigned int num_q_vectors = adapter->num_q_vectors; unsigned int num_q_vectors = adapter->num_q_vectors;
int i = 0, err = 0, vector = 0, free_vector = 0; int i = 0, err = 0, vector = 0, free_vector = 0;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* avoid requesting MSI-X. */ /* avoid requesting MSI-X. */
return 0; return 0;
} }
@ -5519,13 +5522,13 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link; u32 link;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
link = igc_has_link(adapter); link = igc_has_link(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, link); ecdev_set_link(get_ecdev(adapter), link);
return; return;
} }
@ -5782,7 +5785,7 @@ static irqreturn_t igc_intr(int irq, void *data)
static void igc_free_irq(struct igc_adapter *adapter) static void igc_free_irq(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* no IRQ to free in EtherCAT operation */ /* no IRQ to free in EtherCAT operation */
return; return;
} }
@ -5832,7 +5835,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
igc_assign_vector(adapter->q_vector[0], 0); igc_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGC_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGC_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, &igc_intr_msi, 0, err = request_irq(pdev->irq, &igc_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -5843,7 +5846,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_HAS_MSI; adapter->flags &= ~IGC_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -5885,8 +5888,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -5910,7 +5913,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
if (err) if (err)
@ -5922,7 +5925,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
} }
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -5934,11 +5937,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -6739,12 +6742,13 @@ static int igc_probe(struct pci_dev *pdev,
*/ */
igc_get_hw_control(adapter); igc_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = true;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -6807,10 +6811,10 @@ static void igc_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -6834,7 +6838,7 @@ static void igc_remove(struct pci_dev *pdev)
* would have already happened in close and is redundant. * would have already happened in close and is redundant.
*/ */
igc_release_hw_control(adapter); igc_release_hw_control(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -6859,8 +6863,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake,
u32 ctrl, rctl, status; u32 ctrl, rctl, status;
bool wake; bool wake;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
netif_device_detach(netdev); netif_device_detach(netdev);
@ -7000,8 +7004,8 @@ static int __maybe_unused igc_resume(struct device *dev)
wr32(IGC_WUS, ~0); wr32(IGC_WUS, ~0);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_open(adapter->ecdev); ecdev_open(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
if (!err && netif_running(netdev)) if (!err && netif_running(netdev))

View File

@ -211,7 +211,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
{ {
struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* skb is reused in EtherCAT TX operation */ /* skb is reused in EtherCAT TX operation */
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
} }
@ -1202,7 +1202,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
{ {
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -1216,7 +1216,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -1414,7 +1414,7 @@ dma_error:
if (dma_unmap_len(tx_buffer, len)) if (dma_unmap_len(tx_buffer, len))
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -1593,7 +1593,7 @@ done:
goto out_drop; goto out_drop;
} }
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) && test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) {
/* FIXME: add support for retrieving timestamps from /* FIXME: add support for retrieving timestamps from
@ -1636,7 +1636,7 @@ done:
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
@ -2606,10 +2606,10 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
total_packets++; total_packets++;
total_bytes += size; total_bytes += size;
} }
else if (adapter->ecdev) { else if (get_ecdev(adapter)) {
unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, va, size); ecdev_receive(get_ecdev(adapter), va, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igc_reuse_rx_page(rx_ring, rx_buffer); igc_reuse_rx_page(rx_ring, rx_buffer);
} }
@ -2638,7 +2638,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }
@ -2964,7 +2964,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
break; break;
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
} }
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
@ -3007,7 +3007,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -3025,7 +3025,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_xdp_xmit_zc(tx_ring); igc_xdp_xmit_zc(tx_ring);
} }
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
@ -3070,7 +3070,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -4040,7 +4040,7 @@ static void igc_configure_msix(struct igc_adapter *adapter)
*/ */
static void igc_irq_enable(struct igc_adapter *adapter) static void igc_irq_enable(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip enabling interrupts */ /* skip enabling interrupts */
return; return;
} }
@ -4083,7 +4083,7 @@ static void igc_irq_disable(struct igc_adapter *adapter)
wr32(IGC_IMC, ~0); wr32(IGC_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchonizing IRQs */ /* skip synchonizing IRQs */
return; return;
} }
@ -4554,6 +4554,9 @@ static int igc_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter))
return -EBUSY;
if (q_vector->tx.ring) if (q_vector->tx.ring)
clean_complete = igc_clean_tx_irq(q_vector, budget); clean_complete = igc_clean_tx_irq(q_vector, budget);
@ -4846,7 +4849,7 @@ void igc_up(struct igc_adapter *adapter)
igc_configure(adapter); igc_configure(adapter);
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -4859,7 +4862,7 @@ void igc_up(struct igc_adapter *adapter)
rd32(IGC_ICR); rd32(IGC_ICR);
igc_irq_enable(adapter); igc_irq_enable(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -5058,7 +5061,7 @@ void igc_down(struct igc_adapter *adapter)
} }
/* set trans_start so we don't get spurious watchdogs during reset */ /* set trans_start so we don't get spurious watchdogs during reset */
netif_trans_update(netdev); netif_trans_update(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -5078,7 +5081,7 @@ void igc_down(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -5437,7 +5440,7 @@ static int igc_request_msix(struct igc_adapter *adapter)
unsigned int num_q_vectors = adapter->num_q_vectors; unsigned int num_q_vectors = adapter->num_q_vectors;
int i = 0, err = 0, vector = 0, free_vector = 0; int i = 0, err = 0, vector = 0, free_vector = 0;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* avoid requesting MSI-X. */ /* avoid requesting MSI-X. */
return 0; return 0;
} }
@ -5572,13 +5575,13 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link; u32 link;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
link = igc_has_link(adapter); link = igc_has_link(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, link); ecdev_set_link(get_ecdev(adapter), link);
return; return;
} }
@ -5825,7 +5828,7 @@ static irqreturn_t igc_intr(int irq, void *data)
static void igc_free_irq(struct igc_adapter *adapter) static void igc_free_irq(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* no IRQ to free in EtherCAT operation */ /* no IRQ to free in EtherCAT operation */
return; return;
} }
@ -5875,7 +5878,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
igc_assign_vector(adapter->q_vector[0], 0); igc_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGC_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGC_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, &igc_intr_msi, 0, err = request_irq(pdev->irq, &igc_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -5886,7 +5889,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_HAS_MSI; adapter->flags &= ~IGC_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -5928,8 +5931,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -5953,7 +5956,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
if (err) if (err)
@ -5965,7 +5968,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
} }
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -5977,11 +5980,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -6913,12 +6916,13 @@ static int igc_probe(struct pci_dev *pdev,
*/ */
igc_get_hw_control(adapter); igc_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = true;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -6980,10 +6984,10 @@ static void igc_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -7008,7 +7012,7 @@ static void igc_remove(struct pci_dev *pdev)
* would have already happened in close and is redundant. * would have already happened in close and is redundant.
*/ */
igc_release_hw_control(adapter); igc_release_hw_control(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -7031,8 +7035,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake,
u32 ctrl, rctl, status; u32 ctrl, rctl, status;
bool wake; bool wake;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
netif_device_detach(netdev); netif_device_detach(netdev);
@ -7172,8 +7176,8 @@ static int __maybe_unused igc_resume(struct device *dev)
wr32(IGC_WUS, ~0); wr32(IGC_WUS, ~0);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_open(adapter->ecdev); ecdev_open(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
if (!err && netif_running(netdev)) if (!err && netif_running(netdev))

View File

@ -211,7 +211,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
{ {
struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* skb is reused in EtherCAT TX operation */ /* skb is reused in EtherCAT TX operation */
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
} }
@ -1229,7 +1229,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
{ {
struct net_device *netdev = tx_ring->netdev; struct net_device *netdev = tx_ring->netdev;
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_stop_subqueue(netdev, tx_ring->queue_index); netif_stop_subqueue(netdev, tx_ring->queue_index);
} }
@ -1243,7 +1243,7 @@ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
return -EBUSY; return -EBUSY;
/* A reprieve! */ /* A reprieve! */
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_wake_subqueue(netdev, tx_ring->queue_index); netif_wake_subqueue(netdev, tx_ring->queue_index);
} }
@ -1452,7 +1452,7 @@ dma_error:
if (dma_unmap_len(tx_buffer, len)) if (dma_unmap_len(tx_buffer, len))
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL; tx_buffer->skb = NULL;
} }
@ -1651,7 +1651,7 @@ done:
goto out_drop; goto out_drop;
} }
if (unlikely(!adapter->ecdev && if (unlikely(!get_ecdev(adapter) &&
test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) && test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) {
/* FIXME: add support for retrieving timestamps from /* FIXME: add support for retrieving timestamps from
@ -1692,7 +1692,7 @@ done:
return NETDEV_TX_OK; return NETDEV_TX_OK;
out_drop: out_drop:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
dev_kfree_skb_any(first->skb); dev_kfree_skb_any(first->skb);
first->skb = NULL; first->skb = NULL;
} }
@ -2665,10 +2665,10 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
total_packets++; total_packets++;
total_bytes += size; total_bytes += size;
} }
else if (adapter->ecdev) { else if (get_ecdev(adapter)) {
unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); unsigned int size = le16_to_cpu(rx_desc->wb.upper.length);
ecdev_receive(adapter->ecdev, va, size); ecdev_receive(get_ecdev(adapter), va, size);
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
igc_reuse_rx_page(rx_ring, rx_buffer); igc_reuse_rx_page(rx_ring, rx_buffer);
} }
@ -2697,7 +2697,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
continue; continue;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
total_packets++; total_packets++;
continue; continue;
} }
@ -3027,7 +3027,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
break; break;
case IGC_TX_BUFFER_TYPE_SKB: case IGC_TX_BUFFER_TYPE_SKB:
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
napi_consume_skb(tx_buffer->skb, napi_budget); napi_consume_skb(tx_buffer->skb, napi_budget);
} }
igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
@ -3070,7 +3070,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
budget--; budget--;
} while (likely(budget)); } while (likely(budget));
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netdev_tx_completed_queue(txring_txq(tx_ring), netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes); total_packets, total_bytes);
} }
@ -3088,7 +3088,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
igc_xdp_xmit_zc(tx_ring); igc_xdp_xmit_zc(tx_ring);
} }
if (!adapter->ecdev && if (!get_ecdev(adapter) &&
test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
struct igc_hw *hw = &adapter->hw; struct igc_hw *hw = &adapter->hw;
@ -3133,7 +3133,7 @@ static bool igc_clean_tx_irq(struct igc_q_vector *q_vector, int napi_budget)
} }
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(!adapter->ecdev && total_packets && if (unlikely(!get_ecdev(adapter) && total_packets &&
netif_carrier_ok(tx_ring->netdev) && netif_carrier_ok(tx_ring->netdev) &&
igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) {
/* Make sure that anybody stopping the queue after this /* Make sure that anybody stopping the queue after this
@ -4103,7 +4103,7 @@ static void igc_configure_msix(struct igc_adapter *adapter)
*/ */
static void igc_irq_enable(struct igc_adapter *adapter) static void igc_irq_enable(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip enabling interrupts */ /* skip enabling interrupts */
return; return;
} }
@ -4146,7 +4146,7 @@ static void igc_irq_disable(struct igc_adapter *adapter)
wr32(IGC_IMC, ~0); wr32(IGC_IMC, ~0);
wrfl(); wrfl();
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* skip synchonizing IRQs */ /* skip synchonizing IRQs */
return; return;
} }
@ -4617,6 +4617,9 @@ static int igc_poll(struct napi_struct *napi, int budget)
bool clean_complete = true; bool clean_complete = true;
int work_done = 0; int work_done = 0;
if (get_ecdev(q_vector->adapter))
return -EBUSY;
if (q_vector->tx.ring) if (q_vector->tx.ring)
clean_complete = igc_clean_tx_irq(q_vector, budget); clean_complete = igc_clean_tx_irq(q_vector, budget);
@ -4910,7 +4913,7 @@ void igc_up(struct igc_adapter *adapter)
igc_configure(adapter); igc_configure(adapter);
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -4923,7 +4926,7 @@ void igc_up(struct igc_adapter *adapter)
rd32(IGC_ICR); rd32(IGC_ICR);
igc_irq_enable(adapter); igc_irq_enable(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(adapter->netdev); netif_tx_start_all_queues(adapter->netdev);
/* start the watchdog. */ /* start the watchdog. */
@ -5122,7 +5125,7 @@ void igc_down(struct igc_adapter *adapter)
} }
/* set trans_start so we don't get spurious watchdogs during reset */ /* set trans_start so we don't get spurious watchdogs during reset */
netif_trans_update(netdev); netif_trans_update(netdev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
@ -5142,7 +5145,7 @@ void igc_down(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) { for (i = 0; i < adapter->num_q_vectors; i++) {
if (!adapter->ecdev && adapter->q_vector[i]) { if (!get_ecdev(adapter) && adapter->q_vector[i]) {
napi_synchronize(&adapter->q_vector[i]->napi); napi_synchronize(&adapter->q_vector[i]->napi);
napi_disable(&adapter->q_vector[i]->napi); napi_disable(&adapter->q_vector[i]->napi);
} }
@ -5502,7 +5505,7 @@ static int igc_request_msix(struct igc_adapter *adapter)
unsigned int num_q_vectors = adapter->num_q_vectors; unsigned int num_q_vectors = adapter->num_q_vectors;
int i = 0, err = 0, vector = 0, free_vector = 0; int i = 0, err = 0, vector = 0, free_vector = 0;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* avoid requesting MSI-X. */ /* avoid requesting MSI-X. */
return 0; return 0;
} }
@ -5637,13 +5640,13 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link; u32 link;
int i; int i;
if (adapter->ecdev) if (get_ecdev(adapter))
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
link = igc_has_link(adapter); link = igc_has_link(adapter);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, link); ecdev_set_link(get_ecdev(adapter), link);
return; return;
} }
@ -5890,7 +5893,7 @@ static irqreturn_t igc_intr(int irq, void *data)
static void igc_free_irq(struct igc_adapter *adapter) static void igc_free_irq(struct igc_adapter *adapter)
{ {
if (adapter->ecdev) { if (get_ecdev(adapter)) {
/* no IRQ to free in EtherCAT operation */ /* no IRQ to free in EtherCAT operation */
return; return;
} }
@ -5940,7 +5943,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
igc_assign_vector(adapter->q_vector[0], 0); igc_assign_vector(adapter->q_vector[0], 0);
if (!adapter->ecdev && adapter->flags & IGC_FLAG_HAS_MSI) { if (!get_ecdev(adapter) && adapter->flags & IGC_FLAG_HAS_MSI) {
err = request_irq(pdev->irq, &igc_intr_msi, 0, err = request_irq(pdev->irq, &igc_intr_msi, 0,
netdev->name, adapter); netdev->name, adapter);
if (!err) if (!err)
@ -5951,7 +5954,7 @@ static int igc_request_irq(struct igc_adapter *adapter)
adapter->flags &= ~IGC_FLAG_HAS_MSI; adapter->flags &= ~IGC_FLAG_HAS_MSI;
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED,
netdev->name, adapter); netdev->name, adapter);
@ -5993,8 +5996,8 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_set_link(adapter->ecdev, 0); ecdev_set_link(get_ecdev(adapter), 0);
} }
else { else {
netif_carrier_off(netdev); netif_carrier_off(netdev);
@ -6018,7 +6021,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (err) if (err)
goto err_req_irq; goto err_req_irq;
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* Notify the stack of the actual queue counts. */ /* Notify the stack of the actual queue counts. */
err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
if (err) if (err)
@ -6030,7 +6033,7 @@ static int __igc_open(struct net_device *netdev, bool resuming)
} }
clear_bit(__IGC_DOWN, &adapter->state); clear_bit(__IGC_DOWN, &adapter->state);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
for (i = 0; i < adapter->num_q_vectors; i++) for (i = 0; i < adapter->num_q_vectors; i++)
napi_enable(&adapter->q_vector[i]->napi); napi_enable(&adapter->q_vector[i]->napi);
} }
@ -6042,11 +6045,11 @@ static int __igc_open(struct net_device *netdev, bool resuming)
if (!resuming) if (!resuming)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
} }
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
/* start the watchdog. */ /* start the watchdog. */
hw->mac.get_link_status = true; hw->mac.get_link_status = true;
schedule_work(&adapter->watchdog_task); schedule_work(&adapter->watchdog_task);
@ -7053,12 +7056,13 @@ static int igc_probe(struct pci_dev *pdev,
*/ */
igc_get_hw_control(adapter); igc_get_hw_control(adapter);
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) { adapter->ecdev_initialized = true;
if (get_ecdev(adapter)) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev); err = ecdev_open(get_ecdev(adapter));
if (err) { if (err) {
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
goto err_register; goto err_register;
} }
adapter->ec_watchdog_jiffies = jiffies; adapter->ec_watchdog_jiffies = jiffies;
@ -7120,10 +7124,10 @@ static void igc_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct igc_adapter *adapter = netdev_priv(netdev); struct igc_adapter *adapter = netdev_priv(netdev);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
irq_work_sync(&adapter->ec_watchdog_kicker); irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev); ecdev_withdraw(get_ecdev(adapter));
} }
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
@ -7148,7 +7152,7 @@ static void igc_remove(struct pci_dev *pdev)
* would have already happened in close and is redundant. * would have already happened in close and is redundant.
*/ */
igc_release_hw_control(adapter); igc_release_hw_control(adapter);
if (!adapter->ecdev) { if (!get_ecdev(adapter)) {
unregister_netdev(netdev); unregister_netdev(netdev);
} }
@ -7171,8 +7175,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake,
u32 ctrl, rctl, status; u32 ctrl, rctl, status;
bool wake; bool wake;
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_close(adapter->ecdev); ecdev_close(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
netif_device_detach(netdev); netif_device_detach(netdev);
@ -7312,8 +7316,8 @@ static int __maybe_unused igc_resume(struct device *dev)
wr32(IGC_WUS, ~0); wr32(IGC_WUS, ~0);
if (adapter->ecdev) { if (get_ecdev(adapter)) {
ecdev_open(adapter->ecdev); ecdev_open(get_ecdev(adapter));
} else { } else {
rtnl_lock(); rtnl_lock();
if (!err && netif_running(netdev)) if (!err && netif_running(netdev))

View File

@ -41,6 +41,10 @@ ifeq (@R8169_IN_SUBDIR@,1)
r8169_phy_config-@KERNEL_R8169@-ethercat.o r8169_phy_config-@KERNEL_R8169@-ethercat.o
CFLAGS_r8169_main-@KERNEL_R8169@-ethercat.o = -DREV=$(REV) CFLAGS_r8169_main-@KERNEL_R8169@-ethercat.o = -DREV=$(REV)
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
endif endif
endif endif

View File

@ -652,11 +652,20 @@ struct rtl8169_private {
u32 ocp_base; u32 ocp_base;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct rtl8169_private *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@ -1329,7 +1338,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp)
static void rtl_irq_enable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp)
{ {
if (tp->ecdev) if (get_ecdev(tp))
return; return;
if (rtl_is_8125(tp)) if (rtl_is_8125(tp))
RTL_W32(tp, IntrMask_8125, tp->irq_mask); RTL_W32(tp, IntrMask_8125, tp->irq_mask);
@ -2231,7 +2240,7 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp)
static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
{ {
set_bit(flag, tp->wk.flags); set_bit(flag, tp->wk.flags);
if (!tp->ecdev) if (!get_ecdev(tp))
schedule_work(&tp->wk.work); schedule_work(&tp->wk.work);
} }
@ -3973,7 +3982,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
struct sk_buff *skb = tx_skb->skb; struct sk_buff *skb = tx_skb->skb;
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
if (!tp->ecdev && skb) if (!get_ecdev(tp) && skb)
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
} }
@ -3982,13 +3991,13 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
static void rtl8169_tx_clear(struct rtl8169_private *tp) static void rtl8169_tx_clear(struct rtl8169_private *tp)
{ {
rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
if (!tp->ecdev) if (!get_ecdev(tp))
netdev_reset_queue(tp->dev); netdev_reset_queue(tp->dev);
} }
static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down) static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
{ {
if (!tp->ecdev) if (!get_ecdev(tp))
napi_disable(&tp->napi); napi_disable(&tp->napi);
/* Give a racing hard_start_xmit a few cycles to complete. */ /* Give a racing hard_start_xmit a few cycles to complete. */
@ -4032,7 +4041,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
{ {
int i; int i;
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(tp->dev); netif_stop_queue(tp->dev);
rtl8169_cleanup(tp, false); rtl8169_cleanup(tp, false);
@ -4040,7 +4049,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
for (i = 0; i < NUM_RX_DESC; i++) for (i = 0; i < NUM_RX_DESC; i++)
rtl8169_mark_to_asic(tp->RxDescArray + i); rtl8169_mark_to_asic(tp->RxDescArray + i);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
rtl_hw_start(tp); rtl_hw_start(tp);
} }
@ -4329,7 +4338,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
/* Force memory writes to complete before releasing descriptor */ /* Force memory writes to complete before releasing descriptor */
dma_wmb(); dma_wmb();
door_bell = tp->ecdev || __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); door_bell = get_ecdev(tp) || __netdev_sent_queue(dev, skb->len, netdev_xmit_more());
txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag);
@ -4338,7 +4347,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1); WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp);
if (unlikely(stop_queue)) { if (unlikely(stop_queue)) {
/* Avoid wrongly optimistic queue wake-up: rtl_tx thread must /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
* not miss a ring update when it notices a stopped queue. * not miss a ring update when it notices a stopped queue.
@ -4366,13 +4375,13 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
err_dma_1: err_dma_1:
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
err_dma_0: err_dma_0:
if (!tp->ecdev) if (!get_ecdev(tp))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
err_stop_0: err_stop_0:
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
@ -4479,14 +4488,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
if (skb) { if (skb) {
pkts_compl++; pkts_compl++;
bytes_compl += skb->len; bytes_compl += skb->len;
if (!tp->ecdev) if (!get_ecdev(tp))
napi_consume_skb(skb, budget); napi_consume_skb(skb, budget);
} }
dirty_tx++; dirty_tx++;
} }
if (tp->dirty_tx != dirty_tx) { if (tp->dirty_tx != dirty_tx) {
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netdev_completed_queue(dev, pkts_compl, bytes_compl); netdev_completed_queue(dev, pkts_compl, bytes_compl);
dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl); dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl);
} }
@ -4499,7 +4508,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
* ring status. * ring status.
*/ */
smp_store_mb(tp->dirty_tx, dirty_tx); smp_store_mb(tp->dirty_tx, dirty_tx);
if (!tp->ecdev && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp)) if (!get_ecdev(tp) && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp))
netif_wake_queue(dev); netif_wake_queue(dev);
/* /*
* 8168 hack: TxPoll requests are lost when the Tx packets are * 8168 hack: TxPoll requests are lost when the Tx packets are
@ -4581,7 +4590,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
goto release_descriptor; goto release_descriptor;
} }
if (!tp->ecdev) { if (!get_ecdev(tp)) {
skb = napi_alloc_skb(&tp->napi, pkt_size); skb = napi_alloc_skb(&tp->napi, pkt_size);
if (unlikely(!skb)) { if (unlikely(!skb)) {
dev->stats.rx_dropped++; dev->stats.rx_dropped++;
@ -4596,8 +4605,8 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
prefetch(rx_buf); prefetch(rx_buf);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_receive(tp->ecdev, rx_buf, pkt_size); ecdev_receive(get_ecdev(tp), rx_buf, pkt_size);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
@ -4610,7 +4619,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
} }
dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rtl8169_rx_csum(skb, status); rtl8169_rx_csum(skb, status);
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
@ -4756,7 +4765,7 @@ static void rtl8169_up(struct rtl8169_private *tp)
phy_init_hw(tp->phydev); phy_init_hw(tp->phydev);
phy_resume(tp->phydev); phy_resume(tp->phydev);
rtl8169_init_phy(tp); rtl8169_init_phy(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
rtl_reset_work(tp); rtl_reset_work(tp);
@ -4771,14 +4780,14 @@ static int rtl8169_close(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
rtl8169_down(tp); rtl8169_down(tp);
rtl8169_rx_clear(tp); rtl8169_rx_clear(tp);
cancel_work_sync(&tp->wk.work); cancel_work_sync(&tp->wk.work);
if (!tp->ecdev) if (!get_ecdev(tp))
free_irq(pci_irq_vector(pdev, 0), tp); free_irq(pci_irq_vector(pdev, 0), tp);
phy_disconnect(tp->phydev); phy_disconnect(tp->phydev);
@ -4834,7 +4843,7 @@ static int rtl_open(struct net_device *dev)
rtl_request_firmware(tp); rtl_request_firmware(tp);
irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED; irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt, retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt,
irqflags, dev->name, tp); irqflags, dev->name, tp);
if (retval < 0) if (retval < 0)
@ -4847,10 +4856,10 @@ static int rtl_open(struct net_device *dev)
rtl8169_up(tp); rtl8169_up(tp);
rtl8169_init_counter_offsets(tp); rtl8169_init_counter_offsets(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_start_queue(dev); netif_start_queue(dev);
else else
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
out: out:
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
@ -4936,7 +4945,7 @@ static int rtl8169_runtime_resume(struct device *dev)
static int __maybe_unused rtl8169_suspend(struct device *device) static int __maybe_unused rtl8169_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4952,7 +4961,7 @@ static int __maybe_unused rtl8169_suspend(struct device *device)
static int __maybe_unused rtl8169_resume(struct device *device) static int __maybe_unused rtl8169_resume(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4969,7 +4978,7 @@ static int __maybe_unused rtl8169_resume(struct device *device)
static int rtl8169_runtime_suspend(struct device *device) static int rtl8169_runtime_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -5048,10 +5057,10 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_close(tp->ecdev); ecdev_close(get_ecdev(tp));
irq_work_sync(&tp->ec_watchdog_kicker); irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
} else { } else {
unregister_netdev(tp->dev); unregister_netdev(tp->dev);
} }
@ -5361,7 +5370,7 @@ static void ec_poll(struct net_device *dev)
u16 status = rtl_get_events(tp); u16 status = rtl_get_events(tp);
if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) { if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) {
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
} }
@ -5394,6 +5403,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl_netdev_ops; dev->netdev_ops = &rtl_netdev_ops;
tp = netdev_priv(dev); tp = netdev_priv(dev);
tp->ecdev_initialized = false;
tp->dev = dev; tp->dev = dev;
tp->pci_dev = pdev; tp->pci_dev = pdev;
tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
@ -5550,10 +5560,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
return rc; return rc;
tp->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); tp->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE);
tp->ecdev_initialized = true;
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rc = register_netdev(dev); rc = register_netdev(dev);
if (rc) if (rc)
return rc; return rc;
@ -5576,11 +5587,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev); rc = ecdev_open(get_ecdev(tp));
if (rc) { if (rc) {
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
return rc; return rc;
} }
} }

View File

@ -640,11 +640,20 @@ struct rtl8169_private {
u32 ocp_base; u32 ocp_base;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct rtl8169_private *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@ -1317,7 +1326,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp)
static void rtl_irq_enable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp)
{ {
if (tp->ecdev) if (get_ecdev(tp))
return; return;
if (rtl_is_8125(tp)) if (rtl_is_8125(tp))
RTL_W32(tp, IntrMask_8125, tp->irq_mask); RTL_W32(tp, IntrMask_8125, tp->irq_mask);
@ -2203,7 +2212,7 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp)
static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
{ {
set_bit(flag, tp->wk.flags); set_bit(flag, tp->wk.flags);
if (!tp->ecdev) if (!get_ecdev(tp))
schedule_work(&tp->wk.work); schedule_work(&tp->wk.work);
} }
@ -3966,7 +3975,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
struct sk_buff *skb = tx_skb->skb; struct sk_buff *skb = tx_skb->skb;
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
if (!tp->ecdev && skb) if (!get_ecdev(tp) && skb)
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
} }
@ -3975,13 +3984,13 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
static void rtl8169_tx_clear(struct rtl8169_private *tp) static void rtl8169_tx_clear(struct rtl8169_private *tp)
{ {
rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
if (!tp->ecdev) if (!get_ecdev(tp))
netdev_reset_queue(tp->dev); netdev_reset_queue(tp->dev);
} }
static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down) static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down)
{ {
if (!tp->ecdev) if (!get_ecdev(tp))
napi_disable(&tp->napi); napi_disable(&tp->napi);
/* Give a racing hard_start_xmit a few cycles to complete. */ /* Give a racing hard_start_xmit a few cycles to complete. */
@ -4025,7 +4034,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
{ {
int i; int i;
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(tp->dev); netif_stop_queue(tp->dev);
rtl8169_cleanup(tp, false); rtl8169_cleanup(tp, false);
@ -4033,7 +4042,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
for (i = 0; i < NUM_RX_DESC; i++) for (i = 0; i < NUM_RX_DESC; i++)
rtl8169_mark_to_asic(tp->RxDescArray + i); rtl8169_mark_to_asic(tp->RxDescArray + i);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
rtl_hw_start(tp); rtl_hw_start(tp);
} }
@ -4322,7 +4331,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
/* Force memory writes to complete before releasing descriptor */ /* Force memory writes to complete before releasing descriptor */
dma_wmb(); dma_wmb();
door_bell = tp->ecdev || __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); door_bell = get_ecdev(tp) || __netdev_sent_queue(dev, skb->len, netdev_xmit_more());
txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag);
@ -4331,7 +4340,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1); WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp);
if (unlikely(stop_queue)) { if (unlikely(stop_queue)) {
/* Avoid wrongly optimistic queue wake-up: rtl_tx thread must /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
* not miss a ring update when it notices a stopped queue. * not miss a ring update when it notices a stopped queue.
@ -4359,13 +4368,13 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
err_dma_1: err_dma_1:
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
err_dma_0: err_dma_0:
if (!tp->ecdev) if (!get_ecdev(tp))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
err_stop_0: err_stop_0:
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
@ -4472,14 +4481,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
if (skb) { if (skb) {
pkts_compl++; pkts_compl++;
bytes_compl += skb->len; bytes_compl += skb->len;
if (!tp->ecdev) if (!get_ecdev(tp))
napi_consume_skb(skb, budget); napi_consume_skb(skb, budget);
} }
dirty_tx++; dirty_tx++;
} }
if (tp->dirty_tx != dirty_tx) { if (tp->dirty_tx != dirty_tx) {
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netdev_completed_queue(dev, pkts_compl, bytes_compl); netdev_completed_queue(dev, pkts_compl, bytes_compl);
dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl); dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl);
} }
@ -4492,7 +4501,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
* ring status. * ring status.
*/ */
smp_store_mb(tp->dirty_tx, dirty_tx); smp_store_mb(tp->dirty_tx, dirty_tx);
if (!tp->ecdev && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp)) if (!get_ecdev(tp) && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp))
netif_wake_queue(dev); netif_wake_queue(dev);
/* /*
* 8168 hack: TxPoll requests are lost when the Tx packets are * 8168 hack: TxPoll requests are lost when the Tx packets are
@ -4574,7 +4583,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
goto release_descriptor; goto release_descriptor;
} }
if (!tp->ecdev) { if (!get_ecdev(tp)) {
skb = napi_alloc_skb(&tp->napi, pkt_size); skb = napi_alloc_skb(&tp->napi, pkt_size);
if (unlikely(!skb)) { if (unlikely(!skb)) {
dev->stats.rx_dropped++; dev->stats.rx_dropped++;
@ -4589,8 +4598,8 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
prefetch(rx_buf); prefetch(rx_buf);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_receive(tp->ecdev, rx_buf, pkt_size); ecdev_receive(get_ecdev(tp), rx_buf, pkt_size);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
@ -4603,7 +4612,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
} }
dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rtl8169_rx_csum(skb, status); rtl8169_rx_csum(skb, status);
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
@ -4749,7 +4758,7 @@ static void rtl8169_up(struct rtl8169_private *tp)
phy_init_hw(tp->phydev); phy_init_hw(tp->phydev);
phy_resume(tp->phydev); phy_resume(tp->phydev);
rtl8169_init_phy(tp); rtl8169_init_phy(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
rtl_reset_work(tp); rtl_reset_work(tp);
@ -4764,14 +4773,14 @@ static int rtl8169_close(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
rtl8169_down(tp); rtl8169_down(tp);
rtl8169_rx_clear(tp); rtl8169_rx_clear(tp);
cancel_work_sync(&tp->wk.work); cancel_work_sync(&tp->wk.work);
if (!tp->ecdev) if (!get_ecdev(tp))
free_irq(pci_irq_vector(pdev, 0), tp); free_irq(pci_irq_vector(pdev, 0), tp);
phy_disconnect(tp->phydev); phy_disconnect(tp->phydev);
@ -4827,7 +4836,7 @@ static int rtl_open(struct net_device *dev)
rtl_request_firmware(tp); rtl_request_firmware(tp);
irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED; irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt, retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt,
irqflags, dev->name, tp); irqflags, dev->name, tp);
if (retval < 0) if (retval < 0)
@ -4840,10 +4849,10 @@ static int rtl_open(struct net_device *dev)
rtl8169_up(tp); rtl8169_up(tp);
rtl8169_init_counter_offsets(tp); rtl8169_init_counter_offsets(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_start_queue(dev); netif_start_queue(dev);
else else
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
out: out:
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
@ -4929,7 +4938,7 @@ static int rtl8169_runtime_resume(struct device *dev)
static int __maybe_unused rtl8169_suspend(struct device *device) static int __maybe_unused rtl8169_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4945,7 +4954,7 @@ static int __maybe_unused rtl8169_suspend(struct device *device)
static int __maybe_unused rtl8169_resume(struct device *device) static int __maybe_unused rtl8169_resume(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4962,7 +4971,7 @@ static int __maybe_unused rtl8169_resume(struct device *device)
static int rtl8169_runtime_suspend(struct device *device) static int rtl8169_runtime_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -5041,10 +5050,10 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_close(tp->ecdev); ecdev_close(get_ecdev(tp));
irq_work_sync(&tp->ec_watchdog_kicker); irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
} else { } else {
unregister_netdev(tp->dev); unregister_netdev(tp->dev);
} }
@ -5348,7 +5357,7 @@ static void ec_poll(struct net_device *dev)
u16 status = rtl_get_events(tp); u16 status = rtl_get_events(tp);
if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) { if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) {
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
} }
@ -5381,6 +5390,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl_netdev_ops; dev->netdev_ops = &rtl_netdev_ops;
tp = netdev_priv(dev); tp = netdev_priv(dev);
tp->ecdev_initialized = false;
tp->dev = dev; tp->dev = dev;
tp->pci_dev = pdev; tp->pci_dev = pdev;
tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
@ -5536,10 +5546,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
return rc; return rc;
tp->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); tp->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE);
tp->ecdev_initialized = true;
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rc = register_netdev(dev); rc = register_netdev(dev);
if (rc) if (rc)
return rc; return rc;
@ -5562,11 +5573,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev); rc = ecdev_open(get_ecdev(tp));
if (rc) { if (rc) {
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
return rc; return rc;
} }
} }

View File

@ -629,11 +629,20 @@ struct rtl8169_private {
u32 ocp_base; u32 ocp_base;
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct rtl8169_private *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@ -1269,7 +1278,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp)
static void rtl_irq_enable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp)
{ {
if (tp->ecdev) if (get_ecdev(tp))
return; return;
if (rtl_is_8125(tp)) if (rtl_is_8125(tp))
RTL_W32(tp, IntrMask_8125, tp->irq_mask); RTL_W32(tp, IntrMask_8125, tp->irq_mask);
@ -2159,7 +2168,7 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp)
static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
{ {
set_bit(flag, tp->wk.flags); set_bit(flag, tp->wk.flags);
if (!tp->ecdev) if (!get_ecdev(tp))
schedule_work(&tp->wk.work); schedule_work(&tp->wk.work);
} }
@ -3871,7 +3880,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
struct sk_buff *skb = tx_skb->skb; struct sk_buff *skb = tx_skb->skb;
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
if (!tp->ecdev && skb) if (!get_ecdev(tp) && skb)
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
} }
@ -3880,13 +3889,13 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
static void rtl8169_tx_clear(struct rtl8169_private *tp) static void rtl8169_tx_clear(struct rtl8169_private *tp)
{ {
rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
if (!tp->ecdev) if (!get_ecdev(tp))
netdev_reset_queue(tp->dev); netdev_reset_queue(tp->dev);
} }
static void rtl8169_cleanup(struct rtl8169_private *tp) static void rtl8169_cleanup(struct rtl8169_private *tp)
{ {
if (!tp->ecdev) if (!get_ecdev(tp))
napi_disable(&tp->napi); napi_disable(&tp->napi);
/* Give a racing hard_start_xmit a few cycles to complete. */ /* Give a racing hard_start_xmit a few cycles to complete. */
@ -3926,7 +3935,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
{ {
int i; int i;
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(tp->dev); netif_stop_queue(tp->dev);
rtl8169_cleanup(tp); rtl8169_cleanup(tp);
@ -3934,7 +3943,7 @@ static void rtl_reset_work(struct rtl8169_private *tp)
for (i = 0; i < NUM_RX_DESC; i++) for (i = 0; i < NUM_RX_DESC; i++)
rtl8169_mark_to_asic(tp->RxDescArray + i); rtl8169_mark_to_asic(tp->RxDescArray + i);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
rtl_hw_start(tp); rtl_hw_start(tp);
} }
@ -4221,7 +4230,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
/* Force memory writes to complete before releasing descriptor */ /* Force memory writes to complete before releasing descriptor */
dma_wmb(); dma_wmb();
door_bell = tp->ecdev || __netdev_sent_queue(dev, skb->len, netdev_xmit_more()); door_bell = get_ecdev(tp) || __netdev_sent_queue(dev, skb->len, netdev_xmit_more());
txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag); txd_first->opts1 |= cpu_to_le32(DescOwn | FirstFrag);
@ -4230,7 +4239,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1); WRITE_ONCE(tp->cur_tx, tp->cur_tx + frags + 1);
stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp);
if (unlikely(stop_queue)) { if (unlikely(stop_queue)) {
/* Avoid wrongly optimistic queue wake-up: rtl_tx thread must /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
* not miss a ring update when it notices a stopped queue. * not miss a ring update when it notices a stopped queue.
@ -4258,13 +4267,13 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
err_dma_1: err_dma_1:
rtl8169_unmap_tx_skb(tp, entry); rtl8169_unmap_tx_skb(tp, entry);
err_dma_0: err_dma_0:
if (!tp->ecdev) if (!get_ecdev(tp))
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
err_stop_0: err_stop_0:
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
@ -4370,14 +4379,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
if (skb) { if (skb) {
pkts_compl++; pkts_compl++;
bytes_compl += skb->len; bytes_compl += skb->len;
if (!tp->ecdev) if (!get_ecdev(tp))
napi_consume_skb(skb, budget); napi_consume_skb(skb, budget);
} }
dirty_tx++; dirty_tx++;
} }
if (tp->dirty_tx != dirty_tx) { if (tp->dirty_tx != dirty_tx) {
if (!tp->ecdev) { if (!get_ecdev(tp)) {
netdev_completed_queue(dev, pkts_compl, bytes_compl); netdev_completed_queue(dev, pkts_compl, bytes_compl);
dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl); dev_sw_netstats_tx_add(dev, pkts_compl, bytes_compl);
} }
@ -4390,7 +4399,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp,
* ring status. * ring status.
*/ */
smp_store_mb(tp->dirty_tx, dirty_tx); smp_store_mb(tp->dirty_tx, dirty_tx);
if (!tp->ecdev && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp)) if (!get_ecdev(tp) && netif_queue_stopped(dev) && rtl_tx_slots_avail(tp))
netif_wake_queue(dev); netif_wake_queue(dev);
/* /*
* 8168 hack: TxPoll requests are lost when the Tx packets are * 8168 hack: TxPoll requests are lost when the Tx packets are
@ -4472,7 +4481,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
goto release_descriptor; goto release_descriptor;
} }
if (!tp->ecdev) { if (!get_ecdev(tp)) {
skb = napi_alloc_skb(&tp->napi, pkt_size); skb = napi_alloc_skb(&tp->napi, pkt_size);
if (unlikely(!skb)) { if (unlikely(!skb)) {
dev->stats.rx_dropped++; dev->stats.rx_dropped++;
@ -4487,8 +4496,8 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
prefetch(rx_buf); prefetch(rx_buf);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_receive(tp->ecdev, rx_buf, pkt_size); ecdev_receive(get_ecdev(tp), rx_buf, pkt_size);
// No need to detect link status as // No need to detect link status as
// long as frames are received: Reset watchdog. // long as frames are received: Reset watchdog.
@ -4501,7 +4510,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget
} }
dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rtl8169_rx_csum(skb, status); rtl8169_rx_csum(skb, status);
skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, dev);
@ -4647,7 +4656,7 @@ static void rtl8169_up(struct rtl8169_private *tp)
phy_init_hw(tp->phydev); phy_init_hw(tp->phydev);
phy_resume(tp->phydev); phy_resume(tp->phydev);
rtl8169_init_phy(tp); rtl8169_init_phy(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
napi_enable(&tp->napi); napi_enable(&tp->napi);
set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
rtl_reset_work(tp); rtl_reset_work(tp);
@ -4662,14 +4671,14 @@ static int rtl8169_close(struct net_device *dev)
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_stop_queue(dev); netif_stop_queue(dev);
rtl8169_down(tp); rtl8169_down(tp);
rtl8169_rx_clear(tp); rtl8169_rx_clear(tp);
cancel_work_sync(&tp->wk.work); cancel_work_sync(&tp->wk.work);
if (!tp->ecdev) if (!get_ecdev(tp))
free_irq(tp->irq, tp); free_irq(tp->irq, tp);
phy_disconnect(tp->phydev); phy_disconnect(tp->phydev);
@ -4725,7 +4734,7 @@ static int rtl_open(struct net_device *dev)
rtl_request_firmware(tp); rtl_request_firmware(tp);
irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED; irqflags = pci_dev_msi_enabled(pdev) ? IRQF_NO_THREAD : IRQF_SHARED;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
retval = request_irq(tp->irq, rtl8169_interrupt, irqflags, retval = request_irq(tp->irq, rtl8169_interrupt, irqflags,
dev->name, tp); dev->name, tp);
if (retval < 0) if (retval < 0)
@ -4738,10 +4747,10 @@ static int rtl_open(struct net_device *dev)
rtl8169_up(tp); rtl8169_up(tp);
rtl8169_init_counter_offsets(tp); rtl8169_init_counter_offsets(tp);
if (!tp->ecdev) if (!get_ecdev(tp))
netif_start_queue(dev); netif_start_queue(dev);
else else
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
out: out:
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
@ -4825,7 +4834,7 @@ static int rtl8169_runtime_resume(struct device *dev)
static int rtl8169_suspend(struct device *device) static int rtl8169_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4841,7 +4850,7 @@ static int rtl8169_suspend(struct device *device)
static int rtl8169_resume(struct device *device) static int rtl8169_resume(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4858,7 +4867,7 @@ static int rtl8169_resume(struct device *device)
static int rtl8169_runtime_suspend(struct device *device) static int rtl8169_runtime_suspend(struct device *device)
{ {
struct rtl8169_private *tp = dev_get_drvdata(device); struct rtl8169_private *tp = dev_get_drvdata(device);
if (tp->ecdev) { if (get_ecdev(tp)) {
return -EBUSY; return -EBUSY;
} }
@ -4919,10 +4928,10 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
ecdev_close(tp->ecdev); ecdev_close(get_ecdev(tp));
irq_work_sync(&tp->ec_watchdog_kicker); irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
} else { } else {
unregister_netdev(tp->dev); unregister_netdev(tp->dev);
} }
@ -5206,7 +5215,7 @@ static void ec_poll(struct net_device *dev)
u16 status = rtl_get_events(tp); u16 status = rtl_get_events(tp);
if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) { if (jiffies - tp->ec_watchdog_jiffies >= 2 * HZ) {
ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev));
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
} }
@ -5239,6 +5248,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl_netdev_ops; dev->netdev_ops = &rtl_netdev_ops;
tp = netdev_priv(dev); tp = netdev_priv(dev);
tp->ecdev_initialized = false;
tp->dev = dev; tp->dev = dev;
tp->pci_dev = pdev; tp->pci_dev = pdev;
tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
@ -5401,10 +5411,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) if (rc)
return rc; return rc;
tp->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); tp->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE);
tp->ecdev_initialized = true;
tp->ec_watchdog_jiffies = jiffies; tp->ec_watchdog_jiffies = jiffies;
if (!tp->ecdev) { if (!get_ecdev(tp)) {
rc = register_netdev(dev); rc = register_netdev(dev);
if (rc) if (rc)
return rc; return rc;
@ -5426,11 +5437,11 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev)) if (pci_dev_run_wake(pdev))
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) { if (get_ecdev(tp)) {
rc = ecdev_open(get_ecdev(tp));
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) { if (rc) {
ecdev_withdraw(tp->ecdev); ecdev_withdraw(get_ecdev(tp));
return rc; return rc;
} }
} }

View File

@ -39,6 +39,9 @@ REV := $(shell if test -s $(TOPDIR)/revision; then \
git -C $(TOPDIR) describe 2>/dev/null || echo "unknown"; \ git -C $(TOPDIR) describe 2>/dev/null || echo "unknown"; \
fi) fi)
ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1)
ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING
endif
ifeq (@ENABLE_STMMAC@,1) ifeq (@ENABLE_STMMAC@,1)
EC_STMMAC_OBJS := \ EC_STMMAC_OBJS := \

View File

@ -333,11 +333,20 @@ struct stmmac_priv {
struct bpf_prog *xdp_prog; struct bpf_prog *xdp_prog;
/* EtherCAT device variables */ /* EtherCAT device variables */
ec_device_t *ecdev; ec_device_t *ecdev_;
unsigned long ec_watchdog_jiffies; unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker; struct irq_work ec_watchdog_kicker;
bool ecdev_initialized;
}; };
static inline ec_device_t *get_ecdev(struct stmmac_priv *adapter)
{
#ifdef EC_ENABLE_DRIVER_RESOURCE_VERIFYING
WARN_ON(!adapter->ecdev_initialized);
#endif
return adapter->ecdev_;
}
enum stmmac_state { enum stmmac_state {
STMMAC_DOWN, STMMAC_DOWN,
STMMAC_RESET_REQUESTED, STMMAC_RESET_REQUESTED,

View File

@ -213,7 +213,7 @@ static void __stmmac_disable_all_queues(struct stmmac_priv *priv)
u32 maxq = max(rx_queues_cnt, tx_queues_cnt); u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue; u32 queue;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (queue = 0; queue < maxq; queue++) { for (queue = 0; queue < maxq; queue++) {
@ -250,7 +250,7 @@ static void stmmac_disable_all_queues(struct stmmac_priv *priv)
break; break;
} }
} }
if (priv->ecdev) if (get_ecdev(priv))
return; return;
__stmmac_disable_all_queues(priv); __stmmac_disable_all_queues(priv);
@ -267,7 +267,7 @@ static void stmmac_enable_all_queues(struct stmmac_priv *priv)
u32 maxq = max(rx_queues_cnt, tx_queues_cnt); u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue; u32 queue;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (queue = 0; queue < maxq; queue++) { for (queue = 0; queue < maxq; queue++) {
@ -295,8 +295,8 @@ static void stmmac_service_event_schedule(struct stmmac_priv *priv)
static void stmmac_global_err(struct stmmac_priv *priv) static void stmmac_global_err(struct stmmac_priv *priv)
{ {
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_set_link(priv->ecdev, 0); ecdev_set_link(get_ecdev(priv), 0);
} else { } else {
netif_carrier_off(priv->dev); netif_carrier_off(priv->dev);
} }
@ -988,8 +988,8 @@ static void stmmac_mac_link_down(struct phylink_config *config,
{ {
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_set_link(priv->ecdev, false); ecdev_set_link(get_ecdev(priv), false);
} }
stmmac_mac_set(priv, priv->ioaddr, false); stmmac_mac_set(priv, priv->ioaddr, false);
priv->eee_active = false; priv->eee_active = false;
@ -1108,8 +1108,8 @@ static void stmmac_mac_link_up(struct phylink_config *config,
if (priv->dma_cap.fpesel) if (priv->dma_cap.fpesel)
stmmac_fpe_link_state_handle(priv, true); stmmac_fpe_link_state_handle(priv, true);
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_set_link(priv->ecdev, true); ecdev_set_link(get_ecdev(priv), true);
} }
} }
@ -1197,7 +1197,7 @@ static int stmmac_init_phy(struct net_device *dev)
ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0); ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0);
} }
if (!priv->ecdev && !priv->plat->pmt) { if (!get_ecdev(priv) && !priv->plat->pmt) {
struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
phylink_ethtool_get_wol(priv->phylink, &wol); phylink_ethtool_get_wol(priv->phylink, &wol);
@ -1552,7 +1552,7 @@ static void stmmac_free_tx_buffer(struct stmmac_priv *priv,
if (tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_XSK_TX) if (tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_XSK_TX)
tx_q->xsk_frames_done++; tx_q->xsk_frames_done++;
if (!priv->ecdev && if (!get_ecdev(priv) &&
tx_q->tx_skbuff[i] && tx_q->tx_skbuff[i] &&
tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_SKB) { tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_SKB) {
dev_kfree_skb_any(tx_q->tx_skbuff[i]); dev_kfree_skb_any(tx_q->tx_skbuff[i]);
@ -2317,7 +2317,7 @@ static void stmmac_enable_all_dma_irq(struct stmmac_priv *priv)
u32 dma_csr_ch = max(rx_channels_count, tx_channels_count); u32 dma_csr_ch = max(rx_channels_count, tx_channels_count);
u32 chan; u32 chan;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
for (chan = 0; chan < dma_csr_ch; chan++) { for (chan = 0; chan < dma_csr_ch; chan++) {
@ -2566,7 +2566,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
unsigned int bytes_compl = 0, pkts_compl = 0; unsigned int bytes_compl = 0, pkts_compl = 0;
unsigned int entry, xmits = 0, count = 0; unsigned int entry, xmits = 0, count = 0;
if (!priv->ecdev) if (!get_ecdev(priv))
__netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
priv->xstats.tx_clean++; priv->xstats.tx_clean++;
@ -2671,7 +2671,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
if (likely(skb)) { if (likely(skb)) {
pkts_compl++; pkts_compl++;
bytes_compl += skb->len; bytes_compl += skb->len;
if (!priv->ecdev) { if (!get_ecdev(priv)) {
dev_consume_skb_any(skb); dev_consume_skb_any(skb);
} }
tx_q->tx_skbuff[entry] = NULL; tx_q->tx_skbuff[entry] = NULL;
@ -2684,7 +2684,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
} }
tx_q->dirty_tx = entry; tx_q->dirty_tx = entry;
if (!priv->ecdev) { if (!get_ecdev(priv)) {
netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue), netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue),
pkts_compl, bytes_compl); pkts_compl, bytes_compl);
} }
@ -2727,10 +2727,10 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
} }
/* We still have pending packets, let's call for a new scheduling */ /* We still have pending packets, let's call for a new scheduling */
if (!priv->ecdev && tx_q->dirty_tx != tx_q->cur_tx) if (!get_ecdev(priv) && tx_q->dirty_tx != tx_q->cur_tx)
stmmac_tx_timer_arm(priv, queue); stmmac_tx_timer_arm(priv, queue);
if (!priv->ecdev) if (!get_ecdev(priv))
__netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
/* Combine decisions from TX clean and XSK TX */ /* Combine decisions from TX clean and XSK TX */
@ -3015,7 +3015,7 @@ static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
if (!tx_coal_timer) if (!tx_coal_timer)
return; return;
if (priv->ecdev) if (get_ecdev(priv))
return; return;
hrtimer_start(&tx_q->txtimer, hrtimer_start(&tx_q->txtimer,
@ -3887,18 +3887,18 @@ static int __stmmac_open(struct net_device *dev,
goto init_error; goto init_error;
} }
if (!priv->ecdev) { if (!get_ecdev(priv)) {
stmmac_init_coalesce(priv); stmmac_init_coalesce(priv);
} }
if (priv->ecdev) { if (get_ecdev(priv)) {
rtnl_lock(); rtnl_lock();
} }
phylink_start(priv->phylink); phylink_start(priv->phylink);
/* We may have called phylink_speed_down before */ /* We may have called phylink_speed_down before */
phylink_speed_up(priv->phylink); phylink_speed_up(priv->phylink);
if (priv->ecdev) { if (get_ecdev(priv)) {
rtnl_unlock(); rtnl_unlock();
} }
@ -3906,7 +3906,7 @@ static int __stmmac_open(struct net_device *dev,
if (ret) if (ret)
goto irq_error; goto irq_error;
if (!priv->ecdev) { if (!get_ecdev(priv)) {
stmmac_enable_all_queues(priv); stmmac_enable_all_queues(priv);
netif_tx_start_all_queues(priv->dev); netif_tx_start_all_queues(priv->dev);
stmmac_enable_all_dma_irq(priv); stmmac_enable_all_dma_irq(priv);
@ -3969,22 +3969,24 @@ static int stmmac_release(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
u32 chan; u32 chan;
if (get_ecdev(priv)) {
rtnl_lock();
}
if (device_may_wakeup(priv->device)) if (device_may_wakeup(priv->device))
phylink_speed_down(priv->phylink, false); phylink_speed_down(priv->phylink, false);
/* Stop and disconnect the PHY */ /* Stop and disconnect the PHY */
if (priv->ecdev) {
rtnl_lock();
}
phylink_stop(priv->phylink); phylink_stop(priv->phylink);
phylink_disconnect_phy(priv->phylink); phylink_disconnect_phy(priv->phylink);
if (priv->ecdev) { if (get_ecdev(priv)) {
rtnl_unlock(); rtnl_unlock();
} }
stmmac_disable_all_queues(priv); stmmac_disable_all_queues(priv);
for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) if (!get_ecdev(priv)) {
hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
}
netif_tx_disable(dev); netif_tx_disable(dev);
@ -4009,7 +4011,7 @@ static int stmmac_release(struct net_device *dev)
if (priv->plat->serdes_powerdown) if (priv->plat->serdes_powerdown)
priv->plat->serdes_powerdown(dev, priv->plat->bsp_priv); priv->plat->serdes_powerdown(dev, priv->plat->bsp_priv);
if (!priv->ecdev) { if (!get_ecdev(priv)) {
netif_carrier_off(dev); netif_carrier_off(dev);
} }
@ -4379,7 +4381,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
dma_map_err: dma_map_err:
dev_err(priv->device, "Tx dma map failed\n"); dev_err(priv->device, "Tx dma map failed\n");
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb(skb); dev_kfree_skb(skb);
priv->dev->stats.tx_dropped++; priv->dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -4556,7 +4558,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
print_pkt(skb->data, skb->len); print_pkt(skb->data, skb->len);
} }
if ((!priv->ecdev) && (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1)))) { if ((!get_ecdev(priv)) && (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1)))) {
netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n", netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n",
__func__); __func__);
netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
@ -4612,7 +4614,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
stmmac_set_tx_owner(priv, first); stmmac_set_tx_owner(priv, first);
if (!priv->ecdev) if (!get_ecdev(priv))
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len); netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
stmmac_enable_dma_transmission(priv, priv->ioaddr); stmmac_enable_dma_transmission(priv, priv->ioaddr);
@ -4624,7 +4626,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
dma_map_err: dma_map_err:
netdev_err(priv->dev, "Tx DMA map failed\n"); netdev_err(priv->dev, "Tx DMA map failed\n");
if (!priv->ecdev) if (!get_ecdev(priv))
dev_kfree_skb(skb); dev_kfree_skb(skb);
priv->dev->stats.tx_dropped++; priv->dev->stats.tx_dropped++;
return NETDEV_TX_OK; return NETDEV_TX_OK;
@ -4939,7 +4941,7 @@ static void stmmac_finalize_xdp_rx(struct stmmac_priv *priv,
{ {
int cpu; int cpu;
int queue; int queue;
if(priv->ecdev) { if(get_ecdev(priv)) {
return; return;
} }
cpu = smp_processor_id(); cpu = smp_processor_id();
@ -5342,7 +5344,7 @@ read_again:
&priv->xstats, rx_q->dma_erx + entry); &priv->xstats, rx_q->dma_erx + entry);
if (unlikely(status == discard_frame)) { if (unlikely(status == discard_frame)) {
netdev_dbg(priv->dev, "discard frame"); netdev_dbg(priv->dev, "discard frame");
if (!priv->ecdev) { if (!get_ecdev(priv)) {
page_pool_recycle_direct(rx_q->page_pool, buf->page); page_pool_recycle_direct(rx_q->page_pool, buf->page);
buf->page = NULL; buf->page = NULL;
} }
@ -5385,13 +5387,13 @@ read_again:
len -= ETH_FCS_LEN; len -= ETH_FCS_LEN;
} }
} }
if (priv->ecdev) { if (get_ecdev(priv)) {
unsigned char *va; unsigned char *va;
dma_sync_single_for_cpu(priv->device, buf->addr, dma_sync_single_for_cpu(priv->device, buf->addr,
buf1_len, dma_dir); buf1_len, dma_dir);
va = page_address(buf->page) + buf->page_offset; va = page_address(buf->page) + buf->page_offset;
ecdev_receive(priv->ecdev, va, buf1_len); ecdev_receive(get_ecdev(priv), va, buf1_len);
netdev_dbg(priv->dev, "ecdev_receive: %u", buf1_len); netdev_dbg(priv->dev, "ecdev_receive: %u", buf1_len);
priv->ec_watchdog_jiffies = jiffies; priv->ec_watchdog_jiffies = jiffies;
/* keep the page and pass it back to the device manually */ /* keep the page and pass it back to the device manually */
@ -5547,7 +5549,7 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget)
u32 chan = ch->index; u32 chan = ch->index;
int work_done; int work_done;
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
priv->xstats.napi_poll++; priv->xstats.napi_poll++;
@ -5571,7 +5573,7 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget)
u32 chan = ch->index; u32 chan = ch->index;
int work_done; int work_done;
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
priv->xstats.napi_poll++; priv->xstats.napi_poll++;
@ -5597,7 +5599,7 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget)
int rx_done, tx_done, rxtx_done; int rx_done, tx_done, rxtx_done;
u32 chan = ch->index; u32 chan = ch->index;
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
priv->xstats.napi_poll++; priv->xstats.napi_poll++;
@ -5871,14 +5873,14 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
/* PCS link status */ /* PCS link status */
if (priv->hw->pcs) { if (priv->hw->pcs) {
if (priv->xstats.pcs_link) if (priv->xstats.pcs_link)
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_set_link(priv->ecdev, 1); ecdev_set_link(get_ecdev(priv), 1);
} else { } else {
netif_carrier_on(priv->dev); netif_carrier_on(priv->dev);
} }
else else
if (priv->ecdev) { if (get_ecdev(priv)) {
ecdev_set_link(priv->ecdev, 0); ecdev_set_link(get_ecdev(priv), 0);
} else { } else {
netif_carrier_off(priv->dev); netif_carrier_off(priv->dev);
} }
@ -6093,7 +6095,7 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
{ {
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
if (priv->ecdev) if (get_ecdev(priv))
return -EBUSY; return -EBUSY;
switch (type) { switch (type) {
@ -6501,7 +6503,7 @@ static int stmmac_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
if (priv->ecdev) { if (get_ecdev(priv)) {
return -EBUSY; return -EBUSY;
} }
@ -6682,7 +6684,7 @@ void stmmac_xdp_release(struct net_device *dev)
/* Ensure tx function is not running */ /* Ensure tx function is not running */
netif_tx_disable(dev); netif_tx_disable(dev);
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
/* Disable NAPI process */ /* Disable NAPI process */
stmmac_disable_all_queues(priv); stmmac_disable_all_queues(priv);
@ -6722,7 +6724,7 @@ int stmmac_xdp_open(struct net_device *dev)
u32 chan; u32 chan;
int ret; int ret;
BUG_ON(priv->ecdev); BUG_ON(get_ecdev(priv));
ret = alloc_dma_desc_resources(priv, &priv->dma_conf); ret = alloc_dma_desc_resources(priv, &priv->dma_conf);
if (ret < 0) { if (ret < 0) {
@ -6827,7 +6829,7 @@ int stmmac_xsk_wakeup(struct net_device *dev, u32 queue, u32 flags)
struct stmmac_tx_queue *tx_q; struct stmmac_tx_queue *tx_q;
struct stmmac_channel *ch; struct stmmac_channel *ch;
if (priv->ecdev) { if (get_ecdev(priv)) {
return -EBUSY; return -EBUSY;
} }
@ -6904,7 +6906,7 @@ void ec_poll(struct net_device *netdev)
int budget = 128; int budget = 128;
u32 maxq; u32 maxq;
if (!priv->ecdev) if (!get_ecdev(priv))
return; return;
maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use); maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);
@ -7244,7 +7246,8 @@ int stmmac_ec_dvr_probe(struct device *device,
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
priv->device = device; priv->device = device;
priv->dev = ndev; priv->dev = ndev;
priv->ecdev = NULL; priv->ecdev_ = NULL;
priv->ecdev_initialized = false;
stmmac_set_ethtool_ops(ndev); stmmac_set_ethtool_ops(ndev);
priv->pause = pause; priv->pause = pause;
@ -7481,8 +7484,9 @@ int stmmac_ec_dvr_probe(struct device *device,
goto error_phy_setup; goto error_phy_setup;
} }
priv->ecdev = ecdev_offer(ndev, ec_poll, THIS_MODULE); priv->ecdev_ = ecdev_offer(ndev, ec_poll, THIS_MODULE);
if (!priv->ecdev) { priv->ecdev_initialized = true;
if (!get_ecdev(priv)) {
ret = register_netdev(ndev); ret = register_netdev(ndev);
if (ret) { if (ret) {
dev_err(priv->device, "%s: ERROR %i registering the device\n", dev_err(priv->device, "%s: ERROR %i registering the device\n",
@ -7502,11 +7506,11 @@ int stmmac_ec_dvr_probe(struct device *device,
* If CONFIG_PM is not enabled, the clocks will stay powered. * If CONFIG_PM is not enabled, the clocks will stay powered.
*/ */
pm_runtime_put(device); pm_runtime_put(device);
if (priv->ecdev) { if (get_ecdev(priv)) {
init_irq_work(&priv->ec_watchdog_kicker, ec_kick_watchdog); init_irq_work(&priv->ec_watchdog_kicker, ec_kick_watchdog);
ret = ecdev_open(priv->ecdev); ret = ecdev_open(get_ecdev(priv));
if (ret) { if (ret) {
ecdev_withdraw(priv->ecdev); ecdev_withdraw(get_ecdev(priv));
goto error_netdev_register; goto error_netdev_register;
} }
} }
@ -7547,14 +7551,12 @@ int stmmac_ec_dvr_remove(struct device *dev)
stmmac_stop_all_dma(priv); stmmac_stop_all_dma(priv);
stmmac_mac_set(priv, priv->ioaddr, false); stmmac_mac_set(priv, priv->ioaddr, false);
if (priv->ecdev) { if (get_ecdev(priv)) {
mutex_lock(&priv->lock); ecdev_close(get_ecdev(priv));
ecdev_close(priv->ecdev);
irq_work_sync(&priv->ec_watchdog_kicker); irq_work_sync(&priv->ec_watchdog_kicker);
ecdev_withdraw(priv->ecdev); ecdev_withdraw(get_ecdev(priv));
priv->ecdev = NULL; priv->ecdev_ = NULL;
priv->ecdev_initialized = false;
mutex_unlock(&priv->lock);
} else { } else {
netif_carrier_off(ndev); netif_carrier_off(ndev);
unregister_netdev(ndev); unregister_netdev(ndev);
@ -7593,7 +7595,7 @@ int stmmac_suspend(struct device *dev)
struct net_device *ndev = dev_get_drvdata(dev); struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
u32 chan; u32 chan;
if (priv->ecdev) { if (get_ecdev(priv)) {
return -EBUSY; return -EBUSY;
} }
@ -7704,7 +7706,7 @@ int stmmac_resume(struct device *dev)
struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_priv *priv = netdev_priv(ndev);
int ret; int ret;
if (priv->ecdev) { if (get_ecdev(priv)) {
return -EBUSY; return -EBUSY;
} }
if (!netif_running(ndev)) if (!netif_running(ndev))