aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/ef10.c5
-rw-r--r--drivers/net/ethernet/sfc/ptp.c42
2 files changed, 30 insertions, 17 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index a3d891764030..dfff8e7a55e2 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -264,6 +264,8 @@ static int efx_ef10_probe(struct efx_nic *efx)
264 if (rc) 264 if (rc)
265 goto fail3; 265 goto fail3;
266 266
267 efx_ptp_probe(efx, NULL);
268
267 return 0; 269 return 0;
268 270
269fail3: 271fail3:
@@ -472,9 +474,10 @@ static void efx_ef10_remove(struct efx_nic *efx)
472 struct efx_ef10_nic_data *nic_data = efx->nic_data; 474 struct efx_ef10_nic_data *nic_data = efx->nic_data;
473 int rc; 475 int rc;
474 476
477 efx_ptp_remove(efx);
478
475 efx_mcdi_mon_remove(efx); 479 efx_mcdi_mon_remove(efx);
476 480
477 /* This needs to be after efx_ptp_remove_channel() with no filters */
478 efx_ef10_rx_free_indir_table(efx); 481 efx_ef10_rx_free_indir_table(efx);
479 482
480 if (nic_data->wc_membase) 483 if (nic_data->wc_membase)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 843e98dfb1b2..fe3c6d04fce8 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -248,7 +248,7 @@ struct efx_ptp_timeset {
248 * @start: Address at which MC indicates ready for synchronisation 248 * @start: Address at which MC indicates ready for synchronisation
249 * @host_time_pps: Host time at last PPS 249 * @host_time_pps: Host time at last PPS
250 * @current_adjfreq: Current ppb adjustment. 250 * @current_adjfreq: Current ppb adjustment.
251 * @phc_clock: Pointer to registered phc device 251 * @phc_clock: Pointer to registered phc device (if primary function)
252 * @phc_clock_info: Registration structure for phc device 252 * @phc_clock_info: Registration structure for phc device
253 * @pps_work: pps work task for handling pps events 253 * @pps_work: pps work task for handling pps events
254 * @pps_workwq: pps work queue 254 * @pps_workwq: pps work queue
@@ -1163,19 +1163,22 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
1163 if (rc < 0) 1163 if (rc < 0)
1164 goto fail3; 1164 goto fail3;
1165 1165
1166 ptp->phc_clock_info = efx_phc_clock_info; 1166 if (efx->mcdi->fn_flags &
1167 ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info, 1167 (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY)) {
1168 &efx->pci_dev->dev); 1168 ptp->phc_clock_info = efx_phc_clock_info;
1169 if (IS_ERR(ptp->phc_clock)) { 1169 ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info,
1170 rc = PTR_ERR(ptp->phc_clock); 1170 &efx->pci_dev->dev);
1171 goto fail3; 1171 if (IS_ERR(ptp->phc_clock)) {
1172 } 1172 rc = PTR_ERR(ptp->phc_clock);
1173 goto fail3;
1174 }
1173 1175
1174 INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker); 1176 INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker);
1175 ptp->pps_workwq = create_singlethread_workqueue("sfc_pps"); 1177 ptp->pps_workwq = create_singlethread_workqueue("sfc_pps");
1176 if (!ptp->pps_workwq) { 1178 if (!ptp->pps_workwq) {
1177 rc = -ENOMEM; 1179 rc = -ENOMEM;
1178 goto fail4; 1180 goto fail4;
1181 }
1179 } 1182 }
1180 ptp->nic_ts_enabled = false; 1183 ptp->nic_ts_enabled = false;
1181 1184
@@ -1224,10 +1227,12 @@ void efx_ptp_remove(struct efx_nic *efx)
1224 skb_queue_purge(&efx->ptp_data->rxq); 1227 skb_queue_purge(&efx->ptp_data->rxq);
1225 skb_queue_purge(&efx->ptp_data->txq); 1228 skb_queue_purge(&efx->ptp_data->txq);
1226 1229
1227 ptp_clock_unregister(efx->ptp_data->phc_clock); 1230 if (efx->ptp_data->phc_clock) {
1231 destroy_workqueue(efx->ptp_data->pps_workwq);
1232 ptp_clock_unregister(efx->ptp_data->phc_clock);
1233 }
1228 1234
1229 destroy_workqueue(efx->ptp_data->workwq); 1235 destroy_workqueue(efx->ptp_data->workwq);
1230 destroy_workqueue(efx->ptp_data->pps_workwq);
1231 1236
1232 efx_nic_free_buffer(efx, &efx->ptp_data->start); 1237 efx_nic_free_buffer(efx, &efx->ptp_data->start);
1233 kfree(efx->ptp_data); 1238 kfree(efx->ptp_data);
@@ -1440,6 +1445,9 @@ static int efx_ptp_ts_init(struct efx_nic *efx, struct hwtstamp_config *init)
1440void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info) 1445void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
1441{ 1446{
1442 struct efx_ptp_data *ptp = efx->ptp_data; 1447 struct efx_ptp_data *ptp = efx->ptp_data;
1448 struct efx_nic *primary = efx->primary;
1449
1450 ASSERT_RTNL();
1443 1451
1444 if (!ptp) 1452 if (!ptp)
1445 return; 1453 return;
@@ -1447,7 +1455,9 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
1447 ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE | 1455 ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE |
1448 SOF_TIMESTAMPING_RX_HARDWARE | 1456 SOF_TIMESTAMPING_RX_HARDWARE |
1449 SOF_TIMESTAMPING_RAW_HARDWARE); 1457 SOF_TIMESTAMPING_RAW_HARDWARE);
1450 ts_info->phc_index = ptp_clock_index(ptp->phc_clock); 1458 if (primary && primary->ptp_data && primary->ptp_data->phc_clock)
1459 ts_info->phc_index =
1460 ptp_clock_index(primary->ptp_data->phc_clock);
1451 ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; 1461 ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON;
1452 ts_info->rx_filters = ptp->efx->type->hwtstamp_filters; 1462 ts_info->rx_filters = ptp->efx->type->hwtstamp_filters;
1453} 1463}