aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2012-05-22 02:18:08 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-06-14 06:13:48 -0400
commit1d1a79b5b94b0aa84e1e78dd9acdcffb12274848 (patch)
tree9c6833a1486d5695269b35c56c1abbcbd3c618ae /drivers/net/ethernet/intel
parentc19197a7866fee6ff9985d9dc9962bc2ccbd3d7b (diff)
ixgbe: Check PTP Rx timestamps via BPF filter
This patch fixes a potential Rx timestamp deadlock that causes the Rx timestamping to stall indefinitely. The issue could occur when a PTP packet is timestamped by hardware but never reaches the Rx queue. In order to prevent a permanent loss of timestamping, the RXSTMP(L/H) registers have to be read to unlock them. (This used to only occur when a packet that was timestamped reached the software.) However the registers can't be read early otherwise there is no way to correlate them to the packet. This patch introduces a filter function which can be used to determine if a packet should have been timestamped. Supplied with the filter setup by the hwtstamp ioctl, check to make sure the PTP protocol and message type match the expected values. If so, then read the timestamp registers (to free them.) At this point check the descriptor bit, if the bit is set then we know this packet correlates to the timestamp stored in the RXTSTAMP registers. Otherwise, assume that packet was dropped by the hardware, and ignore this timestamp value. However, we have at least unlocked the rxtstamp registers for future timestamping. Due to the way the driver handles skb data, it cannot be directly accessed. In order to work around this, a copy of the skb data into a linear buffer is made. From this buffer it becomes possible to read the data correctly Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Richard Cochran <richardcochran@gmail.com> 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/intel')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c3
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c113
3 files changed, 104 insertions, 14 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 3ef3c5284e52..41f9f6e2a4c1 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -561,6 +561,7 @@ struct ixgbe_adapter {
561 spinlock_t tmreg_lock; 561 spinlock_t tmreg_lock;
562 struct cyclecounter cc; 562 struct cyclecounter cc;
563 struct timecounter tc; 563 struct timecounter tc;
564 int rx_hwtstamp_filter;
564 u32 base_incval; 565 u32 base_incval;
565 u32 cycle_speed; 566 u32 cycle_speed;
566#endif /* CONFIG_IXGBE_PTP */ 567#endif /* CONFIG_IXGBE_PTP */
@@ -718,6 +719,7 @@ extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
718extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, 719extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
719 struct sk_buff *skb); 720 struct sk_buff *skb);
720extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, 721extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
722 union ixgbe_adv_rx_desc *rx_desc,
721 struct sk_buff *skb); 723 struct sk_buff *skb);
722extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, 724extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
723 struct ifreq *ifr, int cmd); 725 struct ifreq *ifr, int cmd);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 1675b662da06..b0ddfd47e473 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1397,8 +1397,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
1397 ixgbe_rx_checksum(rx_ring, rx_desc, skb); 1397 ixgbe_rx_checksum(rx_ring, rx_desc, skb);
1398 1398
1399#ifdef CONFIG_IXGBE_PTP 1399#ifdef CONFIG_IXGBE_PTP
1400 if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)) 1400 ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb);
1401 ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
1402#endif 1401#endif
1403 1402
1404 if ((dev->features & NETIF_F_HW_VLAN_RX) && 1403 if ((dev->features & NETIF_F_HW_VLAN_RX) &&
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 5ed8cffee178..cb7d1b2982c5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -26,6 +26,7 @@
26*******************************************************************************/ 26*******************************************************************************/
27#include "ixgbe.h" 27#include "ixgbe.h"
28#include <linux/export.h> 28#include <linux/export.h>
29#include <linux/ptp_classify.h>
29 30
30/* 31/*
31 * The 82599 and the X540 do not have true 64bit nanosecond scale 32 * The 82599 and the X540 do not have true 64bit nanosecond scale
@@ -100,6 +101,10 @@
100#define NSECS_PER_SEC 1000000000ULL 101#define NSECS_PER_SEC 1000000000ULL
101#endif 102#endif
102 103
104static struct sock_filter ptp_filter[] = {
105 PTP_FILTER
106};
107
103/** 108/**
104 * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) 109 * ixgbe_ptp_read - read raw cycle counter (to be used by time counter)
105 * @cc - the cyclecounter structure 110 * @cc - the cyclecounter structure
@@ -426,6 +431,68 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
426} 431}
427 432
428/** 433/**
434 * ixgbe_ptp_match - determine if this skb matches a ptp packet
435 * @skb: pointer to the skb
436 * @hwtstamp: pointer to the hwtstamp_config to check
437 *
438 * Determine whether the skb should have been timestamped, assuming the
439 * hwtstamp was set via the hwtstamp ioctl. Returns non-zero when the packet
440 * should have a timestamp waiting in the registers, and 0 otherwise.
441 *
442 * V1 packets have to check the version type to determine whether they are
443 * correct. However, we can't directly access the data because it might be
444 * fragmented in the SKB, in paged memory. In order to work around this, we
445 * use skb_copy_bits which will properly copy the data whether it is in the
446 * paged memory fragments or not. We have to copy the IP header as well as the
447 * message type.
448 */
449static int ixgbe_ptp_match(struct sk_buff *skb, int rx_filter)
450{
451 struct iphdr iph;
452 u8 msgtype;
453 unsigned int type, offset;
454
455 if (rx_filter == HWTSTAMP_FILTER_NONE)
456 return 0;
457
458 type = sk_run_filter(skb, ptp_filter);
459
460 if (likely(rx_filter == HWTSTAMP_FILTER_PTP_V2_EVENT))
461 return type & PTP_CLASS_V2;
462
463 /* For the remaining cases actually check message type */
464 switch (type) {
465 case PTP_CLASS_V1_IPV4:
466 skb_copy_bits(skb, OFF_IHL, &iph, sizeof(iph));
467 offset = ETH_HLEN + (iph.ihl << 2) + UDP_HLEN + OFF_PTP_CONTROL;
468 break;
469 case PTP_CLASS_V1_IPV6:
470 offset = OFF_PTP6 + OFF_PTP_CONTROL;
471 break;
472 default:
473 /* other cases invalid or handled above */
474 return 0;
475 }
476
477 /* Make sure our buffer is long enough */
478 if (skb->len < offset)
479 return 0;
480
481 skb_copy_bits(skb, offset, &msgtype, sizeof(msgtype));
482
483 switch (rx_filter) {
484 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
485 return (msgtype == IXGBE_RXMTRL_V1_SYNC_MSG);
486 break;
487 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
488 return (msgtype == IXGBE_RXMTRL_V1_DELAY_REQ_MSG);
489 break;
490 default:
491 return 0;
492 }
493}
494
495/**
429 * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp 496 * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp
430 * @q_vector: structure containing interrupt and ring information 497 * @q_vector: structure containing interrupt and ring information
431 * @skb: particular skb to send timestamp with 498 * @skb: particular skb to send timestamp with
@@ -474,6 +541,7 @@ void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
474/** 541/**
475 * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp 542 * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
476 * @q_vector: structure containing interrupt and ring information 543 * @q_vector: structure containing interrupt and ring information
544 * @rx_desc: the rx descriptor
477 * @skb: particular skb to send timestamp with 545 * @skb: particular skb to send timestamp with
478 * 546 *
479 * if the timestamp is valid, we convert it into the timecounter ns 547 * if the timestamp is valid, we convert it into the timecounter ns
@@ -481,6 +549,7 @@ void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
481 * is passed up the network stack 549 * is passed up the network stack
482 */ 550 */
483void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, 551void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
552 union ixgbe_adv_rx_desc *rx_desc,
484 struct sk_buff *skb) 553 struct sk_buff *skb)
485{ 554{
486 struct ixgbe_adapter *adapter; 555 struct ixgbe_adapter *adapter;
@@ -498,21 +567,33 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
498 hw = &adapter->hw; 567 hw = &adapter->hw;
499 568
500 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); 569 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
570
571 /* Check if we have a valid timestamp and make sure the skb should
572 * have been timestamped */
573 if (likely(!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID) ||
574 !ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter)))
575 return;
576
577 /*
578 * Always read the registers, in order to clear a possible fault
579 * because of stagnant RX timestamp values for a packet that never
580 * reached the queue.
581 */
501 regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); 582 regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
502 regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; 583 regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
503 584
504 /* 585 /*
505 * If this bit is set, then the RX registers contain the time stamp. No 586 * If the timestamp bit is set in the packet's descriptor, we know the
506 * other packet will be time stamped until we read these registers, so 587 * timestamp belongs to this packet. No other packet can be
507 * read the registers to make them available again. Because only one 588 * timestamped until the registers for timestamping have been read.
508 * packet can be time stamped at a time, we know that the register 589 * Therefor only one packet with this bit can be in the queue at a
509 * values must belong to this one here and therefore we don't need to 590 * time, and the rx timestamp values that were in the registers belong
510 * compare any of the additional attributes stored for it. 591 * to this packet.
511 * 592 *
512 * If nothing went wrong, then it should have a skb_shared_tx that we 593 * If nothing went wrong, then it should have a skb_shared_tx that we
513 * can turn into a skb_shared_hwtstamps. 594 * can turn into a skb_shared_hwtstamps.
514 */ 595 */
515 if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) 596 if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
516 return; 597 return;
517 598
518 spin_lock_irqsave(&adapter->tmreg_lock, flags); 599 spin_lock_irqsave(&adapter->tmreg_lock, flags);
@@ -598,19 +679,20 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
598 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 679 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
599 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 680 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
600 tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; 681 tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
601 config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
602 is_l2 = true; 682 is_l2 = true;
603 is_l4 = true; 683 is_l4 = true;
684 config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
604 break; 685 break;
605 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 686 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
606 case HWTSTAMP_FILTER_ALL: 687 case HWTSTAMP_FILTER_ALL:
607 default: 688 default:
608 /* 689 /*
609 * register RXMTRL must be set, therefore it is not 690 * register RXMTRL must be set in order to do V1 packets,
610 * possible to time stamp both V1 Sync and Delay_Req messages 691 * therefore it is not possible to time stamp both V1 Sync and
611 * and hardware does not support timestamping all packets 692 * Delay_Req messages and hardware does not support
612 * => return error 693 * timestamping all packets => return error
613 */ 694 */
695 config.rx_filter = HWTSTAMP_FILTER_NONE;
614 return -ERANGE; 696 return -ERANGE;
615 } 697 }
616 698
@@ -620,6 +702,9 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
620 return 0; 702 return 0;
621 } 703 }
622 704
705 /* Store filter value for later use */
706 adapter->rx_hwtstamp_filter = config.rx_filter;
707
623 /* define ethertype filter for timestamped packets */ 708 /* define ethertype filter for timestamped packets */
624 if (is_l2) 709 if (is_l2)
625 IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 710 IXGBE_WRITE_REG(hw, IXGBE_ETQF(3),
@@ -855,6 +940,10 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
855 return; 940 return;
856 } 941 }
857 942
943 /* initialize the ptp filter */
944 if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter)))
945 e_dev_warn("ptp_filter_init failed\n");
946
858 spin_lock_init(&adapter->tmreg_lock); 947 spin_lock_init(&adapter->tmreg_lock);
859 948
860 ixgbe_ptp_start_cyclecounter(adapter); 949 ixgbe_ptp_start_cyclecounter(adapter);