diff options
author | Laurence Evans <levans@solarflare.com> | 2018-01-25 12:27:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-25 16:05:14 -0500 |
commit | 04796f4c4dc4ac4c4f405c22e20dc9ae1068eea5 (patch) | |
tree | a25d16ed6f81f717717c112a975478e4dd4db88f | |
parent | c4f64fcc4d31e7f773cb4eec9d90c40ebb049c14 (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.c | 58 |
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) | |||
606 | static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx) | 617 | static 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, ×tamps); | 1031 | skb_tstamp_tx(skb, ×tamps); |
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 | ||
1914 | static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) | 1942 | static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) |