Skip to content

Commit

Permalink
sfc: Stop/re-start PTP when stopping/starting the datapath.
Browse files Browse the repository at this point in the history
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: 7c236c4 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
  • Loading branch information
Alexandre Rames authored and Ben Hutchings committed Dec 6, 2013
1 parent 35f9a7a commit 2ea4dc2
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/sfc/nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 27 additions & 3 deletions drivers/net/ethernet/sfc/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,14 @@ static int efx_ptp_start(struct efx_nic *efx)
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,
Expand All @@ -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 =
Expand Down Expand Up @@ -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 */
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

0 comments on commit 2ea4dc2

Please sign in to comment.