Commit 9aecda95 authored by Ben Hutchings's avatar Ben Hutchings

sfc: Enable PTP clock and timestamping for all functions on EF10

The SFC9100 family has only one clock per controller, shared by all
functions.  Therefore only create a clock device under the primary
function, and make all other functions refer to the primary's clock
device.

Since PTP functionality is limited to port 0 and PF 0 on the earlier
SFN[56]322F boards, and we also set the primary flag for that
function, we can make the creation of a clock device conditional only
on this flag.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 0bcf4a64
...@@ -264,6 +264,8 @@ static int efx_ef10_probe(struct efx_nic *efx) ...@@ -264,6 +264,8 @@ static int efx_ef10_probe(struct efx_nic *efx)
if (rc) if (rc)
goto fail3; goto fail3;
efx_ptp_probe(efx, NULL);
return 0; return 0;
fail3: fail3:
...@@ -472,9 +474,10 @@ static void efx_ef10_remove(struct efx_nic *efx) ...@@ -472,9 +474,10 @@ static void efx_ef10_remove(struct efx_nic *efx)
struct efx_ef10_nic_data *nic_data = efx->nic_data; struct efx_ef10_nic_data *nic_data = efx->nic_data;
int rc; int rc;
efx_ptp_remove(efx);
efx_mcdi_mon_remove(efx); efx_mcdi_mon_remove(efx);
/* This needs to be after efx_ptp_remove_channel() with no filters */
efx_ef10_rx_free_indir_table(efx); efx_ef10_rx_free_indir_table(efx);
if (nic_data->wc_membase) if (nic_data->wc_membase)
......
...@@ -248,7 +248,7 @@ struct efx_ptp_timeset { ...@@ -248,7 +248,7 @@ struct efx_ptp_timeset {
* @start: Address at which MC indicates ready for synchronisation * @start: Address at which MC indicates ready for synchronisation
* @host_time_pps: Host time at last PPS * @host_time_pps: Host time at last PPS
* @current_adjfreq: Current ppb adjustment. * @current_adjfreq: Current ppb adjustment.
* @phc_clock: Pointer to registered phc device * @phc_clock: Pointer to registered phc device (if primary function)
* @phc_clock_info: Registration structure for phc device * @phc_clock_info: Registration structure for phc device
* @pps_work: pps work task for handling pps events * @pps_work: pps work task for handling pps events
* @pps_workwq: pps work queue * @pps_workwq: pps work queue
...@@ -1163,19 +1163,22 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) ...@@ -1163,19 +1163,22 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
if (rc < 0) if (rc < 0)
goto fail3; goto fail3;
ptp->phc_clock_info = efx_phc_clock_info; if (efx->mcdi->fn_flags &
ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info, (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY)) {
&efx->pci_dev->dev); ptp->phc_clock_info = efx_phc_clock_info;
if (IS_ERR(ptp->phc_clock)) { ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info,
rc = PTR_ERR(ptp->phc_clock); &efx->pci_dev->dev);
goto fail3; if (IS_ERR(ptp->phc_clock)) {
} rc = PTR_ERR(ptp->phc_clock);
goto fail3;
}
INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker); INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker);
ptp->pps_workwq = create_singlethread_workqueue("sfc_pps"); ptp->pps_workwq = create_singlethread_workqueue("sfc_pps");
if (!ptp->pps_workwq) { if (!ptp->pps_workwq) {
rc = -ENOMEM; rc = -ENOMEM;
goto fail4; goto fail4;
}
} }
ptp->nic_ts_enabled = false; ptp->nic_ts_enabled = false;
...@@ -1224,10 +1227,12 @@ void efx_ptp_remove(struct efx_nic *efx) ...@@ -1224,10 +1227,12 @@ void efx_ptp_remove(struct efx_nic *efx)
skb_queue_purge(&efx->ptp_data->rxq); skb_queue_purge(&efx->ptp_data->rxq);
skb_queue_purge(&efx->ptp_data->txq); skb_queue_purge(&efx->ptp_data->txq);
ptp_clock_unregister(efx->ptp_data->phc_clock); if (efx->ptp_data->phc_clock) {
destroy_workqueue(efx->ptp_data->pps_workwq);
ptp_clock_unregister(efx->ptp_data->phc_clock);
}
destroy_workqueue(efx->ptp_data->workwq); destroy_workqueue(efx->ptp_data->workwq);
destroy_workqueue(efx->ptp_data->pps_workwq);
efx_nic_free_buffer(efx, &efx->ptp_data->start); efx_nic_free_buffer(efx, &efx->ptp_data->start);
kfree(efx->ptp_data); kfree(efx->ptp_data);
...@@ -1440,6 +1445,9 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init) ...@@ -1440,6 +1445,9 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info) void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
{ {
struct efx_ptp_data *ptp = efx->ptp_data; struct efx_ptp_data *ptp = efx->ptp_data;
struct efx_nic *primary = efx->primary;
ASSERT_RTNL();
if (!ptp) if (!ptp)
return; return;
...@@ -1447,7 +1455,9 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info) ...@@ -1447,7 +1455,9 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE | ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE |
SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE); SOF_TIMESTAMPING_RAW_HARDWARE);
ts_info->phc_index = ptp_clock_index(ptp->phc_clock); if (primary && primary->ptp_data && primary->ptp_data->phc_clock)
ts_info->phc_index =
ptp_clock_index(primary->ptp_data->phc_clock);
ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON;
ts_info->rx_filters = ptp->efx->type->hwtstamp_filters; ts_info->rx_filters = ptp->efx->type->hwtstamp_filters;
} }
......
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