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))