aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2013-10-15 12:54:56 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-12-12 17:07:02 -0500
commitac36baf817c39fc9b53eff190f5901610c5dc5b7 (patch)
treea600cefb96cfded628ec1f60bca5f36099654e18
parent62a1c703568b696c2775a9618840865751cd07d8 (diff)
sfc: Remove dependency of PTP on having a dedicated channel
We need a dedicated channel on Siena to ensure we can match up the separate RX and timestamp events for each PTP packet. We won't do this for EF10 as timestamps are delivered inline. Pass a channel index of 0 to MC_CMD_PTP_OP_ENABLE when there is no dedicated channel. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/nic.h4
-rw-r--r--drivers/net/ethernet/sfc/ptp.c59
-rw-r--r--drivers/net/ethernet/sfc/siena.c2
3 files changed, 41 insertions, 24 deletions
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 7ac9c000696f..25178536f053 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -554,7 +554,9 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
554 bool spoofchk); 554 bool spoofchk);
555 555
556struct ethtool_ts_info; 556struct ethtool_ts_info;
557void efx_ptp_probe(struct efx_nic *efx); 557int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel);
558void efx_ptp_defer_probe_with_channel(struct efx_nic *efx);
559void efx_ptp_remove(struct efx_nic *efx);
558int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); 560int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr);
559int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); 561int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr);
560void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); 562void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info);
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 7ae66d900256..aa4876edaac6 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -214,7 +214,8 @@ struct efx_ptp_timeset {
214 214
215/** 215/**
216 * struct efx_ptp_data - Precision Time Protocol (PTP) state 216 * struct efx_ptp_data - Precision Time Protocol (PTP) state
217 * @channel: The PTP channel 217 * @efx: The NIC context
218 * @channel: The PTP channel (Siena only)
218 * @rxq: Receive queue (awaiting timestamps) 219 * @rxq: Receive queue (awaiting timestamps)
219 * @txq: Transmit queue 220 * @txq: Transmit queue
220 * @evt_list: List of MC receive events awaiting packets 221 * @evt_list: List of MC receive events awaiting packets
@@ -265,6 +266,7 @@ struct efx_ptp_timeset {
265 * @timeset: Last set of synchronisation statistics. 266 * @timeset: Last set of synchronisation statistics.
266 */ 267 */
267struct efx_ptp_data { 268struct efx_ptp_data {
269 struct efx_nic *efx;
268 struct efx_channel *channel; 270 struct efx_channel *channel;
269 struct sk_buff_head rxq; 271 struct sk_buff_head rxq;
270 struct sk_buff_head txq; 272 struct sk_buff_head txq;
@@ -319,7 +321,8 @@ static int efx_ptp_enable(struct efx_nic *efx)
319 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE); 321 MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ENABLE);
320 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); 322 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
321 MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_QUEUE, 323 MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_QUEUE,
322 efx->ptp_data->channel->channel); 324 efx->ptp_data->channel ?
325 efx->ptp_data->channel->channel : 0);
323 MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode); 326 MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode);
324 327
325 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), 328 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
@@ -774,7 +777,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
774 struct efx_filter_spec rxfilter; 777 struct efx_filter_spec rxfilter;
775 int rc; 778 int rc;
776 779
777 if (ptp->rxfilter_installed) 780 if (!ptp->channel || ptp->rxfilter_installed)
778 return 0; 781 return 0;
779 782
780 /* Must filter on both event and general ports to ensure 783 /* Must filter on both event and general ports to ensure
@@ -882,7 +885,7 @@ static void efx_ptp_pps_worker(struct work_struct *work)
882{ 885{
883 struct efx_ptp_data *ptp = 886 struct efx_ptp_data *ptp =
884 container_of(work, struct efx_ptp_data, pps_work); 887 container_of(work, struct efx_ptp_data, pps_work);
885 struct efx_nic *efx = ptp->channel->efx; 888 struct efx_nic *efx = ptp->efx;
886 struct ptp_clock_event ptp_evt; 889 struct ptp_clock_event ptp_evt;
887 890
888 if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS)) 891 if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS))
@@ -899,7 +902,7 @@ static void efx_ptp_worker(struct work_struct *work)
899{ 902{
900 struct efx_ptp_data *ptp_data = 903 struct efx_ptp_data *ptp_data =
901 container_of(work, struct efx_ptp_data, work); 904 container_of(work, struct efx_ptp_data, work);
902 struct efx_nic *efx = ptp_data->channel->efx; 905 struct efx_nic *efx = ptp_data->efx;
903 struct sk_buff *skb; 906 struct sk_buff *skb;
904 struct sk_buff_head tempq; 907 struct sk_buff_head tempq;
905 908
@@ -923,31 +926,25 @@ static void efx_ptp_worker(struct work_struct *work)
923 efx_ptp_process_rx(efx, skb); 926 efx_ptp_process_rx(efx, skb);
924} 927}
925 928
926/* Initialise PTP channel and state. 929/* Initialise PTP state. */
927 * 930int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
928 * Setting core_index to zero causes the queue to be initialised and doesn't
929 * overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue.
930 */
931static int efx_ptp_probe_channel(struct efx_channel *channel)
932{ 931{
933 struct efx_nic *efx = channel->efx;
934 struct efx_ptp_data *ptp; 932 struct efx_ptp_data *ptp;
935 int rc = 0; 933 int rc = 0;
936 unsigned int pos; 934 unsigned int pos;
937 935
938 channel->irq_moderation = 0;
939 channel->rx_queue.core_index = 0;
940
941 ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); 936 ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL);
942 efx->ptp_data = ptp; 937 efx->ptp_data = ptp;
943 if (!efx->ptp_data) 938 if (!efx->ptp_data)
944 return -ENOMEM; 939 return -ENOMEM;
945 940
941 ptp->efx = efx;
942 ptp->channel = channel;
943
946 rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL); 944 rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL);
947 if (rc != 0) 945 if (rc != 0)
948 goto fail1; 946 goto fail1;
949 947
950 ptp->channel = channel;
951 skb_queue_head_init(&ptp->rxq); 948 skb_queue_head_init(&ptp->rxq);
952 skb_queue_head_init(&ptp->txq); 949 skb_queue_head_init(&ptp->txq);
953 ptp->workwq = create_singlethread_workqueue("sfc_ptp"); 950 ptp->workwq = create_singlethread_workqueue("sfc_ptp");
@@ -1014,14 +1011,27 @@ fail1:
1014 return rc; 1011 return rc;
1015} 1012}
1016 1013
1017static void efx_ptp_remove_channel(struct efx_channel *channel) 1014/* Initialise PTP channel.
1015 *
1016 * Setting core_index to zero causes the queue to be initialised and doesn't
1017 * overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue.
1018 */
1019static int efx_ptp_probe_channel(struct efx_channel *channel)
1018{ 1020{
1019 struct efx_nic *efx = channel->efx; 1021 struct efx_nic *efx = channel->efx;
1020 1022
1023 channel->irq_moderation = 0;
1024 channel->rx_queue.core_index = 0;
1025
1026 return efx_ptp_probe(efx, channel);
1027}
1028
1029void efx_ptp_remove(struct efx_nic *efx)
1030{
1021 if (!efx->ptp_data) 1031 if (!efx->ptp_data)
1022 return; 1032 return;
1023 1033
1024 (void)efx_ptp_disable(channel->efx); 1034 (void)efx_ptp_disable(efx);
1025 1035
1026 cancel_work_sync(&efx->ptp_data->work); 1036 cancel_work_sync(&efx->ptp_data->work);
1027 cancel_work_sync(&efx->ptp_data->pps_work); 1037 cancel_work_sync(&efx->ptp_data->pps_work);
@@ -1038,6 +1048,11 @@ static void efx_ptp_remove_channel(struct efx_channel *channel)
1038 kfree(efx->ptp_data); 1048 kfree(efx->ptp_data);
1039} 1049}
1040 1050
1051static void efx_ptp_remove_channel(struct efx_channel *channel)
1052{
1053 efx_ptp_remove(channel->efx);
1054}
1055
1041static void efx_ptp_get_channel_name(struct efx_channel *channel, 1056static void efx_ptp_get_channel_name(struct efx_channel *channel,
1042 char *buf, size_t len) 1057 char *buf, size_t len)
1043{ 1058{
@@ -1449,7 +1464,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
1449 struct efx_ptp_data *ptp_data = container_of(ptp, 1464 struct efx_ptp_data *ptp_data = container_of(ptp,
1450 struct efx_ptp_data, 1465 struct efx_ptp_data,
1451 phc_clock_info); 1466 phc_clock_info);
1452 struct efx_nic *efx = ptp_data->channel->efx; 1467 struct efx_nic *efx = ptp_data->efx;
1453 MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN); 1468 MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
1454 s64 adjustment_ns; 1469 s64 adjustment_ns;
1455 int rc; 1470 int rc;
@@ -1482,7 +1497,7 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
1482 struct efx_ptp_data *ptp_data = container_of(ptp, 1497 struct efx_ptp_data *ptp_data = container_of(ptp,
1483 struct efx_ptp_data, 1498 struct efx_ptp_data,
1484 phc_clock_info); 1499 phc_clock_info);
1485 struct efx_nic *efx = ptp_data->channel->efx; 1500 struct efx_nic *efx = ptp_data->efx;
1486 struct timespec delta_ts = ns_to_timespec(delta); 1501 struct timespec delta_ts = ns_to_timespec(delta);
1487 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN); 1502 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN);
1488 1503
@@ -1500,7 +1515,7 @@ static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
1500 struct efx_ptp_data *ptp_data = container_of(ptp, 1515 struct efx_ptp_data *ptp_data = container_of(ptp,
1501 struct efx_ptp_data, 1516 struct efx_ptp_data,
1502 phc_clock_info); 1517 phc_clock_info);
1503 struct efx_nic *efx = ptp_data->channel->efx; 1518 struct efx_nic *efx = ptp_data->efx;
1504 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_READ_NIC_TIME_LEN); 1519 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_READ_NIC_TIME_LEN);
1505 MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_READ_NIC_TIME_LEN); 1520 MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_READ_NIC_TIME_LEN);
1506 int rc; 1521 int rc;
@@ -1566,7 +1581,7 @@ static const struct efx_channel_type efx_ptp_channel_type = {
1566 .keep_eventq = false, 1581 .keep_eventq = false,
1567}; 1582};
1568 1583
1569void efx_ptp_probe(struct efx_nic *efx) 1584void efx_ptp_defer_probe_with_channel(struct efx_nic *efx)
1570{ 1585{
1571 /* Check whether PTP is implemented on this NIC. The DISABLE 1586 /* Check whether PTP is implemented on this NIC. The DISABLE
1572 * operation will succeed if and only if it is implemented. 1587 * operation will succeed if and only if it is implemented.
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index f2a7ad4c76aa..53b4ce67be0e 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -259,7 +259,7 @@ static int siena_probe_nic(struct efx_nic *efx)
259 goto fail5; 259 goto fail5;
260 260
261 efx_sriov_probe(efx); 261 efx_sriov_probe(efx);
262 efx_ptp_probe(efx); 262 efx_ptp_defer_probe_with_channel(efx);
263 263
264 return 0; 264 return 0;
265 265