Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ea4dc28 authored by Alexandre Rames's avatar Alexandre Rames Committed by Ben Hutchings
Browse files

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: 7c236c43 ('sfc: Add support for IEEE-1588 PTP')
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 35f9a7a3
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx)
		WARN_ON(channel->rx_pkt_n_frags);
		WARN_ON(channel->rx_pkt_n_frags);
	}
	}


	efx_ptp_start_datapath(efx);

	if (netif_device_present(efx->net_dev))
	if (netif_device_present(efx->net_dev))
		netif_tx_wake_all_queues(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);
	EFX_ASSERT_RESET_SERIALISED(efx);
	BUG_ON(efx->port_enabled);
	BUG_ON(efx->port_enabled);


	efx_ptp_stop_datapath(efx);

	/* Stop RX refill */
	/* Stop RX refill */
	efx_for_each_channel(channel, efx) {
	efx_for_each_channel(channel, efx) {
		efx_for_each_channel_rx_queue(rx_queue, channel)
		efx_for_each_channel_rx_queue(rx_queue, channel)
+2 −0
Original line number Original line Diff line number Diff line
@@ -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);
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);
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_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_a1_nic_type;
extern const struct efx_nic_type falcon_b0_nic_type;
extern const struct efx_nic_type falcon_b0_nic_type;
+27 −3
Original line number Original line Diff line number Diff line
@@ -801,9 +801,14 @@ fail:
static int efx_ptp_stop(struct efx_nic *efx)
static int efx_ptp_stop(struct efx_nic *efx)
{
{
	struct efx_ptp_data *ptp = efx->ptp_data;
	struct efx_ptp_data *ptp = efx->ptp_data;
	int rc = efx_ptp_disable(efx);
	struct list_head *cursor;
	struct list_head *cursor;
	struct list_head *next;
	struct list_head *next;
	int rc;

	if (ptp == NULL)
		return 0;

	rc = efx_ptp_disable(efx);


	if (ptp->rxfilter_installed) {
	if (ptp->rxfilter_installed) {
		efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
		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;
	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)
static void efx_ptp_pps_worker(struct work_struct *work)
{
{
	struct efx_ptp_data *ptp =
	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) ||
	if ((enable_wanted != efx->ptp_data->enabled) ||
	    (enable_wanted && (efx->ptp_data->mode != new_mode))) {
	    (enable_wanted && (efx->ptp_data->mode != new_mode))) {
		int rc;
		int rc = 0;


		if (enable_wanted) {
		if (enable_wanted) {
			/* Change of mode requires disable */
			/* Change of mode requires disable */
@@ -1142,6 +1154,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
			 * succeed.
			 * succeed.
			 */
			 */
			efx->ptp_data->mode = new_mode;
			efx->ptp_data->mode = new_mode;
			if (netif_running(efx->net_dev))
				rc = efx_ptp_start(efx);
				rc = efx_ptp_start(efx);
			if (rc == 0) {
			if (rc == 0) {
				rc = efx_ptp_synchronize(efx,
				rc = efx_ptp_synchronize(efx,
@@ -1515,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
		efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
		efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
			&efx_ptp_channel_type;
			&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);
}