mirror of https://github.com/torvalds/linux.git
380 lines
11 KiB
C
380 lines
11 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/* Copyright (C) 2024 Intel Corporation */
|
|
|
|
#ifndef _IDPF_PTP_H
|
|
#define _IDPF_PTP_H
|
|
|
|
#include <linux/ptp_clock_kernel.h>
|
|
|
|
/**
|
|
* struct idpf_ptp_cmd - PTP command masks
|
|
* @exec_cmd_mask: mask to trigger command execution
|
|
* @shtime_enable_mask: mask to enable shadow time
|
|
*/
|
|
struct idpf_ptp_cmd {
|
|
u32 exec_cmd_mask;
|
|
u32 shtime_enable_mask;
|
|
};
|
|
|
|
/* struct idpf_ptp_dev_clk_regs - PTP device registers
|
|
* @dev_clk_ns_l: low part of the device clock register
|
|
* @dev_clk_ns_h: high part of the device clock register
|
|
* @phy_clk_ns_l: low part of the PHY clock register
|
|
* @phy_clk_ns_h: high part of the PHY clock register
|
|
* @sys_time_ns_l: low part of the system time register
|
|
* @sys_time_ns_h: high part of the system time register
|
|
* @incval_l: low part of the increment value register
|
|
* @incval_h: high part of the increment value register
|
|
* @shadj_l: low part of the shadow adjust register
|
|
* @shadj_h: high part of the shadow adjust register
|
|
* @phy_incval_l: low part of the PHY increment value register
|
|
* @phy_incval_h: high part of the PHY increment value register
|
|
* @phy_shadj_l: low part of the PHY shadow adjust register
|
|
* @phy_shadj_h: high part of the PHY shadow adjust register
|
|
* @cmd: PTP command register
|
|
* @phy_cmd: PHY command register
|
|
* @cmd_sync: PTP command synchronization register
|
|
*/
|
|
struct idpf_ptp_dev_clk_regs {
|
|
/* Main clock */
|
|
void __iomem *dev_clk_ns_l;
|
|
void __iomem *dev_clk_ns_h;
|
|
|
|
/* PHY timer */
|
|
void __iomem *phy_clk_ns_l;
|
|
void __iomem *phy_clk_ns_h;
|
|
|
|
/* System time */
|
|
void __iomem *sys_time_ns_l;
|
|
void __iomem *sys_time_ns_h;
|
|
|
|
/* Main timer adjustments */
|
|
void __iomem *incval_l;
|
|
void __iomem *incval_h;
|
|
void __iomem *shadj_l;
|
|
void __iomem *shadj_h;
|
|
|
|
/* PHY timer adjustments */
|
|
void __iomem *phy_incval_l;
|
|
void __iomem *phy_incval_h;
|
|
void __iomem *phy_shadj_l;
|
|
void __iomem *phy_shadj_h;
|
|
|
|
/* Command */
|
|
void __iomem *cmd;
|
|
void __iomem *phy_cmd;
|
|
void __iomem *cmd_sync;
|
|
};
|
|
|
|
/**
|
|
* enum idpf_ptp_access - the type of access to PTP operations
|
|
* @IDPF_PTP_NONE: no access
|
|
* @IDPF_PTP_DIRECT: direct access through BAR registers
|
|
* @IDPF_PTP_MAILBOX: access through mailbox messages
|
|
*/
|
|
enum idpf_ptp_access {
|
|
IDPF_PTP_NONE = 0,
|
|
IDPF_PTP_DIRECT,
|
|
IDPF_PTP_MAILBOX,
|
|
};
|
|
|
|
/**
|
|
* struct idpf_ptp_secondary_mbx - PTP secondary mailbox
|
|
* @peer_mbx_q_id: PTP mailbox queue ID
|
|
* @peer_id: Peer ID for PTP Device Control daemon
|
|
* @valid: indicates whether secondary mailblox is supported by the Control
|
|
* Plane
|
|
*/
|
|
struct idpf_ptp_secondary_mbx {
|
|
u16 peer_mbx_q_id;
|
|
u16 peer_id;
|
|
bool valid:1;
|
|
};
|
|
|
|
/**
|
|
* enum idpf_ptp_tx_tstamp_state - Tx timestamp states
|
|
* @IDPF_PTP_FREE: Tx timestamp index free to use
|
|
* @IDPF_PTP_REQUEST: Tx timestamp index set to the Tx descriptor
|
|
* @IDPF_PTP_READ_VALUE: Tx timestamp value ready to be read
|
|
*/
|
|
enum idpf_ptp_tx_tstamp_state {
|
|
IDPF_PTP_FREE,
|
|
IDPF_PTP_REQUEST,
|
|
IDPF_PTP_READ_VALUE,
|
|
};
|
|
|
|
/**
|
|
* struct idpf_ptp_tx_tstamp_status - Parameters to track Tx timestamp
|
|
* @skb: the pointer to the SKB that received the completion tag
|
|
* @state: the state of the Tx timestamp
|
|
*/
|
|
struct idpf_ptp_tx_tstamp_status {
|
|
struct sk_buff *skb;
|
|
enum idpf_ptp_tx_tstamp_state state;
|
|
};
|
|
|
|
/**
|
|
* struct idpf_ptp_tx_tstamp - Parameters for Tx timestamping
|
|
* @list_member: the list member structure
|
|
* @tx_latch_reg_offset_l: Tx tstamp latch low register offset
|
|
* @tx_latch_reg_offset_h: Tx tstamp latch high register offset
|
|
* @skb: the pointer to the SKB for this timestamp request
|
|
* @tstamp: the Tx tstamp value
|
|
* @idx: the index of the Tx tstamp
|
|
*/
|
|
struct idpf_ptp_tx_tstamp {
|
|
struct list_head list_member;
|
|
u32 tx_latch_reg_offset_l;
|
|
u32 tx_latch_reg_offset_h;
|
|
struct sk_buff *skb;
|
|
u64 tstamp;
|
|
u32 idx;
|
|
};
|
|
|
|
/**
|
|
* struct idpf_ptp_vport_tx_tstamp_caps - Tx timestamp capabilities
|
|
* @vport_id: the vport id
|
|
* @num_entries: the number of negotiated Tx timestamp entries
|
|
* @tstamp_ns_lo_bit: first bit for nanosecond part of the timestamp
|
|
* @latches_lock: the lock to the lists of free/used timestamp indexes
|
|
* @status_lock: the lock to the status tracker
|
|
* @access: indicates an access to Tx timestamp
|
|
* @latches_free: the list of the free Tx timestamps latches
|
|
* @latches_in_use: the list of the used Tx timestamps latches
|
|
* @tx_tstamp_status: Tx tstamp status tracker
|
|
*/
|
|
struct idpf_ptp_vport_tx_tstamp_caps {
|
|
u32 vport_id;
|
|
u16 num_entries;
|
|
u16 tstamp_ns_lo_bit;
|
|
spinlock_t latches_lock;
|
|
spinlock_t status_lock;
|
|
bool access:1;
|
|
struct list_head latches_free;
|
|
struct list_head latches_in_use;
|
|
struct idpf_ptp_tx_tstamp_status tx_tstamp_status[];
|
|
};
|
|
|
|
/**
|
|
* struct idpf_ptp - PTP parameters
|
|
* @info: structure defining PTP hardware capabilities
|
|
* @clock: pointer to registered PTP clock device
|
|
* @adapter: back pointer to the adapter
|
|
* @base_incval: base increment value of the PTP clock
|
|
* @max_adj: maximum adjustment of the PTP clock
|
|
* @cmd: HW specific command masks
|
|
* @cached_phc_time: a cached copy of the PHC time for timestamp extension
|
|
* @cached_phc_jiffies: jiffies when cached_phc_time was last updated
|
|
* @dev_clk_regs: the set of registers to access the device clock
|
|
* @caps: PTP capabilities negotiated with the Control Plane
|
|
* @get_dev_clk_time_access: access type for getting the device clock time
|
|
* @get_cross_tstamp_access: access type for the cross timestamping
|
|
* @set_dev_clk_time_access: access type for setting the device clock time
|
|
* @adj_dev_clk_time_access: access type for the adjusting the device clock
|
|
* @tx_tstamp_access: access type for the Tx timestamp value read
|
|
* @rsv: reserved bits
|
|
* @secondary_mbx: parameters for using dedicated PTP mailbox
|
|
* @read_dev_clk_lock: spinlock protecting access to the device clock read
|
|
* operation executed by the HW latch
|
|
*/
|
|
struct idpf_ptp {
|
|
struct ptp_clock_info info;
|
|
struct ptp_clock *clock;
|
|
struct idpf_adapter *adapter;
|
|
u64 base_incval;
|
|
u64 max_adj;
|
|
struct idpf_ptp_cmd cmd;
|
|
u64 cached_phc_time;
|
|
unsigned long cached_phc_jiffies;
|
|
struct idpf_ptp_dev_clk_regs dev_clk_regs;
|
|
u32 caps;
|
|
enum idpf_ptp_access get_dev_clk_time_access:2;
|
|
enum idpf_ptp_access get_cross_tstamp_access:2;
|
|
enum idpf_ptp_access set_dev_clk_time_access:2;
|
|
enum idpf_ptp_access adj_dev_clk_time_access:2;
|
|
enum idpf_ptp_access tx_tstamp_access:2;
|
|
u8 rsv;
|
|
struct idpf_ptp_secondary_mbx secondary_mbx;
|
|
spinlock_t read_dev_clk_lock;
|
|
};
|
|
|
|
/**
|
|
* idpf_ptp_info_to_adapter - get driver adapter struct from ptp_clock_info
|
|
* @info: pointer to ptp_clock_info struct
|
|
*
|
|
* Return: pointer to the corresponding adapter struct
|
|
*/
|
|
static inline struct idpf_adapter *
|
|
idpf_ptp_info_to_adapter(const struct ptp_clock_info *info)
|
|
{
|
|
const struct idpf_ptp *ptp = container_of_const(info, struct idpf_ptp,
|
|
info);
|
|
return ptp->adapter;
|
|
}
|
|
|
|
/**
|
|
* struct idpf_ptp_dev_timers - System time and device time values
|
|
* @sys_time_ns: system time value expressed in nanoseconds
|
|
* @dev_clk_time_ns: device clock time value expressed in nanoseconds
|
|
*/
|
|
struct idpf_ptp_dev_timers {
|
|
u64 sys_time_ns;
|
|
u64 dev_clk_time_ns;
|
|
};
|
|
|
|
/**
|
|
* idpf_ptp_is_vport_tx_tstamp_ena - Verify the Tx timestamping enablement for
|
|
* a given vport.
|
|
* @vport: Virtual port structure
|
|
*
|
|
* Tx timestamp capabilities are negotiated with the Control Plane only if the
|
|
* device clock value can be read, Tx timestamp access type is different than
|
|
* NONE, and the PTP clock for the adapter is created. When all those conditions
|
|
* are satisfied, Tx timestamp feature is enabled and tx_tstamp_caps is
|
|
* allocated and fulfilled.
|
|
*
|
|
* Return: true if the Tx timestamping is enabled, false otherwise.
|
|
*/
|
|
static inline bool idpf_ptp_is_vport_tx_tstamp_ena(struct idpf_vport *vport)
|
|
{
|
|
if (!vport->tx_tstamp_caps)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* idpf_ptp_is_vport_rx_tstamp_ena - Verify the Rx timestamping enablement for
|
|
* a given vport.
|
|
* @vport: Virtual port structure
|
|
*
|
|
* Rx timestamp feature is enabled if the PTP clock for the adapter is created
|
|
* and it is possible to read the value of the device clock. The second
|
|
* assumption comes from the need to extend the Rx timestamp value to 64 bit
|
|
* based on the current device clock time.
|
|
*
|
|
* Return: true if the Rx timestamping is enabled, false otherwise.
|
|
*/
|
|
static inline bool idpf_ptp_is_vport_rx_tstamp_ena(struct idpf_vport *vport)
|
|
{
|
|
if (!vport->adapter->ptp ||
|
|
vport->adapter->ptp->get_dev_clk_time_access == IDPF_PTP_NONE)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
|
|
int idpf_ptp_init(struct idpf_adapter *adapter);
|
|
void idpf_ptp_release(struct idpf_adapter *adapter);
|
|
int idpf_ptp_get_caps(struct idpf_adapter *adapter);
|
|
void idpf_ptp_get_features_access(const struct idpf_adapter *adapter);
|
|
bool idpf_ptp_get_txq_tstamp_capability(struct idpf_tx_queue *txq);
|
|
int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
|
|
struct idpf_ptp_dev_timers *dev_clk_time);
|
|
int idpf_ptp_get_cross_time(struct idpf_adapter *adapter,
|
|
struct idpf_ptp_dev_timers *cross_time);
|
|
int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter, u64 time);
|
|
int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter, u64 incval);
|
|
int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter, s64 delta);
|
|
int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport);
|
|
int idpf_ptp_get_tx_tstamp(struct idpf_vport *vport);
|
|
int idpf_ptp_set_timestamp_mode(struct idpf_vport *vport,
|
|
struct kernel_hwtstamp_config *config);
|
|
u64 idpf_ptp_extend_ts(struct idpf_vport *vport, u64 in_tstamp);
|
|
u64 idpf_ptp_tstamp_extend_32b_to_64b(u64 cached_phc_time, u32 in_timestamp);
|
|
int idpf_ptp_request_ts(struct idpf_tx_queue *tx_q, struct sk_buff *skb,
|
|
u32 *idx);
|
|
void idpf_tstamp_task(struct work_struct *work);
|
|
#else /* CONFIG_PTP_1588_CLOCK */
|
|
static inline int idpf_ptp_init(struct idpf_adapter *adapter)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void idpf_ptp_release(struct idpf_adapter *adapter) { }
|
|
|
|
static inline int idpf_ptp_get_caps(struct idpf_adapter *adapter)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline void
|
|
idpf_ptp_get_features_access(const struct idpf_adapter *adapter) { }
|
|
|
|
static inline bool
|
|
idpf_ptp_get_txq_tstamp_capability(struct idpf_tx_queue *txq)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int
|
|
idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter,
|
|
struct idpf_ptp_dev_timers *dev_clk_time)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int
|
|
idpf_ptp_get_cross_time(struct idpf_adapter *adapter,
|
|
struct idpf_ptp_dev_timers *cross_time)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter,
|
|
u64 time)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter,
|
|
u64 incval)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter,
|
|
s64 delta)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int idpf_ptp_get_tx_tstamp(struct idpf_vport *vport)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int
|
|
idpf_ptp_set_timestamp_mode(struct idpf_vport *vport,
|
|
struct kernel_hwtstamp_config *config)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline u64 idpf_ptp_extend_ts(struct idpf_vport *vport, u32 in_tstamp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline u64 idpf_ptp_tstamp_extend_32b_to_64b(u64 cached_phc_time,
|
|
u32 in_timestamp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int idpf_ptp_request_ts(struct idpf_tx_queue *tx_q,
|
|
struct sk_buff *skb, u32 *idx)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline void idpf_tstamp_task(struct work_struct *work) { }
|
|
#endif /* CONFIG_PTP_1588_CLOCK */
|
|
#endif /* _IDPF_PTP_H */
|