diff --git a/configure.ac b/configure.ac index 9144bcd1..04b78bf4 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,7 @@ AC_ARG_ENABLE([kernel], ;; no) enablekernel=0 ;; - *) AC_MSG_ERROR([Invalid value for --enable-generic]) + *) AC_MSG_ERROR([Invalid value for --enable-kernel]) ;; esac ], @@ -163,6 +163,37 @@ AC_SUBST(INSTALL_MOD_DIR,[$moddir]) AC_MSG_CHECKING([for Linux modules installation directory]) 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 #----------------------------------------------------------------------------- diff --git a/devices/8139too-6.1-ethercat.c b/devices/8139too-6.1-ethercat.c index 4871292a..71759cdf 100644 --- a/devices/8139too-6.1-ethercat.c +++ b/devices/8139too-6.1-ethercat.c @@ -660,9 +660,18 @@ struct rtl8139_private { unsigned int regs_len; 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 "); MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver"); 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 */ // 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", dev->name, 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) RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */ - if (tp->ecdev) { - i = ecdev_open(tp->ecdev); + if (get_ecdev(tp)) { + i = ecdev_open(get_ecdev(tp)); if (i) { - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); goto err_out; } } @@ -1182,9 +1192,9 @@ static void rtl8139_remove_one(struct pci_dev *pdev) assert (dev != NULL); - if (tp->ecdev) { - ecdev_close(tp->ecdev); - ecdev_withdraw(tp->ecdev); + if (get_ecdev(tp)) { + ecdev_close(get_ecdev(tp)); + ecdev_withdraw(get_ecdev(tp)); } else { 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; int retval; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev); if (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, GFP_KERNEL); if (tp->tx_bufs == NULL || tp->rx_ring == NULL) { - if (!tp->ecdev) { + if (!get_ecdev(tp)) { free_irq(irq, dev); } @@ -1426,7 +1436,7 @@ static int rtl8139_open (struct net_device *dev) rtl8139_init_ring (dev); rtl8139_hw_start (dev); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { netif_start_queue (dev); } @@ -1437,7 +1447,7 @@ static int rtl8139_open (struct net_device *dev) irq, RTL_R8 (MediaStatus), tp->mii.full_duplex ? "full" : "half"); - if (!tp->ecdev) { + if (!get_ecdev(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); - if (tp->ecdev) { + if (get_ecdev(tp)) { void __iomem *ioaddr = tp->mmio_addr; 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 { if (tp->phys[0] >= 0) { @@ -1523,7 +1533,7 @@ static void rtl8139_hw_start (struct net_device *dev) if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb))) RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { /* Enable all known interrupts by setting the interrupt mask. */ RTL_W16 (IntrMask, rtl8139_intr_mask); } @@ -1770,7 +1780,7 @@ static void rtl8139_tx_timeout_task (struct work_struct *work) if (tmp8 & CmdTxEnb) RTL_W8 (ChipCmd, CmdRxEnb); - if (tp->ecdev) { + if (get_ecdev(tp)) { rtl8139_tx_clear (tp); 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); tp->watchdog_fired = 1; - if (!tp->ecdev && !tp->have_thread) { + if (!get_ecdev(tp) && !tp->have_thread) { INIT_DELAYED_WORK(&tp->thread, rtl8139_thread); 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) memset(tp->tx_buf[entry], 0, ETH_ZLEN); skb_copy_and_csum_dev(skb, tp->tx_buf[entry]); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { dev_kfree_skb_any(skb); } } else { - if (!tp->ecdev) { + if (!get_ecdev(tp)) { dev_kfree_skb_any(skb); } dev->stats.tx_dropped++; return NETDEV_TX_OK; } - if (!tp->ecdev) { + if (!get_ecdev(tp)) { spin_lock_irqsave(&tp->lock, flags); } /* @@ -1846,7 +1856,7 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb, tp->cur_tx++; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) netif_stop_queue (dev); 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) { tp->dirty_tx = dirty_tx; mb(); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { 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 (RxBufPtr), RTL_R8 (ChipCmd)); - while ((tp->ecdev || netif_running(dev)) + while ((get_ecdev(tp) || netif_running(dev)) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { 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 pkt_size = rx_size; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { if (netif_msg_rx_status(tp)) pr_debug("%s: rtl8139_rx() status %4.4x, size %4.4x," " cur %4.4x.\n", dev->name, rx_status, @@ -2151,8 +2161,8 @@ no_early_rx: } keep_pkt: - if (tp->ecdev) { - ecdev_receive(tp->ecdev, &rx_ring[ring_offset + 4], pkt_size); + if (get_ecdev(tp)) { + ecdev_receive(get_ecdev(tp), &rx_ring[ring_offset + 4], pkt_size); } else { /* 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 handled = 0; - if (tp->ecdev) { + if (get_ecdev(tp)) { status = RTL_R16 (IntrStatus); } else { @@ -2308,7 +2318,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance) if (unlikely(status == 0xFFFF)) goto out; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { /* close possible race's with dev_close */ if (unlikely(!netif_running(dev))) { 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. If not running start it now. */ if (status & RxAckBits){ - if (tp->ecdev) { + if (get_ecdev(tp)) { /* EtherCAT device: Just receive all frames */ rtl8139_rx(dev, tp, 100); // FIXME } else { @@ -2351,7 +2361,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance) RTL_W16 (IntrStatus, TxErr); } out: - if (!tp->ecdev) { + if (!get_ecdev(tp)) { spin_unlock (&tp->lock); } @@ -2405,7 +2415,7 @@ static int rtl8139_close (struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; unsigned long flags = 0; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { netif_stop_queue(dev); napi_disable(&tp->napi); @@ -2426,7 +2436,7 @@ static int rtl8139_close (struct net_device *dev) dev->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { spin_unlock_irqrestore (&tp->lock, flags); 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); int rc; - if (tp->ecdev || !netif_running(dev)) + if (get_ecdev(tp) || !netif_running(dev)) return -EINVAL; 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 int start; - if (tp->ecdev || netif_running(dev)) { + if (get_ecdev(tp) || netif_running(dev)) { spin_lock_irqsave (&tp->lock, flags); dev->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); @@ -2762,7 +2772,7 @@ static int __maybe_unused rtl8139_suspend(struct device *device) void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; - if (tp->ecdev || !netif_running (dev)) + if (get_ecdev(tp) || !netif_running (dev)) return 0; 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 rtl8139_private *tp = netdev_priv(dev); - if (tp->ecdev || !netif_running (dev)) + if (get_ecdev(tp) || !netif_running (dev)) return 0; rtl8139_init_ring (dev); diff --git a/devices/Kbuild.in b/devices/Kbuild.in index acd9a684..a46b0410 100644 --- a/devices/Kbuild.in +++ b/devices/Kbuild.in @@ -26,6 +26,11 @@ src := @abs_srcdir@ 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 \ cat $(src)/../revision; \ else \ diff --git a/devices/e100-6.1-ethercat.c b/devices/e100-6.1-ethercat.c index 7bf75bc0..a8c88dd1 100644 --- a/devices/e100-6.1-ethercat.c +++ b/devices/e100-6.1-ethercat.c @@ -646,10 +646,19 @@ struct nic { __le16 eeprom[256]; spinlock_t mdio_lock; const struct firmware *fw; - ec_device_t *ecdev; + ec_device_t *ecdev_; 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) { /* Flush previous PCI writes through intermediate bridges @@ -661,7 +670,7 @@ static void e100_enable_irq(struct nic *nic) { unsigned long flags; - if (nic->ecdev) + if (get_ecdev(nic)) return; spin_lock_irqsave(&nic->cmd_lock, flags); @@ -674,11 +683,11 @@ static void e100_disable_irq(struct nic *nic) { unsigned long flags = 0; - if (!nic->ecdev) + if (!nic->ecdev_) spin_lock_irqsave(&nic->cmd_lock, flags); iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi); e100_write_flush(nic); - if (!nic->ecdev) + if (!nic->ecdev_) 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; int err = 0; - if (!nic->ecdev) + if (!get_ecdev(nic)) spin_lock_irqsave(&nic->cmd_lock, flags); /* 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); err_unlock: - if (!nic->ecdev) + if (!get_ecdev(nic)) spin_unlock_irqrestore(&nic->cmd_lock, flags); return err; @@ -902,7 +911,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, unsigned long flags; int err; - if (!nic->ecdev) { + if (!get_ecdev(nic)) { 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: - if (!nic->ecdev) { + if (!get_ecdev(nic)) { 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 * procedure it should be done under lock. */ - if (!nic->ecdev) + if (!nic->ecdev_) /* exemption of initialization check */ spin_lock_irqsave(&nic->mdio_lock, flags); for (i = 100; i; --i) { 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)) { 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); 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) break; } - if (!nic->ecdev) + if (!nic->ecdev_) spin_unlock_irqrestore(&nic->mdio_lock, flags); netif_printk(nic, hw, KERN_DEBUG, nic->netdev, "%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 */ /* disable WoL when up */ - if (nic->ecdev || + if (get_ecdev(nic) || (netif_running(nic->netdev) || !(nic->flags & wol_magic))) 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 }; u32 speed; - if (nic->ecdev) { - ecdev_set_link(nic->ecdev, mii_link_ok(&nic->mii) ? 1 : 0); + if (get_ecdev(nic)) { + ecdev_set_link(get_ecdev(nic), mii_link_ok(&nic->mii) ? 1 : 0); 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. */ netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev, "No space for CB\n"); - if (!nic->ecdev) + if (!get_ecdev(nic)) netif_stop_queue(netdev); break; case -ENOMEM: /* This is a hard error - log it. */ netif_printk(nic, tx_err, KERN_DEBUG, nic->netdev, "Out of Tx resources, returning skb\n"); - if (!nic->ecdev) + if (!get_ecdev(nic)) netif_stop_queue(netdev); return NETDEV_TX_BUSY; } @@ -1883,7 +1892,7 @@ static int e100_tx_clean(struct nic *nic) struct cb *cb; int tx_cleaned = 0; - if (!nic->ecdev) + if (!get_ecdev(nic)) spin_lock(&nic->cb_lock); /* 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), le16_to_cpu(cb->u.tcb.tbd.size), DMA_TO_DEVICE); - if (!nic->ecdev) + if (!get_ecdev(nic)) dev_kfree_skb_any(cb->skb); cb->skb = NULL; tx_cleaned = 1; @@ -1913,7 +1922,7 @@ static int e100_tx_clean(struct nic *nic) nic->cbs_avail++; } - if (!nic->ecdev) { + if (!get_ecdev(nic)) { spin_unlock(&nic->cb_lock); /* 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), le16_to_cpu(cb->u.tcb.tbd.size), DMA_TO_DEVICE); - if (!nic->ecdev) + if (!get_ecdev(nic)) dev_kfree_skb(cb->skb); } 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; } - if (!nic->ecdev) { + if (!get_ecdev(nic)) { /* Pull off the RFD and put the actual data (minus eth hdr) */ skb_reserve(skb, sizeof(struct rfd)); 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 (!nic->ecdev) { + if (!get_ecdev(nic)) { /* Don't indicate if hardware indicates errors */ dev_kfree_skb_any(skb); } } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + fcs_pad) { /* Don't indicate oversized frames */ nic->rx_over_length_errors++; - if (!nic->ecdev) { + if (!get_ecdev(nic)) { dev_kfree_skb_any(skb); } } else { process_skb: dev->stats.rx_packets++; dev->stats.rx_bytes += (actual_size - fcs_pad); - if (nic->ecdev) { - ecdev_receive(nic->ecdev, + if (get_ecdev(nic)) { + ecdev_receive(get_ecdev(nic), skb->data + sizeof(struct rfd), actual_size - fcs_pad); // No need to detect link status as // 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; } } else { @@ -2137,7 +2146,7 @@ process_skb: (*work_done)++; } - if (nic->ecdev) { + if (get_ecdev(nic)) { // make receive frame descriptior usable again memcpy(skb->data, &nic->blank_rfd, sizeof(struct rfd)); 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_rfd = (struct rfd *)old_before_last_rx->skb->data; - if (!nic->ecdev) { + if (!get_ecdev(nic)) { /* Alloc new skbs to refill list */ for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { 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. * This lets us update the next pointer on the last buffer without * 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) 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); __napi_schedule(&nic->napi); } @@ -2418,13 +2427,13 @@ static int e100_up(struct nic *nic) goto err_clean_cbs; e100_set_multicast_list(nic->netdev); e100_start_receiver(nic, NULL); - if (!nic->ecdev) { + if (!get_ecdev(nic)) { mod_timer(&nic->watchdog, jiffies); } if ((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, nic->netdev->name, nic->netdev))) goto err_no_irq; - if (!nic->ecdev) { + if (!get_ecdev(nic)) { netif_wake_queue(nic->netdev); napi_enable(&nic->napi); /* enable ints _after_ enabling poll, preventing a race between @@ -2434,7 +2443,7 @@ static int e100_up(struct nic *nic) return 0; err_no_irq: - if (!nic->ecdev) + if (!get_ecdev(nic)) del_timer_sync(&nic->watchdog); err_clean_cbs: e100_clean_cbs(nic); @@ -2445,14 +2454,14 @@ err_rx_clean_list: static void e100_down(struct nic *nic) { - if (!nic->ecdev) { + if (!get_ecdev(nic)) { /* wait here for poll to complete */ napi_disable(&nic->napi); netif_stop_queue(nic->netdev); } e100_hw_reset(nic); free_irq(nic->pdev->irq, nic->netdev); - if (!nic->ecdev) { + if (!get_ecdev(nic)) { del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); } @@ -2929,7 +2938,7 @@ static int e100_open(struct net_device *netdev) struct nic *nic = netdev_priv(netdev); int err = 0; - if (!nic->ecdev) + if (!get_ecdev(nic)) netif_carrier_off(netdev); if ((err = e100_up(nic))) 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); // 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"); if ((err = register_netdev(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), pdev->irq, netdev->dev_addr); - if (nic->ecdev) { - err = ecdev_open(nic->ecdev); + if (get_ecdev(nic)) { + err = ecdev_open(get_ecdev(nic)); if (err) { - ecdev_withdraw(nic->ecdev); + ecdev_withdraw(get_ecdev(nic)); goto err_out_free; } } @@ -3146,9 +3156,9 @@ static void e100_remove(struct pci_dev *pdev) if (netdev) { struct nic *nic = netdev_priv(netdev); - if (nic->ecdev) { - ecdev_close(nic->ecdev); - ecdev_withdraw(nic->ecdev); + if (get_ecdev(nic)) { + ecdev_close(get_ecdev(nic)); + ecdev_withdraw(get_ecdev(nic)); } else { 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 nic *nic = netdev_priv(netdev); - if (nic->ecdev) + if (get_ecdev(nic)) return -EBUSY; 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 nic *nic = netdev_priv(netdev); - if (nic->ecdev) + if (get_ecdev(nic)) return -EBUSY; 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 */ pci_enable_wake(pdev, PCI_D0, 0); - if (!nic->ecdev) + if (!get_ecdev(nic)) netif_device_attach(netdev); - if (nic->ecdev || netif_running(netdev)) { + if (get_ecdev(nic) || netif_running(netdev)) { e100_open(netdev); - if (!nic->ecdev) + if (!get_ecdev(nic)) mod_timer(&nic->watchdog, jiffies); } } diff --git a/devices/e1000/Kbuild.in b/devices/e1000/Kbuild.in index b3738dd8..1bf2fd9a 100644 --- a/devices/e1000/Kbuild.in +++ b/devices/e1000/Kbuild.in @@ -43,6 +43,10 @@ ifeq (@ENABLE_E1000@,1) obj-m += ec_e1000.o ec_e1000-objs := $(EC_E1000_OBJ) CFLAGS_e1000_main-@KERNEL_E1000@-ethercat.o = -DREV=$(REV) + + ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1) + ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING + endif endif KBUILD_EXTRA_SYMBOLS := \ diff --git a/devices/e1000/e1000-5.14-ethercat.h b/devices/e1000/e1000-5.14-ethercat.h index 71aa37ad..f25cd253 100644 --- a/devices/e1000/e1000-5.14-ethercat.h +++ b/devices/e1000/e1000-5.14-ethercat.h @@ -303,11 +303,20 @@ struct e1000_adapter { struct delayed_work fifo_stall_task; struct delayed_work phy_info_task; - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 { __E1000_TESTING, __E1000_RESETTING, diff --git a/devices/e1000/e1000-6.1-ethercat.h b/devices/e1000/e1000-6.1-ethercat.h index 0769b47c..9e986c25 100644 --- a/devices/e1000/e1000-6.1-ethercat.h +++ b/devices/e1000/e1000-6.1-ethercat.h @@ -303,11 +303,20 @@ struct e1000_adapter { struct delayed_work fifo_stall_task; struct delayed_work phy_info_task; - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 { __E1000_TESTING, __E1000_RESETTING, diff --git a/devices/e1000/e1000_main-5.14-ethercat.c b/devices/e1000/e1000_main-5.14-ethercat.c index 2fe1e6ca..128d353e 100644 --- a/devices/e1000/e1000_main-5.14-ethercat.c +++ b/devices/e1000/e1000_main-5.14-ethercat.c @@ -271,7 +271,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter) int irq_flags = IRQF_SHARED; int err; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return 0; } @@ -288,7 +288,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -303,7 +303,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { + if (!adapter->ecdev_) { return; } @@ -320,7 +320,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -407,7 +407,7 @@ static void e1000_configure(struct e1000_adapter *adapter) */ for (i = 0; i < adapter->num_rx_queues; i++) { struct e1000_rx_ring *ring = &adapter->rx_ring[i]; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* fill rx ring completely! */ adapter->alloc_rx_buf(adapter, ring, ring->count); } else { @@ -427,7 +427,7 @@ int e1000_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->flags); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); 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. */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->fifo_stall_task); } /* 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); } @@ -537,7 +537,7 @@ void e1000_down(struct e1000_adapter *adapter) ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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. */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(netdev); 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->bars = bars; adapter->need_ioport = need_ioport; + adapter->ecdev_initialized = 0; hw = &adapter->hw; hw->back = adapter; @@ -1246,12 +1247,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) e1000_reset(adapter); // offer device to EtherCAT master module - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } } 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), netdev->dev_addr); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); } @@ -1323,15 +1325,15 @@ static void e1000_remove(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; bool disable_dev; - if (adapter->ecdev) + if (get_ecdev(adapter)) irq_work_sync(&adapter->ec_watchdog_kicker); e1000_down_and_stop(adapter); e1000_release_manageability(adapter); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); - ecdev_withdraw(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); + ecdev_withdraw(get_ecdev(adapter)); } else { 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() */ clear_bit(__E1000_DOWN, &adapter->flags); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); e1000_irq_enable(adapter); @@ -1926,7 +1928,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; 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 * sizeof(struct e1000_rx_desc); adapter->clean_rx = e1000_clean_jumbo_rx_irq; @@ -2026,7 +2028,7 @@ static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, struct e1000_tx_buffer *buffer_info) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2236,7 +2238,7 @@ static void e1000_enter_82542_rst(struct e1000_adapter *adapter) E1000_WRITE_FLUSH(); mdelay(5); - if (!adapter->ecdev && netif_running(netdev)) + if (!get_ecdev(adapter) && netif_running(netdev)) 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 */ struct e1000_rx_ring *ring = &adapter->rx_ring[0]; e1000_configure_rx(adapter); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* fill rx ring completely! */ adapter->alloc_rx_buf(adapter, ring, ring->count); } else { @@ -2519,12 +2521,12 @@ static void e1000_watchdog(struct work_struct *work) u32 link, tctl; 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; if (link) { - if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) || - (!adapter->ecdev && !netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) || + (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) { u32 ctrl; /* update snapshot of PHY registers on LSC */ e1000_get_speed_and_duplex(hw, @@ -2559,8 +2561,8 @@ static void e1000_watchdog(struct work_struct *work) tctl |= E1000_TCTL_EN; ew32(TCTL, tctl); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 1); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 1); } else { netif_carrier_on(netdev); @@ -2571,15 +2573,15 @@ static void e1000_watchdog(struct work_struct *work) adapter->smartspeed = 0; } } else { - if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) { adapter->link_speed = 0; adapter->link_duplex = 0; pr_info("%s NIC Link is Down\n", netdev->name); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -2607,7 +2609,7 @@ link_up: 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) { /* We've lost link, so the controller stops DMA, * but we've got queued Tx work that's never going @@ -2643,7 +2645,7 @@ link_up: adapter->detect_tx_hung = true; /* 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); } @@ -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_tx_ring *tx_ring = adapter->tx_ring; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -3260,7 +3262,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (!__pskb_pull_tail(skb, pull_size)) { e_err(drv, "__pskb_pull_tail " "failed.\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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) && (e1000_82547_fifo_workaround(adapter, skb)))) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_stop_queue(netdev); if (!test_bit(__E1000_DOWN, &adapter->flags)) 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); if (tso < 0) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_sent_queue(netdev, skb->len); 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. */ 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))) { writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt); } } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -3720,7 +3722,7 @@ void e1000_update_stats(struct e1000_adapter *adapter) if (pci_channel_offline(pdev)) return; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { spin_lock_irqsave(&adapter->stats_lock, flags); } @@ -3851,7 +3853,7 @@ void e1000_update_stats(struct e1000_adapter *adapter) adapter->stats.mgpdc += er32(MGTPDC); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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))) { hw->get_link_status = 1; /* 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); } - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int i, ec_work_done = 0; for (i = 0; i < E1000_MAX_INTR; i++) { 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); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_completed_queue(netdev, pkts_compl, bytes_compl); } #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)) { /* Make sure that anybody stopping the queue after this * 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 * 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); data = buffer_info->rxbuf.data; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { prefetch(data); skb = e1000_copybreak(adapter, buffer_info, length, data); if (!skb) { @@ -4573,7 +4575,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, if (adapter->discarding) { /* All receives must fit into a single buffer */ netdev_dbg(netdev, "Receive packet consumed multiple buffers\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb(skb); } 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) { goto process_skb; } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb(skb); } goto next_desc; @@ -4606,7 +4608,7 @@ process_skb: */ length -= 4; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (buffer_info->rxbuf.data == NULL) skb_put(skb, length); else /* copybreak skb */ @@ -4619,10 +4621,10 @@ process_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, 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 // 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; break; case SIOCGMIIREG: - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EPERM; } 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); break; case SIOCSMIIREG: - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EPERM; } 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 wufc = adapter->wol; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -5339,7 +5341,7 @@ static int __maybe_unused e1000_resume(struct device *dev) struct e1000_hw *hw = &adapter->hw; u32 err; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -5375,7 +5377,7 @@ static int __maybe_unused e1000_resume(struct device *dev) if (netif_running(netdev)) e1000_up(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_device_attach(netdev); } diff --git a/devices/e1000/e1000_main-6.1-ethercat.c b/devices/e1000/e1000_main-6.1-ethercat.c index e9514e51..8d8518ac 100644 --- a/devices/e1000/e1000_main-6.1-ethercat.c +++ b/devices/e1000/e1000_main-6.1-ethercat.c @@ -260,7 +260,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter) int irq_flags = IRQF_SHARED; int err; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return 0; } @@ -277,7 +277,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -292,7 +292,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { + if (adapter->ecdev_) { return; } @@ -309,7 +309,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -396,7 +396,7 @@ static void e1000_configure(struct e1000_adapter *adapter) */ for (i = 0; i < adapter->num_rx_queues; i++) { struct e1000_rx_ring *ring = &adapter->rx_ring[i]; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* fill rx ring completely! */ adapter->alloc_rx_buf(adapter, ring, ring->count); } else { @@ -416,7 +416,7 @@ int e1000_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->flags); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); 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. */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { cancel_delayed_work_sync(&adapter->phy_info_task); cancel_delayed_work_sync(&adapter->fifo_stall_task); } /* 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); } @@ -526,7 +526,7 @@ void e1000_down(struct e1000_adapter *adapter) ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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. */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(netdev); 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->bars = bars; adapter->need_ioport = need_ioport; + adapter->ecdev_initialized = 0; hw = &adapter->hw; hw->back = adapter; @@ -1231,12 +1232,13 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) e1000_reset(adapter); // offer device to EtherCAT master module - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } } 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), netdev->dev_addr); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); } @@ -1308,15 +1310,15 @@ static void e1000_remove(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; bool disable_dev; - if (adapter->ecdev) + if (get_ecdev(adapter)) irq_work_sync(&adapter->ec_watchdog_kicker); e1000_down_and_stop(adapter); e1000_release_manageability(adapter); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); - ecdev_withdraw(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); + ecdev_withdraw(get_ecdev(adapter)); } else { 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() */ clear_bit(__E1000_DOWN, &adapter->flags); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); e1000_irq_enable(adapter); @@ -1911,7 +1913,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; 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 * sizeof(struct e1000_rx_desc); 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, int budget) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2222,7 +2224,7 @@ static void e1000_enter_82542_rst(struct e1000_adapter *adapter) E1000_WRITE_FLUSH(); mdelay(5); - if (!adapter->ecdev && netif_running(netdev)) + if (!get_ecdev(adapter) && netif_running(netdev)) 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 */ struct e1000_rx_ring *ring = &adapter->rx_ring[0]; e1000_configure_rx(adapter); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* fill rx ring completely! */ adapter->alloc_rx_buf(adapter, ring, ring->count); } else { @@ -2501,12 +2503,12 @@ static void e1000_watchdog(struct work_struct *work) u32 link, tctl; 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; if (link) { - if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) || - (!adapter->ecdev && !netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) || + (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) { u32 ctrl; /* update snapshot of PHY registers on LSC */ e1000_get_speed_and_duplex(hw, @@ -2541,8 +2543,8 @@ static void e1000_watchdog(struct work_struct *work) tctl |= E1000_TCTL_EN; ew32(TCTL, tctl); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 1); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 1); } else { netif_carrier_on(netdev); @@ -2553,15 +2555,15 @@ static void e1000_watchdog(struct work_struct *work) adapter->smartspeed = 0; } } else { - if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) { adapter->link_speed = 0; adapter->link_duplex = 0; pr_info("%s NIC Link is Down\n", netdev->name); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -2589,7 +2591,7 @@ link_up: 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) { /* We've lost link, so the controller stops DMA, * but we've got queued Tx work that's never going @@ -2625,7 +2627,7 @@ link_up: adapter->detect_tx_hung = true; /* 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); } @@ -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_tx_ring *tx_ring = adapter->tx_ring; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -3242,7 +3244,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (!__pskb_pull_tail(skb, pull_size)) { e_err(drv, "__pskb_pull_tail " "failed.\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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) && (e1000_82547_fifo_workaround(adapter, skb)))) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_stop_queue(netdev); if (!test_bit(__E1000_DOWN, &adapter->flags)) 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); if (tso < 0) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_sent_queue(netdev, skb->len); 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. */ 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))) { writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt); } } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -3702,7 +3704,7 @@ void e1000_update_stats(struct e1000_adapter *adapter) if (pci_channel_offline(pdev)) return; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { spin_lock_irqsave(&adapter->stats_lock, flags); } @@ -3833,7 +3835,7 @@ void e1000_update_stats(struct e1000_adapter *adapter) adapter->stats.mgpdc += er32(MGTPDC); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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))) { hw->get_link_status = 1; /* 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); } - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int i, ec_work_done = 0; for (i = 0; i < E1000_MAX_INTR; i++) { 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); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_completed_queue(netdev, pkts_compl, bytes_compl); } #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)) { /* Make sure that anybody stopping the queue after this * 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 * 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); data = buffer_info->rxbuf.data; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { prefetch(data); skb = e1000_copybreak(adapter, buffer_info, length, data); if (!skb) { @@ -4556,7 +4558,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, if (adapter->discarding) { /* All receives must fit into a single buffer */ netdev_dbg(netdev, "Receive packet consumed multiple buffers\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb(skb); } 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) { goto process_skb; } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb(skb); } goto next_desc; @@ -4589,7 +4591,7 @@ process_skb: */ length -= 4; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (buffer_info->rxbuf.data == NULL) skb_put(skb, length); else /* copybreak skb */ @@ -4602,10 +4604,10 @@ process_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, 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 // 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; break; case SIOCGMIIREG: - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EPERM; } 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); break; case SIOCSMIIREG: - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EPERM; } 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 wufc = adapter->wol; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -5322,7 +5324,7 @@ static int __maybe_unused e1000_resume(struct device *dev) struct e1000_hw *hw = &adapter->hw; u32 err; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return -EBUSY; } @@ -5358,7 +5360,7 @@ static int __maybe_unused e1000_resume(struct device *dev) if (netif_running(netdev)) e1000_up(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_device_attach(netdev); } diff --git a/devices/e1000e/Kbuild.in b/devices/e1000e/Kbuild.in index a578d296..7712067c 100644 --- a/devices/e1000e/Kbuild.in +++ b/devices/e1000e/Kbuild.in @@ -70,6 +70,10 @@ ifeq (@ENABLE_E1000E@,1) ec_e1000e-objs := $(EC_E1000E_OBJ) CFLAGS_netdev-@KERNEL_E1000E@-ethercat.o = -DREV=$(REV) + + ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1) + ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING + endif endif KBUILD_EXTRA_SYMBOLS := \ diff --git a/devices/e1000e/e1000-5.14-ethercat.h b/devices/e1000e/e1000-5.14-ethercat.h index 2ab0fff1..5e16a3de 100644 --- a/devices/e1000e/e1000-5.14-ethercat.h +++ b/devices/e1000e/e1000-5.14-ethercat.h @@ -336,11 +336,20 @@ struct e1000_adapter { u16 eee_advert; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 { enum e1000_mac_type mac; unsigned int flags; diff --git a/devices/e1000e/e1000-6.1-ethercat.h b/devices/e1000e/e1000-6.1-ethercat.h index 0210c7f5..eb2a1f03 100644 --- a/devices/e1000e/e1000-6.1-ethercat.h +++ b/devices/e1000e/e1000-6.1-ethercat.h @@ -338,11 +338,20 @@ struct e1000_adapter { u16 eee_advert; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 { enum e1000_mac_type mac; unsigned int flags; diff --git a/devices/e1000e/netdev-5.14-ethercat.c b/devices/e1000e/netdev-5.14-ethercat.c index 51850aeb..10a40dc9 100644 --- a/devices/e1000e/netdev-5.14-ethercat.c +++ b/devices/e1000e/netdev-5.14-ethercat.c @@ -45,7 +45,7 @@ char e1000e_driver_name[] = "ec_e1000e"; static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter) { #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 return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA; #endif @@ -959,7 +959,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb = buffer_info->skb; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) buffer_info->skb = NULL; 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; } - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && !(netdev->features & NETIF_F_RXALL))) { /* 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 * of reassembly being done in the stack */ - if (!adapter->ecdev && length < copybreak) { + if (!get_ecdev(adapter) && length < copybreak) { struct sk_buff *new_skb = napi_alloc_skb(&adapter->napi, length); 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); - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { 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; } if (buffer_info->skb) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (drop) dev_kfree_skb_any(buffer_info->skb); else @@ -1153,8 +1153,8 @@ static void e1000_print_hw_hang(struct work_struct *work) } /* Real hang detected */ - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { 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; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_completed_queue(netdev, pkts_compl, bytes_compl); } #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) { /* Make sure that anybody stopping the queue after this * 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 * 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) { 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); } 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) && !(netdev->features & NETIF_F_RXALL))) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_irq(skb); } goto next_desc; @@ -1414,7 +1414,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, if (!length) { e_dbg("Last part of the packet spanning multiple descriptors\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_irq(skb); } goto next_desc; @@ -1503,8 +1503,8 @@ copydone: cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) adapter->rx_hdr_split++; - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { e1000_receive_skb(adapter, netdev, skb, staterr, @@ -1513,7 +1513,7 @@ copydone: next_desc: 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 */ 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; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) buffer_info->skb = NULL; ++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 */ buffer_info->skb = skb; /* 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); rx_ring->rx_skb_top = NULL; 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++; /* 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"); dev_kfree_skb_irq(skb); goto next_desc; } - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { 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; u32 icr = er32(ICR); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); 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; u32 rctl, icr = er32(ICR); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); 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) { hw->mac.get_link_status = true; /* 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); } @@ -2027,7 +2027,7 @@ static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data) rx_ring->set_itr = 0; } - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); } else { @@ -2241,7 +2241,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; int err; - if (adapter->ecdev) + if (get_ecdev(adapter)) return 0; if (adapter->msix_entries) { @@ -2276,7 +2276,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2310,7 +2310,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) ew32(EIAC_82574, 0); e1e_flush(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2332,7 +2332,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->msix_entries) { @@ -3859,7 +3859,7 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL); } else { 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); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (adapter->msix_entries) e1000_configure_msix(adapter); e1000_irq_enable(adapter); @@ -4375,8 +4375,8 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) */ set_bit(__E1000_DOWN, &adapter->state); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -4388,7 +4388,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ - if (!adapter->ecdev) + if (!get_ecdev(adapter)) netif_stop_queue(netdev); /* disable transmits in the hardware */ @@ -4400,7 +4400,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) e1e_flush(); usleep_range(10000, 11000); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { e1000_irq_disable(adapter); napi_synchronize(&adapter->napi); @@ -4733,8 +4733,8 @@ int e1000e_open(struct net_device *netdev) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(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 * 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); if (err) { 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() */ clear_bit(__E1000_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); e1000_irq_enable(adapter); @@ -4854,7 +4854,7 @@ int e1000e_close(struct net_device *netdev) netdev_info(netdev, "NIC Link is Down\n"); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_disable(&adapter->napi); } @@ -5329,9 +5329,9 @@ static void e1000_watchdog_task(struct work_struct *work) return; link = e1000e_has_link(adapter); - if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link) - || (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) { - if (!adapter->ecdev) { + if ((get_ecdev(adapter) && (ecdev_get_link(get_ecdev(adapter))) && link) + || (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)) { + if (!get_ecdev(adapter)) { /* Cancel scheduled suspend requests. */ pm_runtime_resume(netdev->dev.parent); } @@ -5345,8 +5345,8 @@ static void e1000_watchdog_task(struct work_struct *work) e1000_update_mng_vlan(adapter); if (link) { - if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && !netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) { bool txb2b = true; /* Cancel scheduled suspend requests. */ @@ -5462,27 +5462,27 @@ static void e1000_watchdog_task(struct work_struct *work) if (phy->ops.cfg_on_link_up) phy->ops.cfg_on_link_up(hw); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 1); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 1); } else { netif_wake_queue(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, round_jiffies(jiffies + 2 * HZ)); } } else { - if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) { adapter->link_speed = 0; adapter->link_duplex = 0; /* Link status message must follow this format */ netdev_info(netdev, "NIC Link is Down\n"); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -5584,7 +5584,7 @@ link_up: } /* 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, 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); if (test_bit(__E1000_DOWN, &adapter->state)) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); return NETDEV_TX_BUSY; } if (skb->len <= 0) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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); if (!__pskb_pull_tail(skb, pull_size)) { e_err("__pskb_pull_tail failed.\n"); - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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 * 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; 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); if (tso < 0) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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); e1000_tx_queue(tx_ring, tx_flags, count); /* 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, (MAX_SKB_FRAGS * DIV_ROUND_UP(PAGE_SIZE, 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))) { if (check_arbiter_wa_flag(adapter)) 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); } } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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); int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; /* Jumbo frame support */ @@ -7019,7 +7019,7 @@ static int __e1000_resume(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; u16 aspm_disable_flag = 0; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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); int rc; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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->max_hw_frame_size = ei->max_hw_frame_size; adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->ecdev_initialized = 0; mmio_start = pci_resource_start(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) adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } adapter->ec_watchdog_jiffies = jiffies; @@ -7893,10 +7895,10 @@ static void e1000_remove(struct pci_dev *pdev) e1000e_ptp_remove(adapter); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } /* 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); } diff --git a/devices/e1000e/netdev-6.1-ethercat.c b/devices/e1000e/netdev-6.1-ethercat.c index 01685fa4..1c2209d2 100644 --- a/devices/e1000e/netdev-6.1-ethercat.c +++ b/devices/e1000e/netdev-6.1-ethercat.c @@ -34,7 +34,7 @@ char e1000e_driver_name[] = "ec_e1000e"; static inline int check_arbiter_wa_flag(const struct e1000_adapter *adapter) { #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 return adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA; #endif @@ -949,7 +949,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb = buffer_info->skb; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) buffer_info->skb = NULL; 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; } - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) && !(netdev->features & NETIF_F_RXALL))) { /* 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 * of reassembly being done in the stack */ - if (!adapter->ecdev && length < copybreak) { + if (!get_ecdev(adapter) && length < copybreak) { struct sk_buff *new_skb = napi_alloc_skb(&adapter->napi, length); 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); - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { 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; } if (buffer_info->skb) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (drop) dev_kfree_skb_any(buffer_info->skb); else @@ -1143,8 +1143,8 @@ static void e1000_print_hw_hang(struct work_struct *work) } /* Real hang detected */ - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { 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; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_completed_queue(netdev, pkts_compl, bytes_compl); } #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) { /* Make sure that anybody stopping the queue after this * 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 * 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) { 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); } 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) && !(netdev->features & NETIF_F_RXALL))) { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_irq(skb); } goto next_desc; @@ -1404,7 +1404,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, if (!length) { e_dbg("Last part of the packet spanning multiple descriptors\n"); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_irq(skb); } goto next_desc; @@ -1493,8 +1493,8 @@ copydone: cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) adapter->rx_hdr_split++; - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { e1000_receive_skb(adapter, netdev, skb, staterr, @@ -1503,7 +1503,7 @@ copydone: next_desc: 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 */ 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; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) buffer_info->skb = NULL; ++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 */ buffer_info->skb = skb; /* 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); rx_ring->rx_skb_top = NULL; 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++; /* 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"); dev_kfree_skb_irq(skb); goto next_desc; } - if (adapter->ecdev) { - ecdev_receive(adapter->ecdev, skb->data, length); + if (get_ecdev(adapter)) { + ecdev_receive(get_ecdev(adapter), skb->data, length); adapter->ec_watchdog_jiffies = jiffies; } else { 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; u32 icr = er32(ICR); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); 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; u32 rctl, icr = er32(ICR); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); 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) { hw->mac.get_link_status = true; /* 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); } @@ -2017,7 +2017,7 @@ static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data) rx_ring->set_itr = 0; } - if (adapter->ecdev) { + if (get_ecdev(adapter)) { int ec_work_done = 0; adapter->clean_rx(adapter->rx_ring, &ec_work_done, 100); } else { @@ -2231,7 +2231,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; int err; - if (adapter->ecdev) + if (get_ecdev(adapter)) return 0; if (adapter->msix_entries) { @@ -2266,7 +2266,7 @@ static void e1000_free_irq(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2300,7 +2300,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) ew32(EIAC_82574, 0); e1e_flush(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return; } @@ -2322,7 +2322,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->msix_entries) { @@ -3845,7 +3845,7 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { adapter->alloc_rx_buf(rx_ring, adapter->rx_ring->count, GFP_KERNEL); } else { 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); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (adapter->msix_entries) e1000_configure_msix(adapter); e1000_irq_enable(adapter); @@ -4362,8 +4362,8 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) */ set_bit(__E1000_DOWN, &adapter->state); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -4375,7 +4375,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ - if (!adapter->ecdev) + if (!get_ecdev(adapter)) netif_stop_queue(netdev); /* disable transmits in the hardware */ @@ -4387,7 +4387,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) e1e_flush(); usleep_range(10000, 11000); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { e1000_irq_disable(adapter); napi_synchronize(&adapter->napi); @@ -4720,8 +4720,8 @@ int e1000e_open(struct net_device *netdev) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(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 * 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); if (err) { 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() */ clear_bit(__E1000_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_enable(&adapter->napi); e1000_irq_enable(adapter); @@ -4841,7 +4841,7 @@ int e1000e_close(struct net_device *netdev) netdev_info(netdev, "NIC Link is Down\n"); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_disable(&adapter->napi); } @@ -5312,9 +5312,9 @@ static void e1000_watchdog_task(struct work_struct *work) return; link = e1000e_has_link(adapter); - if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link) - || (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) { - if (!adapter->ecdev) { + if ((get_ecdev(adapter) && (ecdev_get_link(get_ecdev(adapter))) && link) + || (!get_ecdev(adapter) && (netif_carrier_ok(netdev)) && link)) { + if (!get_ecdev(adapter)) { /* Cancel scheduled suspend requests. */ pm_runtime_resume(netdev->dev.parent); } @@ -5328,8 +5328,8 @@ static void e1000_watchdog_task(struct work_struct *work) e1000_update_mng_vlan(adapter); if (link) { - if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && !netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && !ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && !netif_carrier_ok(netdev))) { bool txb2b = true; /* Cancel scheduled suspend requests. */ @@ -5420,27 +5420,27 @@ static void e1000_watchdog_task(struct work_struct *work) if (phy->ops.cfg_on_link_up) phy->ops.cfg_on_link_up(hw); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 1); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 1); } else { netif_wake_queue(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, round_jiffies(jiffies + 2 * HZ)); } } else { - if ((adapter->ecdev && ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && netif_carrier_ok(netdev))) { + if ((get_ecdev(adapter) && ecdev_get_link(get_ecdev(adapter))) + || (!get_ecdev(adapter) && netif_carrier_ok(netdev))) { adapter->link_speed = 0; adapter->link_duplex = 0; /* Link status message must follow this format */ netdev_info(netdev, "NIC Link is Down\n"); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -5542,7 +5542,7 @@ link_up: } /* 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, 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); if (test_bit(__E1000_DOWN, &adapter->state)) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); return NETDEV_TX_BUSY; } if (skb->len <= 0) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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); if (!__pskb_pull_tail(skb, pull_size)) { e_err("__pskb_pull_tail failed.\n"); - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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 * 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; 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); if (tso < 0) { - if (!adapter->ecdev) + if (!get_ecdev(adapter)) dev_kfree_skb_any(skb); 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); e1000_tx_queue(tx_ring, tx_flags, count); /* 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, ((MAX_SKB_FRAGS + 1) * DIV_ROUND_UP(PAGE_SIZE, 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))) { if (check_arbiter_wa_flag(adapter)) 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); } } else { - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(skb); } 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); int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; /* Jumbo frame support */ @@ -7033,7 +7033,7 @@ static int __e1000_resume(struct pci_dev *pdev) struct e1000_hw *hw = &adapter->hw; u16 aspm_disable_flag = 0; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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); int rc; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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->max_hw_frame_size = ei->max_hw_frame_size; adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->ecdev_initialized = 0; mmio_start = pci_resource_start(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) adapter->flags2 |= FLAG2_ENABLE_S0IX_FLOWS; - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->watchdog_kicker, ec_watchdog_kicker); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } adapter->ec_watchdog_jiffies = jiffies; @@ -7921,10 +7923,10 @@ static void e1000_remove(struct pci_dev *pdev) e1000e_ptp_remove(adapter); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } /* 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); } diff --git a/devices/genet/Kbuild.in b/devices/genet/Kbuild.in index 40c6f698..425808b1 100644 --- a/devices/genet/Kbuild.in +++ b/devices/genet/Kbuild.in @@ -38,6 +38,10 @@ ifeq (@ENABLE_GENET@,1) bcmmii-@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)\"" endif diff --git a/devices/genet/bcmgenet-6.1-ethercat.c b/devices/genet/bcmgenet-6.1-ethercat.c index f9593fb6..e75925b1 100644 --- a/devices/genet/bcmgenet-6.1-ethercat.c +++ b/devices/genet/bcmgenet-6.1-ethercat.c @@ -1897,7 +1897,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, if (skb) { pkts_compl++; bytes_compl += GENET_CB(skb)->bytes_sent; - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_consume_skb_any(skb); } @@ -1914,7 +1914,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, ring->packets += pkts_compl; ring->bytes += bytes_compl; - if (!priv->ecdev) + if (!get_ecdev(priv)) netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue), pkts_compl, bytes_compl); @@ -1940,7 +1940,7 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget) unsigned int work_done = 0; struct netdev_queue *txq; - if (ring->priv->ecdev) + if (get_ecdev(ring->priv)) return 0; 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 * 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)); if (!new_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); 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); netdev_err(dev, "%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 &= DMA_P_INDEX_MASK; - if (!priv->ecdev) { + if (!get_ecdev(priv)) { netdev_tx_sent_queue(txq, GENET_CB(skb)->bytes_sent); if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) 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 */ bcmgenet_tdma_ring_writel(priv, ring->index, ring->prod_index, TDMA_PROD_INDEX); @@ -2184,7 +2184,7 @@ out_unmap_frags: bcmgenet_free_tx_cb(kdev, tx_cb_ptr); } - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb(skb); goto out; } @@ -2250,7 +2250,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, unsigned int p_index, mask; unsigned int discards; - if (!priv->ecdev) { + if (!get_ecdev(priv)) { /* Clear status before servicing to reduce spurious interrupts */ if (ring->index == DESC_INDEX) { 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; cb = &priv->rx_cbs[ring->read_ptr]; - if (priv->ecdev) + if (get_ecdev(priv)) /* DMA unmap current skb */ skb = bcmgenet_free_rx_cb(kdev, cb); 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"); dev->stats.rx_length_errors++; dev->stats.rx_errors++; - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb_any(skb); goto next; } @@ -2337,7 +2337,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, netif_err(priv, rx_status, dev, "dropping fragmented packet!\n"); ring->errors++; - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb_any(skb); goto next; } @@ -2359,12 +2359,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, if (dma_flag & DMA_RX_LG) dev->stats.rx_length_errors++; dev->stats.rx_errors++; - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb_any(skb); goto next; } /* error packet */ - if (!priv->ecdev) { + if (!get_ecdev(priv)) { skb_put(skb, len); /* 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; if (priv->crc_fwd_en) { - if (!priv->ecdev) + if (!get_ecdev(priv)) skb_trim(skb, 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) dev->stats.multicast++; - if (priv->ecdev) { + if (get_ecdev(priv)) { dma_addr_t mapping; /* skip status block and padding in skb */ const unsigned char *data = skb->data + 66; - ecdev_receive(priv->ecdev, data, len); + ecdev_receive(get_ecdev(priv), data, len); /* remap skb */ 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 = {}; unsigned int work_done; - if (ring->priv->ecdev) + if (get_ecdev(ring->priv)) return 0; 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+ */ if (priv->hw_params->flags & GENET_HAS_MDIO_INTR) { int0_enable |= UMAC_IRQ_MDIO_ERROR; - if (!priv->ecdev) + if (!get_ecdev(priv)) 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; pkts = ring->rx_max_coalesced_frames; - if (ring->priv->ecdev) + if (get_ecdev(ring->priv)) return; /* 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); /* Initialize Tx NAPI */ - if (!priv->ecdev) + if (!get_ecdev(priv)) 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); /* Initialize Rx NAPI */ - if (!priv->ecdev) + if (!get_ecdev(priv)) netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll); 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; struct bcmgenet_tx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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; struct bcmgenet_tx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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; struct bcmgenet_tx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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; struct bcmgenet_rx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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; struct bcmgenet_rx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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; struct bcmgenet_rx_ring *ring; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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); - if (!priv->ecdev) + if (!get_ecdev(priv)) netif_tx_start_all_queues(dev); return 0; @@ -4089,6 +4089,7 @@ static int bcmgenet_probe(struct platform_device *pdev) } priv = netdev_priv(dev); + priv->ecdev_initialized = false; priv->irq0 = platform_get_irq(pdev, 0); if (priv->irq0 < 0) { 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 */ clk_disable_unprepare(priv->clk); - priv->ecdev = ecdev_offer(dev, ec_poll, THIS_MODULE); - if (priv->ecdev) { - err = ecdev_open(priv->ecdev); + priv->ecdev_ = ecdev_offer(dev, ec_poll, THIS_MODULE); + priv->ecdev_initialized = true; + if (get_ecdev(priv)) { + err = ecdev_open(get_ecdev(priv)); if (err) { - ecdev_withdraw(priv->ecdev); - priv->ecdev = NULL; + ecdev_withdraw(get_ecdev(priv)); + priv->ecdev_ = NULL; bcmgenet_mii_exit(dev); goto err; } @@ -4276,10 +4278,10 @@ static int bcmgenet_remove(struct platform_device *pdev) struct bcmgenet_priv *priv = dev_to_priv(&pdev->dev); dev_set_drvdata(&pdev->dev, NULL); - if (priv->ecdev) { - ecdev_close(priv->ecdev); - ecdev_withdraw(priv->ecdev); - priv->ecdev = NULL; + if (get_ecdev(priv)) { + ecdev_close(get_ecdev(priv)); + ecdev_withdraw(get_ecdev(priv)); + priv->ecdev_ = NULL; } else unregister_netdev(priv->dev); bcmgenet_mii_exit(priv->dev); @@ -4301,8 +4303,8 @@ static int bcmgenet_resume_noirq(struct device *d) int ret; u32 reg; - if (priv->ecdev) - ecdev_open(priv->ecdev); + if (get_ecdev(priv)) + ecdev_open(get_ecdev(priv)); else if (!netif_running(dev)) return 0; @@ -4388,8 +4390,8 @@ static int bcmgenet_resume(struct device *d) bcmgenet_netif_start(dev); - if (priv->ecdev) - ecdev_open(priv->ecdev); + if (get_ecdev(priv)) + ecdev_open(get_ecdev(priv)); else netif_device_attach(dev); @@ -4407,8 +4409,8 @@ static int bcmgenet_suspend(struct device *d) struct net_device *dev = dev_get_drvdata(d); struct bcmgenet_priv *priv = netdev_priv(dev); - if (priv->ecdev) { - ecdev_close(priv->ecdev); + if (get_ecdev(priv)) { + ecdev_close(get_ecdev(priv)); } else { if (!netif_running(dev)) return 0; @@ -4433,8 +4435,8 @@ static int bcmgenet_suspend_noirq(struct device *d) struct bcmgenet_priv *priv = netdev_priv(dev); int ret = 0; - if (priv->ecdev) { - ecdev_close(priv->ecdev); + if (get_ecdev(priv)) { + ecdev_close(get_ecdev(priv)); } else if (!netif_running(dev)) return 0; diff --git a/devices/genet/bcmgenet-6.1-ethercat.h b/devices/genet/bcmgenet-6.1-ethercat.h index e624e4cf..aec31f42 100644 --- a/devices/genet/bcmgenet-6.1-ethercat.h +++ b/devices/genet/bcmgenet-6.1-ethercat.h @@ -650,9 +650,19 @@ struct bcmgenet_priv { struct ethtool_eee eee; /* 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) \ static inline u32 bcmgenet_##name##_readl(struct bcmgenet_priv *priv, \ u32 off) \ diff --git a/devices/genet/bcmmii-6.1-ethercat.c b/devices/genet/bcmmii-6.1-ethercat.c index 36bc8a1e..b8ddbaa8 100644 --- a/devices/genet/bcmmii-6.1-ethercat.c +++ b/devices/genet/bcmmii-6.1-ethercat.c @@ -105,8 +105,8 @@ void bcmgenet_mii_setup(struct net_device *dev) if (phydev->link) bcmgenet_mac_config(dev); - if (priv->ecdev) - ecdev_set_link(priv->ecdev, phydev->link); + if (get_ecdev(priv)) + ecdev_set_link(get_ecdev(priv), phydev->link); phy_print_status(phydev); } diff --git a/devices/igb/Kbuild.in b/devices/igb/Kbuild.in index 65c1e58d..3be67397 100644 --- a/devices/igb/Kbuild.in +++ b/devices/igb/Kbuild.in @@ -37,6 +37,10 @@ REV := $(shell if test -s $(TOPDIR)/revision; then \ ifeq (@ENABLE_IGB@,1) obj-m += ec_igb.o +ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1) + ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING +endif + ec_igb-objs := \ e1000_82575-@KERNEL_IGB@-ethercat.o \ e1000_i210-@KERNEL_IGB@-ethercat.o \ diff --git a/devices/igb/igb-5.14-ethercat.h b/devices/igb/igb-5.14-ethercat.h index 59392816..4170d7d4 100644 --- a/devices/igb/igb-5.14-ethercat.h +++ b/devices/igb/igb-5.14-ethercat.h @@ -670,11 +670,20 @@ struct igb_adapter { struct vf_mac_filter *vf_mac_list; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 */ #define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_OVERFLOW_CHECK BIT(1) diff --git a/devices/igb/igb-5.15-ethercat.h b/devices/igb/igb-5.15-ethercat.h index 02c798fe..b28929e8 100644 --- a/devices/igb/igb-5.15-ethercat.h +++ b/devices/igb/igb-5.15-ethercat.h @@ -670,11 +670,20 @@ struct igb_adapter { struct vf_mac_filter *vf_mac_list; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 */ #define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_OVERFLOW_CHECK BIT(1) diff --git a/devices/igb/igb-6.1-ethercat.h b/devices/igb/igb-6.1-ethercat.h index dbdf917d..8ed16222 100644 --- a/devices/igb/igb-6.1-ethercat.h +++ b/devices/igb/igb-6.1-ethercat.h @@ -672,11 +672,20 @@ struct igb_adapter { spinlock_t vfs_lock; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 */ #define IGB_PTP_ENABLED BIT(0) #define IGB_PTP_OVERFLOW_CHECK BIT(1) diff --git a/devices/igb/igb_main-3.18-ethercat.c b/devices/igb/igb_main-3.18-ethercat.c index 36f7bda5..44c41fa4 100644 --- a/devices/igb/igb_main-3.18-ethercat.c +++ b/devices/igb/igb_main-3.18-ethercat.c @@ -1047,10 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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) @@ -1221,11 +1218,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, if (!q_vector) return -ENOMEM; - if (!adapter->ecdev) { - /* initialize NAPI */ - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + /* initialize NAPI */ + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ adapter->q_vector[v_idx] = q_vector; @@ -6430,6 +6425,9 @@ static int igb_poll(struct napi_struct *napi, int budget) napi); bool clean_complete = true; + if (q_vector->adapter->ecdev) + return -EBUSY; + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) igb_update_dca(q_vector); diff --git a/devices/igb/igb_main-4.19-ethercat.c b/devices/igb/igb_main-4.19-ethercat.c index a4169472..d49ae92e 100644 --- a/devices/igb/igb_main-4.19-ethercat.c +++ b/devices/igb/igb_main-4.19-ethercat.c @@ -1037,10 +1037,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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) @@ -1219,11 +1216,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, if (!q_vector) return -ENOMEM; - if (!adapter->ecdev) { - /* initialize NAPI */ - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + /* initialize NAPI */ + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ 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; int work_done = 0; + if (q_vector->adapter->ecdev) + return -EBUSY; + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) igb_update_dca(q_vector); diff --git a/devices/igb/igb_main-4.4-ethercat.c b/devices/igb/igb_main-4.4-ethercat.c index 0d89fde9..c56686fa 100644 --- a/devices/igb/igb_main-4.4-ethercat.c +++ b/devices/igb/igb_main-4.4-ethercat.c @@ -1047,10 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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) @@ -1227,11 +1224,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, if (!q_vector) return -ENOMEM; - if (!adapter->ecdev) { - /* initialize NAPI */ - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + /* initialize NAPI */ + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ 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; int work_done = 0; + if (q_vector->adapter->ecdev) + return -EBUSY; + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) igb_update_dca(q_vector); diff --git a/devices/igb/igb_main-5.10-ethercat.c b/devices/igb/igb_main-5.10-ethercat.c index 719a03d4..8443832c 100644 --- a/devices/igb/igb_main-5.10-ethercat.c +++ b/devices/igb/igb_main-5.10-ethercat.c @@ -1036,9 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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) @@ -1218,10 +1216,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter, return -ENOMEM; /* initialize NAPI */ - if (!adapter->ecdev) { - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ 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->gso_segs = 1; - if (unlikely(!adapter->ecdev && + if (unlikely(!adapter->ecdev && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 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; int work_done = 0; + if (q_vector->adapter->ecdev) { + return -EBUSY; + } + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) 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_packets += total_packets; - if (!adapter->ecdev && + if (!adapter->ecdev && test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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++; continue; } - + /* verify the packet layout is correct */ if (igb_cleanup_headers(rx_ring, rx_desc, skb)) { skb = NULL; diff --git a/devices/igb/igb_main-5.14-ethercat.c b/devices/igb/igb_main-5.14-ethercat.c index c012e353..3c6c20ac 100644 --- a/devices/igb/igb_main-5.14-ethercat.c +++ b/devices/igb/igb_main-5.14-ethercat.c @@ -946,7 +946,7 @@ static int igb_request_msix(struct igb_adapter *adapter) struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return 0; } @@ -1047,8 +1047,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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; /* initialize NAPI */ - if (!adapter->ecdev) { - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ 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); - 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, netdev->name, adapter); if (!err) @@ -1461,7 +1458,7 @@ static int igb_request_irq(struct igb_adapter *adapter) adapter->flags &= ~IGB_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, netdev->name, adapter); @@ -1476,7 +1473,7 @@ request_done: static void igb_free_irq(struct igb_adapter *adapter) { - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { int vector = 0, i; @@ -1516,7 +1513,7 @@ static void igb_irq_disable(struct igb_adapter *adapter) wr32(E1000_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchronizing IRQs */ return; } @@ -1538,7 +1535,7 @@ static void igb_irq_enable(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { @@ -2156,7 +2153,7 @@ int igb_up(struct igb_adapter *adapter) clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&(adapter->q_vector[i]->napi)); } @@ -2179,7 +2176,7 @@ int igb_up(struct igb_adapter *adapter) wr32(E1000_CTRL_EXT, reg_data); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* start the watchdog. */ @@ -2213,7 +2210,7 @@ void igb_down(struct igb_adapter *adapter) igb_nfc_filter_exit(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_disable(&adapter->q_vector[i]->napi); } @@ -2454,7 +2451,7 @@ void igb_reset(struct igb_adapter *adapter) break; } } - if (!adapter->ecdev && !netif_running(adapter->netdev)) + if (!get_ecdev(adapter) && !netif_running(adapter->netdev)) igb_power_down_link(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) { struct igb_adapter *adapter = netdev_priv(dev); - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; @@ -2987,7 +2984,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n, int nxmit = 0; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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 = netdev; adapter->pdev = pdev; + adapter->ecdev_initialized = 0; hw = &adapter->hw; hw->back = adapter; 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); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } pm_runtime_get_noresume(&pdev->dev); @@ -3921,7 +3920,7 @@ static void igb_remove(struct pci_dev *pdev) igb_disable_sriov(pdev); #endif - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -4164,8 +4163,8 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); } @@ -4193,7 +4192,7 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(adapter->netdev, 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() */ clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) 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); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = 1; 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_use = 0; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) rx_ring->xdp_prog = adapter->xdp_prog; /* XDP RX-queue info */ @@ -4795,7 +4794,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, int reg_idx = ring->reg_idx; u32 rxdctl = 0; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, 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 */ struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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 igb_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -6379,7 +6378,7 @@ dma_error: DMA_TO_DEVICE); dma_unmap_len_set(tx_buffer, len, 0); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -6497,7 +6496,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, first->bytecount = skb->len; first->gso_segs = 1; - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 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; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); first->skb = NULL; } 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); adapter->ptp_tx_skb = NULL; 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; int work_done = 0; + if (get_ecdev(q_vector->adapter)) { + return -EBUSY; + } + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) 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; /* free the skb */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (tx_buffer->type == IGB_TYPE_SKB) napi_consume_skb(tx_buffer->skb, napi_budget); else @@ -8267,7 +8270,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget) budget--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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_packets += total_packets; - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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); 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); - ecdev_receive(adapter->ecdev, pktbuf, size); + ecdev_receive(get_ecdev(adapter), pktbuf, size); adapter->ec_watchdog_jiffies = jiffies; igb_reuse_rx_page(rx_ring, rx_buffer); } 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)) continue; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; continue; } diff --git a/devices/igb/igb_main-5.15-ethercat.c b/devices/igb/igb_main-5.15-ethercat.c index 4d3703a5..58db950c 100644 --- a/devices/igb/igb_main-5.15-ethercat.c +++ b/devices/igb/igb_main-5.15-ethercat.c @@ -935,7 +935,7 @@ static int igb_request_msix(struct igb_adapter *adapter) struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return 0; } @@ -1036,8 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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; /* initialize NAPI */ - if (!adapter->ecdev) { - netif_napi_add(adapter->netdev, &q_vector->napi, - igb_poll, 64); - } + netif_napi_add(adapter->netdev, &q_vector->napi, + igb_poll, 64); /* tie q_vector and adapter together */ 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); - 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, netdev->name, adapter); if (!err) @@ -1450,7 +1447,7 @@ static int igb_request_irq(struct igb_adapter *adapter) adapter->flags &= ~IGB_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, netdev->name, adapter); @@ -1465,7 +1462,7 @@ request_done: static void igb_free_irq(struct igb_adapter *adapter) { - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { int vector = 0, i; @@ -1505,7 +1502,7 @@ static void igb_irq_disable(struct igb_adapter *adapter) wr32(E1000_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchronizing IRQs */ return; } @@ -1527,7 +1524,7 @@ static void igb_irq_enable(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { @@ -2145,7 +2142,7 @@ int igb_up(struct igb_adapter *adapter) clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&(adapter->q_vector[i]->napi)); } @@ -2168,7 +2165,7 @@ int igb_up(struct igb_adapter *adapter) wr32(E1000_CTRL_EXT, reg_data); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* start the watchdog. */ @@ -2202,7 +2199,7 @@ void igb_down(struct igb_adapter *adapter) igb_nfc_filter_exit(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_disable(&adapter->q_vector[i]->napi); } @@ -2443,7 +2440,7 @@ void igb_reset(struct igb_adapter *adapter) break; } } - if (!adapter->ecdev && !netif_running(adapter->netdev)) + if (!get_ecdev(adapter) && !netif_running(adapter->netdev)) igb_power_down_link(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) { struct igb_adapter *adapter = netdev_priv(dev); - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; @@ -2976,7 +2973,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n, int nxmit = 0; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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 = netdev; adapter->pdev = pdev; + adapter->ecdev_initialized = 0; hw = &adapter->hw; hw->back = adapter; 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); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } pm_runtime_get_noresume(&pdev->dev); @@ -3906,7 +3905,7 @@ static void igb_remove(struct pci_dev *pdev) igb_disable_sriov(pdev); #endif - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -4149,8 +4148,8 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); } @@ -4178,7 +4177,7 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(adapter->netdev, 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() */ clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) 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); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = 1; 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; int size, res; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* XDP RX-queue info */ if (xdp_rxq_info_is_reg(&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_use = 0; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) rx_ring->xdp_prog = adapter->xdp_prog; return 0; @@ -4789,7 +4788,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, int reg_idx = ring->reg_idx; u32 rxdctl = 0; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, 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 */ struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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 igb_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -6369,7 +6368,7 @@ dma_error: DMA_TO_DEVICE); dma_unmap_len_set(tx_buffer, len, 0); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -6487,7 +6486,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, first->bytecount = skb->len; first->gso_segs = 1; - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 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; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); first->skb = NULL; } 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); adapter->ptp_tx_skb = NULL; 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; int work_done = 0; + if (get_ecdev(q_vector->adapter)) { + return -EBUSY; + } + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) 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; /* free the skb */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (tx_buffer->type == IGB_TYPE_SKB) napi_consume_skb(tx_buffer->skb, napi_budget); else @@ -8257,7 +8260,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget) budget--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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_packets += total_packets; - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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); 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); - ecdev_receive(adapter->ecdev, pktbuf, size); + ecdev_receive(get_ecdev(adapter), pktbuf, size); adapter->ec_watchdog_jiffies = jiffies; igb_reuse_rx_page(rx_ring, rx_buffer); } 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)) continue; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; continue; } - + /* verify the packet layout is correct */ if (igb_cleanup_headers(rx_ring, rx_desc, skb)) { skb = NULL; diff --git a/devices/igb/igb_main-6.1-ethercat.c b/devices/igb/igb_main-6.1-ethercat.c index 8c1c1165..a5dd91a6 100644 --- a/devices/igb/igb_main-6.1-ethercat.c +++ b/devices/igb/igb_main-6.1-ethercat.c @@ -933,7 +933,7 @@ static int igb_request_msix(struct igb_adapter *adapter) struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { return 0; } @@ -1034,8 +1034,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx) if (q_vector->rx.ring) 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; /* 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 */ 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); - 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, netdev->name, adapter); if (!err) @@ -1451,7 +1448,7 @@ static int igb_request_irq(struct igb_adapter *adapter) adapter->flags &= ~IGB_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, igb_intr, IRQF_SHARED, netdev->name, adapter); @@ -1466,7 +1463,7 @@ request_done: static void igb_free_irq(struct igb_adapter *adapter) { - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { int vector = 0, i; @@ -1506,7 +1503,7 @@ static void igb_irq_disable(struct igb_adapter *adapter) wr32(E1000_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchronizing IRQs */ return; } @@ -1528,7 +1525,7 @@ static void igb_irq_enable(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) + if (get_ecdev(adapter)) return; if (adapter->flags & IGB_FLAG_HAS_MSIX) { @@ -2146,7 +2143,7 @@ int igb_up(struct igb_adapter *adapter) clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&(adapter->q_vector[i]->napi)); } @@ -2169,7 +2166,7 @@ int igb_up(struct igb_adapter *adapter) wr32(E1000_CTRL_EXT, reg_data); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* start the watchdog. */ @@ -2203,7 +2200,7 @@ void igb_down(struct igb_adapter *adapter) igb_nfc_filter_exit(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_disable(&adapter->q_vector[i]->napi); } @@ -2469,7 +2466,7 @@ void igb_reset(struct igb_adapter *adapter) break; } } - if (!adapter->ecdev && !netif_running(adapter->netdev)) + if (!get_ecdev(adapter) && !netif_running(adapter->netdev)) igb_power_down_link(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) { struct igb_adapter *adapter = netdev_priv(dev); - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; @@ -3002,7 +2999,7 @@ static int igb_xdp_xmit(struct net_device *dev, int n, int nxmit = 0; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) return -EBUSY; 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 = netdev; adapter->pdev = pdev; + adapter->ecdev_initialized = 0; hw = &adapter->hw; hw->back = adapter; 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); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = 1; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 e1000_hw *hw = &adapter->hw; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } pm_runtime_get_noresume(&pdev->dev); @@ -3933,7 +3932,7 @@ static void igb_remove(struct pci_dev *pdev) igb_disable_sriov(pdev); #endif - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -4179,8 +4178,8 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); } @@ -4208,7 +4207,7 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(adapter->netdev, 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() */ clear_bit(__IGB_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) 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); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = 1; 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; int size, res; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* XDP RX-queue info */ if (xdp_rxq_info_is_reg(&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_use = 0; - if (!adapter->ecdev) + if (!get_ecdev(adapter)) rx_ring->xdp_prog = adapter->xdp_prog; return 0; @@ -4819,7 +4818,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, int reg_idx = ring->reg_idx; u32 rxdctl = 0; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); WARN_ON(xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, 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 */ struct igb_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (tx_buffer->type == IGB_TYPE_SKB) dev_kfree_skb_any(tx_buffer->skb); 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 igb_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -6403,7 +6402,7 @@ dma_error: DMA_TO_DEVICE); dma_unmap_len_set(tx_buffer, len, 0); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -6555,7 +6554,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, first->bytecount = skb->len; first->gso_segs = 1; - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 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; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); first->skb = NULL; } 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); adapter->ptp_tx_skb = NULL; 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; int work_done = 0; + if (get_ecdev(q_vector->adapter)) { + return -EBUSY; + } + #ifdef CONFIG_IGB_DCA if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) 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; /* free the skb */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { if (tx_buffer->type == IGB_TYPE_SKB) napi_consume_skb(tx_buffer->skb, napi_budget); else @@ -8410,7 +8413,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget) budget--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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_packets += total_packets; - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igb_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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); 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); - ecdev_receive(adapter->ecdev, pktbuf, size); + ecdev_receive(get_ecdev(adapter), pktbuf, size); adapter->ec_watchdog_jiffies = jiffies; igb_reuse_rx_page(rx_ring, rx_buffer); } 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)) continue; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; continue; } diff --git a/devices/igc/Kbuild.in b/devices/igc/Kbuild.in index e896c9c1..201ff013 100644 --- a/devices/igc/Kbuild.in +++ b/devices/igc/Kbuild.in @@ -48,6 +48,10 @@ ifeq (@ENABLE_IGC@,1) igc_ethtool-@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) endif diff --git a/devices/igc/igc-5.14-ethercat.h b/devices/igc/igc-5.14-ethercat.h index 78b576a6..c41d6583 100644 --- a/devices/igc/igc-5.14-ethercat.h +++ b/devices/igc/igc-5.14-ethercat.h @@ -249,7 +249,7 @@ struct igc_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); #endif return adapter->ecdev_; diff --git a/devices/igc/igc-6.1-ethercat.h b/devices/igc/igc-6.1-ethercat.h index 0f083bfa..13330ed5 100644 --- a/devices/igc/igc-6.1-ethercat.h +++ b/devices/igc/igc-6.1-ethercat.h @@ -254,11 +254,20 @@ struct igc_adapter { } perout[IGC_N_PEROUT]; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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_down(struct igc_adapter *adapter); int igc_open(struct net_device *netdev); diff --git a/devices/igc/igc-6.4-ethercat.h b/devices/igc/igc-6.4-ethercat.h index 5f01efdf..0b6f7c26 100644 --- a/devices/igc/igc-6.4-ethercat.h +++ b/devices/igc/igc-6.4-ethercat.h @@ -267,11 +267,20 @@ struct igc_adapter { } perout[IGC_N_PEROUT]; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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_down(struct igc_adapter *adapter); int igc_open(struct net_device *netdev); diff --git a/devices/igc/igc-6.6-ethercat.h b/devices/igc/igc-6.6-ethercat.h index dc1b5813..8131a05d 100644 --- a/devices/igc/igc-6.6-ethercat.h +++ b/devices/igc/igc-6.6-ethercat.h @@ -282,11 +282,20 @@ struct igc_adapter { } perout[IGC_N_PEROUT]; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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_down(struct igc_adapter *adapter); int igc_open(struct net_device *netdev); diff --git a/devices/igc/igc_main-5.14-ethercat.c b/devices/igc/igc_main-5.14-ethercat.c index 0c83a84d..2dac8faf 100644 --- a/devices/igc/igc_main-5.14-ethercat.c +++ b/devices/igc/igc_main-5.14-ethercat.c @@ -4023,6 +4023,9 @@ static int igc_poll(struct napi_struct *napi, int budget) bool clean_complete = true; int work_done = 0; + if (get_ecdev(q_vector->adapter)) + return -EBUSY; + if (q_vector->tx.ring) clean_complete = igc_clean_tx_irq(q_vector, budget); diff --git a/devices/igc/igc_main-6.1-ethercat.c b/devices/igc/igc_main-6.1-ethercat.c index bd6cfc46..daaa7f17 100644 --- a/devices/igc/igc_main-6.1-ethercat.c +++ b/devices/igc/igc_main-6.1-ethercat.c @@ -212,7 +212,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring) case IGC_TX_BUFFER_TYPE_SKB: { struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* skb is reused in EtherCAT TX operation */ 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 igc_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -1413,7 +1413,7 @@ dma_error: if (dma_unmap_len(tx_buffer, len)) igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -1584,7 +1584,7 @@ done: first->bytecount = skb->len; first->gso_segs = 1; - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { /* FIXME: add support for retrieving timestamps from * the other timer registers before skipping the @@ -1623,7 +1623,7 @@ done: return NETDEV_TX_OK; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); 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_bytes += size; } - else if (adapter->ecdev) { + else if (get_ecdev(adapter)) { unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; 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; 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; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; 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); break; case IGC_TX_BUFFER_TYPE_SKB: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_consume_skb(tx_buffer->skb, napi_budget); } 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--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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); } - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip enabling interrupts */ return; } @@ -4032,7 +4032,7 @@ static void igc_irq_disable(struct igc_adapter *adapter) wr32(IGC_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchonizing IRQs */ return; } @@ -4503,6 +4503,9 @@ static int igc_poll(struct napi_struct *napi, int budget) bool clean_complete = true; int work_done = 0; + if (get_ecdev(q_vector->adapter)) + return -EBUSY; + if (q_vector->tx.ring) clean_complete = igc_clean_tx_irq(q_vector, budget); @@ -4794,7 +4797,7 @@ void igc_up(struct igc_adapter *adapter) igc_configure(adapter); clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -4807,7 +4810,7 @@ void igc_up(struct igc_adapter *adapter) rd32(IGC_ICR); igc_irq_enable(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* 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 */ netif_trans_update(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_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; int i = 0, err = 0, vector = 0, free_vector = 0; struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* avoid requesting MSI-X. */ return 0; } @@ -5519,13 +5522,13 @@ static void igc_watchdog_task(struct work_struct *work) u32 link; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) hw->mac.get_link_status = true; link = igc_has_link(adapter); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, link); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), link); return; } @@ -5782,7 +5785,7 @@ static irqreturn_t igc_intr(int irq, void *data) static void igc_free_irq(struct igc_adapter *adapter) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* no IRQ to free in EtherCAT operation */ return; } @@ -5832,7 +5835,7 @@ static int igc_request_irq(struct igc_adapter *adapter) 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, netdev->name, adapter); if (!err) @@ -5843,7 +5846,7 @@ static int igc_request_irq(struct igc_adapter *adapter) adapter->flags &= ~IGC_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, netdev->name, adapter); @@ -5885,8 +5888,8 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -5910,7 +5913,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); if (err) @@ -5922,7 +5925,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) } clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -5934,11 +5937,11 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = true; schedule_work(&adapter->watchdog_task); @@ -6739,12 +6742,13 @@ static int igc_probe(struct pci_dev *pdev, */ igc_get_hw_control(adapter); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = true; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 igc_adapter *adapter = netdev_priv(netdev); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } 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. */ igc_release_hw_control(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -6859,8 +6863,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake, u32 ctrl, rctl, status; bool wake; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); } else { rtnl_lock(); netif_device_detach(netdev); @@ -7000,8 +7004,8 @@ static int __maybe_unused igc_resume(struct device *dev) wr32(IGC_WUS, ~0); - if (adapter->ecdev) { - ecdev_open(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_open(get_ecdev(adapter)); } else { rtnl_lock(); if (!err && netif_running(netdev)) diff --git a/devices/igc/igc_main-6.4-ethercat.c b/devices/igc/igc_main-6.4-ethercat.c index b9e24d0b..67001f28 100644 --- a/devices/igc/igc_main-6.4-ethercat.c +++ b/devices/igc/igc_main-6.4-ethercat.c @@ -211,7 +211,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring) case IGC_TX_BUFFER_TYPE_SKB: { struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* skb is reused in EtherCAT TX operation */ 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 igc_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -1414,7 +1414,7 @@ dma_error: if (dma_unmap_len(tx_buffer, len)) igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -1593,7 +1593,7 @@ done: goto out_drop; } - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { /* FIXME: add support for retrieving timestamps from @@ -1636,7 +1636,7 @@ done: return NETDEV_TX_OK; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); 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_bytes += size; } - else if (adapter->ecdev) { + else if (get_ecdev(adapter)) { unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; 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; 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; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; 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); break; case IGC_TX_BUFFER_TYPE_SKB: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_consume_skb(tx_buffer->skb, napi_budget); } 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--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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); } - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip enabling interrupts */ return; } @@ -4083,7 +4083,7 @@ static void igc_irq_disable(struct igc_adapter *adapter) wr32(IGC_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchonizing IRQs */ return; } @@ -4554,6 +4554,9 @@ static int igc_poll(struct napi_struct *napi, int budget) bool clean_complete = true; int work_done = 0; + if (get_ecdev(q_vector->adapter)) + return -EBUSY; + if (q_vector->tx.ring) clean_complete = igc_clean_tx_irq(q_vector, budget); @@ -4846,7 +4849,7 @@ void igc_up(struct igc_adapter *adapter) igc_configure(adapter); clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -4859,7 +4862,7 @@ void igc_up(struct igc_adapter *adapter) rd32(IGC_ICR); igc_irq_enable(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* 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 */ netif_trans_update(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_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; int i = 0, err = 0, vector = 0, free_vector = 0; struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* avoid requesting MSI-X. */ return 0; } @@ -5572,13 +5575,13 @@ static void igc_watchdog_task(struct work_struct *work) u32 link; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) hw->mac.get_link_status = true; link = igc_has_link(adapter); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, link); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), link); return; } @@ -5825,7 +5828,7 @@ static irqreturn_t igc_intr(int irq, void *data) static void igc_free_irq(struct igc_adapter *adapter) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* no IRQ to free in EtherCAT operation */ return; } @@ -5875,7 +5878,7 @@ static int igc_request_irq(struct igc_adapter *adapter) 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, netdev->name, adapter); if (!err) @@ -5886,7 +5889,7 @@ static int igc_request_irq(struct igc_adapter *adapter) adapter->flags &= ~IGC_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, netdev->name, adapter); @@ -5928,8 +5931,8 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -5953,7 +5956,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); if (err) @@ -5965,7 +5968,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) } clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -5977,11 +5980,11 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = true; schedule_work(&adapter->watchdog_task); @@ -6913,12 +6916,13 @@ static int igc_probe(struct pci_dev *pdev, */ igc_get_hw_control(adapter); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = true; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 igc_adapter *adapter = netdev_priv(netdev); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } 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. */ igc_release_hw_control(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -7031,8 +7035,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake, u32 ctrl, rctl, status; bool wake; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); } else { rtnl_lock(); netif_device_detach(netdev); @@ -7172,8 +7176,8 @@ static int __maybe_unused igc_resume(struct device *dev) wr32(IGC_WUS, ~0); - if (adapter->ecdev) { - ecdev_open(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_open(get_ecdev(adapter)); } else { rtnl_lock(); if (!err && netif_running(netdev)) diff --git a/devices/igc/igc_main-6.6-ethercat.c b/devices/igc/igc_main-6.6-ethercat.c index 14cd159f..0a92adb8 100644 --- a/devices/igc/igc_main-6.6-ethercat.c +++ b/devices/igc/igc_main-6.6-ethercat.c @@ -211,7 +211,7 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring) case IGC_TX_BUFFER_TYPE_SKB: { struct igc_adapter *adapter = netdev_priv(tx_ring->netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* skb is reused in EtherCAT TX operation */ 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 igc_adapter *adapter = netdev_priv(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { 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; /* A reprieve! */ - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_wake_subqueue(netdev, tx_ring->queue_index); } @@ -1452,7 +1452,7 @@ dma_error: if (dma_unmap_len(tx_buffer, len)) igc_unmap_tx_buffer(tx_ring->dev, tx_buffer); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(tx_buffer->skb); tx_buffer->skb = NULL; } @@ -1651,7 +1651,7 @@ done: goto out_drop; } - if (unlikely(!adapter->ecdev && + if (unlikely(!get_ecdev(adapter) && test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { /* FIXME: add support for retrieving timestamps from @@ -1692,7 +1692,7 @@ done: return NETDEV_TX_OK; out_drop: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { dev_kfree_skb_any(first->skb); 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_bytes += size; } - else if (adapter->ecdev) { + else if (get_ecdev(adapter)) { unsigned char *va = page_address(rx_buffer->page) + rx_buffer->page_offset; 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; 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; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { total_packets++; 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); break; case IGC_TX_BUFFER_TYPE_SKB: - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { napi_consume_skb(tx_buffer->skb, napi_budget); } 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--; } while (likely(budget)); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netdev_tx_completed_queue(txring_txq(tx_ring), 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); } - if (!adapter->ecdev && + if (!get_ecdev(adapter) && test_bit(IGC_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 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) - if (unlikely(!adapter->ecdev && total_packets && + if (unlikely(!get_ecdev(adapter) && total_packets && netif_carrier_ok(tx_ring->netdev) && igc_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD)) { /* 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) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip enabling interrupts */ return; } @@ -4146,7 +4146,7 @@ static void igc_irq_disable(struct igc_adapter *adapter) wr32(IGC_IMC, ~0); wrfl(); - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* skip synchonizing IRQs */ return; } @@ -4617,6 +4617,9 @@ static int igc_poll(struct napi_struct *napi, int budget) bool clean_complete = true; int work_done = 0; + if (get_ecdev(q_vector->adapter)) + return -EBUSY; + if (q_vector->tx.ring) clean_complete = igc_clean_tx_irq(q_vector, budget); @@ -4910,7 +4913,7 @@ void igc_up(struct igc_adapter *adapter) igc_configure(adapter); clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -4923,7 +4926,7 @@ void igc_up(struct igc_adapter *adapter) rd32(IGC_ICR); igc_irq_enable(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(adapter->netdev); /* 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 */ netif_trans_update(netdev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_carrier_off(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; 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_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; int i = 0, err = 0, vector = 0, free_vector = 0; struct net_device *netdev = adapter->netdev; - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* avoid requesting MSI-X. */ return 0; } @@ -5637,13 +5640,13 @@ static void igc_watchdog_task(struct work_struct *work) u32 link; int i; - if (adapter->ecdev) + if (get_ecdev(adapter)) hw->mac.get_link_status = true; link = igc_has_link(adapter); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, link); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), link); return; } @@ -5890,7 +5893,7 @@ static irqreturn_t igc_intr(int irq, void *data) static void igc_free_irq(struct igc_adapter *adapter) { - if (adapter->ecdev) { + if (get_ecdev(adapter)) { /* no IRQ to free in EtherCAT operation */ return; } @@ -5940,7 +5943,7 @@ static int igc_request_irq(struct igc_adapter *adapter) 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, netdev->name, adapter); if (!err) @@ -5951,7 +5954,7 @@ static int igc_request_irq(struct igc_adapter *adapter) adapter->flags &= ~IGC_FLAG_HAS_MSI; } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { err = request_irq(pdev->irq, &igc_intr, IRQF_SHARED, netdev->name, adapter); @@ -5993,8 +5996,8 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_get_sync(&pdev->dev); - if (adapter->ecdev) { - ecdev_set_link(adapter->ecdev, 0); + if (get_ecdev(adapter)) { + ecdev_set_link(get_ecdev(adapter), 0); } else { netif_carrier_off(netdev); @@ -6018,7 +6021,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* Notify the stack of the actual queue counts. */ err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); if (err) @@ -6030,7 +6033,7 @@ static int __igc_open(struct net_device *netdev, bool resuming) } clear_bit(__IGC_DOWN, &adapter->state); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { for (i = 0; i < adapter->num_q_vectors; i++) napi_enable(&adapter->q_vector[i]->napi); } @@ -6042,11 +6045,11 @@ static int __igc_open(struct net_device *netdev, bool resuming) if (!resuming) pm_runtime_put(&pdev->dev); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { netif_tx_start_all_queues(netdev); } - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { /* start the watchdog. */ hw->mac.get_link_status = true; schedule_work(&adapter->watchdog_task); @@ -7053,12 +7056,13 @@ static int igc_probe(struct pci_dev *pdev, */ igc_get_hw_control(adapter); - adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE); - if (adapter->ecdev) { + adapter->ecdev_ = ecdev_offer(netdev, ec_poll, THIS_MODULE); + adapter->ecdev_initialized = true; + if (get_ecdev(adapter)) { init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog); - err = ecdev_open(adapter->ecdev); + err = ecdev_open(get_ecdev(adapter)); if (err) { - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); goto err_register; } 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 igc_adapter *adapter = netdev_priv(netdev); - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); irq_work_sync(&adapter->ec_watchdog_kicker); - ecdev_withdraw(adapter->ecdev); + ecdev_withdraw(get_ecdev(adapter)); } 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. */ igc_release_hw_control(adapter); - if (!adapter->ecdev) { + if (!get_ecdev(adapter)) { unregister_netdev(netdev); } @@ -7171,8 +7175,8 @@ static int __igc_shutdown(struct pci_dev *pdev, bool *enable_wake, u32 ctrl, rctl, status; bool wake; - if (adapter->ecdev) { - ecdev_close(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_close(get_ecdev(adapter)); } else { rtnl_lock(); netif_device_detach(netdev); @@ -7312,8 +7316,8 @@ static int __maybe_unused igc_resume(struct device *dev) wr32(IGC_WUS, ~0); - if (adapter->ecdev) { - ecdev_open(adapter->ecdev); + if (get_ecdev(adapter)) { + ecdev_open(get_ecdev(adapter)); } else { rtnl_lock(); if (!err && netif_running(netdev)) diff --git a/devices/r8169/Kbuild.in b/devices/r8169/Kbuild.in index b9857d7a..1e55f6ef 100644 --- a/devices/r8169/Kbuild.in +++ b/devices/r8169/Kbuild.in @@ -41,6 +41,10 @@ ifeq (@R8169_IN_SUBDIR@,1) r8169_phy_config-@KERNEL_R8169@-ethercat.o 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 diff --git a/devices/r8169/r8169_main-5.14-ethercat.c b/devices/r8169/r8169_main-5.14-ethercat.c index 7afebba7..287bda91 100644 --- a/devices/r8169/r8169_main-5.14-ethercat.c +++ b/devices/r8169/r8169_main-5.14-ethercat.c @@ -652,11 +652,20 @@ struct rtl8169_private { u32 ocp_base; - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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); MODULE_AUTHOR("Realtek and the Linux r8169 crew "); @@ -1329,7 +1338,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp) { - if (tp->ecdev) + if (get_ecdev(tp)) return; if (rtl_is_8125(tp)) 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) { set_bit(flag, tp->wk.flags); - if (!tp->ecdev) + if (!get_ecdev(tp)) 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; rtl8169_unmap_tx_skb(tp, entry); - if (!tp->ecdev && skb) + if (!get_ecdev(tp) && 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) { rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); - if (!tp->ecdev) + if (!get_ecdev(tp)) netdev_reset_queue(tp->dev); } static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down) { - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_disable(&tp->napi); /* 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; - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(tp->dev); 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++) rtl8169_mark_to_asic(tp->RxDescArray + i); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); 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 */ 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); @@ -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); - stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); + stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp); if (unlikely(stop_queue)) { /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must * 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: rtl8169_unmap_tx_skb(tp, entry); err_dma_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) dev_kfree_skb_any(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; err_stop_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); dev->stats.tx_dropped++; return NETDEV_TX_BUSY; @@ -4479,14 +4488,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, if (skb) { pkts_compl++; bytes_compl += skb->len; - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_consume_skb(skb, budget); } dirty_tx++; } if (tp->dirty_tx != dirty_tx) { - if (!tp->ecdev) { + if (!get_ecdev(tp)) { netdev_completed_queue(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. */ 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); /* * 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; } - if (!tp->ecdev) { + if (!get_ecdev(tp)) { skb = napi_alloc_skb(&tp->napi, pkt_size); if (unlikely(!skb)) { 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); prefetch(rx_buf); - if (tp->ecdev) { - ecdev_receive(tp->ecdev, rx_buf, pkt_size); + if (get_ecdev(tp)) { + ecdev_receive(get_ecdev(tp), rx_buf, pkt_size); // No need to detect link status as // 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); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rtl8169_rx_csum(skb, status); 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_resume(tp->phydev); rtl8169_init_phy(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_reset_work(tp); @@ -4771,14 +4780,14 @@ static int rtl8169_close(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); rtl8169_down(tp); rtl8169_rx_clear(tp); cancel_work_sync(&tp->wk.work); - if (!tp->ecdev) + if (!get_ecdev(tp)) free_irq(pci_irq_vector(pdev, 0), tp); phy_disconnect(tp->phydev); @@ -4834,7 +4843,7 @@ static int rtl_open(struct net_device *dev) rtl_request_firmware(tp); 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, irqflags, dev->name, tp); if (retval < 0) @@ -4847,10 +4856,10 @@ static int rtl_open(struct net_device *dev) rtl8169_up(tp); rtl8169_init_counter_offsets(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_start_queue(dev); else - ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); + ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev)); out: 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) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4952,7 +4961,7 @@ static int __maybe_unused rtl8169_suspend(struct device *device) static int __maybe_unused rtl8169_resume(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4969,7 +4978,7 @@ static int __maybe_unused rtl8169_resume(struct device *device) static int rtl8169_runtime_suspend(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -5048,10 +5057,10 @@ static void rtl_remove_one(struct pci_dev *pdev) if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); - if (tp->ecdev) { - ecdev_close(tp->ecdev); + if (get_ecdev(tp)) { + ecdev_close(get_ecdev(tp)); irq_work_sync(&tp->ec_watchdog_kicker); - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); } else { unregister_netdev(tp->dev); } @@ -5361,7 +5370,7 @@ static void ec_poll(struct net_device *dev) u16 status = rtl_get_events(tp); 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; } @@ -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); dev->netdev_ops = &rtl_netdev_ops; tp = netdev_priv(dev); + tp->ecdev_initialized = false; tp->dev = dev; tp->pci_dev = pdev; 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) 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; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rc = register_netdev(dev); if (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)) pm_runtime_put_sync(&pdev->dev); - if (tp->ecdev) { + if (get_ecdev(tp)) { init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); - rc = ecdev_open(tp->ecdev); + rc = ecdev_open(get_ecdev(tp)); if (rc) { - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); return rc; } } diff --git a/devices/r8169/r8169_main-5.15-ethercat.c b/devices/r8169/r8169_main-5.15-ethercat.c index df956257..0e1f88f9 100644 --- a/devices/r8169/r8169_main-5.15-ethercat.c +++ b/devices/r8169/r8169_main-5.15-ethercat.c @@ -640,11 +640,20 @@ struct rtl8169_private { u32 ocp_base; - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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); MODULE_AUTHOR("Realtek and the Linux r8169 crew "); @@ -1317,7 +1326,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp) { - if (tp->ecdev) + if (get_ecdev(tp)) return; if (rtl_is_8125(tp)) 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) { set_bit(flag, tp->wk.flags); - if (!tp->ecdev) + if (!get_ecdev(tp)) 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; rtl8169_unmap_tx_skb(tp, entry); - if (!tp->ecdev && skb) + if (!get_ecdev(tp) && 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) { rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); - if (!tp->ecdev) + if (!get_ecdev(tp)) netdev_reset_queue(tp->dev); } static void rtl8169_cleanup(struct rtl8169_private *tp, bool going_down) { - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_disable(&tp->napi); /* 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; - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(tp->dev); 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++) rtl8169_mark_to_asic(tp->RxDescArray + i); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); 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 */ 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); @@ -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); - stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); + stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp); if (unlikely(stop_queue)) { /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must * 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: rtl8169_unmap_tx_skb(tp, entry); err_dma_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) dev_kfree_skb_any(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; err_stop_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); dev->stats.tx_dropped++; return NETDEV_TX_BUSY; @@ -4472,14 +4481,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, if (skb) { pkts_compl++; bytes_compl += skb->len; - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_consume_skb(skb, budget); } dirty_tx++; } if (tp->dirty_tx != dirty_tx) { - if (!tp->ecdev) { + if (!get_ecdev(tp)) { netdev_completed_queue(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. */ 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); /* * 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; } - if (!tp->ecdev) { + if (!get_ecdev(tp)) { skb = napi_alloc_skb(&tp->napi, pkt_size); if (unlikely(!skb)) { 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); prefetch(rx_buf); - if (tp->ecdev) { - ecdev_receive(tp->ecdev, rx_buf, pkt_size); + if (get_ecdev(tp)) { + ecdev_receive(get_ecdev(tp), rx_buf, pkt_size); // No need to detect link status as // 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); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rtl8169_rx_csum(skb, status); 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_resume(tp->phydev); rtl8169_init_phy(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_reset_work(tp); @@ -4764,14 +4773,14 @@ static int rtl8169_close(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); rtl8169_down(tp); rtl8169_rx_clear(tp); cancel_work_sync(&tp->wk.work); - if (!tp->ecdev) + if (!get_ecdev(tp)) free_irq(pci_irq_vector(pdev, 0), tp); phy_disconnect(tp->phydev); @@ -4827,7 +4836,7 @@ static int rtl_open(struct net_device *dev) rtl_request_firmware(tp); 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, irqflags, dev->name, tp); if (retval < 0) @@ -4840,10 +4849,10 @@ static int rtl_open(struct net_device *dev) rtl8169_up(tp); rtl8169_init_counter_offsets(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_start_queue(dev); else - ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); + ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev)); out: 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) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4945,7 +4954,7 @@ static int __maybe_unused rtl8169_suspend(struct device *device) static int __maybe_unused rtl8169_resume(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4962,7 +4971,7 @@ static int __maybe_unused rtl8169_resume(struct device *device) static int rtl8169_runtime_suspend(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -5041,10 +5050,10 @@ static void rtl_remove_one(struct pci_dev *pdev) if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); - if (tp->ecdev) { - ecdev_close(tp->ecdev); + if (get_ecdev(tp)) { + ecdev_close(get_ecdev(tp)); irq_work_sync(&tp->ec_watchdog_kicker); - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); } else { unregister_netdev(tp->dev); } @@ -5348,7 +5357,7 @@ static void ec_poll(struct net_device *dev) u16 status = rtl_get_events(tp); 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; } @@ -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); dev->netdev_ops = &rtl_netdev_ops; tp = netdev_priv(dev); + tp->ecdev_initialized = false; tp->dev = dev; tp->pci_dev = pdev; 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) 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; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rc = register_netdev(dev); if (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)) pm_runtime_put_sync(&pdev->dev); - if (tp->ecdev) { + if (get_ecdev(tp)) { init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); - rc = ecdev_open(tp->ecdev); + rc = ecdev_open(get_ecdev(tp)); if (rc) { - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); return rc; } } diff --git a/devices/r8169/r8169_main-6.1-ethercat.c b/devices/r8169/r8169_main-6.1-ethercat.c index 06e02bc6..3f4a77ca 100644 --- a/devices/r8169/r8169_main-6.1-ethercat.c +++ b/devices/r8169/r8169_main-6.1-ethercat.c @@ -629,11 +629,20 @@ struct rtl8169_private { u32 ocp_base; - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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); MODULE_AUTHOR("Realtek and the Linux r8169 crew "); @@ -1269,7 +1278,7 @@ static void rtl_irq_disable(struct rtl8169_private *tp) static void rtl_irq_enable(struct rtl8169_private *tp) { - if (tp->ecdev) + if (get_ecdev(tp)) return; if (rtl_is_8125(tp)) 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) { set_bit(flag, tp->wk.flags); - if (!tp->ecdev) + if (!get_ecdev(tp)) 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; rtl8169_unmap_tx_skb(tp, entry); - if (!tp->ecdev && skb) + if (!get_ecdev(tp) && 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) { rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); - if (!tp->ecdev) + if (!get_ecdev(tp)) netdev_reset_queue(tp->dev); } static void rtl8169_cleanup(struct rtl8169_private *tp) { - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_disable(&tp->napi); /* 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; - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(tp->dev); rtl8169_cleanup(tp); @@ -3934,7 +3943,7 @@ static void rtl_reset_work(struct rtl8169_private *tp) for (i = 0; i < NUM_RX_DESC; i++) rtl8169_mark_to_asic(tp->RxDescArray + i); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); 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 */ 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); @@ -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); - stop_queue = !tp->ecdev && !rtl_tx_slots_avail(tp); + stop_queue = !get_ecdev(tp) && !rtl_tx_slots_avail(tp); if (unlikely(stop_queue)) { /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must * 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: rtl8169_unmap_tx_skb(tp, entry); err_dma_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) dev_kfree_skb_any(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; err_stop_0: - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); dev->stats.tx_dropped++; return NETDEV_TX_BUSY; @@ -4370,14 +4379,14 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, if (skb) { pkts_compl++; bytes_compl += skb->len; - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_consume_skb(skb, budget); } dirty_tx++; } if (tp->dirty_tx != dirty_tx) { - if (!tp->ecdev) { + if (!get_ecdev(tp)) { netdev_completed_queue(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. */ 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); /* * 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; } - if (!tp->ecdev) { + if (!get_ecdev(tp)) { skb = napi_alloc_skb(&tp->napi, pkt_size); if (unlikely(!skb)) { 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); prefetch(rx_buf); - if (tp->ecdev) { - ecdev_receive(tp->ecdev, rx_buf, pkt_size); + if (get_ecdev(tp)) { + ecdev_receive(get_ecdev(tp), rx_buf, pkt_size); // No need to detect link status as // 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); - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rtl8169_rx_csum(skb, status); 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_resume(tp->phydev); rtl8169_init_phy(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) napi_enable(&tp->napi); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_reset_work(tp); @@ -4662,14 +4671,14 @@ static int rtl8169_close(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_stop_queue(dev); rtl8169_down(tp); rtl8169_rx_clear(tp); cancel_work_sync(&tp->wk.work); - if (!tp->ecdev) + if (!get_ecdev(tp)) free_irq(tp->irq, tp); phy_disconnect(tp->phydev); @@ -4725,7 +4734,7 @@ static int rtl_open(struct net_device *dev) rtl_request_firmware(tp); 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, dev->name, tp); if (retval < 0) @@ -4738,10 +4747,10 @@ static int rtl_open(struct net_device *dev) rtl8169_up(tp); rtl8169_init_counter_offsets(tp); - if (!tp->ecdev) + if (!get_ecdev(tp)) netif_start_queue(dev); else - ecdev_set_link(tp->ecdev, netif_carrier_ok(dev)); + ecdev_set_link(get_ecdev(tp), netif_carrier_ok(dev)); out: 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) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4841,7 +4850,7 @@ static int rtl8169_suspend(struct device *device) static int rtl8169_resume(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4858,7 +4867,7 @@ static int rtl8169_resume(struct device *device) static int rtl8169_runtime_suspend(struct device *device) { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->ecdev) { + if (get_ecdev(tp)) { return -EBUSY; } @@ -4919,10 +4928,10 @@ static void rtl_remove_one(struct pci_dev *pdev) if (pci_dev_run_wake(pdev)) pm_runtime_get_noresume(&pdev->dev); - if (tp->ecdev) { - ecdev_close(tp->ecdev); + if (get_ecdev(tp)) { + ecdev_close(get_ecdev(tp)); irq_work_sync(&tp->ec_watchdog_kicker); - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); } else { unregister_netdev(tp->dev); } @@ -5206,7 +5215,7 @@ static void ec_poll(struct net_device *dev) u16 status = rtl_get_events(tp); 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; } @@ -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); dev->netdev_ops = &rtl_netdev_ops; tp = netdev_priv(dev); + tp->ecdev_initialized = false; tp->dev = dev; tp->pci_dev = pdev; 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) 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; - if (!tp->ecdev) { + if (!get_ecdev(tp)) { rc = register_netdev(dev); if (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)) 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); - rc = ecdev_open(tp->ecdev); if (rc) { - ecdev_withdraw(tp->ecdev); + ecdev_withdraw(get_ecdev(tp)); return rc; } } diff --git a/devices/stmmac/Kbuild.in b/devices/stmmac/Kbuild.in index 0c2a1e9e..60564fb4 100644 --- a/devices/stmmac/Kbuild.in +++ b/devices/stmmac/Kbuild.in @@ -39,6 +39,9 @@ REV := $(shell if test -s $(TOPDIR)/revision; then \ git -C $(TOPDIR) describe 2>/dev/null || echo "unknown"; \ fi) +ifeq (@ENABLE_DRIVER_RESOURCE_VERIFYING@,1) + ccflags-y := -DEC_ENABLE_DRIVER_RESOURCE_VERIFYING +endif ifeq (@ENABLE_STMMAC@,1) EC_STMMAC_OBJS := \ diff --git a/devices/stmmac/stmmac-6.1-ethercat.h b/devices/stmmac/stmmac-6.1-ethercat.h index ffc7793c..2a161788 100644 --- a/devices/stmmac/stmmac-6.1-ethercat.h +++ b/devices/stmmac/stmmac-6.1-ethercat.h @@ -333,11 +333,20 @@ struct stmmac_priv { struct bpf_prog *xdp_prog; /* EtherCAT device variables */ - ec_device_t *ecdev; + ec_device_t *ecdev_; unsigned long ec_watchdog_jiffies; 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 { STMMAC_DOWN, STMMAC_RESET_REQUESTED, diff --git a/devices/stmmac/stmmac_main-6.1-ethercat.c b/devices/stmmac/stmmac_main-6.1-ethercat.c index 1e6cb661..bd6eea00 100644 --- a/devices/stmmac/stmmac_main-6.1-ethercat.c +++ b/devices/stmmac/stmmac_main-6.1-ethercat.c @@ -213,7 +213,7 @@ static void __stmmac_disable_all_queues(struct stmmac_priv *priv) u32 maxq = max(rx_queues_cnt, tx_queues_cnt); u32 queue; - if (priv->ecdev) + if (get_ecdev(priv)) return; for (queue = 0; queue < maxq; queue++) { @@ -250,7 +250,7 @@ static void stmmac_disable_all_queues(struct stmmac_priv *priv) break; } } - if (priv->ecdev) + if (get_ecdev(priv)) return; __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 queue; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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) { - if (priv->ecdev) { - ecdev_set_link(priv->ecdev, 0); + if (get_ecdev(priv)) { + ecdev_set_link(get_ecdev(priv), 0); } else { 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)); - if (priv->ecdev) { - ecdev_set_link(priv->ecdev, false); + if (get_ecdev(priv)) { + ecdev_set_link(get_ecdev(priv), false); } stmmac_mac_set(priv, priv->ioaddr, false); priv->eee_active = false; @@ -1108,8 +1108,8 @@ static void stmmac_mac_link_up(struct phylink_config *config, if (priv->dma_cap.fpesel) stmmac_fpe_link_state_handle(priv, true); - if (priv->ecdev) { - ecdev_set_link(priv->ecdev, true); + if (get_ecdev(priv)) { + 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); } - if (!priv->ecdev && !priv->plat->pmt) { + if (!get_ecdev(priv) && !priv->plat->pmt) { struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; 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) tx_q->xsk_frames_done++; - if (!priv->ecdev && + if (!get_ecdev(priv) && tx_q->tx_skbuff[i] && tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_SKB) { 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 chan; - if (priv->ecdev) + if (get_ecdev(priv)) return; 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 entry, xmits = 0, count = 0; - if (!priv->ecdev) + if (!get_ecdev(priv)) __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue)); priv->xstats.tx_clean++; @@ -2671,7 +2671,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) if (likely(skb)) { pkts_compl++; bytes_compl += skb->len; - if (!priv->ecdev) { + if (!get_ecdev(priv)) { dev_consume_skb_any(skb); } 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; - if (!priv->ecdev) { + if (!get_ecdev(priv)) { netdev_tx_completed_queue(netdev_get_tx_queue(priv->dev, queue), 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 */ - 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); - if (!priv->ecdev) + if (!get_ecdev(priv)) __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); /* 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) return; - if (priv->ecdev) + if (get_ecdev(priv)) return; hrtimer_start(&tx_q->txtimer, @@ -3887,18 +3887,18 @@ static int __stmmac_open(struct net_device *dev, goto init_error; } - if (!priv->ecdev) { + if (!get_ecdev(priv)) { stmmac_init_coalesce(priv); } - if (priv->ecdev) { + if (get_ecdev(priv)) { rtnl_lock(); } phylink_start(priv->phylink); /* We may have called phylink_speed_down before */ phylink_speed_up(priv->phylink); - if (priv->ecdev) { + if (get_ecdev(priv)) { rtnl_unlock(); } @@ -3906,7 +3906,7 @@ static int __stmmac_open(struct net_device *dev, if (ret) goto irq_error; - if (!priv->ecdev) { + if (!get_ecdev(priv)) { stmmac_enable_all_queues(priv); netif_tx_start_all_queues(priv->dev); 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); u32 chan; + if (get_ecdev(priv)) { + rtnl_lock(); + } if (device_may_wakeup(priv->device)) phylink_speed_down(priv->phylink, false); /* Stop and disconnect the PHY */ - if (priv->ecdev) { - rtnl_lock(); - } phylink_stop(priv->phylink); phylink_disconnect_phy(priv->phylink); - if (priv->ecdev) { + if (get_ecdev(priv)) { rtnl_unlock(); } stmmac_disable_all_queues(priv); - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) - hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); + if (!get_ecdev(priv)) { + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) + hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); + } netif_tx_disable(dev); @@ -4009,7 +4011,7 @@ static int stmmac_release(struct net_device *dev) if (priv->plat->serdes_powerdown) priv->plat->serdes_powerdown(dev, priv->plat->bsp_priv); - if (!priv->ecdev) { + if (!get_ecdev(priv)) { 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: dev_err(priv->device, "Tx dma map failed\n"); - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb(skb); priv->dev->stats.tx_dropped++; 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); } - 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", __func__); 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); - if (!priv->ecdev) + if (!get_ecdev(priv)) netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len); 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: netdev_err(priv->dev, "Tx DMA map failed\n"); - if (!priv->ecdev) + if (!get_ecdev(priv)) dev_kfree_skb(skb); priv->dev->stats.tx_dropped++; return NETDEV_TX_OK; @@ -4939,7 +4941,7 @@ static void stmmac_finalize_xdp_rx(struct stmmac_priv *priv, { int cpu; int queue; - if(priv->ecdev) { + if(get_ecdev(priv)) { return; } cpu = smp_processor_id(); @@ -5342,7 +5344,7 @@ read_again: &priv->xstats, rx_q->dma_erx + entry); if (unlikely(status == 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); buf->page = NULL; } @@ -5385,13 +5387,13 @@ read_again: len -= ETH_FCS_LEN; } } - if (priv->ecdev) { + if (get_ecdev(priv)) { unsigned char *va; dma_sync_single_for_cpu(priv->device, buf->addr, buf1_len, dma_dir); 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); priv->ec_watchdog_jiffies = jiffies; /* 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; int work_done; - BUG_ON(priv->ecdev); + BUG_ON(get_ecdev(priv)); priv->xstats.napi_poll++; @@ -5571,7 +5573,7 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget) u32 chan = ch->index; int work_done; - BUG_ON(priv->ecdev); + BUG_ON(get_ecdev(priv)); 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; u32 chan = ch->index; - BUG_ON(priv->ecdev); + BUG_ON(get_ecdev(priv)); priv->xstats.napi_poll++; @@ -5871,14 +5873,14 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv) /* PCS link status */ if (priv->hw->pcs) { if (priv->xstats.pcs_link) - if (priv->ecdev) { - ecdev_set_link(priv->ecdev, 1); + if (get_ecdev(priv)) { + ecdev_set_link(get_ecdev(priv), 1); } else { netif_carrier_on(priv->dev); } else - if (priv->ecdev) { - ecdev_set_link(priv->ecdev, 0); + if (get_ecdev(priv)) { + ecdev_set_link(get_ecdev(priv), 0); } else { 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); - if (priv->ecdev) + if (get_ecdev(priv)) return -EBUSY; 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); - if (priv->ecdev) { + if (get_ecdev(priv)) { return -EBUSY; } @@ -6682,7 +6684,7 @@ void stmmac_xdp_release(struct net_device *dev) /* Ensure tx function is not running */ netif_tx_disable(dev); - BUG_ON(priv->ecdev); + BUG_ON(get_ecdev(priv)); /* Disable NAPI process */ stmmac_disable_all_queues(priv); @@ -6722,7 +6724,7 @@ int stmmac_xdp_open(struct net_device *dev) u32 chan; int ret; - BUG_ON(priv->ecdev); + BUG_ON(get_ecdev(priv)); ret = alloc_dma_desc_resources(priv, &priv->dma_conf); 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_channel *ch; - if (priv->ecdev) { + if (get_ecdev(priv)) { return -EBUSY; } @@ -6904,7 +6906,7 @@ void ec_poll(struct net_device *netdev) int budget = 128; u32 maxq; - if (!priv->ecdev) + if (!get_ecdev(priv)) return; 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->device = device; priv->dev = ndev; - priv->ecdev = NULL; + priv->ecdev_ = NULL; + priv->ecdev_initialized = false; stmmac_set_ethtool_ops(ndev); priv->pause = pause; @@ -7481,8 +7484,9 @@ int stmmac_ec_dvr_probe(struct device *device, goto error_phy_setup; } - priv->ecdev = ecdev_offer(ndev, ec_poll, THIS_MODULE); - if (!priv->ecdev) { + priv->ecdev_ = ecdev_offer(ndev, ec_poll, THIS_MODULE); + priv->ecdev_initialized = true; + if (!get_ecdev(priv)) { ret = register_netdev(ndev); if (ret) { 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. */ pm_runtime_put(device); - if (priv->ecdev) { + if (get_ecdev(priv)) { init_irq_work(&priv->ec_watchdog_kicker, ec_kick_watchdog); - ret = ecdev_open(priv->ecdev); + ret = ecdev_open(get_ecdev(priv)); if (ret) { - ecdev_withdraw(priv->ecdev); + ecdev_withdraw(get_ecdev(priv)); goto error_netdev_register; } } @@ -7547,14 +7551,12 @@ int stmmac_ec_dvr_remove(struct device *dev) stmmac_stop_all_dma(priv); stmmac_mac_set(priv, priv->ioaddr, false); - if (priv->ecdev) { - mutex_lock(&priv->lock); - ecdev_close(priv->ecdev); + if (get_ecdev(priv)) { + ecdev_close(get_ecdev(priv)); irq_work_sync(&priv->ec_watchdog_kicker); - ecdev_withdraw(priv->ecdev); - priv->ecdev = NULL; - - mutex_unlock(&priv->lock); + ecdev_withdraw(get_ecdev(priv)); + priv->ecdev_ = NULL; + priv->ecdev_initialized = false; } else { netif_carrier_off(ndev); unregister_netdev(ndev); @@ -7593,7 +7595,7 @@ int stmmac_suspend(struct device *dev) struct net_device *ndev = dev_get_drvdata(dev); struct stmmac_priv *priv = netdev_priv(ndev); u32 chan; - if (priv->ecdev) { + if (get_ecdev(priv)) { return -EBUSY; } @@ -7704,7 +7706,7 @@ int stmmac_resume(struct device *dev) struct stmmac_priv *priv = netdev_priv(ndev); int ret; - if (priv->ecdev) { + if (get_ecdev(priv)) { return -EBUSY; } if (!netif_running(ndev))