Skip to content

Commit

Permalink
Merge branch 'intel-wired-lan-driver-updates-2024-06-25-ice'
Browse files Browse the repository at this point in the history
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2024-06-25 (ice)

This series contains updates to ice driver only.

Milena adds disabling of extts events when PTP is disabled.

Jake prevents possible NULL pointer by checking that timestamps are
ready before processing extts events and adds checks for unsupported
PTP pin configuration.

Petr Oros replaces _test_bit() with the correct test_bit() macro.
v1: https://lore.kernel.org/netdev/20240625170248.199162-1-anthony.l.nguyen@intel.com/
====================

Link: https://patch.msgid.link/20240702171459.2606611-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
kuba-moo committed Jul 4, 2024
2 parents 2a79651 + 7829ee7 commit f66738d
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 31 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/ice/ice_hwmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static bool ice_is_internal_reading_supported(struct ice_pf *pf)

unsigned long sensors = pf->hw.dev_caps.supported_sensors;

return _test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
return test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
};

void ice_hwmon_init(struct ice_pf *pf)
Expand Down
131 changes: 101 additions & 30 deletions drivers/net/ethernet/intel/ice/ice_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,10 @@ void ice_ptp_extts_event(struct ice_pf *pf)
u8 chan, tmr_idx;
u32 hi, lo;

/* Don't process timestamp events if PTP is not ready */
if (pf->ptp.state != ICE_PTP_READY)
return;

tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
/* Event time is captured by one of the two matched registers
* GLTSYN_EVNT_L: 32 LSB of sampled time event
Expand All @@ -1584,27 +1588,33 @@ void ice_ptp_extts_event(struct ice_pf *pf)
/**
* ice_ptp_cfg_extts - Configure EXTTS pin and channel
* @pf: Board private structure
* @ena: true to enable; false to disable
* @chan: GPIO channel (0-3)
* @gpio_pin: GPIO pin
* @extts_flags: request flags from the ptp_extts_request.flags
* @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, bool ena, unsigned int chan, u32 gpio_pin,
unsigned int extts_flags)
static int ice_ptp_cfg_extts(struct ice_pf *pf, unsigned int chan,
struct ice_extts_channel *config, bool store)
{
u32 func, aux_reg, gpio_reg, irq_reg;
struct ice_hw *hw = &pf->hw;
u8 tmr_idx;

if (chan > (unsigned int)pf->ptp.info.n_ext_ts)
return -EINVAL;
/* Reject requests with unsupported flags */
if (config->flags & ~(PTP_ENABLE_FEATURE |
PTP_RISING_EDGE |
PTP_FALLING_EDGE |
PTP_STRICT_FLAGS))
return -EOPNOTSUPP;

tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;

irq_reg = rd32(hw, PFINT_OICR_ENA);

if (ena) {
if (config->ena) {
/* Enable the interrupt */
irq_reg |= PFINT_OICR_TSYN_EVNT_M;
aux_reg = GLTSYN_AUX_IN_0_INT_ENA_M;
Expand All @@ -1613,9 +1623,9 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
#define GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE BIT(1)

/* set event level to requested edge */
if (extts_flags & PTP_FALLING_EDGE)
if (config->flags & PTP_FALLING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_FALLING_EDGE;
if (extts_flags & PTP_RISING_EDGE)
if (config->flags & PTP_RISING_EDGE)
aux_reg |= GLTSYN_AUX_IN_0_EVNTLVL_RISING_EDGE;

/* Write GPIO CTL reg.
Expand All @@ -1636,11 +1646,51 @@ ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,

wr32(hw, PFINT_OICR_ENA, irq_reg);
wr32(hw, GLTSYN_AUX_IN(chan, tmr_idx), aux_reg);
wr32(hw, GLGEN_GPIO_CTL(gpio_pin), gpio_reg);
wr32(hw, GLGEN_GPIO_CTL(config->gpio_pin), gpio_reg);

if (store)
memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));

return 0;
}

/**
* ice_ptp_disable_all_extts - Disable all EXTTS channels
* @pf: Board private structure
*/
static void ice_ptp_disable_all_extts(struct ice_pf *pf)
{
struct ice_extts_channel extts_cfg = {};
int i;

for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
if (pf->ptp.extts_channels[i].ena) {
extts_cfg.gpio_pin = pf->ptp.extts_channels[i].gpio_pin;
extts_cfg.ena = false;
ice_ptp_cfg_extts(pf, i, &extts_cfg, false);
}
}

synchronize_irq(pf->oicr_irq.virq);
}

/**
* 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)
{
int i;

for (i = 0; i < pf->ptp.info.n_ext_ts; i++) {
if (pf->ptp.extts_channels[i].ena)
ice_ptp_cfg_extts(pf, i, &pf->ptp.extts_channels[i],
false);
}
}

/**
* ice_ptp_cfg_clkout - Configure clock to generate periodic wave
* @pf: Board private structure
Expand All @@ -1659,6 +1709,9 @@ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan,
u32 func, val, gpio_pin;
u8 tmr_idx;

if (config && config->flags & ~PTP_PEROUT_PHASE)
return -EOPNOTSUPP;

tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;

/* 0. Reset mode & out_en in AUX_OUT */
Expand Down Expand Up @@ -1795,17 +1848,18 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
struct ptp_clock_request *rq, int on)
{
struct ice_pf *pf = ptp_info_to_pf(info);
struct ice_perout_channel clk_cfg = {0};
bool sma_pres = false;
unsigned int chan;
u32 gpio_pin;
int err;

if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL))
sma_pres = true;

switch (rq->type) {
case PTP_CLK_REQ_PEROUT:
{
struct ice_perout_channel clk_cfg = {};

chan = rq->perout.index;
if (sma_pres) {
if (chan == ice_pin_desc_e810t[SMA1].chan)
Expand All @@ -1825,15 +1879,19 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
clk_cfg.gpio_pin = chan;
}

clk_cfg.flags = rq->perout.flags;
clk_cfg.period = ((rq->perout.period.sec * NSEC_PER_SEC) +
rq->perout.period.nsec);
clk_cfg.start_time = ((rq->perout.start.sec * NSEC_PER_SEC) +
rq->perout.start.nsec);
clk_cfg.ena = !!on;

err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
break;
return ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
}
case PTP_CLK_REQ_EXTTS:
{
struct ice_extts_channel extts_cfg = {};

chan = rq->extts.index;
if (sma_pres) {
if (chan < ice_pin_desc_e810t[SMA2].chan)
Expand All @@ -1849,14 +1907,15 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
gpio_pin = chan;
}

err = ice_ptp_cfg_extts(pf, !!on, chan, gpio_pin,
rq->extts.flags);
break;
extts_cfg.flags = rq->extts.flags;
extts_cfg.gpio_pin = gpio_pin;
extts_cfg.ena = !!on;

return ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
}
default:
return -EOPNOTSUPP;
}

return err;
}

/**
Expand All @@ -1869,26 +1928,32 @@ static int ice_ptp_gpio_enable_e823(struct ptp_clock_info *info,
struct ptp_clock_request *rq, int on)
{
struct ice_pf *pf = ptp_info_to_pf(info);
struct ice_perout_channel clk_cfg = {0};
int err;

switch (rq->type) {
case PTP_CLK_REQ_PPS:
{
struct ice_perout_channel clk_cfg = {};

clk_cfg.flags = rq->perout.flags;
clk_cfg.gpio_pin = PPS_PIN_INDEX;
clk_cfg.period = NSEC_PER_SEC;
clk_cfg.ena = !!on;

err = ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
break;
return ice_ptp_cfg_clkout(pf, PPS_CLK_GEN_CHAN, &clk_cfg, true);
}
case PTP_CLK_REQ_EXTTS:
err = ice_ptp_cfg_extts(pf, !!on, rq->extts.index,
TIME_SYNC_PIN_INDEX, rq->extts.flags);
break;
{
struct ice_extts_channel extts_cfg = {};

extts_cfg.flags = rq->extts.flags;
extts_cfg.gpio_pin = TIME_SYNC_PIN_INDEX;
extts_cfg.ena = !!on;

return ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
}
default:
return -EOPNOTSUPP;
}

return err;
}

/**
Expand Down Expand Up @@ -2720,6 +2785,10 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
ice_ptp_restart_all_phy(pf);
}

/* Re-enable all periodic outputs and external timestamp events */
ice_ptp_enable_all_clkout(pf);
ice_ptp_enable_all_extts(pf);

return 0;
}

Expand Down Expand Up @@ -3275,6 +3344,8 @@ void ice_ptp_release(struct ice_pf *pf)

ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);

ice_ptp_disable_all_extts(pf);

kthread_cancel_delayed_work_sync(&pf->ptp.work);

ice_ptp_port_phy_stop(&pf->ptp.port);
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_ptp.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,17 @@ enum ice_ptp_pin_e810t {
struct ice_perout_channel {
bool ena;
u32 gpio_pin;
u32 flags;
u64 period;
u64 start_time;
};

struct ice_extts_channel {
bool ena;
u32 gpio_pin;
u32 flags;
};

/* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp
* is stored in a buffer of registers. Depending on the specific hardware,
* this buffer might be shared across multiple PHY ports.
Expand Down Expand Up @@ -226,6 +233,7 @@ enum ice_ptp_state {
* @ext_ts_irq: the external timestamp IRQ in use
* @kworker: kwork thread for handling periodic work
* @perout_channels: periodic output data
* @extts_channels: channels for external timestamps
* @info: structure defining PTP hardware capabilities
* @clock: pointer to registered PTP clock device
* @tstamp_config: hardware timestamping configuration
Expand All @@ -249,6 +257,7 @@ struct ice_ptp {
u8 ext_ts_irq;
struct kthread_worker *kworker;
struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX];
struct ice_extts_channel extts_channels[GLTSYN_TGT_H_IDX_MAX];
struct ptp_clock_info info;
struct ptp_clock *clock;
struct hwtstamp_config tstamp_config;
Expand Down

0 comments on commit f66738d

Please sign in to comment.