diff options
| author | Dave Airlie <airlied@redhat.com> | 2023-08-24 07:26:06 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2023-08-24 07:26:06 +1000 | 
| commit | fdebffeba8b877368ddcc139c26278c1c97931a4 (patch) | |
| tree | 5ebf85a3e26d55ea388aa7a8608222205a4d59ba /drivers/net/ethernet/intel/igc/igc_main.c | |
| parent | cacaeb27ade4b793c456179bb6eda4592d206cd8 (diff) | |
| parent | 706a741595047797872e669b3101429ab8d378ef (diff) | |
BackMerge tag 'v6.5-rc7' into drm-next
Linux 6.5-rc7
This is needed for the CI stuff and the msm pull has fixes in it.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 78 | 
1 files changed, 62 insertions, 16 deletions
| diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 9f93f0f4f752..6f557e843e49 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -316,6 +316,33 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter)  			igc_clean_tx_ring(adapter->tx_ring[i]);  } +static void igc_disable_tx_ring_hw(struct igc_ring *ring) +{ +	struct igc_hw *hw = &ring->q_vector->adapter->hw; +	u8 idx = ring->reg_idx; +	u32 txdctl; + +	txdctl = rd32(IGC_TXDCTL(idx)); +	txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; +	txdctl |= IGC_TXDCTL_SWFLUSH; +	wr32(IGC_TXDCTL(idx), txdctl); +} + +/** + * igc_disable_all_tx_rings_hw - Disable all transmit queue operation + * @adapter: board private structure + */ +static void igc_disable_all_tx_rings_hw(struct igc_adapter *adapter) +{ +	int i; + +	for (i = 0; i < adapter->num_tx_queues; i++) { +		struct igc_ring *tx_ring = adapter->tx_ring[i]; + +		igc_disable_tx_ring_hw(tx_ring); +	} +} +  /**   * igc_setup_tx_resources - allocate Tx resources (Descriptors)   * @tx_ring: tx descriptor ring (for a specific queue) to setup @@ -2828,9 +2855,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)  	struct netdev_queue *nq = txring_txq(ring);  	union igc_adv_tx_desc *tx_desc = NULL;  	int cpu = smp_processor_id(); -	u16 ntu = ring->next_to_use;  	struct xdp_desc xdp_desc; -	u16 budget; +	u16 budget, ntu;  	if (!netif_carrier_ok(ring->netdev))  		return; @@ -2840,6 +2866,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)  	/* Avoid transmit queue timeout since we share it with the slow path */  	txq_trans_cond_update(nq); +	ntu = ring->next_to_use;  	budget = igc_desc_unused(ring);  	while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) { @@ -4774,6 +4801,7 @@ static int igc_sw_init(struct igc_adapter *adapter)  	adapter->nfc_rule_count = 0;  	spin_lock_init(&adapter->stats64_lock); +	spin_lock_init(&adapter->qbv_tx_lock);  	/* Assume MSI-X interrupts, will be checked during IRQ allocation */  	adapter->flags |= IGC_FLAG_HAS_MSIX; @@ -5058,6 +5086,7 @@ void igc_down(struct igc_adapter *adapter)  	/* clear VLAN promisc flag so VFTA will be updated if necessary */  	adapter->flags &= ~IGC_FLAG_VLAN_PROMISC; +	igc_disable_all_tx_rings_hw(adapter);  	igc_clean_all_tx_rings(adapter);  	igc_clean_all_rx_rings(adapter);  } @@ -6091,15 +6120,15 @@ static int igc_tsn_enable_launchtime(struct igc_adapter *adapter,  	return igc_tsn_offload_apply(adapter);  } -static int igc_tsn_clear_schedule(struct igc_adapter *adapter) +static int igc_qbv_clear_schedule(struct igc_adapter *adapter)  { +	unsigned long flags;  	int i;  	adapter->base_time = 0;  	adapter->cycle_time = NSEC_PER_SEC;  	adapter->taprio_offload_enable = false;  	adapter->qbv_config_change_errors = 0; -	adapter->qbv_transition = false;  	adapter->qbv_count = 0;  	for (i = 0; i < adapter->num_tx_queues; i++) { @@ -6108,10 +6137,28 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)  		ring->start_time = 0;  		ring->end_time = NSEC_PER_SEC;  		ring->max_sdu = 0; +	} + +	spin_lock_irqsave(&adapter->qbv_tx_lock, flags); + +	adapter->qbv_transition = false; + +	for (i = 0; i < adapter->num_tx_queues; i++) { +		struct igc_ring *ring = adapter->tx_ring[i]; +  		ring->oper_gate_closed = false;  		ring->admin_gate_closed = false;  	} +	spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); + +	return 0; +} + +static int igc_tsn_clear_schedule(struct igc_adapter *adapter) +{ +	igc_qbv_clear_schedule(adapter); +  	return 0;  } @@ -6122,6 +6169,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,  	struct igc_hw *hw = &adapter->hw;  	u32 start_time = 0, end_time = 0;  	struct timespec64 now; +	unsigned long flags;  	size_t n;  	int i; @@ -6189,6 +6237,8 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,  		start_time += e->interval;  	} +	spin_lock_irqsave(&adapter->qbv_tx_lock, flags); +  	/* Check whether a queue gets configured.  	 * If not, set the start and end time to be end time.  	 */ @@ -6213,6 +6263,8 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,  		}  	} +	spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); +  	for (i = 0; i < adapter->num_tx_queues; i++) {  		struct igc_ring *ring = adapter->tx_ring[i];  		struct net_device *dev = adapter->netdev; @@ -6591,8 +6643,11 @@ static enum hrtimer_restart igc_qbv_scheduling_timer(struct hrtimer *timer)  {  	struct igc_adapter *adapter = container_of(timer, struct igc_adapter,  						   hrtimer); +	unsigned long flags;  	unsigned int i; +	spin_lock_irqsave(&adapter->qbv_tx_lock, flags); +  	adapter->qbv_transition = true;  	for (i = 0; i < adapter->num_tx_queues; i++) {  		struct igc_ring *tx_ring = adapter->tx_ring[i]; @@ -6605,6 +6660,9 @@ static enum hrtimer_restart igc_qbv_scheduling_timer(struct hrtimer *timer)  		}  	}  	adapter->qbv_transition = false; + +	spin_unlock_irqrestore(&adapter->qbv_tx_lock, flags); +  	return HRTIMER_NORESTART;  } @@ -7290,18 +7348,6 @@ void igc_enable_rx_ring(struct igc_ring *ring)  		igc_alloc_rx_buffers(ring, igc_desc_unused(ring));  } -static void igc_disable_tx_ring_hw(struct igc_ring *ring) -{ -	struct igc_hw *hw = &ring->q_vector->adapter->hw; -	u8 idx = ring->reg_idx; -	u32 txdctl; - -	txdctl = rd32(IGC_TXDCTL(idx)); -	txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; -	txdctl |= IGC_TXDCTL_SWFLUSH; -	wr32(IGC_TXDCTL(idx), txdctl); -} -  void igc_disable_tx_ring(struct igc_ring *ring)  {  	igc_disable_tx_ring_hw(ring); | 
