aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorJakub Kicinski <kubakici@wp.pl>2014-04-02 06:33:28 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-04-18 21:32:17 -0400
commiteda183c21a444aef5800cef98d63d62914d2a81a (patch)
tree0ec74d649961b7728d4bd41d9eb85440579d7944 /drivers/net/ethernet
parente66c083aab32842f225bae2a2c30744bf96abaec (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.h21
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c3
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c36
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);
944void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); 944void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
945void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); 945void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
946void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); 946void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
947void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, 947void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb);
948 struct sk_buff *skb);
949static 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
965int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); 948int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
966int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); 949int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
967void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); 950void 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)
435void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) 435void 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 */
541void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, 536void 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
578int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) 564int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)