aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Rames <arames@solarflare.com>2013-11-08 05:20:31 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-12-06 17:27:41 -0500
commit2ea4dc28a5bcec408e01a8772763871638a5ec79 (patch)
treebb96ff4fdc285aa0ae708b22d2d7d31da2b0b1a9
parent35f9a7a380728a94d417e5824a866f969423ac83 (diff)
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: 7c236c43b838 ('sfc: Add support for IEEE-1588 PTP') Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/efx.c4
-rw-r--r--drivers/net/ethernet/sfc/nic.h2
-rw-r--r--drivers/net/ethernet/sfc/ptp.c30
3 files changed, 33 insertions, 3 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 2e27837ce6a2..8bd5b485f1bc 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx)
645 WARN_ON(channel->rx_pkt_n_frags); 645 WARN_ON(channel->rx_pkt_n_frags);
646 } 646 }
647 647
648 efx_ptp_start_datapath(efx);
649
648 if (netif_device_present(efx->net_dev)) 650 if (netif_device_present(efx->net_dev))
649 netif_tx_wake_all_queues(efx->net_dev); 651 netif_tx_wake_all_queues(efx->net_dev);
650} 652}
@@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx_nic *efx)
659 EFX_ASSERT_RESET_SERIALISED(efx); 661 EFX_ASSERT_RESET_SERIALISED(efx);
660 BUG_ON(efx->port_enabled); 662 BUG_ON(efx->port_enabled);
661 663
664 efx_ptp_stop_datapath(efx);
665
662 /* Stop RX refill */ 666 /* Stop RX refill */
663 efx_for_each_channel(channel, efx) { 667 efx_for_each_channel(channel, efx) {
664 efx_for_each_channel_rx_queue(rx_queue, channel) 668 efx_for_each_channel_rx_queue(rx_queue, channel)
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 11b6112d9249..91c63ec79c5f 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -560,6 +560,8 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
560bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); 560bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
561int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); 561int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
562void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); 562void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
563void efx_ptp_start_datapath(struct efx_nic *efx);
564void efx_ptp_stop_datapath(struct efx_nic *efx);
563 565
564extern const struct efx_nic_type falcon_a1_nic_type; 566extern const struct efx_nic_type falcon_a1_nic_type;
565extern const struct efx_nic_type falcon_b0_nic_type; 567extern const struct efx_nic_type falcon_b0_nic_type;
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 8c665f1b5480..9bd99edf3f95 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -801,9 +801,14 @@ fail:
801static int efx_ptp_stop(struct efx_nic *efx) 801static int efx_ptp_stop(struct efx_nic *efx)
802{ 802{
803 struct efx_ptp_data *ptp = efx->ptp_data; 803 struct efx_ptp_data *ptp = efx->ptp_data;
804 int rc = efx_ptp_disable(efx);
805 struct list_head *cursor; 804 struct list_head *cursor;
806 struct list_head *next; 805 struct list_head *next;
806 int rc;
807
808 if (ptp == NULL)
809 return 0;
810
811 rc = efx_ptp_disable(efx);
807 812
808 if (ptp->rxfilter_installed) { 813 if (ptp->rxfilter_installed) {
809 efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, 814 efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
@@ -828,6 +833,13 @@ static int efx_ptp_stop(struct efx_nic *efx)
828 return rc; 833 return rc;
829} 834}
830 835
836static int efx_ptp_restart(struct efx_nic *efx)
837{
838 if (efx->ptp_data && efx->ptp_data->enabled)
839 return efx_ptp_start(efx);
840 return 0;
841}
842
831static void efx_ptp_pps_worker(struct work_struct *work) 843static void efx_ptp_pps_worker(struct work_struct *work)
832{ 844{
833 struct efx_ptp_data *ptp = 845 struct efx_ptp_data *ptp =
@@ -1125,7 +1137,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
1125{ 1137{
1126 if ((enable_wanted != efx->ptp_data->enabled) || 1138 if ((enable_wanted != efx->ptp_data->enabled) ||
1127 (enable_wanted && (efx->ptp_data->mode != new_mode))) { 1139 (enable_wanted && (efx->ptp_data->mode != new_mode))) {
1128 int rc; 1140 int rc = 0;
1129 1141
1130 if (enable_wanted) { 1142 if (enable_wanted) {
1131 /* Change of mode requires disable */ 1143 /* Change of mode requires disable */
@@ -1142,7 +1154,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
1142 * succeed. 1154 * succeed.
1143 */ 1155 */
1144 efx->ptp_data->mode = new_mode; 1156 efx->ptp_data->mode = new_mode;
1145 rc = efx_ptp_start(efx); 1157 if (netif_running(efx->net_dev))
1158 rc = efx_ptp_start(efx);
1146 if (rc == 0) { 1159 if (rc == 0) {
1147 rc = efx_ptp_synchronize(efx, 1160 rc = efx_ptp_synchronize(efx,
1148 PTP_SYNC_ATTEMPTS * 2); 1161 PTP_SYNC_ATTEMPTS * 2);
@@ -1515,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx)
1515 efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = 1528 efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] =
1516 &efx_ptp_channel_type; 1529 &efx_ptp_channel_type;
1517} 1530}
1531
1532void efx_ptp_start_datapath(struct efx_nic *efx)
1533{
1534 if (efx_ptp_restart(efx))
1535 netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n");
1536}
1537
1538void efx_ptp_stop_datapath(struct efx_nic *efx)
1539{
1540 efx_ptp_stop(efx);
1541}