Skip to content

Commit

Permalink
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Sep 20, 2023
2 parents a76c22e + 89776a6 commit 4fa7011
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 151 deletions.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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];
};

Expand Down
15 changes: 15 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/intel/ice/ice_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
101 changes: 68 additions & 33 deletions drivers/net/ethernet/intel/ice/ice_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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__);
}
}

/**
Expand Down Expand Up @@ -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) {
Expand All @@ -2014,34 +2031,38 @@ 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
*
* 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 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);
Expand Down Expand Up @@ -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;
}
}

Expand All @@ -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 */
}

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}

/**
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 4fa7011

Please sign in to comment.