aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurence Evans <levans@solarflare.com>2018-01-25 12:27:22 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-25 16:05:14 -0500
commit04796f4c4dc4ac4c4f405c22e20dc9ae1068eea5 (patch)
treea25d16ed6f81f717717c112a975478e4dd4db88f
parentc4f64fcc4d31e7f773cb4eec9d90c40ebb049c14 (diff)
sfc: support separate PTP and general timestamping
Support MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2. Extract general timestamp corrections in addition to PTP corrections. Apply receive timestamp corrections for general datapath receive timestamping, and correspondingly for transmit. Signed-off-by: Laurence Evans <levans@solarflare.com> Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/sfc/ptp.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 29dbb47b270c..63c2b25f9281 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -237,10 +237,17 @@ struct efx_ptp_timeset {
237 * @ns_to_nic_time: Function to convert from scalar nanoseconds to NIC time 237 * @ns_to_nic_time: Function to convert from scalar nanoseconds to NIC time
238 * @nic_to_kernel_time: Function to convert from NIC to kernel time 238 * @nic_to_kernel_time: Function to convert from NIC to kernel time
239 * @min_synchronisation_ns: Minimum acceptable corrected sync window 239 * @min_synchronisation_ns: Minimum acceptable corrected sync window
240 * @ts_corrections.tx: Required driver correction of transmit timestamps 240 * @capabilities: Capabilities flags from the NIC
241 * @ts_corrections.rx: Required driver correction of receive timestamps 241 * @ts_corrections.ptp_tx: Required driver correction of PTP packet transmit
242 * timestamps
243 * @ts_corrections.ptp_rx: Required driver correction of PTP packet receive
244 * timestamps
242 * @ts_corrections.pps_out: PPS output error (information only) 245 * @ts_corrections.pps_out: PPS output error (information only)
243 * @ts_corrections.pps_in: Required driver correction of PPS input timestamps 246 * @ts_corrections.pps_in: Required driver correction of PPS input timestamps
247 * @ts_corrections.general_tx: Required driver correction of general packet
248 * transmit timestamps
249 * @ts_corrections.general_rx: Required driver correction of general packet
250 * receive timestamps
244 * @evt_frags: Partly assembled PTP events 251 * @evt_frags: Partly assembled PTP events
245 * @evt_frag_idx: Current fragment number 252 * @evt_frag_idx: Current fragment number
246 * @evt_code: Last event code 253 * @evt_code: Last event code
@@ -291,10 +298,12 @@ struct efx_ptp_data {
291 s32 correction); 298 s32 correction);
292 unsigned int min_synchronisation_ns; 299 unsigned int min_synchronisation_ns;
293 struct { 300 struct {
294 s32 tx; 301 s32 ptp_tx;
295 s32 rx; 302 s32 ptp_rx;
296 s32 pps_out; 303 s32 pps_out;
297 s32 pps_in; 304 s32 pps_in;
305 s32 general_tx;
306 s32 general_rx;
298 } ts_corrections; 307 } ts_corrections;
299 efx_qword_t evt_frags[MAX_EVENT_FRAGS]; 308 efx_qword_t evt_frags[MAX_EVENT_FRAGS];
300 int evt_frag_idx; 309 int evt_frag_idx;
@@ -537,11 +546,13 @@ ktime_t efx_ptp_nic_to_kernel_time(struct efx_tx_queue *tx_queue)
537 if (efx_ptp_use_mac_tx_timestamps(efx)) 546 if (efx_ptp_use_mac_tx_timestamps(efx))
538 kt = efx_ptp_mac_s27_to_ktime_correction(efx, 547 kt = efx_ptp_mac_s27_to_ktime_correction(efx,
539 tx_queue->completed_timestamp_major, 548 tx_queue->completed_timestamp_major,
540 tx_queue->completed_timestamp_minor, 0); 549 tx_queue->completed_timestamp_minor,
550 ptp->ts_corrections.general_tx);
541 else 551 else
542 kt = ptp->nic_to_kernel_time( 552 kt = ptp->nic_to_kernel_time(
543 tx_queue->completed_timestamp_major, 553 tx_queue->completed_timestamp_major,
544 tx_queue->completed_timestamp_minor, 0); 554 tx_queue->completed_timestamp_minor,
555 ptp->ts_corrections.general_tx);
545 return kt; 556 return kt;
546} 557}
547 558
@@ -606,8 +617,9 @@ static int efx_ptp_get_attributes(struct efx_nic *efx)
606static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx) 617static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx)
607{ 618{
608 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN); 619 MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN);
609 MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_LEN); 620 MCDI_DECLARE_BUF(outbuf, MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_LEN);
610 int rc; 621 int rc;
622 size_t out_len;
611 623
612 /* Get the timestamp corrections from the NIC. If this operation is 624 /* Get the timestamp corrections from the NIC. If this operation is
613 * not supported (older NICs) then no correction is required. 625 * not supported (older NICs) then no correction is required.
@@ -617,21 +629,37 @@ static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx)
617 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); 629 MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0);
618 630
619 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), 631 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
620 outbuf, sizeof(outbuf), NULL); 632 outbuf, sizeof(outbuf), &out_len);
621 if (rc == 0) { 633 if (rc == 0) {
622 efx->ptp_data->ts_corrections.tx = MCDI_DWORD(outbuf, 634 efx->ptp_data->ts_corrections.ptp_tx = MCDI_DWORD(outbuf,
623 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT); 635 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT);
624 efx->ptp_data->ts_corrections.rx = MCDI_DWORD(outbuf, 636 efx->ptp_data->ts_corrections.ptp_rx = MCDI_DWORD(outbuf,
625 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE); 637 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE);
626 efx->ptp_data->ts_corrections.pps_out = MCDI_DWORD(outbuf, 638 efx->ptp_data->ts_corrections.pps_out = MCDI_DWORD(outbuf,
627 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT); 639 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT);
628 efx->ptp_data->ts_corrections.pps_in = MCDI_DWORD(outbuf, 640 efx->ptp_data->ts_corrections.pps_in = MCDI_DWORD(outbuf,
629 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN); 641 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN);
642
643 if (out_len >= MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_LEN) {
644 efx->ptp_data->ts_corrections.general_tx = MCDI_DWORD(
645 outbuf,
646 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_TX);
647 efx->ptp_data->ts_corrections.general_rx = MCDI_DWORD(
648 outbuf,
649 PTP_OUT_GET_TIMESTAMP_CORRECTIONS_V2_GENERAL_RX);
650 } else {
651 efx->ptp_data->ts_corrections.general_tx =
652 efx->ptp_data->ts_corrections.ptp_tx;
653 efx->ptp_data->ts_corrections.general_rx =
654 efx->ptp_data->ts_corrections.ptp_rx;
655 }
630 } else if (rc == -EINVAL) { 656 } else if (rc == -EINVAL) {
631 efx->ptp_data->ts_corrections.tx = 0; 657 efx->ptp_data->ts_corrections.ptp_tx = 0;
632 efx->ptp_data->ts_corrections.rx = 0; 658 efx->ptp_data->ts_corrections.ptp_rx = 0;
633 efx->ptp_data->ts_corrections.pps_out = 0; 659 efx->ptp_data->ts_corrections.pps_out = 0;
634 efx->ptp_data->ts_corrections.pps_in = 0; 660 efx->ptp_data->ts_corrections.pps_in = 0;
661 efx->ptp_data->ts_corrections.general_tx = 0;
662 efx->ptp_data->ts_corrections.general_rx = 0;
635 } else { 663 } else {
636 efx_mcdi_display_error(efx, MC_CMD_PTP, sizeof(inbuf), outbuf, 664 efx_mcdi_display_error(efx, MC_CMD_PTP, sizeof(inbuf), outbuf,
637 sizeof(outbuf), rc); 665 sizeof(outbuf), rc);
@@ -998,7 +1026,7 @@ static void efx_ptp_xmit_skb_mc(struct efx_nic *efx, struct sk_buff *skb)
998 timestamps.hwtstamp = ptp_data->nic_to_kernel_time( 1026 timestamps.hwtstamp = ptp_data->nic_to_kernel_time(
999 MCDI_DWORD(txtime, PTP_OUT_TRANSMIT_MAJOR), 1027 MCDI_DWORD(txtime, PTP_OUT_TRANSMIT_MAJOR),
1000 MCDI_DWORD(txtime, PTP_OUT_TRANSMIT_MINOR), 1028 MCDI_DWORD(txtime, PTP_OUT_TRANSMIT_MINOR),
1001 ptp_data->ts_corrections.tx); 1029 ptp_data->ts_corrections.ptp_tx);
1002 1030
1003 skb_tstamp_tx(skb, &timestamps); 1031 skb_tstamp_tx(skb, &timestamps);
1004 1032
@@ -1745,7 +1773,7 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp)
1745 evt->hwtimestamp = efx->ptp_data->nic_to_kernel_time( 1773 evt->hwtimestamp = efx->ptp_data->nic_to_kernel_time(
1746 EFX_QWORD_FIELD(ptp->evt_frags[0], MCDI_EVENT_DATA), 1774 EFX_QWORD_FIELD(ptp->evt_frags[0], MCDI_EVENT_DATA),
1747 EFX_QWORD_FIELD(ptp->evt_frags[1], MCDI_EVENT_DATA), 1775 EFX_QWORD_FIELD(ptp->evt_frags[1], MCDI_EVENT_DATA),
1748 ptp->ts_corrections.rx); 1776 ptp->ts_corrections.ptp_rx);
1749 evt->expiry = jiffies + msecs_to_jiffies(PKT_EVENT_LIFETIME_MS); 1777 evt->expiry = jiffies + msecs_to_jiffies(PKT_EVENT_LIFETIME_MS);
1750 list_add_tail(&evt->link, &ptp->evt_list); 1778 list_add_tail(&evt->link, &ptp->evt_list);
1751 1779
@@ -1908,7 +1936,7 @@ void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
1908 timestamps->hwtstamp = efx_ptp_s27_to_ktime_correction( 1936 timestamps->hwtstamp = efx_ptp_s27_to_ktime_correction(
1909 pkt_timestamp_major, 1937 pkt_timestamp_major,
1910 pkt_timestamp_minor, 1938 pkt_timestamp_minor,
1911 efx->ptp_data->ts_corrections.rx); 1939 efx->ptp_data->ts_corrections.general_rx);
1912} 1940}
1913 1941
1914static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) 1942static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)