i40e: break PTP hardware control from ioctl command for timestamp mode

This patch facilitates future work by breaking the PTP hardware control
bits out of the i40e_set_ts_config function. By doing this, we can
maintain state about the 1588 timestamping mode and properly re-enable
to the last known mode during a re-initialize of 1588 bits.

This patch also modifies i40e_ptp_init to call the
i40e_ptp_set_timestamp_mode during the reconfiguration process. A
future patch will ensure that the hwtstamp_config structure is not reset
during this process, so that timestamp mode will be maintained across a
reset.

Change-ID: Ic20832c96c5c512ac203b6c7534e10d891c560f0
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Jacob Keller 2014-06-04 06:08:29 +00:00 committed by Jeff Kirsher
parent 69d1a70c3f
commit 189464555a
1 changed files with 43 additions and 16 deletions

View File

@ -423,28 +423,23 @@ int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
} }
/** /**
* i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping * i40e_ptp_set_timestamp_mode - setup hardware for requested timestamp mode
* @pf: Board private structure * @pf: Board private structure
* @ifreq: ioctl data * @config: hwtstamp settings requested or saved
* *
* Respond to the user filter requests and make the appropriate hardware * Control hardware registers to enter the specific mode requested by the
* changes here. The XL710 cannot support splitting of the Tx/Rx timestamping * user. Also used during reset path to ensure that timestamp settings are
* logic, so keep track in software of whether to indicate these timestamps * maintained.
* or not.
* *
* It is permissible to "upgrade" the user request to a broader filter, as long * Note: modifies config in place, and may update the requested mode to be
* as the user receives the timestamps they care about and the user is notified * more broad if the specific filter is not directly supported.
* the filter has been broadened.
**/ **/
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr) static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
struct hwtstamp_config *config)
{ {
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
struct hwtstamp_config *config = &pf->tstamp_config;
u32 pf_id, tsyntype, regval; u32 pf_id, tsyntype, regval;
if (copy_from_user(config, ifr->ifr_data, sizeof(*config)))
return -EFAULT;
/* Reserved for future extensions. */ /* Reserved for future extensions. */
if (config->flags) if (config->flags)
return -EINVAL; return -EINVAL;
@ -535,6 +530,35 @@ int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
wr32(hw, I40E_PRTTSYN_CTL1, regval); wr32(hw, I40E_PRTTSYN_CTL1, regval);
} }
return 0;
}
/**
* i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping
* @pf: Board private structure
* @ifreq: ioctl data
*
* Respond to the user filter requests and make the appropriate hardware
* changes here. The XL710 cannot support splitting of the Tx/Rx timestamping
* logic, so keep track in software of whether to indicate these timestamps
* or not.
*
* It is permissible to "upgrade" the user request to a broader filter, as long
* as the user receives the timestamps they care about and the user is notified
* the filter has been broadened.
**/
int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
{
struct hwtstamp_config *config = &pf->tstamp_config;
int err;
if (copy_from_user(config, ifr->ifr_data, sizeof(*config)))
return -EFAULT;
err = i40e_ptp_set_timestamp_mode(pf, config);
if (err)
return err;
return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
-EFAULT : 0; -EFAULT : 0;
} }
@ -578,6 +602,9 @@ void i40e_ptp_init(struct i40e_pf *pf)
netdev->name); netdev->name);
pf->flags |= I40E_FLAG_PTP; pf->flags |= I40E_FLAG_PTP;
pf->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
pf->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
/* Ensure the clocks are running. */ /* Ensure the clocks are running. */
regval = rd32(hw, I40E_PRTTSYN_CTL0); regval = rd32(hw, I40E_PRTTSYN_CTL0);
regval |= I40E_PRTTSYN_CTL0_TSYNENA_MASK; regval |= I40E_PRTTSYN_CTL0_TSYNENA_MASK;
@ -589,8 +616,8 @@ void i40e_ptp_init(struct i40e_pf *pf)
/* Set the increment value per clock tick. */ /* Set the increment value per clock tick. */
i40e_ptp_set_increment(pf); i40e_ptp_set_increment(pf);
/* reset the tstamp_config */ /* reset timestamping mode */
memset(&pf->tstamp_config, 0, sizeof(pf->tstamp_config)); i40e_ptp_set_timestamp_mode(pf, &pf->tstamp_config);
/* Set the clock value. */ /* Set the clock value. */
ts = ktime_to_timespec(ktime_get_real()); ts = ktime_to_timespec(ktime_get_real());