diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2013-01-18 20:09:58 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-01-27 03:36:35 -0500 |
commit | d89777bf0e42e7cb6ce8eae35190b9375c3b4211 (patch) | |
tree | f1ec4ec54324abc8b19ce0ac04b53b57ca0d4542 /drivers/net/ethernet/intel/e1000e/netdev.c | |
parent | 347b5201cb2e8b9e4a20d81582563f51336eb215 (diff) |
e1000e: add support for IEEE-1588 PTP
Add PTP IEEE-1588 support and make accesible via the PHC subsystem.
v2: make e1000e_ptp_clock_info a static const struct per Stephen Hemminger
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 8bb5d28eca14..34be756ee1e2 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -3413,7 +3413,7 @@ static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) | |||
3413 | * Get attributes for incrementing the System Time Register SYSTIML/H at | 3413 | * Get attributes for incrementing the System Time Register SYSTIML/H at |
3414 | * the default base frequency, and set the cyclecounter shift value. | 3414 | * the default base frequency, and set the cyclecounter shift value. |
3415 | **/ | 3415 | **/ |
3416 | static s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) | 3416 | s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) |
3417 | { | 3417 | { |
3418 | struct e1000_hw *hw = &adapter->hw; | 3418 | struct e1000_hw *hw = &adapter->hw; |
3419 | u32 incvalue, incperiod, shift; | 3419 | u32 incvalue, incperiod, shift; |
@@ -3485,6 +3485,10 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter) | |||
3485 | struct hwtstamp_config *config = &adapter->hwtstamp_config; | 3485 | struct hwtstamp_config *config = &adapter->hwtstamp_config; |
3486 | u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED; | 3486 | u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED; |
3487 | u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED; | 3487 | u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED; |
3488 | u32 rxmtrl = 0; | ||
3489 | u16 rxudp = 0; | ||
3490 | bool is_l4 = false; | ||
3491 | bool is_l2 = false; | ||
3488 | u32 regval; | 3492 | u32 regval; |
3489 | s32 ret_val; | 3493 | s32 ret_val; |
3490 | 3494 | ||
@@ -3509,7 +3513,69 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter) | |||
3509 | case HWTSTAMP_FILTER_NONE: | 3513 | case HWTSTAMP_FILTER_NONE: |
3510 | tsync_rx_ctl = 0; | 3514 | tsync_rx_ctl = 0; |
3511 | break; | 3515 | break; |
3516 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
3517 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1; | ||
3518 | rxmtrl = E1000_RXMTRL_PTP_V1_SYNC_MESSAGE; | ||
3519 | is_l4 = true; | ||
3520 | break; | ||
3521 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
3522 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1; | ||
3523 | rxmtrl = E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE; | ||
3524 | is_l4 = true; | ||
3525 | break; | ||
3526 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
3527 | /* Also time stamps V2 L2 Path Delay Request/Response */ | ||
3528 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2; | ||
3529 | rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE; | ||
3530 | is_l2 = true; | ||
3531 | break; | ||
3532 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
3533 | /* Also time stamps V2 L2 Path Delay Request/Response. */ | ||
3534 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2; | ||
3535 | rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE; | ||
3536 | is_l2 = true; | ||
3537 | break; | ||
3538 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
3539 | /* Hardware cannot filter just V2 L4 Sync messages; | ||
3540 | * fall-through to V2 (both L2 and L4) Sync. | ||
3541 | */ | ||
3542 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
3543 | /* Also time stamps V2 Path Delay Request/Response. */ | ||
3544 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2; | ||
3545 | rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE; | ||
3546 | is_l2 = true; | ||
3547 | is_l4 = true; | ||
3548 | break; | ||
3549 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
3550 | /* Hardware cannot filter just V2 L4 Delay Request messages; | ||
3551 | * fall-through to V2 (both L2 and L4) Delay Request. | ||
3552 | */ | ||
3553 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
3554 | /* Also time stamps V2 Path Delay Request/Response. */ | ||
3555 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2; | ||
3556 | rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE; | ||
3557 | is_l2 = true; | ||
3558 | is_l4 = true; | ||
3559 | break; | ||
3560 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
3561 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
3562 | /* Hardware cannot filter just V2 L4 or L2 Event messages; | ||
3563 | * fall-through to all V2 (both L2 and L4) Events. | ||
3564 | */ | ||
3565 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
3566 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2; | ||
3567 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | ||
3568 | is_l2 = true; | ||
3569 | is_l4 = true; | ||
3570 | break; | ||
3571 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
3572 | /* For V1, the hardware can only filter Sync messages or | ||
3573 | * Delay Request messages but not both so fall-through to | ||
3574 | * time stamp all packets. | ||
3575 | */ | ||
3512 | case HWTSTAMP_FILTER_ALL: | 3576 | case HWTSTAMP_FILTER_ALL: |
3577 | is_l2 = true; | ||
3578 | is_l4 = true; | ||
3513 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL; | 3579 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL; |
3514 | config->rx_filter = HWTSTAMP_FILTER_ALL; | 3580 | config->rx_filter = HWTSTAMP_FILTER_ALL; |
3515 | break; | 3581 | break; |
@@ -3541,6 +3607,22 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter) | |||
3541 | return -EAGAIN; | 3607 | return -EAGAIN; |
3542 | } | 3608 | } |
3543 | 3609 | ||
3610 | /* L2: define ethertype filter for time stamped packets */ | ||
3611 | if (is_l2) | ||
3612 | rxmtrl |= ETH_P_1588; | ||
3613 | |||
3614 | /* define which PTP packets get time stamped */ | ||
3615 | ew32(RXMTRL, rxmtrl); | ||
3616 | |||
3617 | /* Filter by destination port */ | ||
3618 | if (is_l4) { | ||
3619 | rxudp = PTP_EV_PORT; | ||
3620 | cpu_to_be16s(&rxudp); | ||
3621 | } | ||
3622 | ew32(RXUDP, rxudp); | ||
3623 | |||
3624 | e1e_flush(); | ||
3625 | |||
3544 | /* Clear TSYNCRXCTL_VALID & TSYNCTXCTL_VALID bit */ | 3626 | /* Clear TSYNCRXCTL_VALID & TSYNCTXCTL_VALID bit */ |
3545 | regval = er32(RXSTMPH); | 3627 | regval = er32(RXSTMPH); |
3546 | regval = er32(TXSTMPH); | 3628 | regval = er32(TXSTMPH); |
@@ -5665,6 +5747,24 @@ static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) | |||
5665 | 5747 | ||
5666 | config = adapter->hwtstamp_config; | 5748 | config = adapter->hwtstamp_config; |
5667 | 5749 | ||
5750 | switch (config.rx_filter) { | ||
5751 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
5752 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
5753 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
5754 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
5755 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
5756 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
5757 | /* With V2 type filters which specify a Sync or Delay Request, | ||
5758 | * Path Delay Request/Response messages are also time stamped | ||
5759 | * by hardware so notify the caller the requested packets plus | ||
5760 | * some others are time stamped. | ||
5761 | */ | ||
5762 | config.rx_filter = HWTSTAMP_FILTER_SOME; | ||
5763 | break; | ||
5764 | default: | ||
5765 | break; | ||
5766 | } | ||
5767 | |||
5668 | return copy_to_user(ifr->ifr_data, &config, | 5768 | return copy_to_user(ifr->ifr_data, &config, |
5669 | sizeof(config)) ? -EFAULT : 0; | 5769 | sizeof(config)) ? -EFAULT : 0; |
5670 | } | 5770 | } |
@@ -6672,6 +6772,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6672 | /* carrier off reporting is important to ethtool even BEFORE open */ | 6772 | /* carrier off reporting is important to ethtool even BEFORE open */ |
6673 | netif_carrier_off(netdev); | 6773 | netif_carrier_off(netdev); |
6674 | 6774 | ||
6775 | /* init PTP hardware clock */ | ||
6776 | e1000e_ptp_init(adapter); | ||
6777 | |||
6675 | e1000_print_device_info(adapter); | 6778 | e1000_print_device_info(adapter); |
6676 | 6779 | ||
6677 | if (pci_dev_run_wake(pdev)) | 6780 | if (pci_dev_run_wake(pdev)) |
@@ -6720,6 +6823,8 @@ static void e1000_remove(struct pci_dev *pdev) | |||
6720 | struct e1000_adapter *adapter = netdev_priv(netdev); | 6823 | struct e1000_adapter *adapter = netdev_priv(netdev); |
6721 | bool down = test_bit(__E1000_DOWN, &adapter->state); | 6824 | bool down = test_bit(__E1000_DOWN, &adapter->state); |
6722 | 6825 | ||
6826 | e1000e_ptp_remove(adapter); | ||
6827 | |||
6723 | /* The timers may be rescheduled, so explicitly disable them | 6828 | /* The timers may be rescheduled, so explicitly disable them |
6724 | * from being rescheduled. | 6829 | * from being rescheduled. |
6725 | */ | 6830 | */ |