// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** * Driver for Solarflare network controllers and boards * Copyright 2011-2013 Solarflare Communications Inc. */ /* Theory of operation: * * PTP support is assisted by firmware running on the MC, which provides * the hardware timestamping capabilities. Both transmitted and received * PTP event packets are queued onto internal queues for subsequent processing; * this is because the MC operations are relatively long and would block * block NAPI/interrupt operation. * * Receive event processing: * The event contains the packet's UUID and sequence number, together * with the hardware timestamp. The PTP receive packet queue is searched * for this UUID/sequence number and, if found, put on a pending queue. * Packets not matching are delivered without timestamps (MCDI events will * always arrive after the actual packet). * It is important for the operation of the PTP protocol that the ordering * of packets between the event and general port is maintained. * * Work queue processing: * If work waiting, synchronise host/hardware time * * Transmit: send packet through MC, which returns the transmission time * that is converted to an appropriate timestamp. * * Receive: the packet's reception time is converted to an appropriate * timestamp. */ #include <linux/ip.h> #include <linux/udp.h> #include <linux/time.h> #include <linux/errno.h> #include <linux/ktime.h> #include <linux/module.h> #include <linux/pps_kernel.h> #include <linux/ptp_clock_kernel.h> #include "net_driver.h" #include "efx.h" #include "mcdi.h" #include "mcdi_pcol.h" #include "io.h" #include "tx.h" #include "nic.h" /* indirectly includes ptp.h */ #include "efx_channels.h" /* Maximum number of events expected to make up a PTP event */ #define MAX_EVENT_FRAGS … /* Maximum delay, ms, to begin synchronisation */ #define MAX_SYNCHRONISE_WAIT_MS … /* How long, at most, to spend synchronising */ #define SYNCHRONISE_PERIOD_NS … /* How often to update the shared memory time */ #define SYNCHRONISATION_GRANULARITY_NS … /* Minimum permitted length of a (corrected) synchronisation time */ #define DEFAULT_MIN_SYNCHRONISATION_NS … /* Maximum permitted length of a (corrected) synchronisation time */ #define MAX_SYNCHRONISATION_NS … /* How many (MC) receive events that can be queued */ #define MAX_RECEIVE_EVENTS … /* Length of (modified) moving average. */ #define AVERAGE_LENGTH … /* How long an unmatched event or packet can be held */ #define PKT_EVENT_LIFETIME_MS … /* How long unused unicast filters can be held */ #define UCAST_FILTER_EXPIRY_JIFFIES … /* Offsets into PTP packet for identification. These offsets are from the * start of the IP header, not the MAC header. Note that neither PTP V1 nor * PTP V2 permit the use of IPV4 options. */ #define PTP_DPORT_OFFSET … #define PTP_V1_VERSION_LENGTH … #define PTP_V1_VERSION_OFFSET … #define PTP_V1_SEQUENCE_LENGTH … #define PTP_V1_SEQUENCE_OFFSET … /* The minimum length of a PTP V1 packet for offsets, etc. to be valid: * includes IP header. */ #define PTP_V1_MIN_LENGTH … #define PTP_V2_VERSION_LENGTH … #define PTP_V2_VERSION_OFFSET … #define PTP_V2_SEQUENCE_LENGTH … #define PTP_V2_SEQUENCE_OFFSET … /* The minimum length of a PTP V2 packet for offsets, etc. to be valid: * includes IP header. */ #define PTP_V2_MIN_LENGTH … #define PTP_MIN_LENGTH … #define PTP_ADDR_IPV4 … /* ff0e::181 */ static const struct in6_addr ptp_addr_ipv6 = …; /* 01-1B-19-00-00-00 */ static const u8 ptp_addr_ether[ETH_ALEN] __aligned(2) = …; #define PTP_EVENT_PORT … #define PTP_GENERAL_PORT … /* Annoyingly the format of the version numbers are different between * versions 1 and 2 so it isn't possible to simply look for 1 or 2. */ #define PTP_VERSION_V1 … #define PTP_VERSION_V2 … #define PTP_VERSION_V2_MASK … enum ptp_packet_state { … }; /* NIC synchronised with single word of time only comprising * partial seconds and full nanoseconds: 10^9 ~ 2^30 so 2 bits for seconds. */ #define MC_NANOSECOND_BITS … #define MC_NANOSECOND_MASK … #define MC_SECOND_MASK … /* Maximum parts-per-billion adjustment that is acceptable */ #define MAX_PPB … /* Precalculate scale word to avoid long long division at runtime */ /* This is equivalent to 2^66 / 10^9. */ #define PPB_SCALE_WORD … /* How much to shift down after scaling to convert to FP40 */ #define PPB_SHIFT_FP40 … /* ... and FP44. */ #define PPB_SHIFT_FP44 … #define PTP_SYNC_ATTEMPTS … /** * struct efx_ptp_match - Matching structure, stored in sk_buff's cb area. * @expiry: Time after which the packet should be delivered irrespective of * event arrival. * @state: The state of the packet - whether it is ready for processing or * whether that is of no interest. */ struct efx_ptp_match { … }; /** * struct efx_ptp_event_rx - A PTP receive event (from MC) * @link: list of events * @seq0: First part of (PTP) UUID * @seq1: Second part of (PTP) UUID and sequence number * @hwtimestamp: Event timestamp * @expiry: Time which the packet arrived */ struct efx_ptp_event_rx { … }; /** * struct efx_ptp_timeset - Synchronisation between host and MC * @host_start: Host time immediately before hardware timestamp taken * @major: Hardware timestamp, major * @minor: Hardware timestamp, minor * @host_end: Host time immediately after hardware timestamp taken * @wait: Number of NIC clock ticks between hardware timestamp being read and * host end time being seen * @window: Difference of host_end and host_start * @valid: Whether this timeset is valid */ struct efx_ptp_timeset { … }; /** * struct efx_ptp_rxfilter - Filter for PTP packets * @list: Node of the list where the filter is added * @ether_type: Network protocol of the filter (ETHER_P_IP / ETHER_P_IPV6) * @loc_port: UDP port of the filter (PTP_EVENT_PORT / PTP_GENERAL_PORT) * @loc_host: IPv4/v6 address of the filter * @expiry: time when the filter expires, in jiffies * @handle: Handle ID for the MCDI filters table */ struct efx_ptp_rxfilter { … }; /** * struct efx_ptp_data - Precision Time Protocol (PTP) state * @efx: The NIC context * @channel: The PTP channel (for Medford and Medford2) * @rxq: Receive SKB queue (awaiting timestamps) * @txq: Transmit SKB queue * @workwq: Work queue for processing pending PTP operations * @work: Work task * @cleanup_work: Work task for periodic cleanup * @reset_required: A serious error has occurred and the PTP task needs to be * reset (disable, enable). * @rxfilters_mcast: Receive filters for multicast PTP packets * @rxfilters_ucast: Receive filters for unicast PTP packets * @config: Current timestamp configuration * @enabled: PTP operation enabled * @mode: Mode in which PTP operating (PTP version) * @ns_to_nic_time: Function to convert from scalar nanoseconds to NIC time * @nic_to_kernel_time: Function to convert from NIC to kernel time * @nic_time: contains time details * @nic_time.minor_max: Wrap point for NIC minor times * @nic_time.sync_event_diff_min: Minimum acceptable difference between time * in packet prefix and last MCDI time sync event i.e. how much earlier than * the last sync event time a packet timestamp can be. * @nic_time.sync_event_diff_max: Maximum acceptable difference between time * in packet prefix and last MCDI time sync event i.e. how much later than * the last sync event time a packet timestamp can be. * @nic_time.sync_event_minor_shift: Shift required to make minor time from * field in MCDI time sync event. * @min_synchronisation_ns: Minimum acceptable corrected sync window * @capabilities: Capabilities flags from the NIC * @ts_corrections: contains corrections details * @ts_corrections.ptp_tx: Required driver correction of PTP packet transmit * timestamps * @ts_corrections.ptp_rx: Required driver correction of PTP packet receive * timestamps * @ts_corrections.pps_out: PPS output error (information only) * @ts_corrections.pps_in: Required driver correction of PPS input timestamps * @ts_corrections.general_tx: Required driver correction of general packet * transmit timestamps * @ts_corrections.general_rx: Required driver correction of general packet * receive timestamps * @evt_frags: Partly assembled PTP events * @evt_frag_idx: Current fragment number * @evt_code: Last event code * @start: Address at which MC indicates ready for synchronisation * @host_time_pps: Host time at last PPS * @adjfreq_ppb_shift: Shift required to convert scaled parts-per-billion * frequency adjustment into a fixed point fractional nanosecond format. * @current_adjfreq: Current ppb adjustment. * @phc_clock: Pointer to registered phc device (if primary function) * @phc_clock_info: Registration structure for phc device * @pps_work: pps work task for handling pps events * @pps_workwq: pps work queue * @nic_ts_enabled: Flag indicating if NIC generated TS events are handled * @txbuf: Buffer for use when transmitting (PTP) packets to MC (avoids * allocations in main data path). * @good_syncs: Number of successful synchronisations. * @fast_syncs: Number of synchronisations requiring short delay * @bad_syncs: Number of failed synchronisations. * @sync_timeouts: Number of synchronisation timeouts * @no_time_syncs: Number of synchronisations with no good times. * @invalid_sync_windows: Number of sync windows with bad durations. * @undersize_sync_windows: Number of corrected sync windows that are too small * @oversize_sync_windows: Number of corrected sync windows that are too large * @rx_no_timestamp: Number of packets received without a timestamp. * @timeset: Last set of synchronisation statistics. * @xmit_skb: Transmit SKB function. */ struct efx_ptp_data { … }; static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm); static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta); static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts); static int efx_phc_settime(struct ptp_clock_info *ptp, const struct timespec64 *e_ts); static int efx_phc_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on); static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, struct sk_buff *skb); bool efx_ptp_use_mac_tx_timestamps(struct efx_nic *efx) { … } /* PTP 'extra' channel is still a traffic channel, but we only create TX queues * if PTP uses MAC TX timestamps, not if PTP uses the MC directly to transmit. */ static bool efx_ptp_want_txqs(struct efx_channel *channel) { … } #define PTP_SW_STAT(ext_name, field_name) … #define PTP_MC_STAT(ext_name, mcdi_name) … static const struct efx_hw_stat_desc efx_ptp_stat_desc[] = …; #define PTP_STAT_COUNT … static const unsigned long efx_ptp_stat_mask[] = …; size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 *strings) { … } size_t efx_ptp_update_stats(struct efx_nic *efx, u64 *stats) { … } /* To convert from s27 format to ns we multiply then divide by a power of 2. * For the conversion from ns to s27, the operation is also converted to a * multiply and shift. */ #define S27_TO_NS_SHIFT … #define NS_TO_S27_MULT … #define NS_TO_S27_SHIFT … #define S27_MINOR_MAX … /* For Huntington platforms NIC time is in seconds and fractions of a second * where the minor register only uses 27 bits in units of 2^-27s. */ static void efx_ptp_ns_to_s27(s64 ns, u32 *nic_major, u32 *nic_minor) { … } static inline ktime_t efx_ptp_s27_to_ktime(u32 nic_major, u32 nic_minor) { … } static ktime_t efx_ptp_s27_to_ktime_correction(u32 nic_major, u32 nic_minor, s32 correction) { … } /* For Medford2 platforms the time is in seconds and quarter nanoseconds. */ static void efx_ptp_ns_to_s_qns(s64 ns, u32 *nic_major, u32 *nic_minor) { … } static ktime_t efx_ptp_s_qns_to_ktime_correction(u32 nic_major, u32 nic_minor, s32 correction) { … } struct efx_channel *efx_ptp_channel(struct efx_nic *efx) { … } void efx_ptp_update_channel(struct efx_nic *efx, struct efx_channel *channel) { … } static u32 last_sync_timestamp_major(struct efx_nic *efx) { … } /* The 8000 series and later can provide the time from the MAC, which is only * 48 bits long and provides meta-information in the top 2 bits. */ static ktime_t efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx, struct efx_ptp_data *ptp, u32 nic_major, u32 nic_minor, s32 correction) { … } ktime_t efx_ptp_nic_to_kernel_time(struct efx_tx_queue *tx_queue) { … } /* Get PTP attributes and set up time conversions */ static int efx_ptp_get_attributes(struct efx_nic *efx) { … } /* Get PTP timestamp corrections */ static int efx_ptp_get_timestamp_corrections(struct efx_nic *efx) { … } /* Enable MCDI PTP support. */ static int efx_ptp_enable(struct efx_nic *efx) { … } /* Disable MCDI PTP support. * * Note that this function should never rely on the presence of ptp_data - * may be called before that exists. */ static int efx_ptp_disable(struct efx_nic *efx) { … } static void efx_ptp_deliver_rx_queue(struct sk_buff_head *q) { … } static void efx_ptp_handle_no_channel(struct efx_nic *efx) { … } /* Repeatedly send the host time to the MC which will capture the hardware * time. */ static void efx_ptp_send_times(struct efx_nic *efx, struct pps_event_time *last_time) { … } /* Read a timeset from the MC's results and partial process. */ static void efx_ptp_read_timeset(MCDI_DECLARE_STRUCT_PTR(data), struct efx_ptp_timeset *timeset) { … } /* Process times received from MC. * * Extract times from returned results, and establish the minimum value * seen. The minimum value represents the "best" possible time and events * too much greater than this are rejected - the machine is, perhaps, too * busy. A number of readings are taken so that, hopefully, at least one good * synchronisation will be seen in the results. */ static int efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf), size_t response_length, const struct pps_event_time *last_time) { … } /* Synchronize times between the host and the MC */ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings) { … } /* Transmit a PTP packet via the dedicated hardware timestamped queue. */ static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb) { … } /* Transmit a PTP packet, via the MCDI interface, to the wire. */ static void efx_ptp_xmit_skb_mc(struct efx_nic *efx, struct sk_buff *skb) { … } /* Process any queued receive events and corresponding packets * * q is returned with all the packets that are ready for delivery. */ static void efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q) { … } /* Complete processing of a received packet */ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb) { … } static struct efx_ptp_rxfilter * efx_ptp_find_filter(struct list_head *filter_list, struct efx_filter_spec *spec) { … } static void efx_ptp_remove_one_filter(struct efx_nic *efx, struct efx_ptp_rxfilter *rxfilter) { … } static void efx_ptp_remove_filters(struct efx_nic *efx, struct list_head *filter_list) { … } static void efx_ptp_init_filter(struct efx_nic *efx, struct efx_filter_spec *rxfilter) { … } static int efx_ptp_insert_filter(struct efx_nic *efx, struct list_head *filter_list, struct efx_filter_spec *spec, unsigned long expiry) { … } static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx, struct list_head *filter_list, __be32 addr, u16 port, unsigned long expiry) { … } static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx, struct list_head *filter_list, const struct in6_addr *addr, u16 port, unsigned long expiry) { … } static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx) { … } static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) { … } static bool efx_ptp_valid_unicast_event_pkt(struct sk_buff *skb) { … } static int efx_ptp_insert_unicast_filter(struct efx_nic *efx, struct sk_buff *skb) { … } static int efx_ptp_start(struct efx_nic *efx) { … } static int efx_ptp_stop(struct efx_nic *efx) { … } static int efx_ptp_restart(struct efx_nic *efx) { … } static void efx_ptp_pps_worker(struct work_struct *work) { … } static void efx_ptp_worker(struct work_struct *work) { … } static void efx_ptp_cleanup_worker(struct work_struct *work) { … } static const struct ptp_clock_info efx_phc_clock_info = …; /* Initialise PTP state. */ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) { … } /* Initialise PTP channel. * * Setting core_index to zero causes the queue to be initialised and doesn't * overlap with 'rxq0' because ptp.c doesn't use skb_record_rx_queue. */ static int efx_ptp_probe_channel(struct efx_channel *channel) { … } void efx_ptp_remove(struct efx_nic *efx) { … } static void efx_ptp_remove_channel(struct efx_channel *channel) { … } static void efx_ptp_get_channel_name(struct efx_channel *channel, char *buf, size_t len) { … } /* Determine whether this packet should be processed by the PTP module * or transmitted conventionally. */ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) { … } /* Receive a PTP packet. Packets are queued until the arrival of * the receive timestamp from the MC - this will probably occur after the * packet arrival because of the processing in the MC. */ static bool efx_ptp_rx(struct efx_channel *channel, struct sk_buff *skb) { … } /* Transmit a PTP packet. This has to be transmitted by the MC * itself, through an MCDI call. MCDI calls aren't permitted * in the transmit path so defer the actual transmission to a suitable worker. */ int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) { … } int efx_ptp_get_mode(struct efx_nic *efx) { … } int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, unsigned int new_mode) { … } static int efx_ptp_ts_init(struct efx_nic *efx, struct kernel_hwtstamp_config *init) { … } void efx_ptp_get_ts_info(struct efx_nic *efx, struct kernel_ethtool_ts_info *ts_info) { … } int efx_ptp_set_ts_config(struct efx_nic *efx, struct kernel_hwtstamp_config *config, struct netlink_ext_ack __always_unused *extack) { … } int efx_ptp_get_ts_config(struct efx_nic *efx, struct kernel_hwtstamp_config *config) { … } static void ptp_event_failure(struct efx_nic *efx, int expected_frag_len) { … } static void ptp_event_fault(struct efx_nic *efx, struct efx_ptp_data *ptp) { … } static void ptp_event_pps(struct efx_nic *efx, struct efx_ptp_data *ptp) { … } void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) { … } void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev) { … } static inline u32 efx_rx_buf_timestamp_minor(struct efx_nic *efx, const u8 *eh) { … } void __efx_rx_skb_attach_timestamp(struct efx_channel *channel, struct sk_buff *skb) { … } static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) { … } static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) { … } static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { … } static int efx_phc_settime(struct ptp_clock_info *ptp, const struct timespec64 *e_ts) { … } static int efx_phc_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int enable) { … } static const struct efx_channel_type efx_ptp_channel_type = …; void efx_ptp_defer_probe_with_channel(struct efx_nic *efx) { … } void efx_ptp_start_datapath(struct efx_nic *efx) { … } void efx_ptp_stop_datapath(struct efx_nic *efx) { … }