Lines Matching +full:scaled +full:- +full:sync
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright 2011-2013 Solarflare Communications Inc.
116 /* 01-1B-19-00-00-00 */
142 #define MC_NANOSECOND_MASK ((1 << MC_NANOSECOND_BITS) - 1)
143 #define MC_SECOND_MASK ((1 << (32 - MC_NANOSECOND_BITS)) - 1)
145 /* Maximum parts-per-billion adjustment that is acceptable */
160 * struct efx_ptp_match - Matching structure, stored in sk_buff's cb area.
163 * @state: The state of the packet - whether it is ready for processing or
172 * struct efx_ptp_event_rx - A PTP receive event (from MC)
188 * struct efx_ptp_timeset - Synchronisation between host and MC
204 u32 window; /* Derived: end - start, allowing for wrap */
208 * struct efx_ptp_rxfilter - Filter for PTP packets
226 * struct efx_ptp_data - Precision Time Protocol (PTP) state
246 * in packet prefix and last MCDI time sync event i.e. how much earlier than
247 * the last sync event time a packet timestamp can be.
249 * in packet prefix and last MCDI time sync event i.e. how much later than
250 * the last sync event time a packet timestamp can be.
252 * field in MCDI time sync event.
253 * @min_synchronisation_ns: Minimum acceptable corrected sync window
271 * @adjfreq_ppb_shift: Shift required to convert scaled parts-per-billion
286 * @invalid_sync_windows: Number of sync windows with bad durations.
287 * @undersize_sync_windows: Number of corrected sync windows that are too small
288 * @oversize_sync_windows: Number of corrected sync windows that are too large
374 return efx_ptp_use_mac_tx_timestamps(channel->efx); in efx_ptp_want_txqs()
399 [0 ... BITS_TO_LONGS(PTP_STAT_COUNT) - 1] = ~0UL,
404 if (!efx->ptp_data) in efx_ptp_describe_stats()
418 if (!efx->ptp_data) in efx_ptp_update_stats()
425 stats[i] = *(unsigned int *)((char *)efx->ptp_data + in efx_ptp_update_stats()
452 #define NS_TO_S27_SHIFT (63 - S27_TO_NS_SHIFT)
456 * where the minor register only uses 27 bits in units of 2^-27s.
463 (1ULL << (NS_TO_S27_SHIFT - 1))) >> NS_TO_S27_SHIFT); in efx_ptp_ns_to_s27()
469 min -= S27_MINOR_MAX; in efx_ptp_ns_to_s27()
480 (1ULL << (S27_TO_NS_SHIFT - 1))) >> S27_TO_NS_SHIFT); in efx_ptp_s27_to_ktime()
491 nic_major--; in efx_ptp_s27_to_ktime_correction()
493 nic_minor -= S27_MINOR_MAX; in efx_ptp_s27_to_ktime_correction()
522 kt = ktime_sub_ns(kt, (u64)-correction); in efx_ptp_s_qns_to_ktime_correction()
528 return efx->ptp_data ? efx->ptp_data->channel : NULL; in efx_ptp_channel()
533 if (efx->ptp_data) in efx_ptp_update_channel()
534 efx->ptp_data->channel = channel; in efx_ptp_update_channel()
543 major = channel->sync_timestamp_major; in last_sync_timestamp_major()
548 * 48 bits long and provides meta-information in the top 2 bits.
568 * long as the difference between the (real) now and the sync in efx_ptp_mac_nic_to_ktime_correction()
575 * a - b = ((a mod k) - b) mod k in efx_ptp_mac_nic_to_ktime_correction()
577 * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know in efx_ptp_mac_nic_to_ktime_correction()
578 * (a mod k) and b, so can calculate the delta, a - b. in efx_ptp_mac_nic_to_ktime_correction()
586 * we can deal with the (unlikely) case of sync timestamps in efx_ptp_mac_nic_to_ktime_correction()
589 delta = nic_major - sync_timestamp; in efx_ptp_mac_nic_to_ktime_correction()
592 * to the (fully specified) sync time. in efx_ptp_mac_nic_to_ktime_correction()
596 kt = ptp->nic_to_kernel_time(nic_major, nic_minor, in efx_ptp_mac_nic_to_ktime_correction()
604 struct efx_nic *efx = tx_queue->efx; in efx_ptp_nic_to_kernel_time()
605 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_nic_to_kernel_time()
610 tx_queue->completed_timestamp_major, in efx_ptp_nic_to_kernel_time()
611 tx_queue->completed_timestamp_minor, in efx_ptp_nic_to_kernel_time()
612 ptp->ts_corrections.general_tx); in efx_ptp_nic_to_kernel_time()
614 kt = ptp->nic_to_kernel_time( in efx_ptp_nic_to_kernel_time()
615 tx_queue->completed_timestamp_major, in efx_ptp_nic_to_kernel_time()
616 tx_queue->completed_timestamp_minor, in efx_ptp_nic_to_kernel_time()
617 ptp->ts_corrections.general_tx); in efx_ptp_nic_to_kernel_time()
626 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_get_attributes()
641 } else if (rc == -EINVAL) { in efx_ptp_get_attributes()
643 } else if (rc == -EPERM) { in efx_ptp_get_attributes()
644 pci_info(efx->pci_dev, "no PTP support\n"); in efx_ptp_get_attributes()
654 ptp->ns_to_nic_time = efx_ptp_ns_to_s27; in efx_ptp_get_attributes()
655 ptp->nic_to_kernel_time = efx_ptp_s27_to_ktime_correction; in efx_ptp_get_attributes()
656 ptp->nic_time.minor_max = 1 << 27; in efx_ptp_get_attributes()
657 ptp->nic_time.sync_event_minor_shift = 19; in efx_ptp_get_attributes()
660 ptp->ns_to_nic_time = efx_ptp_ns_to_s_qns; in efx_ptp_get_attributes()
661 ptp->nic_to_kernel_time = efx_ptp_s_qns_to_ktime_correction; in efx_ptp_get_attributes()
662 ptp->nic_time.minor_max = 4000000000UL; in efx_ptp_get_attributes()
663 ptp->nic_time.sync_event_minor_shift = 24; in efx_ptp_get_attributes()
666 return -ERANGE; in efx_ptp_get_attributes()
670 * packet prefix and the last MCDI time sync event. We expect the in efx_ptp_get_attributes()
671 * packet prefix timestamp to be after of sync event by up to one in efx_ptp_get_attributes()
672 * sync event interval (0.25s) but we allow it to exceed this by a in efx_ptp_get_attributes()
675 ptp->nic_time.sync_event_diff_min = ptp->nic_time.minor_max in efx_ptp_get_attributes()
676 - (ptp->nic_time.minor_max / 10); in efx_ptp_get_attributes()
677 ptp->nic_time.sync_event_diff_max = (ptp->nic_time.minor_max / 4) in efx_ptp_get_attributes()
678 + (ptp->nic_time.minor_max / 10); in efx_ptp_get_attributes()
689 ptp->min_synchronisation_ns = in efx_ptp_get_attributes()
693 ptp->min_synchronisation_ns = DEFAULT_MIN_SYNCHRONISATION_NS; in efx_ptp_get_attributes()
697 ptp->capabilities = MCDI_DWORD(outbuf, in efx_ptp_get_attributes()
700 ptp->capabilities = 0; in efx_ptp_get_attributes()
703 * adjustments in parts-per-billion and the fixed-point in efx_ptp_get_attributes()
706 if (ptp->capabilities & (1 << MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_LBN)) in efx_ptp_get_attributes()
707 ptp->adjfreq_ppb_shift = PPB_SHIFT_FP44; in efx_ptp_get_attributes()
709 ptp->adjfreq_ppb_shift = PPB_SHIFT_FP40; in efx_ptp_get_attributes()
732 efx->ptp_data->ts_corrections.ptp_tx = MCDI_DWORD(outbuf, in efx_ptp_get_timestamp_corrections()
734 efx->ptp_data->ts_corrections.ptp_rx = MCDI_DWORD(outbuf, in efx_ptp_get_timestamp_corrections()
736 efx->ptp_data->ts_corrections.pps_out = MCDI_DWORD(outbuf, in efx_ptp_get_timestamp_corrections()
738 efx->ptp_data->ts_corrections.pps_in = MCDI_DWORD(outbuf, in efx_ptp_get_timestamp_corrections()
742 efx->ptp_data->ts_corrections.general_tx = MCDI_DWORD( in efx_ptp_get_timestamp_corrections()
745 efx->ptp_data->ts_corrections.general_rx = MCDI_DWORD( in efx_ptp_get_timestamp_corrections()
749 efx->ptp_data->ts_corrections.general_tx = in efx_ptp_get_timestamp_corrections()
750 efx->ptp_data->ts_corrections.ptp_tx; in efx_ptp_get_timestamp_corrections()
751 efx->ptp_data->ts_corrections.general_rx = in efx_ptp_get_timestamp_corrections()
752 efx->ptp_data->ts_corrections.ptp_rx; in efx_ptp_get_timestamp_corrections()
754 } else if (rc == -EINVAL) { in efx_ptp_get_timestamp_corrections()
755 efx->ptp_data->ts_corrections.ptp_tx = 0; in efx_ptp_get_timestamp_corrections()
756 efx->ptp_data->ts_corrections.ptp_rx = 0; in efx_ptp_get_timestamp_corrections()
757 efx->ptp_data->ts_corrections.pps_out = 0; in efx_ptp_get_timestamp_corrections()
758 efx->ptp_data->ts_corrections.pps_in = 0; in efx_ptp_get_timestamp_corrections()
759 efx->ptp_data->ts_corrections.general_tx = 0; in efx_ptp_get_timestamp_corrections()
760 efx->ptp_data->ts_corrections.general_rx = 0; in efx_ptp_get_timestamp_corrections()
780 efx->ptp_data->channel ? in efx_ptp_enable()
781 efx->ptp_data->channel->channel : 0); in efx_ptp_enable()
782 MCDI_SET_DWORD(inbuf, PTP_IN_ENABLE_MODE, efx->ptp_data->mode); in efx_ptp_enable()
786 rc = (rc == -EALREADY) ? 0 : rc; in efx_ptp_enable()
796 * Note that this function should never rely on the presence of ptp_data -
809 rc = (rc == -EALREADY) ? 0 : rc; in efx_ptp_disable()
813 if (rc == -ENOSYS || rc == -EPERM) in efx_ptp_disable()
814 pci_info(efx->pci_dev, "no PTP support\n"); in efx_ptp_disable()
835 netif_err(efx, drv, efx->net_dev, in efx_ptp_handle_no_channel()
836 "ERROR: PTP requires MSI-X and 1 additional interrupt" in efx_ptp_handle_no_channel()
848 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_send_times()
849 int *mc_running = ptp->start.addr; in efx_ptp_send_times()
873 efx->type->ptp_write_host_time(efx, host_time); in efx_ptp_send_times()
884 timeset->host_start = MCDI_DWORD(data, PTP_OUT_SYNCHRONIZE_HOSTSTART); in efx_ptp_read_timeset()
885 timeset->major = MCDI_DWORD(data, PTP_OUT_SYNCHRONIZE_MAJOR); in efx_ptp_read_timeset()
886 timeset->minor = MCDI_DWORD(data, PTP_OUT_SYNCHRONIZE_MINOR); in efx_ptp_read_timeset()
887 timeset->host_end = MCDI_DWORD(data, PTP_OUT_SYNCHRONIZE_HOSTEND); in efx_ptp_read_timeset()
888 timeset->wait = MCDI_DWORD(data, PTP_OUT_SYNCHRONIZE_WAITNS); in efx_ptp_read_timeset()
891 start_ns = timeset->host_start & MC_NANOSECOND_MASK; in efx_ptp_read_timeset()
892 end_ns = timeset->host_end & MC_NANOSECOND_MASK; in efx_ptp_read_timeset()
897 timeset->window = end_ns - start_ns; in efx_ptp_read_timeset()
904 * too much greater than this are rejected - the machine is, perhaps, too
919 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_process_times()
926 return -EAGAIN; in efx_ptp_process_times()
928 /* Read the set of results and find the last good host-MC in efx_ptp_process_times()
941 &ptp->timeset[i]); in efx_ptp_process_times()
944 ptp->nic_to_kernel_time(0, ptp->timeset[i].wait, 0)); in efx_ptp_process_times()
945 window = ptp->timeset[i].window; in efx_ptp_process_times()
946 corrected = window - wait.tv_nsec; in efx_ptp_process_times()
952 * Check that the corrected sync window is in a reasonable in efx_ptp_process_times()
958 ++ptp->invalid_sync_windows; in efx_ptp_process_times()
960 ++ptp->oversize_sync_windows; in efx_ptp_process_times()
961 } else if (corrected < ptp->min_synchronisation_ns) { in efx_ptp_process_times()
962 ++ptp->undersize_sync_windows; in efx_ptp_process_times()
970 netif_warn(efx, drv, efx->net_dev, in efx_ptp_process_times()
972 return -EAGAIN; in efx_ptp_process_times()
975 /* Calculate delay from last good sync (host time) to last_time. in efx_ptp_process_times()
981 start_sec = ptp->timeset[last_good].host_start >> MC_NANOSECOND_BITS; in efx_ptp_process_times()
982 last_sec = last_time->ts_real.tv_sec & MC_SECOND_MASK; in efx_ptp_process_times()
985 netif_warn(efx, hw, efx->net_dev, in efx_ptp_process_times()
987 return -EAGAIN; in efx_ptp_process_times()
989 delta.tv_sec = (last_sec - start_sec) & 1; in efx_ptp_process_times()
991 last_time->ts_real.tv_nsec - in efx_ptp_process_times()
992 (ptp->timeset[last_good].host_start & MC_NANOSECOND_MASK); in efx_ptp_process_times()
994 /* Convert the NIC time at last good sync into kernel time. in efx_ptp_process_times()
995 * No correction is required - this time is the output of a in efx_ptp_process_times()
998 mc_time = ptp->nic_to_kernel_time(ptp->timeset[last_good].major, in efx_ptp_process_times()
999 ptp->timeset[last_good].minor, 0); in efx_ptp_process_times()
1005 ptp->host_time_pps = *last_time; in efx_ptp_process_times()
1006 pps_sub_ts(&ptp->host_time_pps, delta); in efx_ptp_process_times()
1014 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_synchronize()
1021 int *start = ptp->start.addr; in efx_ptp_synchronize()
1028 ptp->start.dma_addr); in efx_ptp_synchronize()
1044 ++ptp->fast_syncs; in efx_ptp_synchronize()
1046 ++ptp->sync_timeouts; in efx_ptp_synchronize()
1060 ++ptp->good_syncs; in efx_ptp_synchronize()
1062 ++ptp->no_time_syncs; in efx_ptp_synchronize()
1069 ++ptp->bad_syncs; in efx_ptp_synchronize()
1077 struct efx_ptp_data *ptp_data = efx->ptp_data; in efx_ptp_xmit_skb_queue()
1081 tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type); in efx_ptp_xmit_skb_queue()
1082 if (tx_queue && tx_queue->timestamping) { in efx_ptp_xmit_skb_queue()
1096 * 1) The code invoked is mainly implemented for non-PTP in efx_ptp_xmit_skb_queue()
1125 struct efx_ptp_data *ptp_data = efx->ptp_data; in efx_ptp_xmit_skb_mc()
1130 MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT); in efx_ptp_xmit_skb_mc()
1131 MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_PERIPH_ID, 0); in efx_ptp_xmit_skb_mc()
1132 MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len); in efx_ptp_xmit_skb_mc()
1133 if (skb_shinfo(skb)->nr_frags != 0) { in efx_ptp_xmit_skb_mc()
1139 if (skb->ip_summed == CHECKSUM_PARTIAL) { in efx_ptp_xmit_skb_mc()
1145 MCDI_PTR(ptp_data->txbuf, in efx_ptp_xmit_skb_mc()
1147 skb->len); in efx_ptp_xmit_skb_mc()
1149 ptp_data->txbuf, MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), in efx_ptp_xmit_skb_mc()
1155 timestamps.hwtstamp = ptp_data->nic_to_kernel_time( in efx_ptp_xmit_skb_mc()
1158 ptp_data->ts_corrections.ptp_tx); in efx_ptp_xmit_skb_mc()
1179 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_process_events()
1182 while ((skb = skb_dequeue(&ptp->rxq))) { in efx_ptp_process_events()
1185 match = (struct efx_ptp_match *)skb->cb; in efx_ptp_process_events()
1186 if (match->state == PTP_PACKET_STATE_MATCH_UNWANTED) { in efx_ptp_process_events()
1188 } else if (time_after(jiffies, match->expiry)) { in efx_ptp_process_events()
1189 match->state = PTP_PACKET_STATE_TIMED_OUT; in efx_ptp_process_events()
1190 ++ptp->rx_no_timestamp; in efx_ptp_process_events()
1194 skb_queue_head(&ptp->rxq, skb); in efx_ptp_process_events()
1214 if (rxfilter->ether_type == spec->ether_type && in efx_ptp_find_filter()
1215 rxfilter->loc_port == spec->loc_port && in efx_ptp_find_filter()
1216 !memcmp(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host))) in efx_ptp_find_filter()
1227 rxfilter->handle); in efx_ptp_remove_one_filter()
1228 list_del(&rxfilter->list); in efx_ptp_remove_one_filter()
1244 struct efx_channel *channel = efx->ptp_data->channel; in efx_ptp_init_filter()
1256 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_insert_filter()
1262 rxfilter->expiry = expiry; in efx_ptp_insert_filter()
1268 return -ENOMEM; in efx_ptp_insert_filter()
1274 rxfilter->handle = rc; in efx_ptp_insert_filter()
1275 rxfilter->ether_type = spec->ether_type; in efx_ptp_insert_filter()
1276 rxfilter->loc_port = spec->loc_port; in efx_ptp_insert_filter()
1277 memcpy(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host)); in efx_ptp_insert_filter()
1278 rxfilter->expiry = expiry; in efx_ptp_insert_filter()
1279 list_add(&rxfilter->list, filter_list); in efx_ptp_insert_filter()
1281 queue_delayed_work(ptp->workwq, &ptp->cleanup_work, in efx_ptp_insert_filter()
1317 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_insert_eth_multicast_filter()
1324 return efx_ptp_insert_filter(efx, &ptp->rxfilters_mcast, &spec, 0); in efx_ptp_insert_eth_multicast_filter()
1329 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_insert_multicast_filters()
1332 if (!ptp->channel || !list_empty(&ptp->rxfilters_mcast)) in efx_ptp_insert_multicast_filters()
1336 * that there is no packet re-ordering. in efx_ptp_insert_multicast_filters()
1338 rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, in efx_ptp_insert_multicast_filters()
1344 rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast, in efx_ptp_insert_multicast_filters()
1354 rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, in efx_ptp_insert_multicast_filters()
1359 rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast, in efx_ptp_insert_multicast_filters()
1367 if (rc < 0 && rc != -EPROTONOSUPPORT) in efx_ptp_insert_multicast_filters()
1374 efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); in efx_ptp_insert_multicast_filters()
1380 if (skb->protocol == htons(ETH_P_IP)) { in efx_ptp_valid_unicast_event_pkt()
1381 return ip_hdr(skb)->daddr != htonl(PTP_ADDR_IPV4) && in efx_ptp_valid_unicast_event_pkt()
1382 ip_hdr(skb)->protocol == IPPROTO_UDP && in efx_ptp_valid_unicast_event_pkt()
1383 udp_hdr(skb)->source == htons(PTP_EVENT_PORT); in efx_ptp_valid_unicast_event_pkt()
1384 } else if (skb->protocol == htons(ETH_P_IPV6)) { in efx_ptp_valid_unicast_event_pkt()
1385 return !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &ptp_addr_ipv6) && in efx_ptp_valid_unicast_event_pkt()
1386 ipv6_hdr(skb)->nexthdr == IPPROTO_UDP && in efx_ptp_valid_unicast_event_pkt()
1387 udp_hdr(skb)->source == htons(PTP_EVENT_PORT); in efx_ptp_valid_unicast_event_pkt()
1395 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_insert_unicast_filter()
1400 return -EINVAL; in efx_ptp_insert_unicast_filter()
1404 if (skb->protocol == htons(ETH_P_IP)) { in efx_ptp_insert_unicast_filter()
1405 __be32 addr = ip_hdr(skb)->saddr; in efx_ptp_insert_unicast_filter()
1407 rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, in efx_ptp_insert_unicast_filter()
1412 rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast, in efx_ptp_insert_unicast_filter()
1416 struct in6_addr *addr = &ipv6_hdr(skb)->saddr; in efx_ptp_insert_unicast_filter()
1418 rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, in efx_ptp_insert_unicast_filter()
1423 rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast, in efx_ptp_insert_unicast_filter()
1426 return -EOPNOTSUPP; in efx_ptp_insert_unicast_filter()
1435 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_start()
1438 ptp->reset_required = false; in efx_ptp_start()
1448 ptp->evt_frag_idx = 0; in efx_ptp_start()
1449 ptp->current_adjfreq = 0; in efx_ptp_start()
1454 efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); in efx_ptp_start()
1460 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_stop()
1468 efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast); in efx_ptp_stop()
1469 efx_ptp_remove_filters(efx, &ptp->rxfilters_ucast); in efx_ptp_stop()
1472 efx_ptp_deliver_rx_queue(&efx->ptp_data->rxq); in efx_ptp_stop()
1473 skb_queue_purge(&efx->ptp_data->txq); in efx_ptp_stop()
1480 if (efx->ptp_data && efx->ptp_data->enabled) in efx_ptp_restart()
1489 struct efx_nic *efx = ptp->efx; in efx_ptp_pps_worker()
1496 ptp_evt.pps_times = ptp->host_time_pps; in efx_ptp_pps_worker()
1497 ptp_clock_event(ptp->phc_clock, &ptp_evt); in efx_ptp_pps_worker()
1504 struct efx_nic *efx = ptp_data->efx; in efx_ptp_worker()
1508 if (ptp_data->reset_required) { in efx_ptp_worker()
1517 while ((skb = skb_dequeue(&ptp_data->txq))) in efx_ptp_worker()
1518 ptp_data->xmit_skb(efx, skb); in efx_ptp_worker()
1530 list_for_each_entry_safe(rxfilter, tmp, &ptp->rxfilters_ucast, list) { in efx_ptp_cleanup_worker()
1531 if (time_is_before_jiffies(rxfilter->expiry)) in efx_ptp_cleanup_worker()
1532 efx_ptp_remove_one_filter(ptp->efx, rxfilter); in efx_ptp_cleanup_worker()
1535 if (!list_empty(&ptp->rxfilters_ucast)) { in efx_ptp_cleanup_worker()
1536 queue_delayed_work(ptp->workwq, &ptp->cleanup_work, in efx_ptp_cleanup_worker()
1563 if (efx->ptp_data) { in efx_ptp_probe()
1564 efx->ptp_data->channel = channel; in efx_ptp_probe()
1569 efx->ptp_data = ptp; in efx_ptp_probe()
1570 if (!efx->ptp_data) in efx_ptp_probe()
1571 return -ENOMEM; in efx_ptp_probe()
1573 ptp->efx = efx; in efx_ptp_probe()
1574 ptp->channel = channel; in efx_ptp_probe()
1576 rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL); in efx_ptp_probe()
1580 skb_queue_head_init(&ptp->rxq); in efx_ptp_probe()
1581 skb_queue_head_init(&ptp->txq); in efx_ptp_probe()
1582 ptp->workwq = create_singlethread_workqueue("sfc_ptp"); in efx_ptp_probe()
1583 if (!ptp->workwq) { in efx_ptp_probe()
1584 rc = -ENOMEM; in efx_ptp_probe()
1589 ptp->xmit_skb = efx_ptp_xmit_skb_queue; in efx_ptp_probe()
1590 /* Request sync events on this channel. */ in efx_ptp_probe()
1591 channel->sync_events_state = SYNC_EVENTS_QUIESCENT; in efx_ptp_probe()
1593 ptp->xmit_skb = efx_ptp_xmit_skb_mc; in efx_ptp_probe()
1596 INIT_WORK(&ptp->work, efx_ptp_worker); in efx_ptp_probe()
1597 INIT_DELAYED_WORK(&ptp->cleanup_work, efx_ptp_cleanup_worker); in efx_ptp_probe()
1598 ptp->config.flags = 0; in efx_ptp_probe()
1599 ptp->config.tx_type = HWTSTAMP_TX_OFF; in efx_ptp_probe()
1600 ptp->config.rx_filter = HWTSTAMP_FILTER_NONE; in efx_ptp_probe()
1601 INIT_LIST_HEAD(&ptp->rxfilters_mcast); in efx_ptp_probe()
1602 INIT_LIST_HEAD(&ptp->rxfilters_ucast); in efx_ptp_probe()
1614 if (efx->mcdi->fn_flags & in efx_ptp_probe()
1616 ptp->phc_clock_info = efx_phc_clock_info; in efx_ptp_probe()
1617 ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info, in efx_ptp_probe()
1618 &efx->pci_dev->dev); in efx_ptp_probe()
1619 if (IS_ERR(ptp->phc_clock)) { in efx_ptp_probe()
1620 rc = PTR_ERR(ptp->phc_clock); in efx_ptp_probe()
1622 } else if (ptp->phc_clock) { in efx_ptp_probe()
1623 INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker); in efx_ptp_probe()
1624 ptp->pps_workwq = create_singlethread_workqueue("sfc_pps"); in efx_ptp_probe()
1625 if (!ptp->pps_workwq) { in efx_ptp_probe()
1626 rc = -ENOMEM; in efx_ptp_probe()
1631 ptp->nic_ts_enabled = false; in efx_ptp_probe()
1635 ptp_clock_unregister(efx->ptp_data->phc_clock); in efx_ptp_probe()
1638 destroy_workqueue(efx->ptp_data->workwq); in efx_ptp_probe()
1641 efx_nic_free_buffer(efx, &ptp->start); in efx_ptp_probe()
1644 kfree(efx->ptp_data); in efx_ptp_probe()
1645 efx->ptp_data = NULL; in efx_ptp_probe()
1657 struct efx_nic *efx = channel->efx; in efx_ptp_probe_channel()
1660 channel->irq_moderation_us = 0; in efx_ptp_probe_channel()
1661 channel->rx_queue.core_index = 0; in efx_ptp_probe_channel()
1669 if (rc && rc != -EPERM) in efx_ptp_probe_channel()
1670 netif_warn(efx, drv, efx->net_dev, in efx_ptp_probe_channel()
1677 if (!efx->ptp_data) in efx_ptp_remove()
1682 cancel_work_sync(&efx->ptp_data->work); in efx_ptp_remove()
1683 cancel_delayed_work_sync(&efx->ptp_data->cleanup_work); in efx_ptp_remove()
1684 if (efx->ptp_data->pps_workwq) in efx_ptp_remove()
1685 cancel_work_sync(&efx->ptp_data->pps_work); in efx_ptp_remove()
1687 skb_queue_purge(&efx->ptp_data->rxq); in efx_ptp_remove()
1688 skb_queue_purge(&efx->ptp_data->txq); in efx_ptp_remove()
1690 if (efx->ptp_data->phc_clock) { in efx_ptp_remove()
1691 destroy_workqueue(efx->ptp_data->pps_workwq); in efx_ptp_remove()
1692 ptp_clock_unregister(efx->ptp_data->phc_clock); in efx_ptp_remove()
1695 destroy_workqueue(efx->ptp_data->workwq); in efx_ptp_remove()
1697 efx_nic_free_buffer(efx, &efx->ptp_data->start); in efx_ptp_remove()
1698 kfree(efx->ptp_data); in efx_ptp_remove()
1699 efx->ptp_data = NULL; in efx_ptp_remove()
1704 efx_ptp_remove(channel->efx); in efx_ptp_remove_channel()
1710 snprintf(buf, len, "%s-ptp", channel->efx->name); in efx_ptp_get_channel_name()
1718 return efx->ptp_data && in efx_ptp_is_ptp_tx()
1719 efx->ptp_data->enabled && in efx_ptp_is_ptp_tx()
1720 skb->len >= PTP_MIN_LENGTH && in efx_ptp_is_ptp_tx()
1721 skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM && in efx_ptp_is_ptp_tx()
1722 likely(skb->protocol == htons(ETH_P_IP)) && in efx_ptp_is_ptp_tx()
1725 ip_hdr(skb)->protocol == IPPROTO_UDP && in efx_ptp_is_ptp_tx()
1728 udp_hdr(skb)->dest == htons(PTP_EVENT_PORT); in efx_ptp_is_ptp_tx()
1732 * the receive timestamp from the MC - this will probably occur after the
1737 struct efx_nic *efx = channel->efx; in efx_ptp_rx()
1738 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_rx()
1739 struct efx_ptp_match *match = (struct efx_ptp_match *)skb->cb; in efx_ptp_rx()
1743 match->expiry = jiffies + msecs_to_jiffies(PKT_EVENT_LIFETIME_MS); in efx_ptp_rx()
1746 if (ptp->mode == MC_CMD_PTP_MODE_V1) { in efx_ptp_rx()
1750 data = skb->data; in efx_ptp_rx()
1759 data = skb->data; in efx_ptp_rx()
1768 match->state = PTP_PACKET_STATE_UNMATCHED; in efx_ptp_rx()
1776 match->state = PTP_PACKET_STATE_MATCH_UNWANTED; in efx_ptp_rx()
1779 skb_queue_tail(&ptp->rxq, skb); in efx_ptp_rx()
1780 queue_work(ptp->workwq, &ptp->work); in efx_ptp_rx()
1791 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_tx()
1793 skb_queue_tail(&ptp->txq, skb); in efx_ptp_tx()
1795 if ((udp_hdr(skb)->dest == htons(PTP_EVENT_PORT)) && in efx_ptp_tx()
1796 (skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM)) in efx_ptp_tx()
1798 queue_work(ptp->workwq, &ptp->work); in efx_ptp_tx()
1806 if ((enable_wanted != efx->ptp_data->enabled) || in efx_ptp_change_mode()
1807 (enable_wanted && (efx->ptp_data->mode != new_mode))) { in efx_ptp_change_mode()
1812 if (efx->ptp_data->enabled && in efx_ptp_change_mode()
1813 (efx->ptp_data->mode != new_mode)) { in efx_ptp_change_mode()
1814 efx->ptp_data->enabled = false; in efx_ptp_change_mode()
1824 efx->ptp_data->mode = new_mode; in efx_ptp_change_mode()
1825 if (netif_running(efx->net_dev)) in efx_ptp_change_mode()
1840 efx->ptp_data->enabled = enable_wanted; in efx_ptp_change_mode()
1850 if ((init->tx_type != HWTSTAMP_TX_OFF) && in efx_ptp_ts_init()
1851 (init->tx_type != HWTSTAMP_TX_ON)) in efx_ptp_ts_init()
1852 return -ERANGE; in efx_ptp_ts_init()
1854 rc = efx->type->ptp_set_ts_config(efx, init); in efx_ptp_ts_init()
1858 efx->ptp_data->config = *init; in efx_ptp_ts_init()
1864 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_get_ts_info()
1865 struct efx_nic *primary = efx->primary; in efx_ptp_get_ts_info()
1872 ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE | in efx_ptp_get_ts_info()
1879 struct efx_ef10_nic_data *nic_data = efx->nic_data; in efx_ptp_get_ts_info()
1881 if (!(nic_data->licensed_features & in efx_ptp_get_ts_info()
1883 ts_info->so_timestamping &= in efx_ptp_get_ts_info()
1886 if (primary && primary->ptp_data && primary->ptp_data->phc_clock) in efx_ptp_get_ts_info()
1887 ts_info->phc_index = in efx_ptp_get_ts_info()
1888 ptp_clock_index(primary->ptp_data->phc_clock); in efx_ptp_get_ts_info()
1889 ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; in efx_ptp_get_ts_info()
1890 ts_info->rx_filters = ptp->efx->type->hwtstamp_filters; in efx_ptp_get_ts_info()
1898 if (!efx->ptp_data) in efx_ptp_set_ts_config()
1899 return -EOPNOTSUPP; in efx_ptp_set_ts_config()
1908 if (!efx->ptp_data) in efx_ptp_get_ts_config()
1909 return -EOPNOTSUPP; in efx_ptp_get_ts_config()
1910 *config = efx->ptp_data->config; in efx_ptp_get_ts_config()
1916 struct efx_ptp_data *ptp = efx->ptp_data; in ptp_event_failure()
1918 netif_err(efx, hw, efx->net_dev, in ptp_event_failure()
1920 ptp->evt_frag_idx, expected_frag_len); in ptp_event_failure()
1921 ptp->reset_required = true; in ptp_event_failure()
1922 queue_work(ptp->workwq, &ptp->work); in ptp_event_failure()
1927 int code = EFX_QWORD_FIELD(ptp->evt_frags[0], MCDI_EVENT_DATA); in ptp_event_fault()
1928 if (ptp->evt_frag_idx != 1) { in ptp_event_fault()
1933 netif_err(efx, hw, efx->net_dev, "PTP error %d\n", code); in ptp_event_fault()
1938 if (ptp->nic_ts_enabled) in ptp_event_pps()
1939 queue_work(ptp->pps_workwq, &ptp->pps_work); in ptp_event_pps()
1944 struct efx_ptp_data *ptp = efx->ptp_data; in efx_ptp_event()
1948 if (!efx->ptp_warned) { in efx_ptp_event()
1949 netif_warn(efx, drv, efx->net_dev, in efx_ptp_event()
1951 efx->ptp_warned = true; in efx_ptp_event()
1956 if (!ptp->enabled) in efx_ptp_event()
1959 if (ptp->evt_frag_idx == 0) { in efx_ptp_event()
1960 ptp->evt_code = code; in efx_ptp_event()
1961 } else if (ptp->evt_code != code) { in efx_ptp_event()
1962 netif_err(efx, hw, efx->net_dev, in efx_ptp_event()
1964 ptp->evt_frag_idx = 0; in efx_ptp_event()
1967 ptp->evt_frags[ptp->evt_frag_idx++] = *ev; in efx_ptp_event()
1978 netif_err(efx, hw, efx->net_dev, in efx_ptp_event()
1982 ptp->evt_frag_idx = 0; in efx_ptp_event()
1983 } else if (MAX_EVENT_FRAGS == ptp->evt_frag_idx) { in efx_ptp_event()
1984 netif_err(efx, hw, efx->net_dev, in efx_ptp_event()
1986 ptp->evt_frag_idx = 0; in efx_ptp_event()
1992 struct efx_nic *efx = channel->efx; in efx_time_sync_event()
1993 struct efx_ptp_data *ptp = efx->ptp_data; in efx_time_sync_event()
1995 /* When extracting the sync timestamp minor value, we should discard in efx_time_sync_event()
1997 * to reconstruct full-range timestamps and they are optionally used in efx_time_sync_event()
1999 * for sync events. in efx_time_sync_event()
2001 channel->sync_timestamp_major = MCDI_EVENT_FIELD(*ev, PTP_TIME_MAJOR); in efx_time_sync_event()
2002 channel->sync_timestamp_minor = in efx_time_sync_event()
2004 << ptp->nic_time.sync_event_minor_shift; in efx_time_sync_event()
2006 /* if sync events have been disabled then we want to silently ignore in efx_time_sync_event()
2009 (void) cmpxchg(&channel->sync_events_state, SYNC_EVENTS_REQUESTED, in efx_time_sync_event()
2016 return __le32_to_cpup((const __le32 *)(eh + efx->rx_packet_ts_offset)); in efx_rx_buf_timestamp_minor()
2018 const u8 *data = eh + efx->rx_packet_ts_offset; in efx_rx_buf_timestamp_minor()
2029 struct efx_nic *efx = channel->efx; in __efx_rx_skb_attach_timestamp()
2030 struct efx_ptp_data *ptp = efx->ptp_data; in __efx_rx_skb_attach_timestamp()
2035 if (channel->sync_events_state != SYNC_EVENTS_VALID) in __efx_rx_skb_attach_timestamp()
2040 /* get the difference between the packet and sync timestamps, in __efx_rx_skb_attach_timestamp()
2043 diff = pkt_timestamp_minor - channel->sync_timestamp_minor; in __efx_rx_skb_attach_timestamp()
2044 if (pkt_timestamp_minor < channel->sync_timestamp_minor) in __efx_rx_skb_attach_timestamp()
2045 diff += ptp->nic_time.minor_max; in __efx_rx_skb_attach_timestamp()
2048 carry = (channel->sync_timestamp_minor >= ptp->nic_time.minor_max - diff) ? in __efx_rx_skb_attach_timestamp()
2051 if (diff <= ptp->nic_time.sync_event_diff_max) { in __efx_rx_skb_attach_timestamp()
2052 /* packet is ahead of the sync event by a quarter of a second or in __efx_rx_skb_attach_timestamp()
2055 pkt_timestamp_major = channel->sync_timestamp_major + carry; in __efx_rx_skb_attach_timestamp()
2056 } else if (diff >= ptp->nic_time.sync_event_diff_min) { in __efx_rx_skb_attach_timestamp()
2057 /* packet is behind the sync event but within the fuzz factor. in __efx_rx_skb_attach_timestamp()
2058 * This means the RX packet and sync event crossed as they were in __efx_rx_skb_attach_timestamp()
2061 pkt_timestamp_major = channel->sync_timestamp_major - 1 + carry; in __efx_rx_skb_attach_timestamp()
2064 * indicative of us missing sync events for some reason, so in __efx_rx_skb_attach_timestamp()
2068 netif_vdbg(efx, drv, efx->net_dev, in __efx_rx_skb_attach_timestamp()
2069 "packet timestamp %x too far from sync event %x:%x\n", in __efx_rx_skb_attach_timestamp()
2070 pkt_timestamp_minor, channel->sync_timestamp_major, in __efx_rx_skb_attach_timestamp()
2071 channel->sync_timestamp_minor); in __efx_rx_skb_attach_timestamp()
2077 timestamps->hwtstamp = in __efx_rx_skb_attach_timestamp()
2078 ptp->nic_to_kernel_time(pkt_timestamp_major, in __efx_rx_skb_attach_timestamp()
2080 ptp->ts_corrections.general_rx); in __efx_rx_skb_attach_timestamp()
2089 struct efx_nic *efx = ptp_data->efx; in efx_phc_adjfine()
2096 else if (delta < -MAX_PPB) in efx_phc_adjfine()
2097 delta = -MAX_PPB; in efx_phc_adjfine()
2101 (1 << (ptp_data->adjfreq_ppb_shift - 1))) >> in efx_phc_adjfine()
2102 ptp_data->adjfreq_ppb_shift; in efx_phc_adjfine()
2114 ptp_data->current_adjfreq = adjustment_ns; in efx_phc_adjfine()
2124 struct efx_nic *efx = ptp_data->efx; in efx_phc_adjtime()
2127 efx->ptp_data->ns_to_nic_time(delta, &nic_major, &nic_minor); in efx_phc_adjtime()
2131 MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq); in efx_phc_adjtime()
2143 struct efx_nic *efx = ptp_data->efx; in efx_phc_gettime()
2157 kt = ptp_data->nic_to_kernel_time( in efx_phc_gettime()
2195 if (request->type != PTP_CLK_REQ_PPS) in efx_phc_enable()
2196 return -EOPNOTSUPP; in efx_phc_enable()
2198 ptp_data->nic_ts_enabled = !!enable; in efx_phc_enable()
2219 efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = in efx_ptp_defer_probe_with_channel()
2226 netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n"); in efx_ptp_start_datapath()
2227 /* re-enable timestamping if it was previously enabled */ in efx_ptp_start_datapath()
2228 if (efx->type->ptp_set_ts_sync_events) in efx_ptp_start_datapath()
2229 efx->type->ptp_set_ts_sync_events(efx, true, true); in efx_ptp_start_datapath()
2235 if (efx->type->ptp_set_ts_sync_events) in efx_ptp_stop_datapath()
2236 efx->type->ptp_set_ts_sync_events(efx, false, true); in efx_ptp_stop_datapath()