diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igc')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_defines.h | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_ethtool.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_main.c | 15 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_regs.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_tsn.c | 30 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_tsn.h | 1 | 
6 files changed, 58 insertions, 10 deletions
| diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h index 4f9d7f013a95..f7311aeb293b 100644 --- a/drivers/net/ethernet/intel/igc/igc_defines.h +++ b/drivers/net/ethernet/intel/igc/igc_defines.h @@ -400,6 +400,15 @@  #define IGC_DTXMXPKTSZ_TSN	0x19 /* 1600 bytes of max TX DMA packet size */  #define IGC_DTXMXPKTSZ_DEFAULT	0x98 /* 9728-byte Jumbo frames */ +/* Transmit Scheduling Latency */ +/* Latency between transmission scheduling (LaunchTime) and the time + * the packet is transmitted to the network in nanosecond. + */ +#define IGC_TXOFFSET_SPEED_10	0x000034BC +#define IGC_TXOFFSET_SPEED_100	0x00000578 +#define IGC_TXOFFSET_SPEED_1000	0x0000012C +#define IGC_TXOFFSET_SPEED_2500	0x00000578 +  /* Time Sync Interrupt Causes */  #define IGC_TSICR_SYS_WRAP	BIT(0) /* SYSTIM Wrap around. */  #define IGC_TSICR_TXTS		BIT(1) /* Transmit Timestamp. */ diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 8cc077b712ad..5a26a7805ef8 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -839,15 +839,15 @@ static void igc_ethtool_get_stats(struct net_device *netdev,  		ring = adapter->tx_ring[j];  		do { -			start = u64_stats_fetch_begin_irq(&ring->tx_syncp); +			start = u64_stats_fetch_begin(&ring->tx_syncp);  			data[i]   = ring->tx_stats.packets;  			data[i + 1] = ring->tx_stats.bytes;  			data[i + 2] = ring->tx_stats.restart_queue; -		} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); +		} while (u64_stats_fetch_retry(&ring->tx_syncp, start));  		do { -			start = u64_stats_fetch_begin_irq(&ring->tx_syncp2); +			start = u64_stats_fetch_begin(&ring->tx_syncp2);  			restart2  = ring->tx_stats.restart_queue2; -		} while (u64_stats_fetch_retry_irq(&ring->tx_syncp2, start)); +		} while (u64_stats_fetch_retry(&ring->tx_syncp2, start));  		data[i + 2] += restart2;  		i += IGC_TX_QUEUE_STATS_LEN; @@ -855,13 +855,13 @@ static void igc_ethtool_get_stats(struct net_device *netdev,  	for (j = 0; j < adapter->num_rx_queues; j++) {  		ring = adapter->rx_ring[j];  		do { -			start = u64_stats_fetch_begin_irq(&ring->rx_syncp); +			start = u64_stats_fetch_begin(&ring->rx_syncp);  			data[i]   = ring->rx_stats.packets;  			data[i + 1] = ring->rx_stats.bytes;  			data[i + 2] = ring->rx_stats.drops;  			data[i + 3] = ring->rx_stats.csum_err;  			data[i + 4] = ring->rx_stats.alloc_failed; -		} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); +		} while (u64_stats_fetch_retry(&ring->rx_syncp, start));  		i += IGC_RX_QUEUE_STATS_LEN;  	}  	spin_unlock(&adapter->stats64_lock); diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 34889be63e78..1586e1e435c6 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4682,10 +4682,10 @@ void igc_update_stats(struct igc_adapter *adapter)  		}  		do { -			start = u64_stats_fetch_begin_irq(&ring->rx_syncp); +			start = u64_stats_fetch_begin(&ring->rx_syncp);  			_bytes = ring->rx_stats.bytes;  			_packets = ring->rx_stats.packets; -		} while (u64_stats_fetch_retry_irq(&ring->rx_syncp, start)); +		} while (u64_stats_fetch_retry(&ring->rx_syncp, start));  		bytes += _bytes;  		packets += _packets;  	} @@ -4699,10 +4699,10 @@ void igc_update_stats(struct igc_adapter *adapter)  		struct igc_ring *ring = adapter->tx_ring[i];  		do { -			start = u64_stats_fetch_begin_irq(&ring->tx_syncp); +			start = u64_stats_fetch_begin(&ring->tx_syncp);  			_bytes = ring->tx_stats.bytes;  			_packets = ring->tx_stats.packets; -		} while (u64_stats_fetch_retry_irq(&ring->tx_syncp, start)); +		} while (u64_stats_fetch_retry(&ring->tx_syncp, start));  		bytes += _bytes;  		packets += _packets;  	} @@ -5381,6 +5381,13 @@ static void igc_watchdog_task(struct work_struct *work)  				break;  			} +			/* Once the launch time has been set on the wire, there +			 * is a delay before the link speed can be determined +			 * based on link-up activity. Write into the register +			 * as soon as we know the correct link speed. +			 */ +			igc_tsn_adjust_txtime_offset(adapter); +  			if (adapter->link_speed != SPEED_1000)  				goto no_wait; diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h index c0d8214148d1..01c86d36856d 100644 --- a/drivers/net/ethernet/intel/igc/igc_regs.h +++ b/drivers/net/ethernet/intel/igc/igc_regs.h @@ -224,6 +224,7 @@  /* Transmit Scheduling Registers */  #define IGC_TQAVCTRL		0x3570  #define IGC_TXQCTL(_n)		(0x3344 + 0x4 * (_n)) +#define IGC_GTXOFFSET		0x3310  #define IGC_BASET_L		0x3314  #define IGC_BASET_H		0x3318  #define IGC_QBVCYCLET		0x331C diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c index 0fce22de2ab8..f975ed807da1 100644 --- a/drivers/net/ethernet/intel/igc/igc_tsn.c +++ b/drivers/net/ethernet/intel/igc/igc_tsn.c @@ -48,6 +48,35 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)  	return new_flags;  } +void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter) +{ +	struct igc_hw *hw = &adapter->hw; +	u16 txoffset; + +	if (!is_any_launchtime(adapter)) +		return; + +	switch (adapter->link_speed) { +	case SPEED_10: +		txoffset = IGC_TXOFFSET_SPEED_10; +		break; +	case SPEED_100: +		txoffset = IGC_TXOFFSET_SPEED_100; +		break; +	case SPEED_1000: +		txoffset = IGC_TXOFFSET_SPEED_1000; +		break; +	case SPEED_2500: +		txoffset = IGC_TXOFFSET_SPEED_2500; +		break; +	default: +		txoffset = 0; +		break; +	} + +	wr32(IGC_GTXOFFSET, txoffset); +} +  /* Returns the TSN specific registers to their default values after   * the adapter is reset.   */ @@ -57,6 +86,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)  	u32 tqavctrl;  	int i; +	wr32(IGC_GTXOFFSET, 0);  	wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);  	wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT); diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.h b/drivers/net/ethernet/intel/igc/igc_tsn.h index 1512307f5a52..b53e6af560b7 100644 --- a/drivers/net/ethernet/intel/igc/igc_tsn.h +++ b/drivers/net/ethernet/intel/igc/igc_tsn.h @@ -6,5 +6,6 @@  int igc_tsn_offload_apply(struct igc_adapter *adapter);  int igc_tsn_reset(struct igc_adapter *adapter); +void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter);  #endif /* _IGC_BASE_H */ |