Commit 4fa7011d authored by David S. Miller's avatar David S. Miller

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-09-18 (ice)

This series contains updates to ice driver only.

Sergey prepends ICE_ to PTP timer commands to clearly convey namespace
of commands.

Karol adds retrying to acquire hardware semaphore for cross-timestamping
and avoids writing to timestamp registers on E822 devices. He also
renames some defines to be more clear and align with the data sheet.
Additionally, a range check is moved in order to reduce duplicated code.

Jake adds cross-timestamping support for E823 devices as well as adds
checks against netlist to aid in determining support for GNSS. He also
corrects improper pin assignment for certain E810-T devices and
refactors/cleanups PTP related code such as adding PHY model to ease checks
for different needed implementations, removing unneeded EXTTS flag, and
adding macro to check for source timer owner.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a76c22e2 89776a6a
......@@ -196,9 +196,10 @@
#define ice_pf_to_dev(pf) (&((pf)->pdev->dev))
#define ice_pf_src_tmr_owned(pf) ((pf)->hw.func_caps.ts_func_info.src_tmr_owned)
enum ice_feature {
ICE_F_DSCP,
ICE_F_PTP_EXTTS,
ICE_F_PHY_RCLK,
ICE_F_SMA_CTRL,
ICE_F_CGU,
......
......@@ -1393,6 +1393,7 @@ struct ice_aqc_link_topo_params {
#define ICE_AQC_LINK_TOPO_NODE_TYPE_ID_EEPROM 8
#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL 9
#define ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX 10
#define ICE_AQC_LINK_TOPO_NODE_TYPE_GPS 11
#define ICE_AQC_LINK_TOPO_NODE_CTX_S 4
#define ICE_AQC_LINK_TOPO_NODE_CTX_M \
(0xF << ICE_AQC_LINK_TOPO_NODE_CTX_S)
......@@ -1435,6 +1436,7 @@ struct ice_aqc_get_link_topo {
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY 0x30
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_C827 0x31
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX 0x47
#define ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS 0x48
u8 rsvd[9];
};
......
......@@ -2764,6 +2764,21 @@ bool ice_is_pf_c827(struct ice_hw *hw)
return false;
}
/**
* ice_is_gps_in_netlist
* @hw: pointer to the hw struct
*
* Check if the GPS generic device is present in the netlist
*/
bool ice_is_gps_in_netlist(struct ice_hw *hw)
{
if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
return false;
return true;
}
/**
* ice_aq_list_caps - query function/device capabilities
* @hw: pointer to the HW struct
......
......@@ -93,6 +93,7 @@ ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
struct ice_aqc_get_phy_caps_data *caps,
struct ice_sq_cd *cd);
bool ice_is_pf_c827(struct ice_hw *hw);
bool ice_is_gps_in_netlist(struct ice_hw *hw);
int
ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
u16 *node_handle);
......
......@@ -389,6 +389,9 @@ bool ice_gnss_is_gps_present(struct ice_hw *hw)
if (!hw->func_caps.ts_func_info.src_tmr_owned)
return false;
if (!ice_is_gps_in_netlist(hw))
return false;
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
if (ice_is_e810t(hw)) {
int err;
......
......@@ -3989,11 +3989,10 @@ void ice_init_feature_support(struct ice_pf *pf)
case ICE_DEV_ID_E810_XXV_QSFP:
case ICE_DEV_ID_E810_XXV_SFP:
ice_set_feature_support(pf, ICE_F_DSCP);
ice_set_feature_support(pf, ICE_F_PTP_EXTTS);
if (ice_is_phy_rclk_present(&pf->hw))
ice_set_feature_support(pf, ICE_F_PHY_RCLK);
/* If we don't own the timer - don't enable other caps */
if (!pf->hw.func_caps.ts_func_info.src_tmr_owned)
if (!ice_pf_src_tmr_owned(pf))
break;
if (ice_is_cgu_present(&pf->hw))
ice_set_feature_support(pf, ICE_F_CGU);
......
......@@ -3159,7 +3159,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
ena_mask &= ~PFINT_OICR_TSYN_EVNT_M;
if (hw->func_caps.ts_func_info.src_tmr_owned) {
if (ice_pf_src_tmr_owned(pf)) {
/* Save EVENTs from GLTSYN register */
pf->ptp.ext_ts_irq |= gltsyn_stat &
(GLTSYN_STAT_EVENT0_M |
......
......@@ -436,7 +436,7 @@ static void ice_clear_ptp_clock_index(struct ice_pf *pf)
int err;
/* Do not clear the index if we don't own the timer */
if (!hw->func_caps.ts_func_info.src_tmr_owned)
if (!ice_pf_src_tmr_owned(pf))
return;
tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
......@@ -1366,6 +1366,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
{
struct ice_ptp_port *ptp_port;
struct ice_hw *hw = &pf->hw;
if (!test_bit(ICE_FLAG_PTP, pf->flags))
return;
......@@ -1380,11 +1381,16 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
/* Update cached link status for this port immediately */
ptp_port->link_up = linkup;
/* E810 devices do not need to reconfigure the PHY */
if (ice_is_e810(&pf->hw))
switch (hw->phy_model) {
case ICE_PHY_E810:
/* Do not reconfigure E810 PHY */
return;
ice_ptp_port_phy_restart(ptp_port);
case ICE_PHY_E822:
ice_ptp_port_phy_restart(ptp_port);
return;
default:
dev_warn(ice_pf_to_dev(pf), "%s: Unknown PHY type\n", __func__);
}
}
/**
......@@ -1976,21 +1982,32 @@ ice_ptp_get_syncdevicetime(ktime_t *device,
u32 hh_lock, hh_art_ctl;
int i;
/* Get the HW lock */
hh_lock = rd32(hw, PFHH_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
#define MAX_HH_HW_LOCK_TRIES 5
#define MAX_HH_CTL_LOCK_TRIES 100
for (i = 0; i < MAX_HH_HW_LOCK_TRIES; i++) {
/* Get the HW lock */
hh_lock = rd32(hw, PFHH_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
if (hh_lock & PFHH_SEM_BUSY_M) {
usleep_range(10000, 15000);
continue;
}
break;
}
if (hh_lock & PFHH_SEM_BUSY_M) {
dev_err(ice_pf_to_dev(pf), "PTP failed to get hh lock\n");
return -EFAULT;
return -EBUSY;
}
/* Program cmd to master timer */
ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
/* Start the ART and device clock sync sequence */
hh_art_ctl = rd32(hw, GLHH_ART_CTL);
hh_art_ctl = hh_art_ctl | GLHH_ART_CTL_ACTIVE_M;
wr32(hw, GLHH_ART_CTL, hh_art_ctl);
#define MAX_HH_LOCK_TRIES 100
for (i = 0; i < MAX_HH_LOCK_TRIES; i++) {
for (i = 0; i < MAX_HH_CTL_LOCK_TRIES; i++) {
/* Wait for sync to complete */
hh_art_ctl = rd32(hw, GLHH_ART_CTL);
if (hh_art_ctl & GLHH_ART_CTL_ACTIVE_M) {
......@@ -2014,19 +2031,23 @@ ice_ptp_get_syncdevicetime(ktime_t *device,
break;
}
}
/* Clear the master timer */
ice_ptp_src_cmd(hw, ICE_PTP_NOP);
/* Release HW lock */
hh_lock = rd32(hw, PFHH_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
hh_lock = hh_lock & ~PFHH_SEM_BUSY_M;
wr32(hw, PFHH_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), hh_lock);
if (i == MAX_HH_LOCK_TRIES)
if (i == MAX_HH_CTL_LOCK_TRIES)
return -ETIMEDOUT;
return 0;
}
/**
* ice_ptp_getcrosststamp_e822 - Capture a device cross timestamp
* 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
*
......@@ -2034,14 +2055,14 @@ ice_ptp_get_syncdevicetime(ktime_t *device,
* clock. Fill the cross timestamp information and report it back to the
* caller.
*
* This is only valid for E822 devices which have support for generating the
* cross timestamp via PCIe PTM.
* 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_e822(struct ptp_clock_info *info,
ice_ptp_getcrosststamp_e82x(struct ptp_clock_info *info,
struct system_device_crosststamp *cts)
{
struct ice_pf *pf = ptp_info_to_pf(info);
......@@ -2246,18 +2267,20 @@ ice_ptp_setup_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info)
static void
ice_ptp_setup_pins_e810(struct ice_pf *pf, struct ptp_clock_info *info)
{
info->n_per_out = N_PER_OUT_E810;
if (ice_is_feature_supported(pf, ICE_F_PTP_EXTTS))
info->n_ext_ts = N_EXT_TS_E810;
if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) {
info->n_ext_ts = N_EXT_TS_E810;
info->n_per_out = N_PER_OUT_E810T;
info->n_pins = NUM_PTP_PINS_E810T;
info->verify = ice_verify_pin_e810t;
/* Complete setup of the SMA pins */
ice_ptp_setup_sma_pins_e810t(pf, info);
} else if (ice_is_e810t(&pf->hw)) {
info->n_ext_ts = N_EXT_TS_NO_SMA_E810T;
info->n_per_out = N_PER_OUT_NO_SMA_E810T;
} else {
info->n_per_out = N_PER_OUT_E810;
info->n_ext_ts = N_EXT_TS_E810;
}
}
......@@ -2275,22 +2298,22 @@ ice_ptp_setup_pins_e823(struct ice_pf *pf, struct ptp_clock_info *info)
}
/**
* ice_ptp_set_funcs_e822 - Set specialized functions for E822 support
* 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 E822 devices.
* 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 E822
* in ice_ptp_set_caps. Only add functions here which are distinct for E82x
* devices.
*/
static void
ice_ptp_set_funcs_e822(struct ice_pf *pf, struct ptp_clock_info *info)
ice_ptp_set_funcs_e82x(struct ice_pf *pf, struct ptp_clock_info *info)
{
#ifdef CONFIG_ICE_HWTS
if (boot_cpu_has(X86_FEATURE_ART) &&
boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ))
info->getcrosststamp = ice_ptp_getcrosststamp_e822;
info->getcrosststamp = ice_ptp_getcrosststamp_e82x;
#endif /* CONFIG_ICE_HWTS */
}
......@@ -2324,6 +2347,8 @@ ice_ptp_set_funcs_e810(struct ice_pf *pf, struct ptp_clock_info *info)
static void
ice_ptp_set_funcs_e823(struct ice_pf *pf, struct ptp_clock_info *info)
{
ice_ptp_set_funcs_e82x(pf, info);
info->enable = ice_ptp_gpio_enable_e823;
ice_ptp_setup_pins_e823(pf, info);
}
......@@ -2351,7 +2376,7 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
else if (ice_is_e823(&pf->hw))
ice_ptp_set_funcs_e823(pf, info);
else
ice_ptp_set_funcs_e822(pf, info);
ice_ptp_set_funcs_e82x(pf, info);
}
/**
......@@ -2474,7 +2499,7 @@ void ice_ptp_reset(struct ice_pf *pf)
if (test_bit(ICE_PFR_REQ, pf->state))
goto pfr;
if (!hw->func_caps.ts_func_info.src_tmr_owned)
if (!ice_pf_src_tmr_owned(pf))
goto reset_ts;
err = ice_ptp_init_phc(hw);
......@@ -2685,14 +2710,22 @@ static int ice_ptp_init_work(struct ice_pf *pf, struct ice_ptp *ptp)
*/
static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
{
struct ice_hw *hw = &pf->hw;
mutex_init(&ptp_port->ps_lock);
if (ice_is_e810(&pf->hw))
switch (hw->phy_model) {
case ICE_PHY_E810:
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
case ICE_PHY_E822:
kthread_init_delayed_work(&ptp_port->ov_work,
ice_ptp_wait_for_offsets);
kthread_init_delayed_work(&ptp_port->ov_work,
ice_ptp_wait_for_offsets);
return ice_ptp_init_tx_e822(pf, &ptp_port->tx, ptp_port->port_num);
return ice_ptp_init_tx_e822(pf, &ptp_port->tx,
ptp_port->port_num);
default:
return -ENODEV;
}
}
/**
......@@ -2713,10 +2746,12 @@ void ice_ptp_init(struct ice_pf *pf)
struct ice_hw *hw = &pf->hw;
int err;
ice_ptp_init_phy_model(hw);
/* If this function owns the clock hardware, it must allocate and
* configure the PTP clock device to represent it.
*/
if (hw->func_caps.ts_func_info.src_tmr_owned) {
if (ice_pf_src_tmr_owned(pf)) {
err = ice_ptp_init_owner(pf);
if (err)
goto err;
......
This diff is collapsed.
......@@ -6,11 +6,11 @@
#include <linux/dpll.h>
enum ice_ptp_tmr_cmd {
INIT_TIME,
INIT_INCVAL,
ADJ_TIME,
ADJ_TIME_AT_TIME,
READ_TIME,
ICE_PTP_INIT_TIME,
ICE_PTP_INIT_INCVAL,
ICE_PTP_ADJ_TIME,
ICE_PTP_ADJ_TIME_AT_TIME,
ICE_PTP_READ_TIME,
ICE_PTP_NOP,
};
......@@ -203,6 +203,7 @@ extern const struct ice_vernier_info_e822 e822_vernier[NUM_ICE_PTP_LNK_SPD];
u8 ice_get_ptp_src_clock_index(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);
int ice_ptp_init_time(struct ice_hw *hw, u64 time);
int ice_ptp_write_incval(struct ice_hw *hw, u64 incval);
int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval);
......@@ -284,6 +285,8 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
enum dpll_lock_status *dpll_state);
int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
void ice_ptp_init_phy_model(struct ice_hw *hw);
#define PFTSYN_SEM_BYTES 4
#define ICE_PTP_CLOCK_INDEX_0 0x00
......
......@@ -822,6 +822,13 @@ struct ice_mbx_data {
u16 async_watermark_val;
};
/* PHY model */
enum ice_phy_model {
ICE_PHY_UNSUP = -1,
ICE_PHY_E810 = 1,
ICE_PHY_E822,
};
/* Port hardware description */
struct ice_hw {
u8 __iomem *hw_addr;
......@@ -843,6 +850,7 @@ struct ice_hw {
u8 revision_id;
u8 pf_id; /* device profile info */
enum ice_phy_model phy_model;
u16 max_burst_size; /* driver sets this value */
......@@ -901,13 +909,13 @@ struct ice_hw {
/* INTRL granularity in 1 us */
u8 intrl_gran;
#define ICE_PHY_PER_NAC 1
#define ICE_MAX_QUAD 2
#define ICE_NUM_QUAD_TYPE 2
#define ICE_PORTS_PER_QUAD 4
#define ICE_PHY_0_LAST_QUAD 1
#define ICE_PORTS_PER_PHY 8
#define ICE_NUM_EXTERNAL_PORTS ICE_PORTS_PER_PHY
#define ICE_PHY_PER_NAC_E822 1
#define ICE_MAX_QUAD 2
#define ICE_QUADS_PER_PHY_E822 2
#define ICE_PORTS_PER_PHY_E822 8
#define ICE_PORTS_PER_QUAD 4
#define ICE_PORTS_PER_PHY_E810 4
#define ICE_NUM_EXTERNAL_PORTS (ICE_MAX_QUAD * ICE_PORTS_PER_QUAD)
/* Active package version (currently active) */
struct ice_pkg_ver active_pkg_ver;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment