sfc: Stop/re-start PTP when stopping/starting the datapath.
This disables PTP when we bring the interface down to avoid getting
unmatched RX timestamp events, and tries to re-enable it when bringing
the interface up.
[bwh: Make efx_ptp_stop() safe on Falcon. Introduce
efx_ptp_{start,stop}_datapath() functions; we'll expand them later.]
Fixes: 7c236c43b8
('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
Родитель
35f9a7a380
Коммит
2ea4dc28a5
|
@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx)
|
|||
WARN_ON(channel->rx_pkt_n_frags);
|
||||
}
|
||||
|
||||
efx_ptp_start_datapath(efx);
|
||||
|
||||
if (netif_device_present(efx->net_dev))
|
||||
netif_tx_wake_all_queues(efx->net_dev);
|
||||
}
|
||||
|
@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx_nic *efx)
|
|||
EFX_ASSERT_RESET_SERIALISED(efx);
|
||||
BUG_ON(efx->port_enabled);
|
||||
|
||||
efx_ptp_stop_datapath(efx);
|
||||
|
||||
/* Stop RX refill */
|
||||
efx_for_each_channel(channel, efx) {
|
||||
efx_for_each_channel_rx_queue(rx_queue, channel)
|
||||
|
|
|
@ -560,6 +560,8 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
|
|||
bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||
int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
|
||||
void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
|
||||
void efx_ptp_start_datapath(struct efx_nic *efx);
|
||||
void efx_ptp_stop_datapath(struct efx_nic *efx);
|
||||
|
||||
extern const struct efx_nic_type falcon_a1_nic_type;
|
||||
extern const struct efx_nic_type falcon_b0_nic_type;
|
||||
|
|
|
@ -801,9 +801,14 @@ fail:
|
|||
static int efx_ptp_stop(struct efx_nic *efx)
|
||||
{
|
||||
struct efx_ptp_data *ptp = efx->ptp_data;
|
||||
int rc = efx_ptp_disable(efx);
|
||||
struct list_head *cursor;
|
||||
struct list_head *next;
|
||||
int rc;
|
||||
|
||||
if (ptp == NULL)
|
||||
return 0;
|
||||
|
||||
rc = efx_ptp_disable(efx);
|
||||
|
||||
if (ptp->rxfilter_installed) {
|
||||
efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
|
||||
|
@ -828,6 +833,13 @@ static int efx_ptp_stop(struct efx_nic *efx)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int efx_ptp_restart(struct efx_nic *efx)
|
||||
{
|
||||
if (efx->ptp_data && efx->ptp_data->enabled)
|
||||
return efx_ptp_start(efx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void efx_ptp_pps_worker(struct work_struct *work)
|
||||
{
|
||||
struct efx_ptp_data *ptp =
|
||||
|
@ -1125,7 +1137,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
|
|||
{
|
||||
if ((enable_wanted != efx->ptp_data->enabled) ||
|
||||
(enable_wanted && (efx->ptp_data->mode != new_mode))) {
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (enable_wanted) {
|
||||
/* Change of mode requires disable */
|
||||
|
@ -1142,7 +1154,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
|
|||
* succeed.
|
||||
*/
|
||||
efx->ptp_data->mode = new_mode;
|
||||
rc = efx_ptp_start(efx);
|
||||
if (netif_running(efx->net_dev))
|
||||
rc = efx_ptp_start(efx);
|
||||
if (rc == 0) {
|
||||
rc = efx_ptp_synchronize(efx,
|
||||
PTP_SYNC_ATTEMPTS * 2);
|
||||
|
@ -1515,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
|
|||
efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
|
||||
&efx_ptp_channel_type;
|
||||
}
|
||||
|
||||
void efx_ptp_start_datapath(struct efx_nic *efx)
|
||||
{
|
||||
if (efx_ptp_restart(efx))
|
||||
netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
|
||||
}
|
||||
|
||||
void efx_ptp_stop_datapath(struct efx_nic *efx)
|
||||
{
|
||||
efx_ptp_stop(efx);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче