diff options
author | Jakub Kicinski <kubakici@wp.pl> | 2014-04-02 06:33:28 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-04-18 21:32:17 -0400 |
commit | eda183c21a444aef5800cef98d63d62914d2a81a (patch) | |
tree | 0ec74d649961b7728d4bd41d9eb85440579d7944 /drivers/net/ethernet | |
parent | e66c083aab32842f225bae2a2c30744bf96abaec (diff) |
ixgbe: clean up Rx time stamping code
Time stamping resources are per-interface so there is no need
to keep separate last_rx_timestamp for each Rx ring, move
last_rx_timestamp to the adapter structure.
With last_rx_timestamp inside adapter, ixgbe_ptp_rx_hwtstamp()
inline function is reduced to a single if statement so it is
no longer necessary. If statement is placed directly in
ixgbe_process_skb_fields() fixing likely/unlikely marking.
Checks for q_vector or adapter to be NULL are superfluous.
Comment about taking I/O hit is a leftover from previous design.
Signed-off-by: Jakub Kicinski <kubakici@wp.pl>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe.h | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 36 |
3 files changed, 15 insertions, 45 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 1a12c1dd7a27..c6c4ca7d68e6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h | |||
@@ -256,7 +256,6 @@ struct ixgbe_ring { | |||
256 | struct ixgbe_tx_buffer *tx_buffer_info; | 256 | struct ixgbe_tx_buffer *tx_buffer_info; |
257 | struct ixgbe_rx_buffer *rx_buffer_info; | 257 | struct ixgbe_rx_buffer *rx_buffer_info; |
258 | }; | 258 | }; |
259 | unsigned long last_rx_timestamp; | ||
260 | unsigned long state; | 259 | unsigned long state; |
261 | u8 __iomem *tail; | 260 | u8 __iomem *tail; |
262 | dma_addr_t dma; /* phys. address of descriptor ring */ | 261 | dma_addr_t dma; /* phys. address of descriptor ring */ |
@@ -770,6 +769,7 @@ struct ixgbe_adapter { | |||
770 | unsigned long ptp_tx_start; | 769 | unsigned long ptp_tx_start; |
771 | unsigned long last_overflow_check; | 770 | unsigned long last_overflow_check; |
772 | unsigned long last_rx_ptp_check; | 771 | unsigned long last_rx_ptp_check; |
772 | unsigned long last_rx_timestamp; | ||
773 | spinlock_t tmreg_lock; | 773 | spinlock_t tmreg_lock; |
774 | struct cyclecounter cc; | 774 | struct cyclecounter cc; |
775 | struct timecounter tc; | 775 | struct timecounter tc; |
@@ -944,24 +944,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter); | |||
944 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); | 944 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); |
945 | void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); | 945 | void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); |
946 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); | 946 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); |
947 | void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | 947 | void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb); |
948 | struct sk_buff *skb); | ||
949 | static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, | ||
950 | union ixgbe_adv_rx_desc *rx_desc, | ||
951 | struct sk_buff *skb) | ||
952 | { | ||
953 | if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) | ||
954 | return; | ||
955 | |||
956 | __ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); | ||
957 | |||
958 | /* | ||
959 | * Update the last_rx_timestamp timer in order to enable watchdog check | ||
960 | * for error case of latched timestamp on a dropped packet. | ||
961 | */ | ||
962 | rx_ring->last_rx_timestamp = jiffies; | ||
963 | } | ||
964 | |||
965 | int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | 948 | int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); |
966 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | 949 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); |
967 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); | 950 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index c4c526b7f99f..d62e7a25cf97 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -1664,7 +1664,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, | |||
1664 | 1664 | ||
1665 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); | 1665 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); |
1666 | 1666 | ||
1667 | ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb); | 1667 | if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) |
1668 | ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb); | ||
1668 | 1669 | ||
1669 | if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && | 1670 | if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && |
1670 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { | 1671 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 63515a6f67fa..c247a225a3e0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -435,10 +435,8 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) | |||
435 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) | 435 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) |
436 | { | 436 | { |
437 | struct ixgbe_hw *hw = &adapter->hw; | 437 | struct ixgbe_hw *hw = &adapter->hw; |
438 | struct ixgbe_ring *rx_ring; | ||
439 | u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | 438 | u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
440 | unsigned long rx_event; | 439 | unsigned long rx_event; |
441 | int n; | ||
442 | 440 | ||
443 | /* if we don't have a valid timestamp in the registers, just update the | 441 | /* if we don't have a valid timestamp in the registers, just update the |
444 | * timeout counter and exit | 442 | * timeout counter and exit |
@@ -450,11 +448,8 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) | |||
450 | 448 | ||
451 | /* determine the most recent watchdog or rx_timestamp event */ | 449 | /* determine the most recent watchdog or rx_timestamp event */ |
452 | rx_event = adapter->last_rx_ptp_check; | 450 | rx_event = adapter->last_rx_ptp_check; |
453 | for (n = 0; n < adapter->num_rx_queues; n++) { | 451 | if (time_after(adapter->last_rx_timestamp, rx_event)) |
454 | rx_ring = adapter->rx_ring[n]; | 452 | rx_event = adapter->last_rx_timestamp; |
455 | if (time_after(rx_ring->last_rx_timestamp, rx_event)) | ||
456 | rx_event = rx_ring->last_rx_timestamp; | ||
457 | } | ||
458 | 453 | ||
459 | /* only need to read the high RXSTMP register to clear the lock */ | 454 | /* only need to read the high RXSTMP register to clear the lock */ |
460 | if (time_is_before_jiffies(rx_event + 5*HZ)) { | 455 | if (time_is_before_jiffies(rx_event + 5*HZ)) { |
@@ -530,35 +525,22 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) | |||
530 | } | 525 | } |
531 | 526 | ||
532 | /** | 527 | /** |
533 | * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp | 528 | * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp |
534 | * @q_vector: structure containing interrupt and ring information | 529 | * @adapter: pointer to adapter struct |
535 | * @skb: particular skb to send timestamp with | 530 | * @skb: particular skb to send timestamp with |
536 | * | 531 | * |
537 | * if the timestamp is valid, we convert it into the timecounter ns | 532 | * if the timestamp is valid, we convert it into the timecounter ns |
538 | * value, then store that result into the shhwtstamps structure which | 533 | * value, then store that result into the shhwtstamps structure which |
539 | * is passed up the network stack | 534 | * is passed up the network stack |
540 | */ | 535 | */ |
541 | void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | 536 | void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb) |
542 | struct sk_buff *skb) | ||
543 | { | 537 | { |
544 | struct ixgbe_adapter *adapter; | 538 | struct ixgbe_hw *hw = &adapter->hw; |
545 | struct ixgbe_hw *hw; | ||
546 | struct skb_shared_hwtstamps *shhwtstamps; | 539 | struct skb_shared_hwtstamps *shhwtstamps; |
547 | u64 regval = 0, ns; | 540 | u64 regval = 0, ns; |
548 | u32 tsyncrxctl; | 541 | u32 tsyncrxctl; |
549 | unsigned long flags; | 542 | unsigned long flags; |
550 | 543 | ||
551 | /* we cannot process timestamps on a ring without a q_vector */ | ||
552 | if (!q_vector || !q_vector->adapter) | ||
553 | return; | ||
554 | |||
555 | adapter = q_vector->adapter; | ||
556 | hw = &adapter->hw; | ||
557 | |||
558 | /* | ||
559 | * Read the tsyncrxctl register afterwards in order to prevent taking an | ||
560 | * I/O hit on every packet. | ||
561 | */ | ||
562 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | 544 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
563 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) | 545 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) |
564 | return; | 546 | return; |
@@ -566,13 +548,17 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | |||
566 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); | 548 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); |
567 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; | 549 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; |
568 | 550 | ||
569 | |||
570 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | 551 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
571 | ns = timecounter_cyc2time(&adapter->tc, regval); | 552 | ns = timecounter_cyc2time(&adapter->tc, regval); |
572 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | 553 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
573 | 554 | ||
574 | shhwtstamps = skb_hwtstamps(skb); | 555 | shhwtstamps = skb_hwtstamps(skb); |
575 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | 556 | shhwtstamps->hwtstamp = ns_to_ktime(ns); |
557 | |||
558 | /* Update the last_rx_timestamp timer in order to enable watchdog check | ||
559 | * for error case of latched timestamp on a dropped packet. | ||
560 | */ | ||
561 | adapter->last_rx_timestamp = jiffies; | ||
576 | } | 562 | } |
577 | 563 | ||
578 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) | 564 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) |