Commit 1a71ab24 authored by Jacob Keller's avatar Jacob Keller Committed by Jeff Kirsher

ixgbe: (PTP) refactor init, cyclecounter and reset

This patch modifies when and where PTP registers and data are set. Previously
a work-around was used inside cyclecounter_start in order to reset some of the
time registers. This patch creates a new ixgbe_ptp_reset specifically for this
purpose. The cyclecounter configuration has trimmed down to only modify what
is necessary. Due to hardware conditions after probe and before open, PTP init
has now moved into the ixgbe_open call. This allows the ptp device name in the
sysfs to be the ethernet device name instead of the MAC address.

The cyclecounter check flag is renamed to PTP_ENABLED and is used to prevent
PTP init from happening when PTP has not been enabled.

CC: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent f8a06c2c
...@@ -483,7 +483,7 @@ struct ixgbe_adapter { ...@@ -483,7 +483,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
#define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8) #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8)
#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9) #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9)
#define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 10) #define IXGBE_FLAG2_PTP_ENABLED (u32)(1 << 10)
#define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11) #define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11)
/* Tx fast path data */ /* Tx fast path data */
...@@ -581,7 +581,6 @@ struct ixgbe_adapter { ...@@ -581,7 +581,6 @@ struct ixgbe_adapter {
struct timecounter tc; struct timecounter tc;
int rx_hwtstamp_filter; int rx_hwtstamp_filter;
u32 base_incval; u32 base_incval;
u32 cycle_speed;
#endif /* CONFIG_IXGBE_PTP */ #endif /* CONFIG_IXGBE_PTP */
/* SR-IOV */ /* SR-IOV */
...@@ -754,6 +753,7 @@ extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, ...@@ -754,6 +753,7 @@ extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
struct ifreq *ifr, int cmd); struct ifreq *ifr, int cmd);
extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
#endif /* CONFIG_IXGBE_PTP */ #endif /* CONFIG_IXGBE_PTP */
......
...@@ -4210,6 +4210,11 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) ...@@ -4210,6 +4210,11 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
/* update SAN MAC vmdq pool selection */ /* update SAN MAC vmdq pool selection */
if (hw->mac.san_mac_rar_index) if (hw->mac.san_mac_rar_index)
hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0)); hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0));
#ifdef CONFIG_IXGBE_PTP
if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
ixgbe_ptp_reset(adapter);
#endif
} }
/** /**
...@@ -4919,6 +4924,10 @@ static int ixgbe_open(struct net_device *netdev) ...@@ -4919,6 +4924,10 @@ static int ixgbe_open(struct net_device *netdev)
if (err) if (err)
goto err_set_queues; goto err_set_queues;
#ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_init(adapter);
#endif /* CONFIG_IXGBE_PTP*/
ixgbe_up_complete(adapter); ixgbe_up_complete(adapter);
return 0; return 0;
...@@ -4950,6 +4959,10 @@ static int ixgbe_close(struct net_device *netdev) ...@@ -4950,6 +4959,10 @@ static int ixgbe_close(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
#ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_stop(adapter);
#endif
ixgbe_down(adapter); ixgbe_down(adapter);
ixgbe_free_irq(adapter); ixgbe_free_irq(adapter);
...@@ -5518,7 +5531,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) ...@@ -5518,7 +5531,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
} }
#ifdef CONFIG_IXGBE_PTP #ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_start_cyclecounter(adapter); if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
ixgbe_ptp_start_cyclecounter(adapter);
#endif #endif
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
...@@ -5565,7 +5579,8 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) ...@@ -5565,7 +5579,8 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
#ifdef CONFIG_IXGBE_PTP #ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_start_cyclecounter(adapter); if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
ixgbe_ptp_start_cyclecounter(adapter);
#endif #endif
e_info(drv, "NIC Link is Down\n"); e_info(drv, "NIC Link is Down\n");
...@@ -7403,10 +7418,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7403,10 +7418,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
#ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_init(adapter);
#endif /* CONFIG_IXGBE_PTP*/
/* save off EEPROM version number */ /* save off EEPROM version number */
hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh); hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh);
hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl); hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl);
...@@ -7544,9 +7555,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ...@@ -7544,9 +7555,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
set_bit(__IXGBE_DOWN, &adapter->state); set_bit(__IXGBE_DOWN, &adapter->state);
cancel_work_sync(&adapter->service_task); cancel_work_sync(&adapter->service_task);
#ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_stop(adapter);
#endif
#ifdef CONFIG_IXGBE_DCA #ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
......
...@@ -411,7 +411,7 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) ...@@ -411,7 +411,7 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies; unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies;
struct timespec ts; struct timespec ts;
if ((adapter->flags2 & IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED) && if ((adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) &&
(elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) { (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) {
ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); ixgbe_ptp_gettime(&adapter->ptp_caps, &ts);
adapter->last_overflow_check = jiffies; adapter->last_overflow_check = jiffies;
...@@ -759,57 +759,19 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, ...@@ -759,57 +759,19 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
* ixgbe_ptp_start_cyclecounter - create the cycle counter from hw * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
* @adapter: pointer to the adapter structure * @adapter: pointer to the adapter structure
* *
* this function initializes the timecounter and cyclecounter * This function should be called to set the proper values for the TIMINCA
* structures for use in generated a ns counter from the arbitrary * register and tell the cyclecounter structure what the tick rate of SYSTIME
* fixed point cycles registers in the hardware. * is. It does not directly modify SYSTIME registers or the timecounter
* * structure. It should be called whenever a new TIMINCA value is necessary,
* A change in link speed impacts the frequency of the DMA clock on * such as during initialization or when the link speed changes.
* the device, which is used to generate the cycle counter
* registers. Therefor this function is called whenever the link speed
* changes.
*
* This function also turns on the SDP pin for clock out feature (X540
* only), because this is where the shift is first calculated.
*/ */
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 incval = 0; u32 incval = 0;
u32 timinca = 0;
u32 shift = 0; u32 shift = 0;
u32 cycle_speed;
unsigned long flags; unsigned long flags;
/**
* Determine what speed we need to set the cyclecounter
* for. It should be different for 100Mb, 1Gb, and 10Gb. Treat
* unknown speeds as 10Gb. (Hence why we can't just copy the
* link_speed.
*/
switch (adapter->link_speed) {
case IXGBE_LINK_SPEED_100_FULL:
case IXGBE_LINK_SPEED_1GB_FULL:
case IXGBE_LINK_SPEED_10GB_FULL:
cycle_speed = adapter->link_speed;
break;
default:
/* cycle speed should be 10Gb when there is no link */
cycle_speed = IXGBE_LINK_SPEED_10GB_FULL;
break;
}
/*
* grab the current TIMINCA value from the register so that it can be
* double checked. If the register value has been cleared, it must be
* reset to the correct value for generating a cyclecounter. If
* TIMINCA is zero, the SYSTIME registers do not increment at all.
*/
timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA);
/* Bail if the cycle speed didn't change and TIMINCA is non-zero */
if (adapter->cycle_speed == cycle_speed && timinca)
return;
/** /**
* Scale the NIC cycle counter by a large factor so that * Scale the NIC cycle counter by a large factor so that
* relatively small corrections to the frequency can be added * relatively small corrections to the frequency can be added
...@@ -819,8 +781,12 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) ...@@ -819,8 +781,12 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
* to nanoseconds using only a multiplier and a right-shift, * to nanoseconds using only a multiplier and a right-shift,
* and (c) the value must fit within the timinca register space * and (c) the value must fit within the timinca register space
* => math based on internal DMA clock rate and available bits * => math based on internal DMA clock rate and available bits
*
* Note that when there is no link, internal DMA clock is same as when
* link speed is 10Gb. Set the registers correctly even when link is
* down to preserve the clock setting
*/ */
switch (cycle_speed) { switch (adapter->link_speed) {
case IXGBE_LINK_SPEED_100_FULL: case IXGBE_LINK_SPEED_100_FULL:
incval = IXGBE_INCVAL_100; incval = IXGBE_INCVAL_100;
shift = IXGBE_INCVAL_SHIFT_100; shift = IXGBE_INCVAL_SHIFT_100;
...@@ -830,6 +796,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) ...@@ -830,6 +796,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
shift = IXGBE_INCVAL_SHIFT_1GB; shift = IXGBE_INCVAL_SHIFT_1GB;
break; break;
case IXGBE_LINK_SPEED_10GB_FULL: case IXGBE_LINK_SPEED_10GB_FULL:
default:
incval = IXGBE_INCVAL_10GB; incval = IXGBE_INCVAL_10GB;
shift = IXGBE_INCVAL_SHIFT_10GB; shift = IXGBE_INCVAL_SHIFT_10GB;
break; break;
...@@ -857,18 +824,11 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) ...@@ -857,18 +824,11 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
return; return;
} }
/* reset the system time registers */ /* update the base incval used to calculate frequency adjustment */
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
IXGBE_WRITE_FLUSH(hw);
/* store the new cycle speed */
adapter->cycle_speed = cycle_speed;
ACCESS_ONCE(adapter->base_incval) = incval; ACCESS_ONCE(adapter->base_incval) = incval;
smp_mb(); smp_mb();
/* grab the ptp lock */ /* need lock to prevent incorrect read while modifying cyclecounter */
spin_lock_irqsave(&adapter->tmreg_lock, flags); spin_lock_irqsave(&adapter->tmreg_lock, flags);
memset(&adapter->cc, 0, sizeof(adapter->cc)); memset(&adapter->cc, 0, sizeof(adapter->cc));
...@@ -877,6 +837,31 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) ...@@ -877,6 +837,31 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
adapter->cc.shift = shift; adapter->cc.shift = shift;
adapter->cc.mult = 1; adapter->cc.mult = 1;
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
}
/**
* ixgbe_ptp_reset
* @adapter: the ixgbe private board structure
*
* When the MAC resets, all timesync features are reset. This function should be
* called to re-enable the PTP clock structure. It will re-init the timecounter
* structure based on the kernel time as well as setup the cycle counter data.
*/
void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
unsigned long flags;
/* set SYSTIME registers to 0 just in case */
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
IXGBE_WRITE_FLUSH(hw);
ixgbe_ptp_start_cyclecounter(adapter);
spin_lock_irqsave(&adapter->tmreg_lock, flags);
/* reset the ns time counter */ /* reset the ns time counter */
timecounter_init(&adapter->tc, &adapter->cc, timecounter_init(&adapter->tc, &adapter->cc,
ktime_to_ns(ktime_get_real())); ktime_to_ns(ktime_get_real()));
...@@ -904,7 +889,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) ...@@ -904,7 +889,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_X540: case ixgbe_mac_X540:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name);
adapter->ptp_caps.owner = THIS_MODULE; adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 250000000; adapter->ptp_caps.max_adj = 250000000;
adapter->ptp_caps.n_alarm = 0; adapter->ptp_caps.n_alarm = 0;
...@@ -918,7 +903,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) ...@@ -918,7 +903,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
adapter->ptp_caps.enable = ixgbe_ptp_enable; adapter->ptp_caps.enable = ixgbe_ptp_enable;
break; break;
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name);
adapter->ptp_caps.owner = THIS_MODULE; adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 250000000; adapter->ptp_caps.max_adj = 250000000;
adapter->ptp_caps.n_alarm = 0; adapter->ptp_caps.n_alarm = 0;
...@@ -942,11 +927,6 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) ...@@ -942,11 +927,6 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
spin_lock_init(&adapter->tmreg_lock); spin_lock_init(&adapter->tmreg_lock);
ixgbe_ptp_start_cyclecounter(adapter);
/* (Re)start the overflow check */
adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED;
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
&adapter->pdev->dev); &adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) { if (IS_ERR(adapter->ptp_clock)) {
...@@ -955,6 +935,11 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) ...@@ -955,6 +935,11 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
} else } else
e_dev_info("registered PHC device on %s\n", netdev->name); e_dev_info("registered PHC device on %s\n", netdev->name);
ixgbe_ptp_reset(adapter);
/* set the flag that PTP has been enabled */
adapter->flags2 |= IXGBE_FLAG2_PTP_ENABLED;
return; return;
} }
...@@ -967,7 +952,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) ...@@ -967,7 +952,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
{ {
/* stop the overflow check task */ /* stop the overflow check task */
adapter->flags2 &= ~(IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED | adapter->flags2 &= ~(IXGBE_FLAG2_PTP_ENABLED |
IXGBE_FLAG2_PTP_PPS_ENABLED); IXGBE_FLAG2_PTP_PPS_ENABLED);
ixgbe_ptp_setup_sdp(adapter); ixgbe_ptp_setup_sdp(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment