Commit 236f3873 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:

====================
ice: add PTP auxiliary bus support

Michal Michalik says:

Auxiliary bus allows exchanging information between PFs, which allows
both fixing problems and simplifying new features implementation.
The auxiliary bus is enabled for all devices supported by ice driver.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7c7dd1d6 170911bb
......@@ -673,6 +673,18 @@ static inline bool ice_vector_ch_enabled(struct ice_q_vector *qv)
return !!qv->ch; /* Enable it to run with TC */
}
/**
* ice_ptp_pf_handles_tx_interrupt - Check if PF handles Tx interrupt
* @pf: Board private structure
*
* Return true if this PF should respond to the Tx timestamp interrupt
* indication in the miscellaneous OICR interrupt handler.
*/
static inline bool ice_ptp_pf_handles_tx_interrupt(struct ice_pf *pf)
{
return pf->ptp.tx_interrupt_mode != ICE_PTP_TX_INTERRUPT_NONE;
}
/**
* ice_irq_dynamic_ena - Enable default interrupt generation settings
* @hw: pointer to HW struct
......
......@@ -2358,16 +2358,6 @@ struct ice_aqc_driver_shared_params {
__le32 addr_low;
};
enum ice_aqc_driver_params {
/* OS clock index for PTP timer Domain 0 */
ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0 = 0,
/* OS clock index for PTP timer Domain 1 */
ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1,
/* Add new parameters above */
ICE_AQC_DRIVER_PARAM_MAX = 16,
};
/* Lan Queue Overflow Event (direct, 0x1001) */
struct ice_aqc_event_lan_overflow {
__le32 prtdcb_ruptq;
......
......@@ -5720,81 +5720,6 @@ ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
/**
* ice_aq_set_driver_param - Set driver parameter to share via firmware
* @hw: pointer to the HW struct
* @idx: parameter index to set
* @value: the value to set the parameter to
* @cd: pointer to command details structure or NULL
*
* Set the value of one of the software defined parameters. All PFs connected
* to this device can read the value using ice_aq_get_driver_param.
*
* Note that firmware provides no synchronization or locking, and will not
* save the parameter value during a device reset. It is expected that
* a single PF will write the parameter value, while all other PFs will only
* read it.
*/
int
ice_aq_set_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
u32 value, struct ice_sq_cd *cd)
{
struct ice_aqc_driver_shared_params *cmd;
struct ice_aq_desc desc;
if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
return -EIO;
cmd = &desc.params.drv_shared_params;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_SET;
cmd->param_indx = idx;
cmd->param_val = cpu_to_le32(value);
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
/**
* ice_aq_get_driver_param - Get driver parameter shared via firmware
* @hw: pointer to the HW struct
* @idx: parameter index to set
* @value: storage to return the shared parameter
* @cd: pointer to command details structure or NULL
*
* Get the value of one of the software defined parameters.
*
* Note that firmware provides no synchronization or locking. It is expected
* that only a single PF will write a given parameter.
*/
int
ice_aq_get_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
u32 *value, struct ice_sq_cd *cd)
{
struct ice_aqc_driver_shared_params *cmd;
struct ice_aq_desc desc;
int status;
if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
return -EIO;
cmd = &desc.params.drv_shared_params;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_GET;
cmd->param_indx = idx;
status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
if (status)
return status;
*value = le32_to_cpu(cmd->param_val);
return 0;
}
/**
* ice_aq_set_gpio
* @hw: pointer to the hw struct
......
......@@ -253,12 +253,6 @@ int
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
struct ice_aqc_txsched_elem_data *buf);
int
ice_aq_set_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
u32 value, struct ice_sq_cd *cd);
int
ice_aq_get_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
u32 *value, struct ice_sq_cd *cd);
int
ice_aq_set_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, bool value,
struct ice_sq_cd *cd);
int
......
......@@ -3285,7 +3285,7 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;
info->phc_index = ice_get_ptp_clock_index(pf);
info->phc_index = ice_ptp_clock_index(pf);
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
......
......@@ -231,6 +231,7 @@
#define PFINT_SB_CTL 0x0016B600
#define PFINT_SB_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
#define PFINT_SB_CTL_CAUSE_ENA_M BIT(30)
#define PFINT_TSYN_MSK 0x0016C980
#define QINT_RQCTL(_QRX) (0x00150000 + ((_QRX) * 4))
#define QINT_RQCTL_MSIX_INDX_S 0
#define QINT_RQCTL_MSIX_INDX_M ICE_M(0x7FF, 0)
......
......@@ -3149,7 +3149,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
if (oicr & PFINT_OICR_TSYN_TX_M) {
ena_mask &= ~PFINT_OICR_TSYN_TX_M;
if (!hw->reset_ongoing)
if (!hw->reset_ongoing && ice_ptp_pf_handles_tx_interrupt(pf))
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
}
......@@ -7375,8 +7375,13 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
}
/* configure PTP timestamping after VSI rebuild */
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
ice_ptp_cfg_timestamp(pf, false);
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
ice_ptp_cfg_timestamp(pf, false);
else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL)
/* for E82x PHC owner always need to have interrupts */
ice_ptp_cfg_timestamp(pf, true);
}
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
if (err) {
......
This diff is collapsed.
......@@ -157,7 +157,9 @@ struct ice_ptp_tx {
* ready for PTP functionality. It is used to track the port initialization
* and determine when the port's PHY offset is valid.
*
* @list_member: list member structure of auxiliary device
* @tx: Tx timestamp tracking for this port
* @aux_dev: auxiliary device associated with this port
* @ov_work: delayed work task for tracking when PHY offset is valid
* @ps_lock: mutex used to protect the overall PTP PHY start procedure
* @link_up: indicates whether the link is up
......@@ -165,7 +167,9 @@ struct ice_ptp_tx {
* @port_num: the port number this structure represents
*/
struct ice_ptp_port {
struct list_head list_member;
struct ice_ptp_tx tx;
struct auxiliary_device aux_dev;
struct kthread_delayed_work ov_work;
struct mutex ps_lock; /* protects overall PTP PHY start procedure */
bool link_up;
......@@ -173,11 +177,35 @@ struct ice_ptp_port {
u8 port_num;
};
enum ice_ptp_tx_interrupt {
ICE_PTP_TX_INTERRUPT_NONE = 0,
ICE_PTP_TX_INTERRUPT_SELF,
ICE_PTP_TX_INTERRUPT_ALL,
};
/**
* struct ice_ptp_port_owner - data used to handle the PTP clock owner info
*
* This structure contains data necessary for the PTP clock owner to correctly
* handle the timestamping feature for all attached ports.
*
* @aux_driver: the structure carring the auxiliary driver information
* @ports: list of porst handled by this port owner
* @lock: protect access to ports list
*/
struct ice_ptp_port_owner {
struct auxiliary_driver aux_driver;
struct list_head ports;
struct mutex lock;
};
#define GLTSYN_TGT_H_IDX_MAX 4
/**
* struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
* @tx_interrupt_mode: the TX interrupt mode for the PTP clock
* @port: data for the PHY port initialization procedure
* @ports_owner: data for the auxiliary driver owner
* @work: delayed work function for periodic tasks
* @cached_phc_time: a cached copy of the PHC time for timestamp extension
* @cached_phc_jiffies: jiffies when cached_phc_time was last updated
......@@ -197,7 +225,9 @@ struct ice_ptp_port {
* @late_cached_phc_updates: number of times cached PHC update is late
*/
struct ice_ptp {
enum ice_ptp_tx_interrupt tx_interrupt_mode;
struct ice_ptp_port port;
struct ice_ptp_port_owner ports_owner;
struct kthread_delayed_work work;
u64 cached_phc_time;
unsigned long cached_phc_jiffies;
......@@ -258,11 +288,11 @@ struct ice_ptp {
#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4))
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
int ice_ptp_clock_index(struct ice_pf *pf);
struct ice_pf;
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
int ice_get_ptp_clock_index(struct ice_pf *pf);
void ice_ptp_extts_event(struct ice_pf *pf);
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
......@@ -288,10 +318,6 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
}
static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
static inline int ice_get_ptp_clock_index(struct ice_pf *pf)
{
return -1;
}
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
static inline s8
......@@ -314,5 +340,10 @@ static inline void ice_ptp_release(struct ice_pf *pf) { }
static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
{
}
static inline int ice_ptp_clock_index(struct ice_pf *pf)
{
return -1;
}
#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
#endif /* _ICE_PTP_H_ */
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