net/ice/base: add functions for device clock control

The ice hardware supports exposing a hardware clock for high precision
timestamping. This is primarily intended for accelerating the Precision
Time Protocol.

Add several low level functions intended to be used as the basis for
enabling the device clock, and ensuring that the port timers are
synchronized properly.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Junfeng Guo <junfeng.guo@intel.com>
This commit is contained in:
Qi Zhang 2021-08-10 10:51:14 +08:00
parent c9d0fccff0
commit 97f4f78bbd
10 changed files with 2697 additions and 1 deletions

View File

@ -3077,6 +3077,7 @@ enum ice_adminq_opc {
ice_aqc_opc_set_event_mask = 0x0613,
ice_aqc_opc_set_mac_lb = 0x0620,
ice_aqc_opc_get_link_topo = 0x06E0,
ice_aqc_opc_get_link_topo_pin = 0x06E1,
ice_aqc_opc_read_i2c = 0x06E2,
ice_aqc_opc_write_i2c = 0x06E3,
ice_aqc_opc_set_port_id_led = 0x06E9,

View File

@ -64,6 +64,28 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
return ICE_SUCCESS;
}
/**
* ice_is_generic_mac
* @hw: pointer to the hardware structure
*
* returns true if mac_type is ICE_MAC_GENERIC, false if not
*/
bool ice_is_generic_mac(struct ice_hw *hw)
{
return hw->mac_type == ICE_MAC_GENERIC;
}
/**
* ice_is_e810
* @hw: pointer to the hardware structure
*
* returns true if the device is E810 based, false if not.
*/
bool ice_is_e810(struct ice_hw *hw)
{
return hw->mac_type == ICE_MAC_E810;
}
/**
* ice_clear_pf_cfg - Clear PF configuration
* @hw: pointer to the hardware structure
@ -1350,6 +1372,127 @@ ice_clear_tx_drbell_q_ctx(struct ice_hw *hw, u32 tx_drbell_q_index)
return ICE_SUCCESS;
}
/* Sideband Queue command wrappers */
/**
* ice_get_sbq - returns the right control queue to use for sideband
* @hw: pointer to the hardware structure
*/
static struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw)
{
if (!ice_is_generic_mac(hw))
return &hw->adminq;
return &hw->sbq;
}
/**
* ice_sbq_send_cmd - send Sideband Queue command to Sideband Queue
* @hw: pointer to the HW struct
* @desc: descriptor describing the command
* @buf: buffer to use for indirect commands (NULL for direct commands)
* @buf_size: size of buffer for indirect commands (0 for direct commands)
* @cd: pointer to command details structure
*/
static enum ice_status
ice_sbq_send_cmd(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
void *buf, u16 buf_size, struct ice_sq_cd *cd)
{
return ice_sq_send_cmd(hw, ice_get_sbq(hw), (struct ice_aq_desc *)desc,
buf, buf_size, cd);
}
/**
* ice_sbq_send_cmd_nolock - send Sideband Queue command to Sideband Queue
* but do not lock sq_lock
* @hw: pointer to the HW struct
* @desc: descriptor describing the command
* @buf: buffer to use for indirect commands (NULL for direct commands)
* @buf_size: size of buffer for indirect commands (0 for direct commands)
* @cd: pointer to command details structure
*/
static enum ice_status
ice_sbq_send_cmd_nolock(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
void *buf, u16 buf_size, struct ice_sq_cd *cd)
{
return ice_sq_send_cmd_nolock(hw, ice_get_sbq(hw),
(struct ice_aq_desc *)desc, buf,
buf_size, cd);
}
/**
* ice_sbq_rw_reg_lp - Fill Sideband Queue command, with lock parameter
* @hw: pointer to the HW struct
* @in: message info to be filled in descriptor
* @lock: true to lock the sq_lock (the usual case); false if the sq_lock has
* already been locked at a higher level
*/
enum ice_status ice_sbq_rw_reg_lp(struct ice_hw *hw,
struct ice_sbq_msg_input *in, bool lock)
{
struct ice_sbq_cmd_desc desc = {0};
struct ice_sbq_msg_req msg = {0};
enum ice_status status;
u16 msg_len;
msg_len = sizeof(msg);
msg.dest_dev = in->dest_dev;
msg.opcode = in->opcode;
msg.flags = ICE_SBQ_MSG_FLAGS;
msg.sbe_fbe = ICE_SBQ_MSG_SBE_FBE;
msg.msg_addr_low = CPU_TO_LE16(in->msg_addr_low);
msg.msg_addr_high = CPU_TO_LE32(in->msg_addr_high);
if (in->opcode)
msg.data = CPU_TO_LE32(in->data);
else
/* data read comes back in completion, so shorten the struct by
* sizeof(msg.data)
*/
msg_len -= sizeof(msg.data);
desc.flags = CPU_TO_LE16(ICE_AQ_FLAG_RD);
desc.opcode = CPU_TO_LE16(ice_sbq_opc_neigh_dev_req);
desc.param0.cmd_len = CPU_TO_LE16(msg_len);
if (lock)
status = ice_sbq_send_cmd(hw, &desc, &msg, msg_len, NULL);
else
status = ice_sbq_send_cmd_nolock(hw, &desc, &msg, msg_len,
NULL);
if (!status && !in->opcode)
in->data = LE32_TO_CPU
(((struct ice_sbq_msg_cmpl *)&msg)->data);
return status;
}
/**
* ice_sbq_rw_reg - Fill Sideband Queue command
* @hw: pointer to the HW struct
* @in: message info to be filled in descriptor
*/
enum ice_status ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in)
{
return ice_sbq_rw_reg_lp(hw, in, true);
}
/**
* ice_sbq_lock - Lock the sideband queue's sq_lock
* @hw: pointer to the HW struct
*/
void ice_sbq_lock(struct ice_hw *hw)
{
ice_acquire_lock(&ice_get_sbq(hw)->sq_lock);
}
/**
* ice_sbq_unlock - Unlock the sideband queue's sq_lock
* @hw: pointer to the HW struct
*/
void ice_sbq_unlock(struct ice_hw *hw)
{
ice_release_lock(&ice_get_sbq(hw)->sq_lock);
}
/* FW Admin Queue command wrappers */
/**

View File

@ -51,6 +51,10 @@ ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size,
enum ice_adminq_opc opc, struct ice_sq_cd *cd);
enum ice_status
ice_sq_send_cmd_nolock(struct ice_hw *hw, struct ice_ctl_q_info *cq,
struct ice_aq_desc *desc, void *buf, u16 buf_size,
struct ice_sq_cd *cd);
enum ice_status
ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,
struct ice_aq_desc *desc, void *buf, u16 buf_size,
struct ice_sq_cd *cd);
@ -215,6 +219,11 @@ enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
void ice_replay_post(struct ice_hw *hw);
struct ice_q_ctx *
ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
enum ice_status ice_sbq_rw_reg_lp(struct ice_hw *hw,
struct ice_sbq_msg_input *in, bool lock);
void ice_sbq_lock(struct ice_hw *hw);
void ice_sbq_unlock(struct ice_hw *hw);
enum ice_status ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in);
void
ice_stat_update40(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
u64 *prev_stat, u64 *cur_stat);
@ -226,6 +235,8 @@ ice_stat_update_repc(struct ice_hw *hw, u16 vsi_handle, bool prev_stat_loaded,
struct ice_eth_stats *cur_stats);
enum ice_fw_modes ice_get_fw_mode(struct ice_hw *hw);
void ice_print_rollback_msg(struct ice_hw *hw);
bool ice_is_generic_mac(struct ice_hw *hw);
bool ice_is_e810(struct ice_hw *hw);
enum ice_status
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
struct ice_aqc_txsched_elem_data *buf);

View File

@ -54,6 +54,21 @@ static void ice_mailbox_init_regs(struct ice_hw *hw)
ICE_CQ_INIT_REGS(cq, PF_MBX);
}
/**
* ice_sb_init_regs - Initialize Sideband registers
* @hw: pointer to the hardware structure
*
* This assumes the alloc_sq and alloc_rq functions have already been called
*/
static void ice_sb_init_regs(struct ice_hw *hw)
{
struct ice_ctl_q_info *cq = &hw->sbq;
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
ICE_CQ_INIT_REGS(cq, PF_SB);
}
/**
* ice_check_sq_alive
* @hw: pointer to the HW struct
@ -584,6 +599,10 @@ static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
ice_adminq_init_regs(hw);
cq = &hw->adminq;
break;
case ICE_CTL_Q_SB:
ice_sb_init_regs(hw);
cq = &hw->sbq;
break;
case ICE_CTL_Q_MAILBOX:
ice_mailbox_init_regs(hw);
cq = &hw->mailboxq;
@ -620,6 +639,18 @@ static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
return ret_code;
}
/**
* ice_is_sbq_supported - is the sideband queue supported
* @hw: pointer to the hardware structure
*
* Returns true if the sideband control queue interface is
* supported for the device, false otherwise
*/
static bool ice_is_sbq_supported(struct ice_hw *hw)
{
return ice_is_generic_mac(hw);
}
/**
* ice_shutdown_ctrlq - shutdown routine for any control queue
* @hw: pointer to the hardware structure
@ -639,6 +670,9 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
if (ice_check_sq_alive(hw, cq))
ice_aq_q_shutdown(hw, true);
break;
case ICE_CTL_Q_SB:
cq = &hw->sbq;
break;
case ICE_CTL_Q_MAILBOX:
cq = &hw->mailboxq;
break;
@ -663,6 +697,9 @@ void ice_shutdown_all_ctrlq(struct ice_hw *hw)
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
/* Shutdown FW admin queue */
ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
/* Shutdown PHY Sideband */
if (ice_is_sbq_supported(hw))
ice_shutdown_ctrlq(hw, ICE_CTL_Q_SB);
/* Shutdown PF-VF Mailbox */
ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}
@ -704,6 +741,15 @@ enum ice_status ice_init_all_ctrlq(struct ice_hw *hw)
if (status)
return status;
/* sideband control queue (SBQ) interface is not supported on some
* devices. Initialize if supported, else fallback to the admin queue
* interface
*/
if (ice_is_sbq_supported(hw)) {
status = ice_init_ctrlq(hw, ICE_CTL_Q_SB);
if (status)
return status;
}
/* Init Mailbox queue */
return ice_init_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}
@ -739,6 +785,8 @@ static void ice_init_ctrlq_locks(struct ice_ctl_q_info *cq)
enum ice_status ice_create_all_ctrlq(struct ice_hw *hw)
{
ice_init_ctrlq_locks(&hw->adminq);
if (ice_is_sbq_supported(hw))
ice_init_ctrlq_locks(&hw->sbq);
ice_init_ctrlq_locks(&hw->mailboxq);
return ice_init_all_ctrlq(hw);
@ -771,6 +819,8 @@ void ice_destroy_all_ctrlq(struct ice_hw *hw)
ice_shutdown_all_ctrlq(hw);
ice_destroy_ctrlq_locks(&hw->adminq);
if (ice_is_sbq_supported(hw))
ice_destroy_ctrlq_locks(&hw->sbq);
ice_destroy_ctrlq_locks(&hw->mailboxq);
}
@ -882,7 +932,7 @@ static bool ice_sq_done(struct ice_hw *hw, struct ice_ctl_q_info *cq)
* This is the main send command routine for the ATQ. It runs the queue,
* cleans the queue, etc.
*/
static enum ice_status
enum ice_status
ice_sq_send_cmd_nolock(struct ice_hw *hw, struct ice_ctl_q_info *cq,
struct ice_aq_desc *desc, void *buf, u16 buf_size,
struct ice_sq_cd *cd)

View File

@ -10,6 +10,7 @@
/* Maximum buffer lengths for all control queue types */
#define ICE_AQ_MAX_BUF_LEN 4096
#define ICE_MBXQ_MAX_BUF_LEN 4096
#define ICE_SBQ_MAX_BUF_LEN 512
#define ICE_CTL_Q_DESC(R, i) \
(&(((struct ice_aq_desc *)((R).desc_buf.va))[i]))
@ -30,6 +31,7 @@ enum ice_ctl_q {
ICE_CTL_Q_UNKNOWN = 0,
ICE_CTL_Q_ADMIN,
ICE_CTL_Q_MAILBOX,
ICE_CTL_Q_SB,
};
/* Control Queue timeout settings - max delay 1s */

View File

@ -0,0 +1,86 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2001-2021 Intel Corporation
*/
#ifndef _ICE_PTP_CONSTS_H_
#define _ICE_PTP_CONSTS_H_
/* Constant definitions related to the hardware clock used for PTP 1588
* features and functionality.
*/
/* Constants defined for the PTP 1588 clock hardware. */
/*
* struct ice_time_ref_info_e822
*
* E822 hardware can use different sources as the reference for the PTP
* hardware clock. Each clock has different characteristics such as a slightly
* different frequency, etc.
*
* This lookup table defines several constants that depend on the current time
* reference. See the struct ice_time_ref_info_e822 for information about the
* meaning of each constant.
*/
const struct ice_time_ref_info_e822 e822_time_ref[NUM_ICE_TIME_REF_FREQ] = {
/* ICE_TIME_REF_FREQ_25_000 -> 25 MHz */
{
/* pll_freq */
823437500, /* 823.4375 MHz PLL */
/* nominal_incval */
0x136e44fabULL,
/* pps_delay */
11,
},
/* ICE_TIME_REF_FREQ_122_880 -> 122.88 MHz */
{
/* pll_freq */
783360000, /* 783.36 MHz */
/* nominal_incval */
0x146cc2177ULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_125_000 -> 125 MHz */
{
/* pll_freq */
796875000, /* 796.875 MHz */
/* nominal_incval */
0x141414141ULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_153_600 -> 153.6 MHz */
{
/* pll_freq */
816000000, /* 816 MHz */
/* nominal_incval */
0x139b9b9baULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_156_250 -> 156.25 MHz */
{
/* pll_freq */
830078125, /* 830.78125 MHz */
/* nominal_incval */
0x134679aceULL,
/* pps_delay */
11,
},
/* ICE_TIME_REF_FREQ_245_760 -> 245.76 MHz */
{
/* pll_freq */
783360000, /* 783.36 MHz */
/* nominal_incval */
0x146cc2177ULL,
/* pps_delay */
12,
},
};
#endif /* _ICE_PTP_CONSTS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,376 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2001-2021 Intel Corporation
*/
#ifndef _ICE_PTP_HW_H_
#define _ICE_PTP_HW_H_
enum ice_ptp_tmr_cmd {
INIT_TIME,
INIT_INCVAL,
ADJ_TIME,
ADJ_TIME_AT_TIME,
READ_TIME
};
enum ice_ptp_serdes {
ICE_PTP_SERDES_1G,
ICE_PTP_SERDES_10G,
ICE_PTP_SERDES_25G,
ICE_PTP_SERDES_40G,
ICE_PTP_SERDES_50G,
ICE_PTP_SERDES_100G
};
enum ice_ptp_link_spd {
ICE_PTP_LNK_SPD_1G,
ICE_PTP_LNK_SPD_10G,
ICE_PTP_LNK_SPD_25G,
ICE_PTP_LNK_SPD_25G_RS,
ICE_PTP_LNK_SPD_40G,
ICE_PTP_LNK_SPD_50G,
ICE_PTP_LNK_SPD_50G_RS,
ICE_PTP_LNK_SPD_100G_RS,
NUM_ICE_PTP_LNK_SPD /* Must be last */
};
enum ice_ptp_fec_mode {
ICE_PTP_FEC_MODE_NONE,
ICE_PTP_FEC_MODE_CLAUSE74,
ICE_PTP_FEC_MODE_RS_FEC
};
/**
* struct ice_time_ref_info_e822
* @pll_freq: Frequency of PLL that drives timer ticks in Hz
* @nominal_incval: increment to generate nanoseconds in GLTSYN_TIME_L
* @pps_delay: propagation delay of the PPS output signal
*
* Characteristic information for the various TIME_REF sources possible in the
* E822 devices
*/
struct ice_time_ref_info_e822 {
u64 pll_freq;
u64 nominal_incval;
u8 pps_delay;
};
/* Table of constants related to possible TIME_REF sources */
extern const struct ice_time_ref_info_e822 e822_time_ref[NUM_ICE_TIME_REF_FREQ];
/* Increment value to generate nanoseconds in the GLTSYN_TIME_L register for
* the E810 devices. Based off of a PLL with an 812.5 MHz frequency.
*/
#define ICE_PTP_NOMINAL_INCVAL_E810 0x13b13b13bULL
/* Device agnostic functions */
u8 ice_get_ptp_src_clock_index(struct ice_hw *hw);
u64 ice_ptp_read_src_incval(struct ice_hw *hw);
bool ice_ptp_lock(struct ice_hw *hw);
void ice_ptp_unlock(struct ice_hw *hw);
void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd);
enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time);
enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval);
enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval);
enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq);
enum ice_status
ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj);
enum ice_status
ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
enum ice_status
ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx);
/* E822 family functions */
enum ice_status
ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val);
enum ice_status
ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val);
enum ice_status
ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val);
enum ice_status
ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val);
enum ice_status
ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
bool lock_sbq);
enum ice_status
ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval);
enum ice_status
ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts);
enum ice_status
ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
bool lock_sbq);
static inline u64 ice_e822_pll_freq(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].pll_freq;
}
static inline u64 ice_e822_nominal_incval(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].nominal_incval;
}
static inline u64 ice_e822_pps_delay(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].pps_delay;
}
/* E822 Vernier calibration functions */
enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw);
enum ice_status
ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
enum ice_ptp_link_spd *link_out,
enum ice_ptp_fec_mode *fec_out);
void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port);
/* E810 family functions */
enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw);
#define PFTSYN_SEM_BYTES 4
#define ICE_PTP_CLOCK_INDEX_0 0x00
#define ICE_PTP_CLOCK_INDEX_1 0x01
/* PHY timer commands */
#define SEL_CPK_SRC 8
#define SEL_PHY_SRC 3
/* Time Sync command Definitions */
#define GLTSYN_CMD_INIT_TIME BIT(0)
#define GLTSYN_CMD_INIT_INCVAL BIT(1)
#define GLTSYN_CMD_INIT_TIME_INCVAL (BIT(0) | BIT(1))
#define GLTSYN_CMD_ADJ_TIME BIT(2)
#define GLTSYN_CMD_ADJ_INIT_TIME (BIT(2) | BIT(3))
#define GLTSYN_CMD_READ_TIME BIT(7)
/* PHY port Time Sync command definitions */
#define PHY_CMD_INIT_TIME BIT(0)
#define PHY_CMD_INIT_INCVAL BIT(1)
#define PHY_CMD_ADJ_TIME (BIT(0) | BIT(1))
#define PHY_CMD_ADJ_TIME_AT_TIME (BIT(0) | BIT(2))
#define PHY_CMD_READ_TIME (BIT(0) | BIT(1) | BIT(2))
#define TS_CMD_MASK_E810 0xFF
#define TS_CMD_MASK 0xF
#define SYNC_EXEC_CMD 0x3
/* Macros to derive port low and high addresses on both quads */
#define P_Q0_L(a, p) ((((a) + (0x2000 * (p)))) & 0xFFFF)
#define P_Q0_H(a, p) ((((a) + (0x2000 * (p)))) >> 16)
#define P_Q1_L(a, p) ((((a) - (0x2000 * ((p) - ICE_PORTS_PER_QUAD)))) & 0xFFFF)
#define P_Q1_H(a, p) ((((a) - (0x2000 * ((p) - ICE_PORTS_PER_QUAD)))) >> 16)
/* PHY QUAD register base addresses */
#define Q_0_BASE 0x94000
#define Q_1_BASE 0x114000
/* Timestamp memory reset registers */
#define Q_REG_TS_CTRL 0x618
#define Q_REG_TS_CTRL_S 0
#define Q_REG_TS_CTRL_M BIT(0)
/* Timestamp availability status registers */
#define Q_REG_TX_MEMORY_STATUS_L 0xCF0
#define Q_REG_TX_MEMORY_STATUS_U 0xCF4
/* Tx FIFO status registers */
#define Q_REG_FIFO23_STATUS 0xCF8
#define Q_REG_FIFO01_STATUS 0xCFC
#define Q_REG_FIFO02_S 0
#define Q_REG_FIFO02_M MAKEMASK(0x3FF, 0)
#define Q_REG_FIFO13_S 10
#define Q_REG_FIFO13_M MAKEMASK(0x3FF, 10)
/* Interrupt control Config registers */
#define Q_REG_TX_MEM_GBL_CFG 0xC08
#define Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_S 0
#define Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M BIT(0)
#define Q_REG_TX_MEM_GBL_CFG_TX_TYPE_S 1
#define Q_REG_TX_MEM_GBL_CFG_TX_TYPE_M MAKEMASK(0xFF, 1)
#define Q_REG_TX_MEM_GBL_CFG_INTR_THR_S 9
#define Q_REG_TX_MEM_GBL_CFG_INTR_THR_M MAKEMASK(0x3F, 9)
#define Q_REG_TX_MEM_GBL_CFG_INTR_ENA_S 15
#define Q_REG_TX_MEM_GBL_CFG_INTR_ENA_M BIT(15)
/* Tx Timestamp data registers */
#define Q_REG_TX_MEMORY_BANK_START 0xA00
/* PHY port register base addresses */
#define P_0_BASE 0x80000
#define P_4_BASE 0x106000
/* Timestamp init registers */
#define P_REG_RX_TIMER_INC_PRE_L 0x46C
#define P_REG_RX_TIMER_INC_PRE_U 0x470
#define P_REG_TX_TIMER_INC_PRE_L 0x44C
#define P_REG_TX_TIMER_INC_PRE_U 0x450
/* Timestamp match and adjust target registers */
#define P_REG_RX_TIMER_CNT_ADJ_L 0x474
#define P_REG_RX_TIMER_CNT_ADJ_U 0x478
#define P_REG_TX_TIMER_CNT_ADJ_L 0x454
#define P_REG_TX_TIMER_CNT_ADJ_U 0x458
/* Timestamp capture registers */
#define P_REG_RX_CAPTURE_L 0x4D8
#define P_REG_RX_CAPTURE_U 0x4DC
#define P_REG_TX_CAPTURE_L 0x4B4
#define P_REG_TX_CAPTURE_U 0x4B8
/* Timestamp PHY incval registers */
#define P_REG_TIMETUS_L 0x410
#define P_REG_TIMETUS_U 0x414
#define P_REG_40B_LOW_M 0xFF
#define P_REG_40B_HIGH_S 8
/* PHY window length registers */
#define P_REG_WL 0x40C
#define PTP_VERNIER_WL 0x111ed
/* PHY start registers */
#define P_REG_PS 0x408
#define P_REG_PS_START_S 0
#define P_REG_PS_START_M BIT(0)
#define P_REG_PS_BYPASS_MODE_S 1
#define P_REG_PS_BYPASS_MODE_M BIT(1)
#define P_REG_PS_ENA_CLK_S 2
#define P_REG_PS_ENA_CLK_M BIT(2)
#define P_REG_PS_LOAD_OFFSET_S 3
#define P_REG_PS_LOAD_OFFSET_M BIT(3)
#define P_REG_PS_SFT_RESET_S 11
#define P_REG_PS_SFT_RESET_M BIT(11)
/* PHY offset valid registers */
#define P_REG_TX_OV_STATUS 0x4D4
#define P_REG_TX_OV_STATUS_OV_S 0
#define P_REG_TX_OV_STATUS_OV_M BIT(0)
#define P_REG_RX_OV_STATUS 0x4F8
#define P_REG_RX_OV_STATUS_OV_S 0
#define P_REG_RX_OV_STATUS_OV_M BIT(0)
/* PHY offset ready registers */
#define P_REG_TX_OR 0x45C
#define P_REG_RX_OR 0x47C
/* PHY total offset registers */
#define P_REG_TOTAL_RX_OFFSET_L 0x460
#define P_REG_TOTAL_RX_OFFSET_U 0x464
#define P_REG_TOTAL_TX_OFFSET_L 0x440
#define P_REG_TOTAL_TX_OFFSET_U 0x444
/* Timestamp PAR/PCS registers */
#define P_REG_UIX66_10G_40G_L 0x480
#define P_REG_UIX66_10G_40G_U 0x484
#define P_REG_UIX66_25G_100G_L 0x488
#define P_REG_UIX66_25G_100G_U 0x48C
#define P_REG_DESK_PAR_RX_TUS_L 0x490
#define P_REG_DESK_PAR_RX_TUS_U 0x494
#define P_REG_DESK_PAR_TX_TUS_L 0x498
#define P_REG_DESK_PAR_TX_TUS_U 0x49C
#define P_REG_DESK_PCS_RX_TUS_L 0x4A0
#define P_REG_DESK_PCS_RX_TUS_U 0x4A4
#define P_REG_DESK_PCS_TX_TUS_L 0x4A8
#define P_REG_DESK_PCS_TX_TUS_U 0x4AC
#define P_REG_PAR_RX_TUS_L 0x420
#define P_REG_PAR_RX_TUS_U 0x424
#define P_REG_PAR_TX_TUS_L 0x428
#define P_REG_PAR_TX_TUS_U 0x42C
#define P_REG_PCS_RX_TUS_L 0x430
#define P_REG_PCS_RX_TUS_U 0x434
#define P_REG_PCS_TX_TUS_L 0x438
#define P_REG_PCS_TX_TUS_U 0x43C
#define P_REG_PAR_RX_TIME_L 0x4F0
#define P_REG_PAR_RX_TIME_U 0x4F4
#define P_REG_PAR_TX_TIME_L 0x4CC
#define P_REG_PAR_TX_TIME_U 0x4D0
#define P_REG_PAR_PCS_RX_OFFSET_L 0x4E8
#define P_REG_PAR_PCS_RX_OFFSET_U 0x4EC
#define P_REG_PAR_PCS_TX_OFFSET_L 0x4C4
#define P_REG_PAR_PCS_TX_OFFSET_U 0x4C8
#define P_REG_LINK_SPEED 0x4FC
#define P_REG_LINK_SPEED_SERDES_S 0
#define P_REG_LINK_SPEED_SERDES_M MAKEMASK(0x7, 0)
#define P_REG_LINK_SPEED_FEC_MODE_S 3
#define P_REG_LINK_SPEED_FEC_MODE_M MAKEMASK(0x3, 3)
#define P_REG_LINK_SPEED_FEC_MODE(reg) \
(((reg) & P_REG_LINK_SPEED_FEC_MODE_M) >> \
P_REG_LINK_SPEED_FEC_MODE_S)
/* PHY timestamp related registers */
#define P_REG_PMD_ALIGNMENT 0x0FC
#define P_REG_RX_80_TO_160_CNT 0x6FC
#define P_REG_RX_80_TO_160_CNT_RXCYC_S 0
#define P_REG_RX_80_TO_160_CNT_RXCYC_M BIT(0)
#define P_REG_RX_40_TO_160_CNT 0x8FC
#define P_REG_RX_40_TO_160_CNT_RXCYC_S 0
#define P_REG_RX_40_TO_160_CNT_RXCYC_M MAKEMASK(0x3, 0)
/* Rx FIFO status registers */
#define P_REG_RX_OV_FS 0x4F8
#define P_REG_RX_OV_FS_FIFO_STATUS_S 2
#define P_REG_RX_OV_FS_FIFO_STATUS_M MAKEMASK(0x3FF, 2)
/* Timestamp command registers */
#define P_REG_TX_TMR_CMD 0x448
#define P_REG_RX_TMR_CMD 0x468
/* E810 timesync enable register */
#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4))
/* E810 shadow init time registers */
#define ETH_GLTSYN_SHTIME_0(i) (0x03000368 + ((i) * 32))
#define ETH_GLTSYN_SHTIME_L(i) (0x0300036C + ((i) * 32))
/* E810 shadow time adjust registers */
#define ETH_GLTSYN_SHADJ_L(_i) (0x03000378 + ((_i) * 32))
#define ETH_GLTSYN_SHADJ_H(_i) (0x0300037C + ((_i) * 32))
/* E810 timer command register */
#define ETH_GLTSYN_CMD 0x03000344
/* Source timer incval macros */
#define INCVAL_HIGH_M 0xFF
/* Timestamp block macros */
#define TS_LOW_M 0xFFFFFFFF
#define TS_HIGH_M 0xFF
#define TS_HIGH_S 32
#define TS_PHY_LOW_M 0xFF
#define TS_PHY_HIGH_M 0xFFFFFFFF
#define TS_PHY_HIGH_S 8
#define BYTES_PER_IDX_ADDR_L_U 8
#define BYTES_PER_IDX_ADDR_L 4
/* Internal PHY timestamp address */
#define TS_L(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U))
#define TS_H(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U + \
BYTES_PER_IDX_ADDR_L))
/* External PHY timestamp address */
#define TS_EXT(a, port, idx) ((a) + (0x1000 * (port)) + \
((idx) * BYTES_PER_IDX_ADDR_L_U))
#define LOW_TX_MEMORY_BANK_START 0x03090000
#define HIGH_TX_MEMORY_BANK_START 0x03090004
/* E810T PCA9575 IO controller registers */
#define ICE_PCA9575_P0_IN 0x0
#define ICE_PCA9575_P1_IN 0x1
#define ICE_PCA9575_P0_CFG 0x8
#define ICE_PCA9575_P1_CFG 0x9
#define ICE_PCA9575_P0_OUT 0xA
#define ICE_PCA9575_P1_OUT 0xB
/* E810T PCA9575 IO controller pin control */
#define ICE_E810T_P0_GNSS_PRSNT_N BIT(4)
#define ICE_E810T_P1_SMA1_DIR_EN BIT(4)
#define ICE_E810T_P1_SMA1_TX_EN BIT(5)
#define ICE_E810T_P1_SMA2_UFL2_RX_DIS BIT(3)
#define ICE_E810T_P1_SMA2_DIR_EN BIT(6)
#define ICE_E810T_P1_SMA2_TX_EN BIT(7)
#endif /* _ICE_PTP_HW_H_ */

View File

@ -55,6 +55,7 @@
#include "ice_lan_tx_rx.h"
#include "ice_flex_type.h"
#include "ice_protocol_type.h"
#include "ice_sbq_cmd.h"
#include "ice_vlan_mode.h"
/**
@ -131,6 +132,7 @@ static inline u32 ice_round_to_num(u32 N, u32 R)
#define ICE_DBG_PKG BIT_ULL(16)
#define ICE_DBG_RES BIT_ULL(17)
#define ICE_DBG_ACL BIT_ULL(18)
#define ICE_DBG_PTP BIT_ULL(19)
#define ICE_DBG_AQ_MSG BIT_ULL(24)
#define ICE_DBG_AQ_DESC BIT_ULL(25)
#define ICE_DBG_AQ_DESC_BUF BIT_ULL(26)
@ -1016,6 +1018,7 @@ struct ice_hw {
/* Control Queue info */
struct ice_ctl_q_info adminq;
struct ice_ctl_q_info sbq;
struct ice_ctl_q_info mailboxq;
/* Additional function to send AdminQ command */
int (*aq_send_cmd_fn)(void *param, struct ice_aq_desc *desc,

View File

@ -14,6 +14,7 @@ sources = [
'ice_acl.c',
'ice_acl_ctrl.c',
'ice_vlan_mode.c',
'ice_ptp_hw.c',
]
error_cflags = [