// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2021, Intel Corporation. */ #include "ice.h" #include "ice_lib.h" #include "ice_trace.h" #define E810_OUT_PROP_DELAY_NS … static const struct ptp_pin_desc ice_pin_desc_e810t[] = …; /** * ice_get_sma_config_e810t * @hw: pointer to the hw struct * @ptp_pins: pointer to the ptp_pin_desc struture * * Read the configuration of the SMA control logic and put it into the * ptp_pin_desc structure */ static int ice_get_sma_config_e810t(struct ice_hw *hw, struct ptp_pin_desc *ptp_pins) { … } /** * ice_ptp_set_sma_config_e810t * @hw: pointer to the hw struct * @ptp_pins: pointer to the ptp_pin_desc struture * * Set the configuration of the SMA control logic based on the configuration in * num_pins parameter */ static int ice_ptp_set_sma_config_e810t(struct ice_hw *hw, const struct ptp_pin_desc *ptp_pins) { … } /** * ice_ptp_set_sma_e810t * @info: the driver's PTP info structure * @pin: pin index in kernel structure * @func: Pin function to be set (PTP_PF_NONE, PTP_PF_EXTTS or PTP_PF_PEROUT) * * Set the configuration of a single SMA pin */ static int ice_ptp_set_sma_e810t(struct ptp_clock_info *info, unsigned int pin, enum ptp_pin_function func) { … } /** * ice_verify_pin_e810t * @info: the driver's PTP info structure * @pin: Pin index * @func: Assigned function * @chan: Assigned channel * * Verify if pin supports requested pin function. If the Check pins consistency. * Reconfigure the SMA logic attached to the given pin to enable its * desired functionality */ static int ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin, enum ptp_pin_function func, unsigned int chan) { … } /** * ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device * @pf: Board private structure * * Program the device to respond appropriately to the Tx timestamp interrupt * cause. */ static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf) { … } /** * ice_set_rx_tstamp - Enable or disable Rx timestamping * @pf: The PF pointer to search in * @on: bool value for whether timestamps are enabled or disabled */ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on) { … } /** * ice_ptp_disable_timestamp_mode - Disable current timestamp mode * @pf: Board private structure * * Called during preparation for reset to temporarily disable timestamping on * the device. Called during remove to disable timestamping while cleaning up * driver resources. */ static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf) { … } /** * ice_ptp_restore_timestamp_mode - Restore timestamp configuration * @pf: Board private structure * * Called at the end of rebuild to restore timestamp configuration after * a device reset. */ void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { … } /** * ice_ptp_read_src_clk_reg - Read the source clock register * @pf: Board private structure * @sts: Optional parameter for holding a pair of system timestamps from * the system clock. Will be ignored if NULL is given. */ static u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf, struct ptp_system_timestamp *sts) { … } /** * ice_ptp_extend_32b_ts - Convert a 32b nanoseconds timestamp to 64b * @cached_phc_time: recently cached copy of PHC time * @in_tstamp: Ingress/egress 32b nanoseconds timestamp value * * Hardware captures timestamps which contain only 32 bits of nominal * nanoseconds, as opposed to the 64bit timestamps that the stack expects. * Note that the captured timestamp values may be 40 bits, but the lower * 8 bits are sub-nanoseconds and generally discarded. * * Extend the 32bit nanosecond timestamp using the following algorithm and * assumptions: * * 1) have a recently cached copy of the PHC time * 2) assume that the in_tstamp was captured 2^31 nanoseconds (~2.1 * seconds) before or after the PHC time was captured. * 3) calculate the delta between the cached time and the timestamp * 4) if the delta is smaller than 2^31 nanoseconds, then the timestamp was * captured after the PHC time. In this case, the full timestamp is just * the cached PHC time plus the delta. * 5) otherwise, if the delta is larger than 2^31 nanoseconds, then the * timestamp was captured *before* the PHC time, i.e. because the PHC * cache was updated after the timestamp was captured by hardware. In this * case, the full timestamp is the cached time minus the inverse delta. * * This algorithm works even if the PHC time was updated after a Tx timestamp * was requested, but before the Tx timestamp event was reported from * hardware. * * This calculation primarily relies on keeping the cached PHC time up to * date. If the timestamp was captured more than 2^31 nanoseconds after the * PHC time, it is possible that the lower 32bits of PHC time have * overflowed more than once, and we might generate an incorrect timestamp. * * This is prevented by (a) periodically updating the cached PHC time once * a second, and (b) discarding any Tx timestamp packet if it has waited for * a timestamp for more than one second. */ static u64 ice_ptp_extend_32b_ts(u64 cached_phc_time, u32 in_tstamp) { … } /** * ice_ptp_extend_40b_ts - Convert a 40b timestamp to 64b nanoseconds * @pf: Board private structure * @in_tstamp: Ingress/egress 40b timestamp value * * The Tx and Rx timestamps are 40 bits wide, including 32 bits of nominal * nanoseconds, 7 bits of sub-nanoseconds, and a valid bit. * * *--------------------------------------------------------------* * | 32 bits of nanoseconds | 7 high bits of sub ns underflow | v | * *--------------------------------------------------------------* * * The low bit is an indicator of whether the timestamp is valid. The next * 7 bits are a capture of the upper 7 bits of the sub-nanosecond underflow, * and the remaining 32 bits are the lower 32 bits of the PHC timer. * * It is assumed that the caller verifies the timestamp is valid prior to * calling this function. * * Extract the 32bit nominal nanoseconds and extend them. Use the cached PHC * time stored in the device private PTP structure as the basis for timestamp * extension. * * See ice_ptp_extend_32b_ts for a detailed explanation of the extension * algorithm. */ static u64 ice_ptp_extend_40b_ts(struct ice_pf *pf, u64 in_tstamp) { … } /** * ice_ptp_is_tx_tracker_up - Check if Tx tracker is ready for new timestamps * @tx: the PTP Tx timestamp tracker to check * * Check that a given PTP Tx timestamp tracker is up, i.e. that it is ready * to accept new timestamp requests. * * Assumes the tx->lock spinlock is already held. */ static bool ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx) { … } /** * ice_ptp_req_tx_single_tstamp - Request Tx timestamp for a port from FW * @tx: the PTP Tx timestamp tracker * @idx: index of the timestamp to request */ void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) { … } /** * ice_ptp_complete_tx_single_tstamp - Complete Tx timestamp for a port * @tx: the PTP Tx timestamp tracker */ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { … } /** * ice_ptp_process_tx_tstamp - Process Tx timestamps for a port * @tx: the PTP Tx timestamp tracker * * Process timestamps captured by the PHY associated with this port. To do * this, loop over each index with a waiting skb. * * If a given index has a valid timestamp, perform the following steps: * * 1) check that the timestamp request is not stale * 2) check that a timestamp is ready and available in the PHY memory bank * 3) read and copy the timestamp out of the PHY register * 4) unlock the index by clearing the associated in_use bit * 5) check if the timestamp is stale, and discard if so * 6) extend the 40 bit timestamp value to get a 64 bit timestamp value * 7) send this 64 bit timestamp to the stack * * Note that we do not hold the tracking lock while reading the Tx timestamp. * This is because reading the timestamp requires taking a mutex that might * sleep. * * The only place where we set in_use is when a new timestamp is initiated * with a slot index. This is only called in the hard xmit routine where an * SKB has a request flag set. The only places where we clear this bit is this * function, or during teardown when the Tx timestamp tracker is being * removed. A timestamp index will never be re-used until the in_use bit for * that index is cleared. * * If a Tx thread starts a new timestamp, we might not begin processing it * right away but we will notice it at the end when we re-queue the task. * * If a Tx thread starts a new timestamp just after this function exits, the * interrupt for that timestamp should re-trigger this function once * a timestamp is ready. * * In cases where the PTP hardware clock was directly adjusted, some * timestamps may not be able to safely use the timestamp extension math. In * this case, software will set the stale bit for any outstanding Tx * timestamps when the clock is adjusted. Then this function will discard * those captured timestamps instead of sending them to the stack. * * If a Tx packet has been waiting for more than 2 seconds, it is not possible * to correctly extend the timestamp using the cached PHC time. It is * extremely unlikely that a packet will ever take this long to timestamp. If * we detect a Tx timestamp request that has waited for this long we assume * the packet will never be sent by hardware and discard it without reading * the timestamp register. */ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx) { … } /** * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device * @pf: Board private structure */ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) { … } /** * ice_ptp_tx_tstamp - Process Tx timestamps for this function. * @tx: Tx tracking structure to initialize * * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding incomplete * Tx timestamps, or ICE_TX_TSTAMP_WORK_DONE otherwise. */ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx) { … } /** * ice_ptp_alloc_tx_tracker - Initialize tracking for Tx timestamps * @tx: Tx tracking structure to initialize * * Assumes that the length has already been initialized. Do not call directly, * use the ice_ptp_init_tx_* instead. */ static int ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx) { … } /** * ice_ptp_flush_tx_tracker - Flush any remaining timestamps from the tracker * @pf: Board private structure * @tx: the tracker to flush * * Called during teardown when a Tx tracker is being removed. */ static void ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx) { … } /** * ice_ptp_mark_tx_tracker_stale - Mark unfinished timestamps as stale * @tx: the tracker to mark * * Mark currently outstanding Tx timestamps as stale. This prevents sending * their timestamp value to the stack. This is required to prevent extending * the 40bit hardware timestamp incorrectly. * * This should be called when the PTP clock is modified such as after a set * time request. */ static void ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx) { … } /** * ice_ptp_flush_all_tx_tracker - Flush all timestamp trackers on this clock * @pf: Board private structure * * Called by the clock owner to flush all the Tx timestamp trackers associated * with the clock. */ static void ice_ptp_flush_all_tx_tracker(struct ice_pf *pf) { … } /** * ice_ptp_release_tx_tracker - Release allocated memory for Tx tracker * @pf: Board private structure * @tx: Tx tracking structure to release * * Free memory associated with the Tx timestamp tracker. */ static void ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx) { … } /** * ice_ptp_init_tx_eth56g - Initialize tracking for Tx timestamps * @pf: Board private structure * @tx: the Tx tracking structure to initialize * @port: the port this structure tracks * * Initialize the Tx timestamp tracker for this port. ETH56G PHYs * have independent memory blocks for all ports. * * Return: 0 for success, -ENOMEM when failed to allocate Tx tracker */ static int ice_ptp_init_tx_eth56g(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) { … } /** * ice_ptp_init_tx_e82x - Initialize tracking for Tx timestamps * @pf: Board private structure * @tx: the Tx tracking structure to initialize * @port: the port this structure tracks * * Initialize the Tx timestamp tracker for this port. For generic MAC devices, * the timestamp block is shared for all ports in the same quad. To avoid * ports using the same timestamp index, logically break the block of * registers into chunks based on the port number. */ static int ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port) { … } /** * ice_ptp_init_tx_e810 - Initialize tracking for Tx timestamps * @pf: Board private structure * @tx: the Tx tracking structure to initialize * * Initialize the Tx timestamp tracker for this PF. For E810 devices, each * port has its own block of timestamps, independent of the other ports. */ static int ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx) { … } /** * ice_ptp_update_cached_phctime - Update the cached PHC time values * @pf: Board specific private structure * * This function updates the system time values which are cached in the PF * structure and the Rx rings. * * This function must be called periodically to ensure that the cached value * is never more than 2 seconds old. * * Note that the cached copy in the PF PTP structure is always updated, even * if we can't update the copy in the Rx rings. * * Return: * * 0 - OK, successfully updated * * -EAGAIN - PF was busy, need to reschedule the update */ static int ice_ptp_update_cached_phctime(struct ice_pf *pf) { … } /** * ice_ptp_reset_cached_phctime - Reset cached PHC time after an update * @pf: Board specific private structure * * This function must be called when the cached PHC time is no longer valid, * such as after a time adjustment. It marks any currently outstanding Tx * timestamps as stale and updates the cached PHC time for both the PF and Rx * rings. * * If updating the PHC time cannot be done immediately, a warning message is * logged and the work item is scheduled immediately to minimize the window * with a wrong cached timestamp. */ static void ice_ptp_reset_cached_phctime(struct ice_pf *pf) { … } /** * ice_ptp_write_init - Set PHC time to provided value * @pf: Board private structure * @ts: timespec structure that holds the new time value * * Set the PHC time to the specified time provided in the timespec. */ static int ice_ptp_write_init(struct ice_pf *pf, struct timespec64 *ts) { … } /** * ice_ptp_write_adj - Adjust PHC clock time atomically * @pf: Board private structure * @adj: Adjustment in nanoseconds * * Perform an atomic adjustment of the PHC time by the specified number of * nanoseconds. */ static int ice_ptp_write_adj(struct ice_pf *pf, s32 adj) { … } /** * ice_base_incval - Get base timer increment value * @pf: Board private structure * * Look up the base timer increment value for this device. The base increment * value is used to define the nominal clock tick rate. This increment value * is programmed during device initialization. It is also used as the basis * for calculating adjustments using scaled_ppm. */ static u64 ice_base_incval(struct ice_pf *pf) { … } /** * ice_ptp_check_tx_fifo - Check whether Tx FIFO is in an OK state * @port: PTP port for which Tx FIFO is checked */ static int ice_ptp_check_tx_fifo(struct ice_ptp_port *port) { … } /** * ice_ptp_wait_for_offsets - Check for valid Tx and Rx offsets * @work: Pointer to the kthread_work structure for this task * * Check whether hardware has completed measuring the Tx and Rx offset values * used to configure and enable vernier timestamp calibration. * * Once the offset in either direction is measured, configure the associated * registers with the calibrated offset values and enable timestamping. The Tx * and Rx directions are configured independently as soon as their associated * offsets are known. * * This function reschedules itself until both Tx and Rx calibration have * completed. */ static void ice_ptp_wait_for_offsets(struct kthread_work *work) { … } /** * ice_ptp_port_phy_stop - Stop timestamping for a PHY port * @ptp_port: PTP port to stop */ static int ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port) { … } /** * ice_ptp_port_phy_restart - (Re)start and calibrate PHY timestamping * @ptp_port: PTP port for which the PHY start is set * * Start the PHY timestamping block, and initiate Vernier timestamping * calibration. If timestamping cannot be calibrated (such as if link is down) * then disable the timestamping block instead. */ static int ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port) { … } /** * ice_ptp_link_change - Reconfigure PTP after link status change * @pf: Board private structure * @port: Port for which the PHY start is set * @linkup: Link is up or down */ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) { … } /** * ice_ptp_cfg_phy_interrupt - Configure PHY interrupt settings * @pf: PF private structure * @ena: bool value to enable or disable interrupt * @threshold: Minimum number of packets at which intr is triggered * * Utility function to configure all the PHY interrupt settings, including * whether the PHY interrupt is enabled, and what threshold to use. Also * configures The E82X timestamp owner to react to interrupts from all PHYs. * * Return: 0 on success, -EOPNOTSUPP when PHY model incorrect, other error codes * when failed to configure PHY interrupt for E82X */ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold) { … } /** * ice_ptp_reset_phy_timestamping - Reset PHY timestamping block * @pf: Board private structure */ static void ice_ptp_reset_phy_timestamping(struct ice_pf *pf) { … } /** * ice_ptp_restart_all_phy - Restart all PHYs to recalibrate timestamping * @pf: Board private structure */ static void ice_ptp_restart_all_phy(struct ice_pf *pf) { … } /** * ice_ptp_adjfine - Adjust clock increment rate * @info: the driver's PTP info structure * @scaled_ppm: Parts per million with 16-bit fractional field * * Adjust the frequency of the clock by the indicated scaled ppm from the * base frequency. */ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm) { … } /** * ice_ptp_extts_event - Process PTP external clock event * @pf: Board private structure */ void ice_ptp_extts_event(struct ice_pf *pf) { … } /** * ice_ptp_cfg_extts - Configure EXTTS pin and channel * @pf: Board private structure * @chan: GPIO channel (0-3) * @config: desired EXTTS configuration. * @store: If set to true, the values will be stored * * Configure an external timestamp event on the requested channel. * * Return: 0 on success, -EOPNOTUSPP on unsupported flags */ static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan, struct ice_extts_channel *config, bool store) { … } /** * ice_ptp_disable_all_extts - Disable all EXTTS channels * @pf: Board private structure */ static void ice_ptp_disable_all_extts(struct ice_pf *pf) { … } /** * ice_ptp_enable_all_extts - Enable all EXTTS channels * @pf: Board private structure * * Called during reset to restore user configuration. */ static void ice_ptp_enable_all_extts(struct ice_pf *pf) { … } /** * ice_ptp_cfg_clkout - Configure clock to generate periodic wave * @pf: Board private structure * @chan: GPIO channel (0-3) * @config: desired periodic clk configuration. NULL will disable channel * @store: If set to true the values will be stored * * Configure the internal clock generator modules to generate the clock wave of * specified period. */ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan, struct ice_perout_channel *config, bool store) { … } /** * ice_ptp_disable_all_clkout - Disable all currently configured outputs * @pf: pointer to the PF structure * * Disable all currently configured clock outputs. This is necessary before * certain changes to the PTP hardware clock. Use ice_ptp_enable_all_clkout to * re-enable the clocks again. */ static void ice_ptp_disable_all_clkout(struct ice_pf *pf) { … } /** * ice_ptp_enable_all_clkout - Enable all configured periodic clock outputs * @pf: pointer to the PF structure * * Enable all currently configured clock outputs. Use this after * ice_ptp_disable_all_clkout to reconfigure the output signals according to * their configuration. */ static void ice_ptp_enable_all_clkout(struct ice_pf *pf) { … } /** * ice_ptp_gpio_enable_e810 - Enable/disable ancillary features of PHC * @info: the driver's PTP info structure * @rq: The requested feature to change * @on: Enable/disable flag */ static int ice_ptp_gpio_enable_e810(struct ptp_clock_info *info, struct ptp_clock_request *rq, int on) { … } /** * ice_ptp_gpio_enable_e823 - Enable/disable ancillary features of PHC * @info: the driver's PTP info structure * @rq: The requested feature to change * @on: Enable/disable flag */ static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info, struct ptp_clock_request *rq, int on) { … } /** * ice_ptp_gettimex64 - Get the time of the clock * @info: the driver's PTP info structure * @ts: timespec64 structure to hold the current time value * @sts: Optional parameter for holding a pair of system timestamps from * the system clock. Will be ignored if NULL is given. * * Read the device clock and return the correct value on ns, after converting it * into a timespec struct. */ static int ice_ptp_gettimex64(struct ptp_clock_info *info, struct timespec64 *ts, struct ptp_system_timestamp *sts) { … } /** * ice_ptp_settime64 - Set the time of the clock * @info: the driver's PTP info structure * @ts: timespec64 structure that holds the new time value * * Set the device clock to the user input value. The conversion from timespec * to ns happens in the write function. */ static int ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts) { … } /** * ice_ptp_adjtime_nonatomic - Do a non-atomic clock adjustment * @info: the driver's PTP info structure * @delta: Offset in nanoseconds to adjust the time by */ static int ice_ptp_adjtime_nonatomic(struct ptp_clock_info *info, s64 delta) { … } /** * ice_ptp_adjtime - Adjust the time of the clock by the indicated delta * @info: the driver's PTP info structure * @delta: Offset in nanoseconds to adjust the time by */ static int ice_ptp_adjtime(struct ptp_clock_info *info, s64 delta) { … } #ifdef CONFIG_ICE_HWTS /** * ice_ptp_get_syncdevicetime - Get the cross time stamp info * @device: Current device time * @system: System counter value read synchronously with device time * @ctx: Context provided by timekeeping code * * Read device and system (ART) clock simultaneously and return the corrected * clock values in ns. */ static int ice_ptp_get_syncdevicetime(ktime_t *device, struct system_counterval_t *system, void *ctx) { … } /** * ice_ptp_getcrosststamp_e82x - Capture a device cross timestamp * @info: the driver's PTP info structure * @cts: The memory to fill the cross timestamp info * * Capture a cross timestamp between the ART and the device PTP hardware * clock. Fill the cross timestamp information and report it back to the * caller. * * This is only valid for E822 and E823 devices which have support for * generating the cross timestamp via PCIe PTM. * * In order to correctly correlate the ART timestamp back to the TSC time, the * CPU must have X86_FEATURE_TSC_KNOWN_FREQ. */ static int ice_ptp_getcrosststamp_e82x(struct ptp_clock_info *info, struct system_device_crosststamp *cts) { … } #endif /* CONFIG_ICE_HWTS */ /** * ice_ptp_get_ts_config - ioctl interface to read the timestamping config * @pf: Board private structure * @ifr: ioctl data * * Copy the timestamping config to user buffer */ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr) { … } /** * ice_ptp_set_timestamp_mode - Setup driver for requested timestamp mode * @pf: Board private structure * @config: hwtstamp settings requested or saved */ static int ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config) { … } /** * ice_ptp_set_ts_config - ioctl interface to control the timestamping * @pf: Board private structure * @ifr: ioctl data * * Get the user config and store it */ int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr) { … } /** * ice_ptp_get_rx_hwts - Get packet Rx timestamp in ns * @rx_desc: Receive descriptor * @pkt_ctx: Packet context to get the cached time * * The driver receives a notification in the receive descriptor with timestamp. */ u64 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc, const struct ice_pkt_ctx *pkt_ctx) { … } /** * ice_ptp_disable_sma_pins_e810t - Disable E810-T SMA pins * @pf: pointer to the PF structure * @info: PTP clock info structure * * Disable the OS access to the SMA pins. Called to clear out the OS * indications of pin support when we fail to setup the E810-T SMA control * register. */ static void ice_ptp_disable_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_setup_sma_pins_e810t - Setup the SMA pins * @pf: pointer to the PF structure * @info: PTP clock info structure * * Finish setting up the SMA pins by allocating pin_config, and setting it up * according to the current status of the SMA. On failure, disable all of the * extended SMA pin support. */ static void ice_ptp_setup_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_setup_pins_e810 - Setup PTP pins in sysfs * @pf: pointer to the PF instance * @info: PTP clock capabilities */ static void ice_ptp_setup_pins_e810(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_setup_pins_e823 - Setup PTP pins in sysfs * @pf: pointer to the PF instance * @info: PTP clock capabilities */ static void ice_ptp_setup_pins_e823(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_set_funcs_e82x - Set specialized functions for E82x support * @pf: Board private structure * @info: PTP info to fill * * Assign functions to the PTP capabiltiies structure for E82x devices. * Functions which operate across all device families should be set directly * in ice_ptp_set_caps. Only add functions here which are distinct for E82x * devices. */ static void ice_ptp_set_funcs_e82x(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_set_funcs_e810 - Set specialized functions for E810 support * @pf: Board private structure * @info: PTP info to fill * * Assign functions to the PTP capabiltiies structure for E810 devices. * Functions which operate across all device families should be set directly * in ice_ptp_set_caps. Only add functions here which are distinct for e810 * devices. */ static void ice_ptp_set_funcs_e810(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_set_funcs_e823 - Set specialized functions for E823 support * @pf: Board private structure * @info: PTP info to fill * * Assign functions to the PTP capabiltiies structure for E823 devices. * Functions which operate across all device families should be set directly * in ice_ptp_set_caps. Only add functions here which are distinct for e823 * devices. */ static void ice_ptp_set_funcs_e823(struct ice_pf *pf, struct ptp_clock_info *info) { … } /** * ice_ptp_set_caps - Set PTP capabilities * @pf: Board private structure */ static void ice_ptp_set_caps(struct ice_pf *pf) { … } /** * ice_ptp_create_clock - Create PTP clock device for userspace * @pf: Board private structure * * This function creates a new PTP clock device. It only creates one if we * don't already have one. Will return error if it can't create one, but success * if we already have a device. Should be used by ice_ptp_init to create clock * initially, and prevent global resets from creating new clock devices. */ static long ice_ptp_create_clock(struct ice_pf *pf) { … } /** * ice_ptp_request_ts - Request an available Tx timestamp index * @tx: the PTP Tx timestamp tracker to request from * @skb: the SKB to associate with this timestamp request */ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb) { … } /** * ice_ptp_process_ts - Process the PTP Tx timestamps * @pf: Board private structure * * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding Tx * timestamps that need processing, and ICE_TX_TSTAMP_WORK_DONE otherwise. */ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf) { … } /** * ice_ptp_maybe_trigger_tx_interrupt - Trigger Tx timstamp interrupt * @pf: Board private structure * * The device PHY issues Tx timestamp interrupts to the driver for processing * timestamp data from the PHY. It will not interrupt again until all * current timestamp data is read. In rare circumstances, it is possible that * the driver fails to read all outstanding data. * * To avoid getting permanently stuck, periodically check if the PHY has * outstanding timestamp data. If so, trigger an interrupt from software to * process this data. */ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf) { … } static void ice_ptp_periodic_work(struct kthread_work *work) { … } /** * ice_ptp_prepare_for_reset - Prepare PTP for reset * @pf: Board private structure * @reset_type: the reset type being performed */ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) { … } /** * ice_ptp_rebuild_owner - Initialize PTP clock owner after reset * @pf: Board private structure * * Companion function for ice_ptp_rebuild() which handles tasks that only the * PTP clock owner instance should perform. */ static int ice_ptp_rebuild_owner(struct ice_pf *pf) { … } /** * ice_ptp_rebuild - Initialize PTP hardware clock support after reset * @pf: Board private structure * @reset_type: the reset type being performed */ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) { … } /** * ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device * @aux_dev: auxiliary device to get the auxiliary PF for */ static struct ice_pf * ice_ptp_aux_dev_to_aux_pf(struct auxiliary_device *aux_dev) { … } /** * ice_ptp_aux_dev_to_owner_pf - Get PF handle for the auxiliary device * @aux_dev: auxiliary device to get the PF for */ static struct ice_pf * ice_ptp_aux_dev_to_owner_pf(struct auxiliary_device *aux_dev) { … } /** * ice_ptp_auxbus_probe - Probe auxiliary devices * @aux_dev: PF's auxiliary device * @id: Auxiliary device ID */ static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *id) { … } /** * ice_ptp_auxbus_remove - Remove auxiliary devices from the bus * @aux_dev: PF's auxiliary device */ static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev) { … } /** * ice_ptp_auxbus_shutdown * @aux_dev: PF's auxiliary device */ static void ice_ptp_auxbus_shutdown(struct auxiliary_device *aux_dev) { … } /** * ice_ptp_auxbus_suspend * @aux_dev: PF's auxiliary device * @state: power management state indicator */ static int ice_ptp_auxbus_suspend(struct auxiliary_device *aux_dev, pm_message_t state) { … } /** * ice_ptp_auxbus_resume * @aux_dev: PF's auxiliary device */ static int ice_ptp_auxbus_resume(struct auxiliary_device *aux_dev) { … } /** * ice_ptp_auxbus_create_id_table - Create auxiliary device ID table * @pf: Board private structure * @name: auxiliary bus driver name */ static struct auxiliary_device_id * ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name) { … } /** * ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver * @pf: Board private structure */ static int ice_ptp_register_auxbus_driver(struct ice_pf *pf) { … } /** * ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver * @pf: Board private structure */ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf) { … } /** * ice_ptp_clock_index - Get the PTP clock index for this device * @pf: Board private structure * * Returns: the PTP clock index associated with this PF, or -1 if no PTP clock * is associated. */ int ice_ptp_clock_index(struct ice_pf *pf) { … } /** * ice_ptp_init_owner - Initialize PTP_1588_CLOCK device * @pf: Board private structure * * Setup and initialize a PTP clock device that represents the device hardware * clock. Save the clock index for other functions connected to the same * hardware resource. */ static int ice_ptp_init_owner(struct ice_pf *pf) { … } /** * ice_ptp_init_work - Initialize PTP work threads * @pf: Board private structure * @ptp: PF PTP structure */ static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp) { … } /** * ice_ptp_init_port - Initialize PTP port structure * @pf: Board private structure * @ptp_port: PTP port structure */ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port) { … } /** * ice_ptp_release_auxbus_device * @dev: device that utilizes the auxbus */ static void ice_ptp_release_auxbus_device(struct device *dev) { … } /** * ice_ptp_create_auxbus_device - Create PTP auxiliary bus device * @pf: Board private structure */ static int ice_ptp_create_auxbus_device(struct ice_pf *pf) { … } /** * ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device * @pf: Board private structure */ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf) { … } /** * ice_ptp_init_tx_interrupt_mode - Initialize device Tx interrupt mode * @pf: Board private structure * * Initialize the Tx timestamp interrupt mode for this device. For most device * types, each PF processes the interrupt and manages its own timestamps. For * E822-based devices, only the clock owner processes the timestamps. Other * PFs disable the interrupt and do not process their own timestamps. */ static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf) { … } /** * ice_ptp_init - Initialize PTP hardware clock support * @pf: Board private structure * * Set up the device for interacting with the PTP hardware clock for all * functions, both the function that owns the clock hardware, and the * functions connected to the clock hardware. * * The clock owner will allocate and register a ptp_clock with the * PTP_1588_CLOCK infrastructure. All functions allocate a kthread and work * items used for asynchronous work such as Tx timestamps and periodic work. */ void ice_ptp_init(struct ice_pf *pf) { … } /** * ice_ptp_release - Disable the driver/HW support and unregister the clock * @pf: Board private structure * * This function handles the cleanup work required from the initialization by * clearing out the important information and unregistering the clock */ void ice_ptp_release(struct ice_pf *pf) { … }