ice: Additional patches to support the customer use cases
Intel listed total 28 commits that need us to back port. There are 9 commits that are already included in our code base. The commit "ice: Add support for E825-C TS PLL handling" will not be back ported since we're not dealing with E825 for 24.09. So we need back port 18 commits. These commits were introduced in linux-6.9.y and linux-6.10.y. To back port these 18 commits successfully, we totally back ported 37 upstream commits. 1) The patches 1-15 are cherry picked to fix the conflicts for patch 16 ("ice: introduce PTP state machine") and patch 36 "ice: Introduce ice_ptp_hw struct". Also will be helpful for the subsequent commits back porting. 2) The patches 24-27 are cherry picked to fix the conflicts for patch 28 ("ice: Fix debugfs with devlink reload") 3) The minor adjust was done for the patches 17, 21, 23 and 33 to fit with the context change. Verification: - installs from iso succeed on servers with ice(Intel Ethernet Controller E810-XXVDA4T Westport Channel) and i40e hw(Intel Ethernet Controller X710) for rt and std. - interfaces are up and pass packets for rt and std. - create vfs, ensure that they are picked up by the new iavf driver and that the interface can come up and pass packets on rt and std system. - Check dmesg to see DDP package is loaded successfully and the version is 1.3.36.0 for rt and std. Story: 2011056 Task: 50950 Change-Id: I9aef0378ea01451684341093a167eaead3edc458 Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
This commit is contained in:
parent
a146061fae
commit
5be9ba03ba
@ -0,0 +1,684 @@
|
||||
From ba0d88d4ff54805aac7aec77cc5b05d0df9114da Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:34 +0200
|
||||
Subject: [PATCH 01/36] ice: Auxbus devices & driver for E822 TS
|
||||
|
||||
There is a problem in HW in E822-based devices leading to race
|
||||
condition.
|
||||
It might happen that, in order:
|
||||
- PF0 (which owns the PHC) requests few timestamps,
|
||||
- PF1 requests a timestamp,
|
||||
- interrupt is being triggered and both PF0 and PF1 threads are woken
|
||||
up,
|
||||
- PF0 got one timestamp, still waiting for others so not going to sleep,
|
||||
- PF1 gets it's timestamp, process it and go to sleep,
|
||||
- PF1 requests a timestamp again,
|
||||
- just before PF0 goes to sleep timestamp of PF1 appear,
|
||||
- PF0 finishes all it's timestamps and go to sleep (PF1 also sleeping).
|
||||
That leaves PF1 timestamp memory not read, which lead to blocking the
|
||||
next interrupt from arriving.
|
||||
|
||||
Fix it by adding auxiliary devices and only one driver to handle all the
|
||||
timestamps for all PF's by PHC owner. In the past each PF requested it's
|
||||
own timestamps and process it from the start till the end which causes
|
||||
problem described above. Currently each PF requests the timestamps as
|
||||
before, but the actual reading of the completed timestamps is being done
|
||||
by the PTP auxiliary driver, which is registered by the PF which owns PHC.
|
||||
|
||||
Additionally, the newly introduced auxiliary driver/devices for PTP clock
|
||||
owner will be used for other features in all products (including E810).
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d938a8cca88a5f02f523f95fe3d2d1214f4b4a8d)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 12 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 11 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 393 +++++++++++++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 30 ++
|
||||
5 files changed, 430 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index b9cd0113b859..0a3d76d184ba 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -671,6 +671,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
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 531cc2194741..6756f3d51d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -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)
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8a6acb5a722e..39cb6ee52abe 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,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);
|
||||
}
|
||||
|
||||
@@ -7444,8 +7444,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) {
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 3648d3cccacc..e3012608c9dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -255,6 +255,24 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
return ice_ptp_set_sma_e810t(info, pin, func);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
+ * @pf: The PF pointer to search in
|
||||
+ * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ */
|
||||
+static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Configure the Tx timestamp interrupt */
|
||||
+ val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
+ if (on)
|
||||
+ val |= PFINT_OICR_TSYN_TX_M;
|
||||
+ else
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -263,7 +281,6 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
struct ice_vsi *vsi;
|
||||
- u32 val;
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
@@ -277,13 +294,8 @@ static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
vsi->tx_rings[i]->ptp_tx = on;
|
||||
}
|
||||
|
||||
- /* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
- val |= PFINT_OICR_TSYN_TX_M;
|
||||
- else
|
||||
- val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
+ ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
}
|
||||
@@ -674,9 +686,6 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
int err;
|
||||
u8 idx;
|
||||
|
||||
- if (!tx->init)
|
||||
- return;
|
||||
-
|
||||
ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
pf = ptp_port_to_pf(ptp_port);
|
||||
hw = &pf->hw;
|
||||
@@ -774,6 +783,39 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ mutex_lock(&pf->ptp.ports_owner.lock);
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) {
|
||||
+ struct ice_ptp_tx *tx = &port->tx;
|
||||
+
|
||||
+ if (!tx || !tx->init)
|
||||
+ continue;
|
||||
+
|
||||
+ ice_ptp_process_tx_tstamp(tx);
|
||||
+ }
|
||||
+ mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Read the Tx ready status first */
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (err || tstamp_ready)
|
||||
+ return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
+ }
|
||||
+
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_tx_tstamp - Process Tx timestamps for this function.
|
||||
* @tx: Tx tracking structure to initialize
|
||||
@@ -2448,7 +2490,21 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
*/
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
- return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* This device has the clock owner handle timestamps for it */
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ /* This device handles its own timestamps */
|
||||
+ return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* This device handles timestamps for all ports */
|
||||
+ return ice_ptp_tx_tstamp_owner(pf);
|
||||
+ default:
|
||||
+ WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n",
|
||||
+ pf->ptp.tx_interrupt_mode);
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
@@ -2557,6 +2613,187 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the auxiliary PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_aux_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port *aux_port;
|
||||
+ struct ice_ptp *aux_ptp;
|
||||
+
|
||||
+ aux_port = container_of(aux_dev, struct ice_ptp_port, aux_dev);
|
||||
+ aux_ptp = container_of(aux_port, struct ice_ptp, port);
|
||||
+
|
||||
+ return container_of(aux_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_owner_pf - Get PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_owner_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port_owner *ports_owner;
|
||||
+ struct auxiliary_driver *aux_drv;
|
||||
+ struct ice_ptp *owner_ptp;
|
||||
+
|
||||
+ if (!aux_dev->dev.driver)
|
||||
+ return NULL;
|
||||
+
|
||||
+ aux_drv = to_auxiliary_drv(aux_dev->dev.driver);
|
||||
+ ports_owner = container_of(aux_drv, struct ice_ptp_port_owner,
|
||||
+ aux_driver);
|
||||
+ owner_ptp = container_of(ports_owner, struct ice_ptp, ports_owner);
|
||||
+ return container_of(owner_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_probe - Probe auxiliary devices
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @id: Auxiliary device ID
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev,
|
||||
+ const struct auxiliary_device_id *id)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ if (WARN_ON(!owner_pf))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_add(&aux_pf->ptp.port.list_member,
|
||||
+ &owner_pf->ptp.ports_owner.ports);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_remove - Remove auxiliary devices from the bus
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_del(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_shutdown
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_shutdown(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_suspend
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @state: power management state indicator
|
||||
+ */
|
||||
+static int
|
||||
+ice_ptp_auxbus_suspend(struct auxiliary_device *aux_dev, pm_message_t state)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_resume
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_resume(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_create_id_table - Create auxiliary device ID table
|
||||
+ * @pf: Board private structure
|
||||
+ * @name: auxiliary bus driver name
|
||||
+ */
|
||||
+static struct auxiliary_device_id *
|
||||
+ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name)
|
||||
+{
|
||||
+ struct auxiliary_device_id *ids;
|
||||
+
|
||||
+ /* Second id left empty to terminate the array */
|
||||
+ ids = devm_kcalloc(ice_pf_to_dev(pf), 2,
|
||||
+ sizeof(struct auxiliary_device_id), GFP_KERNEL);
|
||||
+ if (!ids)
|
||||
+ return NULL;
|
||||
+
|
||||
+ snprintf(ids[0].name, sizeof(ids[0].name), "ice.%s", name);
|
||||
+
|
||||
+ return ids;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+ aux_driver = &ptp->ports_owner.aux_driver;
|
||||
+ INIT_LIST_HEAD(&ptp->ports_owner.ports);
|
||||
+ mutex_init(&ptp->ports_owner.lock);
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_driver->name = name;
|
||||
+ aux_driver->shutdown = ice_ptp_auxbus_shutdown;
|
||||
+ aux_driver->suspend = ice_ptp_auxbus_suspend;
|
||||
+ aux_driver->remove = ice_ptp_auxbus_remove;
|
||||
+ aux_driver->resume = ice_ptp_auxbus_resume;
|
||||
+ aux_driver->probe = ice_ptp_auxbus_probe;
|
||||
+ aux_driver->id_table = ice_ptp_auxbus_create_id_table(pf, name);
|
||||
+ if (!aux_driver->id_table)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = auxiliary_driver_register(aux_driver);
|
||||
+ if (err) {
|
||||
+ devm_kfree(dev, aux_driver->id_table);
|
||||
+ dev_err(dev, "Failed registering aux_driver, name <%s>\n",
|
||||
+ name);
|
||||
+ }
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver;
|
||||
+
|
||||
+ auxiliary_driver_unregister(aux_driver);
|
||||
+ devm_kfree(ice_pf_to_dev(pf), aux_driver->id_table);
|
||||
+
|
||||
+ mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -2635,7 +2872,15 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (!ice_is_e810(hw)) {
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
+ /* The clock owner for this device type handles the timestamp
|
||||
+ * interrupt for all ports.
|
||||
+ */
|
||||
+ ice_ptp_configure_tx_tstamp(pf, true);
|
||||
+
|
||||
+ /* React on all quads interrupts for E82x */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2650,8 +2895,16 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Store the PTP clock index for other PFs */
|
||||
ice_set_ptp_clock_index(pf);
|
||||
|
||||
- return 0;
|
||||
+ err = ice_ptp_register_auxbus_driver(pf);
|
||||
+ if (err) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
+ goto err_aux;
|
||||
+ }
|
||||
|
||||
+ return 0;
|
||||
+err_aux:
|
||||
+ ice_clear_ptp_clock_index(pf);
|
||||
+ ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
err_exit:
|
||||
@@ -2701,6 +2954,13 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
+ /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
+ * neither on own quad nor on others
|
||||
+ */
|
||||
+ if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ ice_ptp_configure_tx_tstamp(pf, false);
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -2711,6 +2971,101 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_release_auxbus_device
|
||||
+ * @dev: device that utilizes the auxbus
|
||||
+ */
|
||||
+static void ice_ptp_release_auxbus_device(struct device *dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbux device must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_create_auxbus_device - Create PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_create_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+ u32 id;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ id = ptp->port.port_num;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+
|
||||
+ aux_dev = &ptp->port.aux_dev;
|
||||
+
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_dev->name = name;
|
||||
+ aux_dev->id = id;
|
||||
+ aux_dev->dev.release = ice_ptp_release_auxbus_device;
|
||||
+ aux_dev->dev.parent = dev;
|
||||
+
|
||||
+ err = auxiliary_device_init(aux_dev);
|
||||
+ if (err)
|
||||
+ goto aux_err;
|
||||
+
|
||||
+ err = auxiliary_device_add(aux_dev);
|
||||
+ if (err) {
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+ goto aux_err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+aux_err:
|
||||
+ dev_err(dev, "Failed to create PTP auxiliary bus device <%s>\n", name);
|
||||
+ devm_kfree(dev, name);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev;
|
||||
+
|
||||
+ auxiliary_device_delete(aux_dev);
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+
|
||||
+ memset(aux_dev, 0, sizeof(*aux_dev));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_init_tx_interrupt_mode - Initialize device Tx interrupt mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Initialize the Tx timestamp interrupt mode for this device. For most device
|
||||
+ * types, each PF processes the interrupt and manages its own timestamps. For
|
||||
+ * E822-based devices, only the clock owner processes the timestamps. Other
|
||||
+ * PFs disable the interrupt and do not process their own timestamps.
|
||||
+ */
|
||||
+static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ switch (pf->hw.phy_model) {
|
||||
+ case ICE_PHY_E822:
|
||||
+ /* E822 based PHY has the clock owner process the interrupt
|
||||
+ * for all ports.
|
||||
+ */
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL;
|
||||
+ else
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_NONE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* other PHY types handle their own Tx interrupt */
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_SELF;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_init - Initialize PTP hardware clock support
|
||||
* @pf: Board private structure
|
||||
@@ -2731,6 +3086,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
+ ice_ptp_init_tx_interrupt_mode(pf);
|
||||
+
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
@@ -2753,6 +3110,10 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
+ if (err)
|
||||
+ goto err;
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
|
||||
return;
|
||||
|
||||
@@ -2781,6 +3142,8 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_cfg_timestamp(pf, false);
|
||||
|
||||
+ ice_ptp_remove_auxbus_device(pf);
|
||||
+
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
@@ -2804,5 +3167,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 995a57019ba7..d94c22329df0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,95 @@
|
||||
From f6af978ef435067b4c9f5ff5e159f8b65d969268 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 8 Sep 2023 14:37:14 -0700
|
||||
Subject: [PATCH 02/36] ice: introduce ice_pf_src_tmr_owned
|
||||
|
||||
Add ice_pf_src_tmr_owned() macro to check the function capability bit
|
||||
indicating if the current function owns the PTP hardware clock. This is
|
||||
slightly shorter than the more verbose access via
|
||||
hw.func_caps.ts_func_info.src_tmr_owned. Use this where possible rather
|
||||
than open coding its equivalent.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 42d40bb21e332151da6fb689bf7d4af8195866ed)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 6 +++---
|
||||
4 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 0a3d76d184ba..54a98c4032b7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -197,6 +197,8 @@ extern const char ice_drv_ver[];
|
||||
|
||||
#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_PHY_RCLK,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 632091487413..106ef843f4b5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -4010,7 +4010,7 @@ void ice_init_feature_support(struct ice_pf *pf)
|
||||
if (ice_is_phy_rclk_in_netlist(&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_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_CGU);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 39cb6ee52abe..e957529b3fd6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3200,7 +3200,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 |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index e3012608c9dd..b1951357ba9f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -448,7 +448,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;
|
||||
@@ -2538,7 +2538,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);
|
||||
@@ -3091,7 +3091,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* 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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 3c155fbf8e2a0546302a01cc06e8ece18468148e Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:42 -0800
|
||||
Subject: [PATCH 03/36] ice: Re-enable timestamping correctly after reset
|
||||
|
||||
During reset, TX_TSYN interrupt should be processed as it may process
|
||||
timestamps in brief moments before and after reset.
|
||||
Timestamping should be enabled on VSIs at the end of reset procedure.
|
||||
On ice_get_phy_tx_tstamp_ready error, interrupt should not be rearmed
|
||||
because error only happens on resets.
|
||||
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1cc5b6eaad92d69fe4d84bbee5c12ee297d56296)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 19 ++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index e957529b3fd6..d2f3b4374d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,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 && ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b1951357ba9f..92459589f6ce 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -809,7 +809,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
- if (err || tstamp_ready)
|
||||
+ if (err)
|
||||
+ break;
|
||||
+ else if (tstamp_ready)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
}
|
||||
|
||||
@@ -2535,12 +2537,10 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
+ !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- goto reset_ts;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
goto err;
|
||||
@@ -2584,10 +2584,6 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-reset_ts:
|
||||
- /* Restart the PHY timestamping block */
|
||||
- ice_ptp_reset_phy_timestamping(pf);
|
||||
-
|
||||
pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
@@ -2603,6 +2599,11 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
+ /* Restart the PHY timestamping block */
|
||||
+ if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
+ ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,121 @@
|
||||
From 214f06259ade960e3790b62f96bc1b75e5b76e79 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:43 -0800
|
||||
Subject: [PATCH 04/36] ice: periodically kick Tx timestamp interrupt
|
||||
|
||||
The E822 hardware for Tx timestamping keeps track of how many
|
||||
outstanding timestamps are still in the PHY memory block. It will not
|
||||
generate a new interrupt to the MAC until all of the timestamps in the
|
||||
region have been read.
|
||||
|
||||
If somehow all the available data is not read, but the driver has exited
|
||||
its interrupt routine already, the PHY will not generate a new interrupt
|
||||
even if new timestamp data is captured. Because no interrupt is
|
||||
generated, the driver never processes the timestamp data. This state
|
||||
results in a permanent failure for all future Tx timestamps.
|
||||
|
||||
It is not clear how the driver and hardware could enter this state.
|
||||
However, if it does, there is currently no recovery mechanism.
|
||||
|
||||
Add a recovery mechanism via the periodic PTP work thread which invokes
|
||||
ice_ptp_periodic_work(). Introduce a new check,
|
||||
ice_ptp_maybe_trigger_tx_interrupt() which checks the PHY timestamp
|
||||
ready bitmask. If any bits are set, trigger a software interrupt by
|
||||
writing to PFINT_OICR.
|
||||
|
||||
Once triggered, the main timestamp processing thread will read through
|
||||
the PHY data and clear the outstanding timestamp data. Once cleared, new
|
||||
data should trigger interrupts as expected.
|
||||
|
||||
This should allow recovery from such a state rather than leaving the
|
||||
device in a state where we cannot process Tx timestamps.
|
||||
|
||||
It is possible that this function checks for timestamp data
|
||||
simultaneously with the interrupt, and it might trigger additional
|
||||
unnecessary interrupts. This will cause a small amount of additional
|
||||
processing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Andrii Staikov <andrii.staikov@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 712e876371f8350c446a33577cf4a0aedcd4742a)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 50 ++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 92459589f6ce..0d6c7215e0c1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2509,6 +2509,54 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_maybe_trigger_tx_interrupt - Trigger Tx timstamp interrupt
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * The device PHY issues Tx timestamp interrupts to the driver for processing
|
||||
+ * timestamp data from the PHY. It will not interrupt again until all
|
||||
+ * current timestamp data is read. In rare circumstances, it is possible that
|
||||
+ * the driver fails to read all outstanding data.
|
||||
+ *
|
||||
+ * To avoid getting permanently stuck, periodically check if the PHY has
|
||||
+ * outstanding timestamp data. If so, trigger an interrupt from software to
|
||||
+ * process this data.
|
||||
+ */
|
||||
+static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool trigger_oicr = false;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (ice_is_e810(hw))
|
||||
+ return;
|
||||
+
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (!err && tstamp_ready) {
|
||||
+ trigger_oicr = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (trigger_oicr) {
|
||||
+ /* Trigger a software interrupt, to ensure this data
|
||||
+ * gets processed.
|
||||
+ */
|
||||
+ dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
|
||||
+
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
{
|
||||
struct ice_ptp *ptp = container_of(work, struct ice_ptp, work.work);
|
||||
@@ -2520,6 +2568,8 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
|
||||
+ ice_ptp_maybe_trigger_tx_interrupt(pf);
|
||||
+
|
||||
/* Run twice a second or reschedule if phc update failed */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work,
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,81 @@
|
||||
From c25fc364d599195403ed9ba51ef8fa6ed3b642ff Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:44 -0700
|
||||
Subject: [PATCH 05/36] ice: PTP: Rename macros used for PHY/QUAD port
|
||||
definitions
|
||||
|
||||
The ice_fill_phy_msg_e822 function uses several macros to specify the
|
||||
correct address when sending a sideband message to the PHY block in
|
||||
hardware.
|
||||
|
||||
The names of these macros are fairly generic and confusing. Future
|
||||
development is going to extend the driver to support new hardware families
|
||||
which have different relationships between PHY and QUAD. Rename the macros
|
||||
for clarity and to indicate that they are E822 specific. This also matches
|
||||
closer to the hardware specification in the data sheet.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 64fd7de2469dd52a7f1517ce95ae22fcb391a8a1)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 8 ++++----
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 14 +++++++-------
|
||||
2 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index a299af39a7c4..03c4aa995e8d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -294,9 +294,9 @@ ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY;
|
||||
- phy = port / ICE_PORTS_PER_PHY;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_NUM_QUAD_TYPE;
|
||||
+ phy_port = port % ICE_PORTS_PER_PHY_E822;
|
||||
+ phy = port / ICE_PORTS_PER_PHY_E822;
|
||||
+ quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E822;
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -628,7 +628,7 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_NUM_QUAD_TYPE) == 0)
|
||||
+ if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 4cd131546aa9..bb5d8b681bc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -909,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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 13f48f4c94ad4d317e7c7ccaa188a11850a8aa32 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:45 -0700
|
||||
Subject: [PATCH 06/36] ice: PTP: move quad value check inside
|
||||
ice_fill_phy_msg_e822
|
||||
|
||||
The callers of ice_fill_phy_msg_e822 check for whether the quad number is
|
||||
within the expected range. Move this check inside the ice_fill_phy_msg_e822
|
||||
function instead of duplicating it twice.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit dd84744cf5ea967c8d53aae6b6a45703dbc5c5c4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 19 ++++++++++++-------
|
||||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 03c4aa995e8d..e024b88ce32b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -621,11 +621,14 @@ ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
*/
|
||||
-static void
|
||||
+static int
|
||||
ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
+ if (quad >= ICE_MAX_QUAD)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
@@ -635,6 +638,8 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->msg_addr_low = lower_16_bits(addr);
|
||||
msg->msg_addr_high = upper_16_bits(addr);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,10 +658,10 @@ ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -687,10 +692,10 @@ ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,97 @@
|
||||
From 7dae9333af82f6c9e2db1940c3a10ae38dabea7b Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:55 -0800
|
||||
Subject: [PATCH 07/36] ice: remove ptp_tx ring parameter flag
|
||||
|
||||
Before performing a Tx timestamp in ice_stamp(), the driver checks a ptp_tx
|
||||
ring variable to see if timestamping is enabled on that ring. This value is
|
||||
set for all rings whenever userspace configures Tx timestamping.
|
||||
|
||||
Ostensibly this was done to avoid wasting cycles checking other fields when
|
||||
timestamping has not been enabled. However, for Tx timestamps we already
|
||||
get an individual per-SKB flag indicating whether userspace wants to
|
||||
request a timestamp on that packet. We do not gain much by also having
|
||||
a separate flag to check for whether timestamping was enabled.
|
||||
|
||||
In fact, the driver currently fails to restore the field after a PF reset.
|
||||
Because of this, if a PF reset occurs, timestamps will be disabled.
|
||||
|
||||
Since this flag doesn't add value in the hotpath, remove it and always
|
||||
provide a timestamp if the SKB flag has been set.
|
||||
|
||||
A following change will fix the reset path to properly restore user
|
||||
timestamping configuration completely.
|
||||
|
||||
This went unnoticed for some time because one of the most common
|
||||
applications using Tx timestamps, ptp4l, will reconfigure the socket as
|
||||
part of its fault recovery logic.
|
||||
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 0ffb08b1a45bd6b7694e01da0e1d9e3e788418fb)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 14 --------------
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.c | 3 ---
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.h | 1 -
|
||||
3 files changed, 18 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 0d6c7215e0c1..c03153bdb7c3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -280,20 +280,6 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- struct ice_vsi *vsi;
|
||||
- u16 i;
|
||||
-
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- /* Set the timestamp enable flag for all the Tx rings */
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (!vsi->tx_rings[i])
|
||||
- continue;
|
||||
- vsi->tx_rings[i]->ptp_tx = on;
|
||||
- }
|
||||
-
|
||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
index 24c914015973..9170a3e8f088 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
@@ -2305,9 +2305,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb,
|
||||
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
|
||||
return;
|
||||
|
||||
- if (!tx_ring->ptp_tx)
|
||||
- return;
|
||||
-
|
||||
/* Tx timestamps cannot be sampled when doing TSO */
|
||||
if (first->tx_flags & ICE_TX_FLAGS_TSO)
|
||||
return;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
index 407d4c320097..b28b9826bbcd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
@@ -381,7 +381,6 @@ struct ice_tx_ring {
|
||||
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
|
||||
u8 flags;
|
||||
u8 dcb_tc; /* Traffic class of ring */
|
||||
- u8 ptp_tx;
|
||||
} ____cacheline_internodealigned_in_smp;
|
||||
|
||||
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,160 @@
|
||||
From 99007ca6255e2c35256bd97fa141705d301eb934 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:56 -0800
|
||||
Subject: [PATCH 08/36] ice: unify logic for programming PFINT_TSYN_MSK
|
||||
|
||||
Commit d938a8cca88a ("ice: Auxbus devices & driver for E822 TS") modified
|
||||
how Tx timestamps are handled for E822 devices. On these devices, only the
|
||||
clock owner handles reading the Tx timestamp data from firmware. To do
|
||||
this, the PFINT_TSYN_MSK register is modified from the default value to one
|
||||
which enables reacting to a Tx timestamp on all PHY ports.
|
||||
|
||||
The driver currently programs PFINT_TSYN_MSK in different places depending
|
||||
on whether the port is the clock owner or not. For the clock owner, the
|
||||
PFINT_TSYN_MSK value is programmed during ice_ptp_init_owner just before
|
||||
calling ice_ptp_tx_ena_intr to program the PHY ports.
|
||||
|
||||
For the non-clock owner ports, the PFINT_TSYN_MSK is programmed during
|
||||
ice_ptp_init_port.
|
||||
|
||||
If a large enough device reset occurs, the PFINT_TSYN_MSK register will be
|
||||
reset to the default value in which only the PHY associated directly with
|
||||
the PF will cause the Tx timestamp interrupt to trigger.
|
||||
|
||||
The driver lacks logic to reprogram the PFINT_TSYN_MSK register after a
|
||||
device reset. For the E822 device, this results in the PF no longer
|
||||
responding to interrupts for other ports. This results in failure to
|
||||
deliver Tx timestamps to user space applications.
|
||||
|
||||
Rename ice_ptp_configure_tx_tstamp to ice_ptp_cfg_tx_interrupt, and unify
|
||||
the logic for programming PFINT_TSYN_MSK and PFINT_OICR_ENA into one place.
|
||||
This function will program both registers according to the combination of
|
||||
user configuration and device requirements.
|
||||
|
||||
This ensures that PFINT_TSYN_MSK is always restored when we configure the
|
||||
Tx timestamp interrupt.
|
||||
|
||||
Fixes: d938a8cca88a ("ice: Auxbus devices & driver for E822 TS")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7d606a1e2d0575b6c3a2600f43f90d1e409f9661)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 60 ++++++++++++++----------
|
||||
1 file changed, 34 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c03153bdb7c3..b0bba866e8a2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -256,21 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ * ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Program the device to respond appropriately to the Tx timestamp interrupt
|
||||
+ * cause.
|
||||
*/
|
||||
-static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable;
|
||||
u32 val;
|
||||
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* React to interrupts across all quads. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+ enable = true;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* Do not react to interrupts on any quad. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ enable = false;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ default:
|
||||
+ enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ if (enable)
|
||||
val |= PFINT_OICR_TSYN_TX_M;
|
||||
else
|
||||
val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,10 +301,9 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
- ice_ptp_configure_tx_tstamp(pf, on);
|
||||
-
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2909,15 +2929,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
- /* The clock owner for this device type handles the timestamp
|
||||
- * interrupt for all ports.
|
||||
- */
|
||||
- ice_ptp_configure_tx_tstamp(pf, true);
|
||||
-
|
||||
- /* React on all quads interrupts for E82x */
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
-
|
||||
+ if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2991,13 +3003,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
- /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
- * neither on own quad nor on others
|
||||
- */
|
||||
- if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
- ice_ptp_configure_tx_tstamp(pf, false);
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
- }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -3142,6 +3147,9 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Start the PHY timestamping block */
|
||||
ice_ptp_reset_phy_timestamping(pf);
|
||||
|
||||
+ /* Configure initial Tx interrupt settings */
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,147 @@
|
||||
From e5a65377977e338a8f7baf92892481acf1c62403 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:43 -0700
|
||||
Subject: [PATCH 09/36] ice: PTP: Clean up timestamp registers correctly
|
||||
|
||||
E822 PHY TS registers should not be written and the only way to clean up
|
||||
them is to reset QUAD memory.
|
||||
|
||||
To ensure that the status bit for the timestamp index is cleared, ensure
|
||||
that ice_clear_phy_tstamp implementations first read the timestamp out.
|
||||
Implementations which can write the register continue to do so.
|
||||
|
||||
Add a note to indicate this function should only be called on timestamps
|
||||
which have their valid bit set. Update the dynamic debug messages to
|
||||
reflect the actual action taken.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit be65a1a33bdee3912daac50aa6c5270ec9c37010)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 70 +++++++++++++--------
|
||||
1 file changed, 45 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index e024b88ce32b..cd28430cfdda 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -759,29 +759,32 @@ ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
|
||||
* @quad: the quad to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the PHY quad block that is
|
||||
- * shared between the internal PHYs on the E822 devices.
|
||||
+ * Read the timestamp out of the quad to clear its timestamp status bit from
|
||||
+ * the PHY quad block that is shared between the internal PHYs of the E822
|
||||
+ * devices.
|
||||
+ *
|
||||
+ * Note that unlike E810, software cannot directly write to the quad memory
|
||||
+ * bank registers. E822 relies on the ice_get_phy_tx_tstamp_ready() function
|
||||
+ * to determine which timestamps are valid. Reading a timestamp auto-clears
|
||||
+ * the valid bit.
|
||||
+ *
|
||||
+ * To directly clear the contents of the timestamp block entirely, discarding
|
||||
+ * all timestamp data at once, software should instead use
|
||||
+ * ice_ptp_reset_ts_memory_quad_e822().
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int
|
||||
ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
|
||||
{
|
||||
- u16 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
- lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
- hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
|
||||
- if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
|
||||
+ err = ice_read_phy_tstamp_e822(hw, quad, idx, &unused_tstamp);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for quad %u, idx %u, err %d\n",
|
||||
+ quad, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2816,28 +2819,39 @@ ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
|
||||
* @lport: the lport to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block of the
|
||||
- * external PHY on the E810 device.
|
||||
+ * Read the timestamp and then forcibly overwrite its value to clear the valid
|
||||
+ * bit from the timestamp block of the external PHY on the E810 device.
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
{
|
||||
u32 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
+ err = ice_read_phy_tstamp_e810(hw, lport, idx, &unused_tstamp);
|
||||
+ if (err) {
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
|
||||
hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, lo_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, hi_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3519,9 +3533,15 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
* @block: the block to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block. For
|
||||
- * E822 devices, the block is the quad to clear from. For E810 devices, the
|
||||
- * block is the logical port to clear from.
|
||||
+ * Clear a timestamp from the timestamp block, discarding its value without
|
||||
+ * returning it. This resets the memory status bit for the timestamp index
|
||||
+ * allowing it to be reused for another timestamp in the future.
|
||||
+ *
|
||||
+ * For E822 devices, the block number is the PHY quad to clear from. For E810
|
||||
+ * devices, the block number is the logical port to clear from.
|
||||
+ *
|
||||
+ * This function must only be called on a timestamp index whose valid bit is
|
||||
+ * set according to ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,65 @@
|
||||
From e2a74a0a7dd399b0ee2ddd4889c609dedb85bfb5 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:35 +0200
|
||||
Subject: [PATCH 10/36] ice: Use PTP auxbus for all PHYs restart in E822
|
||||
|
||||
The E822 (and other devices based on the same PHY) is having issue while
|
||||
setting the PHC timer - the PHY timers are drifting from the PHC. After
|
||||
such a set all PHYs need to be restarted and resynchronised - do it
|
||||
using auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit af3c5c8748e6d286d4f2dd9800f9d27f29b8e2ef)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 24 +++++++++++++++++++++---
|
||||
1 file changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b0bba866e8a2..42eb1418eb90 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1496,6 +1496,24 @@ static void ice_ptp_reset_phy_timestamping(struct ice_pf *pf)
|
||||
ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_restart_all_phy - Restart all PHYs to recalibrate timestamping
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_restart_all_phy(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct list_head *entry;
|
||||
+
|
||||
+ list_for_each(entry, &pf->ptp.ports_owner.ports) {
|
||||
+ struct ice_ptp_port *port = list_entry(entry,
|
||||
+ struct ice_ptp_port,
|
||||
+ list_member);
|
||||
+
|
||||
+ if (port->link_up)
|
||||
+ ice_ptp_port_phy_restart(port);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_adjfine - Adjust clock increment rate
|
||||
* @info: the driver's PTP info structure
|
||||
@@ -1933,9 +1951,9 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
/* Reenable periodic outputs */
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
- /* Recalibrate and re-enable timestamp block */
|
||||
- if (pf->ptp.port.link_up)
|
||||
- ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
+ /* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
+ if (hw->phy_model == ICE_PHY_E822)
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err);
|
||||
--
|
||||
2.43.0
|
||||
|
2177
kernel-rt/debian/patches/ice-VDF/0011-ice-Rename-E822-to-E82X.patch
Normal file
2177
kernel-rt/debian/patches/ice-VDF/0011-ice-Rename-E822-to-E82X.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,104 @@
|
||||
From 3b37119a08ffe4be182ade746a6b1fe3bcf65921 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:22 +0100
|
||||
Subject: [PATCH 12/36] ice: Schedule service task in IRQ top half
|
||||
|
||||
Schedule service task and EXTTS in the top half to avoid bottom half
|
||||
scheduling if possible, which significantly reduces timestamping delay.
|
||||
|
||||
Co-developed-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 00d50001444ef5c75c8ab476a6674708f3ff613b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 20 +++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 54a98c4032b7..efe78d5e4da1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -517,7 +517,6 @@ enum ice_pf_flags {
|
||||
};
|
||||
|
||||
enum ice_misc_thread_tasks {
|
||||
- ICE_MISC_THREAD_EXTTS_EVENT,
|
||||
ICE_MISC_THREAD_TX_TSTAMP,
|
||||
ICE_MISC_THREAD_NBITS /* must be last */
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d2f3b4374d14..2acaa17a12bf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3109,6 +3109,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
{
|
||||
struct ice_pf *pf = (struct ice_pf *)data;
|
||||
+ irqreturn_t ret = IRQ_HANDLED;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct device *dev;
|
||||
u32 oicr, ena_mask;
|
||||
@@ -3190,8 +3191,10 @@ 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 (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
+ ret = IRQ_WAKE_THREAD;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_EVNT_M) {
|
||||
@@ -3207,7 +3210,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
GLTSYN_STAT_EVENT1_M |
|
||||
GLTSYN_STAT_EVENT2_M);
|
||||
|
||||
- set_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread);
|
||||
+ ice_ptp_extts_event(pf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,8 +3233,11 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
set_bit(ICE_PFR_REQ, pf->state);
|
||||
}
|
||||
}
|
||||
+ ice_service_task_schedule(pf);
|
||||
+ if (ret == IRQ_HANDLED)
|
||||
+ ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
- return IRQ_WAKE_THREAD;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3247,12 +3253,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
hw = &pf->hw;
|
||||
|
||||
if (ice_is_reset_in_progress(pf->state))
|
||||
- return IRQ_HANDLED;
|
||||
-
|
||||
- ice_service_task_schedule(pf);
|
||||
-
|
||||
- if (test_and_clear_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread))
|
||||
- ice_ptp_extts_event(pf);
|
||||
+ goto skip_irq;
|
||||
|
||||
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
|
||||
/* Process outstanding Tx timestamps. If there is more work,
|
||||
@@ -3264,6 +3265,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
+skip_irq:
|
||||
ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,660 @@
|
||||
From c4ab92eb3ee89178a012702f2a98477d683fad31 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:23 +0100
|
||||
Subject: [PATCH 13/36] ice: Enable SW interrupt from FW for LL TS
|
||||
|
||||
Introduce new capability - Low Latency Timestamping with Interrupt.
|
||||
On supported devices, driver can request a single timestamp from FW
|
||||
without polling the register afterwards. Instead, FW can issue
|
||||
a dedicated interrupt when the timestamp was read from the PHY register
|
||||
and its value is available to read from the register.
|
||||
This eliminates the need of bottom half scheduling, which results in
|
||||
minimal delay for timestamping.
|
||||
|
||||
For this mode, allocate TS indices sequentially, so that timestamps are
|
||||
always completed in FIFO manner.
|
||||
|
||||
Co-developed-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Signed-off-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 82e71b226e0ef770d7bc143701c8b4960b4eb3d5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 3 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 120 +++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 ++++++++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 9 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 2 +
|
||||
8 files changed, 274 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index efe78d5e4da1..ee42a504c2f4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -594,6 +594,7 @@ struct ice_pf {
|
||||
u32 hw_csum_rx_error;
|
||||
u32 oicr_err_reg;
|
||||
struct msi_map oicr_irq; /* Other interrupt cause MSIX vector */
|
||||
+ struct msi_map ll_ts_irq; /* LL_TS interrupt MSIX vector */
|
||||
u16 max_pf_txqs; /* Total Tx queues PF wide */
|
||||
u16 max_pf_rxqs; /* Total Rx queues PF wide */
|
||||
u16 num_lan_msix; /* Total MSIX vectors for base driver */
|
||||
@@ -618,6 +619,7 @@ struct ice_pf {
|
||||
unsigned long tx_timeout_last_recovery;
|
||||
u32 tx_timeout_recovery_level;
|
||||
char int_name[ICE_INT_NAME_STR_LEN];
|
||||
+ char int_name_ll_ts[ICE_INT_NAME_STR_LEN];
|
||||
struct auxiliary_device *adev;
|
||||
int aux_idx;
|
||||
u32 sw_int_count;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 7674267a2d90..acf6ac00f804 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -2624,6 +2624,7 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
|
||||
|
||||
info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0);
|
||||
+ info->ts_ll_int_read = ((number & ICE_TS_LL_TX_TS_INT_READ_M) != 0);
|
||||
|
||||
info->ena_ports = logical_id;
|
||||
info->tmr_own_map = phys_id;
|
||||
@@ -2644,6 +2645,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_read = %u\n",
|
||||
info->ts_ll_read);
|
||||
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_int_read = %u\n",
|
||||
+ info->ts_ll_int_read);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n",
|
||||
info->ena_ports);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 6756f3d51d14..fa730bca7f15 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -200,6 +200,8 @@
|
||||
#define GLINT_VECT2FUNC_PF_NUM_M ICE_M(0x7, 12)
|
||||
#define GLINT_VECT2FUNC_IS_PF_S 16
|
||||
#define GLINT_VECT2FUNC_IS_PF_M BIT(16)
|
||||
+#define PFINT_ALLOC 0x001D2600
|
||||
+#define PFINT_ALLOC_FIRST ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL 0x0016C800
|
||||
#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL_ITR_INDX_S 11
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 2acaa17a12bf..9163a72368b3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3071,6 +3071,7 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
|
||||
static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ u32 pf_intr_start_offset;
|
||||
u32 val;
|
||||
|
||||
/* Disable anti-spoof detection interrupt to prevent spurious event
|
||||
@@ -3099,6 +3100,47 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
/* SW_ITR_IDX = 0, but don't change INTENA */
|
||||
wr32(hw, GLINT_DYN_CTL(pf->oicr_irq.index),
|
||||
GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ return;
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ll_ts_intr - ll_ts interrupt handler
|
||||
+ * @irq: interrupt number
|
||||
+ * @data: pointer to a q_vector
|
||||
+ */
|
||||
+static irqreturn_t ice_ll_ts_intr(int __always_unused irq, void *data)
|
||||
+{
|
||||
+ struct ice_pf *pf = data;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct ice_ptp_tx *tx;
|
||||
+ unsigned long flags;
|
||||
+ struct ice_hw *hw;
|
||||
+ u32 val;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ hw = &pf->hw;
|
||||
+ tx = &pf->ptp.port.tx;
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ ice_ptp_complete_tx_single_tstamp(tx);
|
||||
+
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+
|
||||
+ val = GLINT_DYN_CTL_INTENA_M | GLINT_DYN_CTL_CLEARPBA_M |
|
||||
+ (ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S);
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ val);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3191,7 +3233,19 @@ 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 (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ if (ice_pf_state_is_nominal(pf) &&
|
||||
+ pf->hw.dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ struct ice_ptp_tx *tx = &pf->ptp.port.tx;
|
||||
+ unsigned long flags;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+ } else if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
@@ -3295,6 +3349,20 @@ static void ice_dis_ctrlq_interrupts(struct ice_hw *hw)
|
||||
ice_flush(hw);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_free_irq_msix_ll_ts- Unroll ll_ts vector setup
|
||||
+ * @pf: board private structure
|
||||
+ */
|
||||
+static void ice_free_irq_msix_ll_ts(struct ice_pf *pf)
|
||||
+{
|
||||
+ int irq_num = pf->ll_ts_irq.virq;
|
||||
+
|
||||
+ synchronize_irq(irq_num);
|
||||
+ devm_free_irq(ice_pf_to_dev(pf), irq_num, pf);
|
||||
+
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_free_irq_msix_misc - Unroll misc vector setup
|
||||
* @pf: board private structure
|
||||
@@ -3314,6 +3382,8 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
|
||||
devm_free_irq(ice_pf_to_dev(pf), misc_irq_num, pf);
|
||||
|
||||
ice_free_irq(pf, pf->oicr_irq);
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ ice_free_irq_msix_ll_ts(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3339,10 +3409,12 @@ static void ice_ena_ctrlq_interrupts(struct ice_hw *hw, u16 reg_idx)
|
||||
PFINT_MBX_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, PFINT_MBX_CTL, val);
|
||||
|
||||
- /* This enables Sideband queue Interrupt causes */
|
||||
- val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
- PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
- wr32(hw, PFINT_SB_CTL, val);
|
||||
+ if (!hw->dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ /* enable Sideband queue Interrupt causes */
|
||||
+ val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
+ PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
+ wr32(hw, PFINT_SB_CTL, val);
|
||||
+ }
|
||||
|
||||
ice_flush(hw);
|
||||
}
|
||||
@@ -3359,13 +3431,17 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
- struct msi_map oicr_irq;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct msi_map irq;
|
||||
int err = 0;
|
||||
|
||||
if (!pf->int_name[0])
|
||||
snprintf(pf->int_name, sizeof(pf->int_name) - 1, "%s-%s:misc",
|
||||
dev_driver_string(dev), dev_name(dev));
|
||||
|
||||
+ if (!pf->int_name_ll_ts[0])
|
||||
+ snprintf(pf->int_name_ll_ts, sizeof(pf->int_name_ll_ts) - 1,
|
||||
+ "%s-%s:ll_ts", dev_driver_string(dev), dev_name(dev));
|
||||
/* Do not request IRQ but do enable OICR interrupt since settings are
|
||||
* lost during reset. Note that this function is called only during
|
||||
* rebuild path and not while reset is in progress.
|
||||
@@ -3374,11 +3450,11 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
goto skip_req_irq;
|
||||
|
||||
/* reserve one vector in irq_tracker for misc interrupts */
|
||||
- oicr_irq = ice_alloc_irq(pf, false);
|
||||
- if (oicr_irq.index < 0)
|
||||
- return oicr_irq.index;
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
|
||||
- pf->oicr_irq = oicr_irq;
|
||||
+ pf->oicr_irq = irq;
|
||||
err = devm_request_threaded_irq(dev, pf->oicr_irq.virq, ice_misc_intr,
|
||||
ice_misc_intr_thread_fn, 0,
|
||||
pf->int_name, pf);
|
||||
@@ -3389,10 +3465,34 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
+ /* reserve one vector in irq_tracker for ll_ts interrupt */
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ goto skip_req_irq;
|
||||
+
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
+
|
||||
+ pf->ll_ts_irq = irq;
|
||||
+ err = devm_request_irq(dev, pf->ll_ts_irq.virq, ice_ll_ts_intr, 0,
|
||||
+ pf->int_name_ll_ts, pf);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "devm_request_irq for %s failed: %d\n",
|
||||
+ pf->int_name_ll_ts, err);
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
skip_req_irq:
|
||||
ice_ena_misc_vector(pf);
|
||||
|
||||
ice_ena_ctrlq_interrupts(hw, pf->oicr_irq.index);
|
||||
+ /* This enables LL TS interrupt */
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ wr32(hw, PFINT_SB_CTL,
|
||||
+ ((pf->ll_ts_irq.index + pf_intr_start_offset) &
|
||||
+ PFINT_SB_CTL_MSIX_INDX_M) | PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_irq.index),
|
||||
ITR_REG_ALIGN(ICE_ITR_8K) >> ICE_ITR_GRAN_S);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 2e6e1fc84d11..75038d826f71 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -634,6 +634,119 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
return tx->init && !tx->calibrating;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_req_tx_single_tstamp - Request Tx timestamp for a port from FW
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ * @idx: index of the timestamp to request
|
||||
+ */
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+
|
||||
+ if (!tx->init)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ /* Drop packets which have waited for more than 2 seconds */
|
||||
+ if (time_is_before_jiffies(tx->tstamps[idx].start + 2 * HZ)) {
|
||||
+ /* Count the number of Tx timestamps that timed out */
|
||||
+ pf->ptp.tx_hwtstamp_timeouts++;
|
||||
+
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_req, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ /* Write TS index to read to the PF register so the FW can read it */
|
||||
+ wr32(&pf->hw, PF_SB_ATQBAL,
|
||||
+ TS_LL_READ_TS_INTR | FIELD_PREP(TS_LL_READ_TS_IDX, idx) |
|
||||
+ TS_LL_READ_TS);
|
||||
+ tx->last_ll_ts_idx_read = idx;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_complete_tx_single_tstamp - Complete Tx timestamp for a port
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ */
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
+{
|
||||
+ struct skb_shared_hwtstamps shhwtstamps = {};
|
||||
+ u8 idx = tx->last_ll_ts_idx_read;
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ u64 raw_tstamp, tstamp;
|
||||
+ bool drop_ts = false;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (!tx->init || tx->last_ll_ts_idx_read < 0)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ val = rd32(&pf->hw, PF_SB_ATQBAL);
|
||||
+
|
||||
+ /* When the bit is cleared, the TS is ready in the register */
|
||||
+ if (val & TS_LL_READ_TS) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to get the Tx tstamp - FW not ready");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* High 8 bit value of the TS is on the bits 16:23 */
|
||||
+ raw_tstamp = FIELD_GET(TS_LL_READ_TS_HIGH, val);
|
||||
+ raw_tstamp <<= 32;
|
||||
+
|
||||
+ /* Read the low 32 bit value */
|
||||
+ raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
+
|
||||
+ /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
+ * verify that the timestamp value is different from the last cached
|
||||
+ * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
+ * been captured by hardware.
|
||||
+ */
|
||||
+ if (!drop_ts && tx->verify_cached &&
|
||||
+ raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ return;
|
||||
+
|
||||
+ if (tx->verify_cached && raw_tstamp)
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ if (test_and_clear_bit(idx, tx->stale))
|
||||
+ drop_ts = true;
|
||||
+
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ if (drop_ts) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Extend the timestamp using cached PHC time */
|
||||
+ tstamp = ice_ptp_extend_40b_ts(pf, raw_tstamp);
|
||||
+ if (tstamp) {
|
||||
+ shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
|
||||
+ ice_trace(tx_tstamp_complete, skb, idx);
|
||||
+ }
|
||||
+
|
||||
+ skb_tstamp_tx(skb, &shhwtstamps);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_process_tx_tstamp - Process Tx timestamps for a port
|
||||
* @tx: the PTP Tx timestamp tracker
|
||||
@@ -685,6 +798,7 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_ptp_port *ptp_port;
|
||||
+ unsigned long flags;
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u64 tstamp_ready;
|
||||
@@ -756,7 +870,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
drop_ts = true;
|
||||
|
||||
skip_ts_read:
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
if (tx->verify_cached && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
@@ -764,7 +878,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
if (test_and_clear_bit(idx, tx->stale))
|
||||
drop_ts = true;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* It is unlikely but possible that the SKB will have been
|
||||
* flushed at this point due to link change or teardown.
|
||||
@@ -834,6 +948,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
bool more_timestamps;
|
||||
+ unsigned long flags;
|
||||
|
||||
if (!tx->init)
|
||||
return ICE_TX_TSTAMP_WORK_DONE;
|
||||
@@ -842,9 +957,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
ice_ptp_process_tx_tstamp(tx);
|
||||
|
||||
/* Check if there are outstanding Tx timestamps */
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
if (more_timestamps)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
@@ -881,6 +996,7 @@ ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx)
|
||||
tx->in_use = in_use;
|
||||
tx->stale = stale;
|
||||
tx->init = 1;
|
||||
+ tx->last_ll_ts_idx_read = -1;
|
||||
|
||||
spin_lock_init(&tx->lock);
|
||||
|
||||
@@ -898,6 +1014,7 @@ static void
|
||||
ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
u8 idx;
|
||||
@@ -921,12 +1038,12 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
if (!hw->reset_ongoing && (tstamp_ready & BIT_ULL(phy_idx)))
|
||||
ice_clear_phy_tstamp(hw, tx->block, phy_idx);
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
clear_bit(idx, tx->in_use);
|
||||
clear_bit(idx, tx->stale);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* Count the number of Tx timestamps flushed */
|
||||
pf->ptp.tx_hwtstamp_flushed++;
|
||||
@@ -950,9 +1067,11 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
bitmap_or(tx->stale, tx->stale, tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -965,9 +1084,11 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
tx->init = 0;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* wait for potentially outstanding interrupt to complete */
|
||||
synchronize_irq(pf->oicr_irq.virq);
|
||||
@@ -1367,6 +1488,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
struct ice_pf *pf = ptp_port_to_pf(ptp_port);
|
||||
u8 port = ptp_port->port_num;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
int err;
|
||||
|
||||
if (ice_is_e810(hw))
|
||||
@@ -1380,9 +1502,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
kthread_cancel_delayed_work_sync(&ptp_port->ov_work);
|
||||
|
||||
/* temporarily disable Tx timestamps while calibrating PHY offset */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = true;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx_fifo_busy_cnt = 0;
|
||||
|
||||
/* Start the PHY timer in Vernier mode */
|
||||
@@ -1391,9 +1513,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
goto out_unlock;
|
||||
|
||||
/* Enable Tx timestamps right away */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = false;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
|
||||
kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work, 0);
|
||||
|
||||
@@ -2471,18 +2593,23 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
*/
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
{
|
||||
+ unsigned long flags;
|
||||
u8 idx;
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
|
||||
/* Check that this tracker is accepting new timestamp requests */
|
||||
if (!ice_ptp_is_tx_tracker_up(tx)) {
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find and set the first available index */
|
||||
- idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+ idx = find_next_zero_bit(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx == tx->len)
|
||||
+ idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+
|
||||
if (idx < tx->len) {
|
||||
/* We got a valid index that no other thread could have set. Store
|
||||
* a reference to the skb and the start time to allow discarding old
|
||||
@@ -2496,7 +2623,7 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
ice_trace(tx_tstamp_request, skb, idx);
|
||||
}
|
||||
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* return the appropriate PHY timestamp register index, -1 if no
|
||||
* indexes were available.
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index a3ae008a3539..64679d3d2c49 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -131,6 +131,7 @@ enum ice_tx_tstamp_work {
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
* @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
spinlock_t lock; /* lock protecting in_use bitmap */
|
||||
@@ -143,6 +144,7 @@ struct ice_ptp_tx {
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
u8 verify_cached : 1;
|
||||
+ s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
/* Quad and port information for initializing timestamp blocks */
|
||||
@@ -296,6 +298,8 @@ 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);
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx);
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx);
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
|
||||
void
|
||||
@@ -330,6 +334,11 @@ ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static inline void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{ }
|
||||
+
|
||||
+static inline void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { }
|
||||
+
|
||||
static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
return true;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 0cc285614c72..7e8fd369ef7c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -509,6 +509,7 @@ int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
#define TS_LL_READ_RETRIES 200
|
||||
#define TS_LL_READ_TS_HIGH GENMASK(23, 16)
|
||||
#define TS_LL_READ_TS_IDX GENMASK(29, 24)
|
||||
+#define TS_LL_READ_TS_INTR BIT(30)
|
||||
#define TS_LL_READ_TS BIT(31)
|
||||
|
||||
/* Internal PHY timestamp address */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index f8b658386552..b0f1f4db1d8b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -350,6 +350,7 @@ struct ice_ts_func_info {
|
||||
#define ICE_TS_TMR0_ENA_M BIT(25)
|
||||
#define ICE_TS_TMR1_ENA_M BIT(26)
|
||||
#define ICE_TS_LL_TX_TS_READ_M BIT(28)
|
||||
+#define ICE_TS_LL_TX_TS_INT_READ_M BIT(29)
|
||||
|
||||
struct ice_ts_dev_info {
|
||||
/* Device specific info */
|
||||
@@ -363,6 +364,7 @@ struct ice_ts_dev_info {
|
||||
u8 tmr0_ena;
|
||||
u8 tmr1_ena;
|
||||
u8 ts_ll_read;
|
||||
+ u8 ts_ll_int_read;
|
||||
};
|
||||
|
||||
/* Function specific capabilities */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,310 @@
|
||||
From f267daca86600496d536f85c4d1945558b982427 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:36 +0200
|
||||
Subject: [PATCH 14/36] ice: PTP: add clock domain number to auxiliary
|
||||
interface
|
||||
|
||||
The PHC clock id used to be moved between PFs using FW admin queue
|
||||
shared parameters - move the implementation to auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit fcd2c1e3139a27766ef263bd2011195dbc8a79f5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 5 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 +++---------------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 11 +-
|
||||
4 files changed, 34 insertions(+), 147 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 353ac55bdb9d..9bacb69ead8c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2360,11 +2360,6 @@ struct ice_aqc_driver_shared_params {
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 456cf4785c74..057453d589d5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3286,7 +3286,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);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 75038d826f71..a2d0da7dfe83 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -345,131 +345,6 @@ void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
ice_set_rx_tstamp(pf, ena);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_ptp_clock_index - Get the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Determine the clock index of the PTP clock associated with this device. If
|
||||
- * this is the PF controlling the clock, just use the local access to the
|
||||
- * clock device pointer.
|
||||
- *
|
||||
- * Otherwise, read from the driver shared parameters to determine the clock
|
||||
- * index value.
|
||||
- *
|
||||
- * Returns: the index of the PTP clock associated with this device, or -1 if
|
||||
- * there is no associated clock.
|
||||
- */
|
||||
-int ice_get_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- /* Use the ptp_clock structure if we're the main PF */
|
||||
- if (pf->ptp.clock)
|
||||
- return ptp_clock_index(pf->ptp.clock);
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_get_driver_param(hw, param_idx, &value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to read PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* The PTP clock index is an integer, and will be between 0 and
|
||||
- * INT_MAX. The highest bit of the driver shared parameter is used to
|
||||
- * indicate whether or not the currently stored clock index is valid.
|
||||
- */
|
||||
- if (!(value & PTP_SHARED_CLK_IDX_VALID))
|
||||
- return -1;
|
||||
-
|
||||
- return value & ~PTP_SHARED_CLK_IDX_VALID;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_set_ptp_clock_index - Set the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Set the PTP clock index for this device into the shared driver parameters,
|
||||
- * so that other PFs associated with this device can read it.
|
||||
- *
|
||||
- * If the PF is unable to store the clock index, it will log an error, but
|
||||
- * will continue operating PTP.
|
||||
- */
|
||||
-static void ice_set_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- if (!pf->ptp.clock)
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- value = (u32)ptp_clock_index(pf->ptp.clock);
|
||||
- if (value > INT_MAX) {
|
||||
- dev_err(dev, "PTP Clock index is too large to store\n");
|
||||
- return;
|
||||
- }
|
||||
- value |= PTP_SHARED_CLK_IDX_VALID;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to set PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_clear_ptp_clock_index - Clear the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Clear the PTP clock index for this device. Must be called when
|
||||
- * unregistering the PTP clock, in order to ensure other PFs stop reporting
|
||||
- * a clock object that no longer exists.
|
||||
- */
|
||||
-static void ice_clear_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- int err;
|
||||
-
|
||||
- /* Do not clear the index if we don't own the timer */
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, 0, NULL);
|
||||
- if (err) {
|
||||
- dev_dbg(dev, "Failed to clear PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_read_src_clk_reg - Read the source clock register
|
||||
* @pf: Board private structure
|
||||
@@ -2564,7 +2439,6 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
|
||||
static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
{
|
||||
struct ptp_clock_info *info;
|
||||
- struct ptp_clock *clock;
|
||||
struct device *dev;
|
||||
|
||||
/* No need to create a clock device if we already have one */
|
||||
@@ -2577,11 +2451,11 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
/* Attempt to register the clock before enabling the hardware. */
|
||||
- clock = ptp_clock_register(info, dev);
|
||||
- if (IS_ERR(clock))
|
||||
- return PTR_ERR(clock);
|
||||
-
|
||||
- pf->ptp.clock = clock;
|
||||
+ pf->ptp.clock = ptp_clock_register(info, dev);
|
||||
+ if (IS_ERR(pf->ptp.clock)) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP clock device");
|
||||
+ return PTR_ERR(pf->ptp.clock);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2996,6 +2870,28 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_clock_index - Get the PTP clock index for this device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Returns: the PTP clock index associated with this PF, or -1 if no PTP clock
|
||||
+ * is associated.
|
||||
+ */
|
||||
+int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_pf *owner_pf;
|
||||
+ struct ptp_clock *clock;
|
||||
+
|
||||
+ aux_dev = &pf->ptp.port.aux_dev;
|
||||
+ owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ if (!owner_pf)
|
||||
+ return -1;
|
||||
+ clock = owner_pf->ptp.clock;
|
||||
+
|
||||
+ return clock ? ptp_clock_index(clock) : -1;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -3086,9 +2982,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err_clk;
|
||||
|
||||
- /* Store the PTP clock index for other PFs */
|
||||
- ice_set_ptp_clock_index(pf);
|
||||
-
|
||||
err = ice_ptp_register_auxbus_driver(pf);
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
@@ -3097,7 +2990,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
return 0;
|
||||
err_aux:
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
@@ -3353,7 +3245,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable periodic outputs */
|
||||
ice_ptp_disable_all_clkout(pf);
|
||||
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 64679d3d2c49..95ebd7a048ec 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -290,11 +290,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);
|
||||
@@ -322,10 +322,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
|
||||
@@ -353,5 +349,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_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,266 @@
|
||||
From eb63973adae478fdcc324f5490d6803646f0cc76 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:57 -0800
|
||||
Subject: [PATCH 15/36] ice: restore timestamp configuration after device reset
|
||||
|
||||
The driver calls ice_ptp_cfg_timestamp() during ice_ptp_prepare_for_reset()
|
||||
to disable timestamping while the device is resetting. This operation
|
||||
destroys the user requested configuration. While the driver does call
|
||||
ice_ptp_cfg_timestamp in ice_rebuild() to restore some hardware settings
|
||||
after a reset, it unconditionally passes true or false, resulting in
|
||||
failure to restore previous user space configuration.
|
||||
|
||||
This results in a device reset forcibly disabling timestamp configuration
|
||||
regardless of current user settings.
|
||||
|
||||
This was not detected previously due to a quirk of the LinuxPTP ptp4l
|
||||
application. If ptp4l detects a missing timestamp, it enters a fault state
|
||||
and performs recovery logic which includes executing SIOCSHWTSTAMP again,
|
||||
restoring the now accidentally cleared configuration.
|
||||
|
||||
Not every application does this, and for these applications, timestamps
|
||||
will mysteriously stop after a PF reset, without being restored until an
|
||||
application restart.
|
||||
|
||||
Fix this by replacing ice_ptp_cfg_timestamp() with two new functions:
|
||||
|
||||
1) ice_ptp_disable_timestamp_mode() which unconditionally disables the
|
||||
timestamping logic in ice_ptp_prepare_for_reset() and ice_ptp_release()
|
||||
|
||||
2) ice_ptp_restore_timestamp_mode() which calls
|
||||
ice_ptp_restore_tx_interrupt() to restore Tx timestamping configuration,
|
||||
calls ice_set_rx_tstamp() to restore Rx timestamping configuration, and
|
||||
issues an immediate TSYN_TX interrupt to ensure that timestamps which
|
||||
may have occurred during the device reset get processed.
|
||||
|
||||
Modify the ice_ptp_set_timestamp_mode to directly save the user
|
||||
configuration and then call ice_ptp_restore_timestamp_mode. This way, reset
|
||||
no longer destroys the saved user configuration.
|
||||
|
||||
This obsoletes the ice_set_tx_tstamp() function which can now be safely
|
||||
removed.
|
||||
|
||||
With this change, all devices should now restore Tx and Rx timestamping
|
||||
functionality correctly after a PF reset without application intervention.
|
||||
|
||||
Fixes: 77a781155a65 ("ice: enable receive hardware timestamping")
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7758017911a4f2578d54c318e8fe77bcb5899054)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 12 +---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 74 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 5 +-
|
||||
3 files changed, 51 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 9163a72368b3..8cfb923198e9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7545,15 +7545,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err_vsi_rebuild;
|
||||
}
|
||||
|
||||
- /* configure PTP timestamping after VSI rebuild */
|
||||
- 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) {
|
||||
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
|
||||
@@ -7605,6 +7596,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_plug_aux_dev(pf);
|
||||
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
|
||||
ice_lag_rebuild(pf);
|
||||
+
|
||||
+ /* Restore timestamp mode settings after VSI rebuild */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
return;
|
||||
|
||||
err_vsi_rebuild:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a2d0da7dfe83..8fc6905b0f79 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -294,18 +294,6 @@ static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamps are enabled or disabled
|
||||
- */
|
||||
-static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
-{
|
||||
- pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
-
|
||||
- ice_ptp_cfg_tx_interrupt(pf);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_set_rx_tstamp - Enable or disable Rx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -317,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
+ if (!vsi || !vsi->rx_rings)
|
||||
return;
|
||||
|
||||
/* Set the timestamp flag for all the Rx rings */
|
||||
@@ -326,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
continue;
|
||||
vsi->rx_rings[i]->ptp_rx = on;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_disable_timestamp_mode - Disable current timestamp mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called during preparation for reset to temporarily disable timestamping on
|
||||
+ * the device. Called during remove to disable timestamping while cleaning up
|
||||
+ * driver resources.
|
||||
+ */
|
||||
+static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
|
||||
- pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
|
||||
- HWTSTAMP_FILTER_NONE;
|
||||
+ ice_set_rx_tstamp(pf, false);
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
|
||||
+ * ice_ptp_restore_timestamp_mode - Restore timestamp configuration
|
||||
* @pf: Board private structure
|
||||
- * @ena: bool value to enable or disable time stamp
|
||||
*
|
||||
- * This function will configure timestamping during PTP initialization
|
||||
- * and deinitialization
|
||||
+ * Called at the end of rebuild to restore timestamp configuration after
|
||||
+ * a device reset.
|
||||
*/
|
||||
-void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
+void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
|
||||
{
|
||||
- ice_set_tx_tstamp(pf, ena);
|
||||
- ice_set_rx_tstamp(pf, ena);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable_rx;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
+ enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL;
|
||||
+ ice_set_rx_tstamp(pf, enable_rx);
|
||||
+
|
||||
+ /* Trigger an immediate software interrupt to ensure that timestamps
|
||||
+ * which occurred during reset are handled now.
|
||||
+ */
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2152,10 +2167,10 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
{
|
||||
switch (config->tx_type) {
|
||||
case HWTSTAMP_TX_OFF:
|
||||
- ice_set_tx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
|
||||
break;
|
||||
case HWTSTAMP_TX_ON:
|
||||
- ice_set_tx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
@@ -2163,7 +2178,7 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
|
||||
switch (config->rx_filter) {
|
||||
case HWTSTAMP_FILTER_NONE:
|
||||
- ice_set_rx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
@@ -2179,12 +2194,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_NTP_ALL:
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
- ice_set_rx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
+ /* Immediately update the device timestamping mode */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2904,7 +2922,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
@@ -3222,7 +3240,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
ice_ptp_remove_auxbus_device(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 95ebd7a048ec..130e6d2ae9a5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -294,7 +294,7 @@ 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);
|
||||
+void ice_ptp_restore_timestamp_mode(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);
|
||||
@@ -321,8 +321,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
-static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
|
||||
-
|
||||
+static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
||||
static inline s8
|
||||
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,316 @@
|
||||
From 5c6115d27a377927d6392b3bfbe9739188c8153c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:49 -0800
|
||||
Subject: [PATCH 16/36] ice: introduce PTP state machine
|
||||
|
||||
Add PTP state machine so that the driver can correctly identify PTP
|
||||
state around resets.
|
||||
When the driver got information about ungraceful reset, PTP was not
|
||||
prepared for reset and it returned error. When this situation occurs,
|
||||
prepare PTP before rebuilding its structures.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 8293e4cb2ff54b1ec4f7206dcb74c908f62a3fb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 110 +++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 10 ++
|
||||
4 files changed, 74 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index ee42a504c2f4..3278d032a2bd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -492,7 +492,6 @@ enum ice_pf_flags {
|
||||
ICE_FLAG_DCB_ENA,
|
||||
ICE_FLAG_FD_ENA,
|
||||
ICE_FLAG_PTP_SUPPORTED, /* PTP is supported by NVM */
|
||||
- ICE_FLAG_PTP, /* PTP is enabled by software */
|
||||
ICE_FLAG_ADV_FEATURES,
|
||||
ICE_FLAG_TC_MQPRIO, /* support for Multi queue TC */
|
||||
ICE_FLAG_CLS_FLOWER,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 057453d589d5..9e949c493c38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3276,7 +3276,7 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
|
||||
struct ice_pf *pf = ice_netdev_to_pf(dev);
|
||||
|
||||
/* only report timestamping if PTP is enabled */
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return ethtool_op_get_ts_info(dev, info);
|
||||
|
||||
info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 8fc6905b0f79..36c81c5ee83b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1430,7 +1430,7 @@ 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))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
@@ -2148,7 +2148,7 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
{
|
||||
struct hwtstamp_config *config;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EIO;
|
||||
|
||||
config = &pf->ptp.tstamp_config;
|
||||
@@ -2218,7 +2218,7 @@ int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
struct hwtstamp_config config;
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EAGAIN;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
@@ -2606,7 +2606,7 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp);
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
@@ -2618,6 +2618,42 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ u8 src_tmr;
|
||||
+
|
||||
+ if (ptp->state != ICE_PTP_READY)
|
||||
+ return;
|
||||
+
|
||||
+ ptp->state = ICE_PTP_RESETTING;
|
||||
+
|
||||
+ /* Disable timestamping for both Tx and Rx */
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
+
|
||||
+ kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
+
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ return;
|
||||
+
|
||||
+ ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
+
|
||||
+ /* Disable periodic outputs */
|
||||
+ ice_ptp_disable_all_clkout(pf);
|
||||
+
|
||||
+ src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
+
|
||||
+ /* Disable source clock */
|
||||
+ wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
+
|
||||
+ /* Acquire PHC and system timer to restore after reset */
|
||||
+ ptp->reset_time = ktime_get_real_ns();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
@@ -2630,6 +2666,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
!ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
@@ -2690,7 +2734,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Restart the PHY timestamping block */
|
||||
if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
@@ -2704,6 +2748,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
err:
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -2910,39 +2955,6 @@ int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
return clock ? ptp_clock_index(clock) : -1;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
- * @pf: Board private structure
|
||||
- */
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_ptp *ptp = &pf->ptp;
|
||||
- u8 src_tmr;
|
||||
-
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
- /* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_disable_timestamp_mode(pf);
|
||||
-
|
||||
- kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
-
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
- return;
|
||||
-
|
||||
- ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
-
|
||||
- /* Disable periodic outputs */
|
||||
- ice_ptp_disable_all_clkout(pf);
|
||||
-
|
||||
- src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
-
|
||||
- /* Disable source clock */
|
||||
- wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
-
|
||||
- /* Acquire PHC and system timer to restore after reset */
|
||||
- ptp->reset_time = ktime_get_real_ns();
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_init_owner - Initialize PTP_1588_CLOCK device
|
||||
* @pf: Board private structure
|
||||
@@ -3181,6 +3193,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err;
|
||||
|
||||
+ ptp->state = ICE_PTP_INITIALIZING;
|
||||
+
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
@@ -3205,12 +3219,13 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Configure initial Tx interrupt settings */
|
||||
ice_ptp_cfg_tx_interrupt(pf);
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
- err = ice_ptp_init_work(pf, ptp);
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- err = ice_ptp_create_auxbus_device(pf);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
+
|
||||
+ err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
@@ -3223,7 +3238,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
ptp_clock_unregister(ptp->clock);
|
||||
pf->ptp.clock = NULL;
|
||||
}
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -3236,9 +3251,11 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
*/
|
||||
void ice_ptp_release(struct ice_pf *pf)
|
||||
{
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
+ pf->ptp.state = ICE_PTP_UNINIT;
|
||||
+
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
@@ -3246,8 +3263,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
kthread_cancel_delayed_work_sync(&pf->ptp.work);
|
||||
|
||||
ice_ptp_port_phy_stop(&pf->ptp.port);
|
||||
@@ -3257,6 +3272,9 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
pf->ptp.kworker = NULL;
|
||||
}
|
||||
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
if (!pf->ptp.clock)
|
||||
return;
|
||||
|
||||
@@ -3266,7 +3284,5 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
- ice_ptp_unregister_auxbus_driver(pf);
|
||||
-
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 130e6d2ae9a5..e3cc69692405 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -203,8 +203,17 @@ struct ice_ptp_port_owner {
|
||||
|
||||
#define GLTSYN_TGT_H_IDX_MAX 4
|
||||
|
||||
+enum ice_ptp_state {
|
||||
+ ICE_PTP_UNINIT = 0,
|
||||
+ ICE_PTP_INITIALIZING,
|
||||
+ ICE_PTP_READY,
|
||||
+ ICE_PTP_RESETTING,
|
||||
+ ICE_PTP_ERROR,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
|
||||
+ * @state: current state of PTP state machine
|
||||
* @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
|
||||
@@ -227,6 +236,7 @@ struct ice_ptp_port_owner {
|
||||
* @late_cached_phc_updates: number of times cached PHC update is late
|
||||
*/
|
||||
struct ice_ptp {
|
||||
+ enum ice_ptp_state state;
|
||||
enum ice_ptp_tx_interrupt tx_interrupt_mode;
|
||||
struct ice_ptp_port port;
|
||||
struct ice_ptp_port_owner ports_owner;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 68d481b41ee5c177a1376fb82a98c09c148d982a Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:50 -0800
|
||||
Subject: [PATCH 17/36] ice: pass reset type to PTP reset functions
|
||||
|
||||
The ice_ptp_prepare_for_reset() and ice_ptp_reset() functions currently
|
||||
check the pf->flags ICE_FLAG_PFR_REQ bit to determine if the current
|
||||
reset is a PF reset or not.
|
||||
|
||||
This is problematic, because it is possible that a PF reset and a higher
|
||||
level reset (CORE reset, GLOBAL reset, EMP reset) are requested
|
||||
simultaneously. In that case, the driver performs the highest level
|
||||
reset requested. However, the ICE_FLAG_PFR_REQ flag will still be set.
|
||||
|
||||
The main driver reset functions take an enum ice_reset_req indicating
|
||||
which reset is actually being performed. Pass this data into the PTP
|
||||
functions and rely on this instead of relying on the driver flags.
|
||||
|
||||
This ensures that the PTP code performs the proper level of reset that
|
||||
the driver is actually undergoing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit c75d5e675a8542274fa0f7e52f3c4db1d4859a0c)
|
||||
[Adjust the ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 4 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 13 +++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 17 +++++++++++++----
|
||||
3 files changed, 22 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8cfb923198e9..d5321410f2d7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -615,7 +615,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_pf_dis_all_vsi(pf, false);
|
||||
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_exit(pf);
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf);
|
||||
+ ice_ptp_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 36c81c5ee83b..20d1d22235d3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2621,8 +2621,9 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
u8 src_tmr;
|
||||
@@ -2637,7 +2638,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (reset_type == ICE_RESET_PFR)
|
||||
return;
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
@@ -2657,8 +2658,9 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,15 +2669,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
u64 time_diff;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
} else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
err = -EINVAL;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
- !ice_pf_src_tmr_owned(pf))
|
||||
+ if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index e3cc69692405..cd74712a17a1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -315,8 +315,9 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf);
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf);
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
void ice_ptp_release(struct ice_pf *pf);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
|
||||
@@ -351,8 +352,16 @@ static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf) { }
|
||||
-static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { }
|
||||
+
|
||||
+static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
||||
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)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,119 @@
|
||||
From 084497314e63f3d92178bc44500a27a277abc378 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:51 -0800
|
||||
Subject: [PATCH 18/36] ice: rename verify_cached to has_ready_bitmap
|
||||
|
||||
The tx->verify_cached flag is used to inform the Tx timestamp tracking
|
||||
code whether it needs to verify the cached Tx timestamp value against
|
||||
a previous captured value. This is necessary on E810 hardware which does
|
||||
not have a Tx timestamp ready bitmap.
|
||||
|
||||
In addition, we currently rely on the fact that the
|
||||
ice_get_phy_tx_tstamp_ready() function returns all 1s for E810 hardware.
|
||||
Instead of introducing a brand new flag, rename and verify_cached to
|
||||
has_ready_bitmap, inverting the relevant checks.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 3f2216e8dbce04da5376ea7df410541f7b687cb0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 +++++---
|
||||
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 20d1d22235d3..a8c6b83579e6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -606,11 +606,11 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
* timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
* been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -751,7 +751,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* from the last cached timestamp. If it is not, skip this for
|
||||
* now assuming it hasn't yet been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
continue;
|
||||
|
||||
@@ -761,7 +761,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
|
||||
skip_ts_read:
|
||||
spin_lock_irqsave(&tx->lock, flags);
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -1014,7 +1014,7 @@ ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
- tx->verify_cached = 0;
|
||||
+ tx->has_ready_bitmap = 1;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
* verify new timestamps against cached copy of the last read
|
||||
* timestamp.
|
||||
*/
|
||||
- tx->verify_cached = 1;
|
||||
+ tx->has_ready_bitmap = 0;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index cd74712a17a1..1486a0b3b016 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -100,7 +100,7 @@ struct ice_perout_channel {
|
||||
* the last timestamp we read for a given index. If the current timestamp
|
||||
* value is the same as the cached value, we assume a new timestamp hasn't
|
||||
* been captured. This avoids reporting stale timestamps to the stack. This is
|
||||
- * only done if the verify_cached flag is set in ice_ptp_tx structure.
|
||||
+ * only done if the has_ready_bitmap flag is not set in ice_ptp_tx structure.
|
||||
*/
|
||||
struct ice_tx_tstamp {
|
||||
struct sk_buff *skb;
|
||||
@@ -130,7 +130,9 @@ enum ice_tx_tstamp_work {
|
||||
* @init: if true, the tracker is initialized;
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
- * @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @has_ready_bitmap: if true, the hardware has a valid Tx timestamp ready
|
||||
+ * bitmap register. If false, fall back to verifying new
|
||||
+ * timestamp values against previously cached copy.
|
||||
* @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
@@ -143,7 +145,7 @@ struct ice_ptp_tx {
|
||||
u8 len;
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
- u8 verify_cached : 1;
|
||||
+ u8 has_ready_bitmap : 1;
|
||||
s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,77 @@
|
||||
From 375bced6b51243a8c8708204dd32960d076d5b83 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:52 -0800
|
||||
Subject: [PATCH 19/36] ice: don't check has_ready_bitmap in E810 functions
|
||||
|
||||
E810 hardware does not have a Tx timestamp ready bitmap. Don't check
|
||||
has_ready_bitmap in E810-specific functions.
|
||||
Add has_ready_bitmap check in ice_ptp_process_tx_tstamp() to stop
|
||||
relying on the fact that ice_get_phy_tx_tstamp_ready() returns all 1s.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit fea82915fca626eaa83f36d8a23194e8593ef4b4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 23 +++++++++++------------
|
||||
1 file changed, 11 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a8c6b83579e6..ddc2dd0b2a28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -601,17 +601,13 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
/* Read the low 32 bit value */
|
||||
raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
|
||||
- /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
- * verify that the timestamp value is different from the last cached
|
||||
- * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
- * been captured by hardware.
|
||||
+ /* Devices using this interface always verify the timestamp differs
|
||||
+ * relative to the last cached timestamp value.
|
||||
*/
|
||||
- if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
- raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ if (raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
- tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
@@ -701,9 +697,11 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
hw = &pf->hw;
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
- err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
- if (err)
|
||||
- return;
|
||||
+ if (tx->has_ready_bitmap) {
|
||||
+ err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
+ if (err)
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* Drop packets if the link went down */
|
||||
link_up = ptp_port->link_up;
|
||||
@@ -731,7 +729,8 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* If we do not, the hardware logic for generating a new
|
||||
* interrupt can get stuck on some devices.
|
||||
*/
|
||||
- if (!(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
+ if (tx->has_ready_bitmap &&
|
||||
+ !(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
if (drop_ts)
|
||||
goto skip_ts_read;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,88 @@
|
||||
From a5318a3a04ed9535ab18ef0f0537b3d33862bee9 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:53 -0800
|
||||
Subject: [PATCH 20/36] ice: rename ice_ptp_tx_cfg_intr
|
||||
|
||||
The ice_ptp_tx_cfg_intr() function sends a control queue message to
|
||||
configure the PHY timestamp interrupt block. This is a very similar name
|
||||
to a function which is used to configure the MAC Other Interrupt Cause
|
||||
Enable register.
|
||||
|
||||
Rename this function to ice_ptp_cfg_phy_interrupt in order to make it
|
||||
more obvious to the reader what action it performs, and distinguish it
|
||||
from other similarly named functions.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1abefdca85e8664374f53c7bc80d5f5f827ce711)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ddc2dd0b2a28..c6e9d77fc59b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1455,14 +1455,14 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_tx_ena_intr - Enable or disable the Tx timestamp interrupt
|
||||
+ * ice_ptp_cfg_phy_interrupt - Configure PHY interrupt settings
|
||||
* @pf: PF private structure
|
||||
* @ena: bool value to enable or disable interrupt
|
||||
* @threshold: Minimum number of packets at which intr is triggered
|
||||
*
|
||||
* Utility function to enable or disable Tx timestamp interrupt and threshold
|
||||
*/
|
||||
-static int ice_ptp_tx_ena_intr(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
+static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err = 0;
|
||||
@@ -2664,8 +2664,8 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
u64 time_diff;
|
||||
+ int err;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
@@ -2716,7 +2716,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
@@ -2967,7 +2967,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
+ int err;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err) {
|
||||
@@ -3002,7 +3002,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,191 @@
|
||||
From 9411c5b82a7196b9712488631fd14e67e2d919fa Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:54 -0800
|
||||
Subject: [PATCH 21/36] ice: factor out ice_ptp_rebuild_owner()
|
||||
|
||||
The ice_ptp_reset() function uses a goto to skip past clock owner
|
||||
operations if performing a PF reset or if the device is not the clock
|
||||
owner. This is a bit confusing. Factor this out into
|
||||
ice_ptp_rebuild_owner() instead.
|
||||
|
||||
The ice_ptp_reset() function is called by ice_rebuild() to restore PTP
|
||||
functionality after a device reset. Follow the convention set by the
|
||||
ice_main.c file and rename this function to ice_ptp_rebuild(), in the
|
||||
same way that we have ice_prepare_for_reset() and
|
||||
ice_ptp_prepare_for_reset().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 803bef817807d2d36c930dada20c96fffae0dd19)
|
||||
[Adjust ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 62 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 6 +--
|
||||
3 files changed, 42 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d5321410f2d7..a04dcc89c35d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf, reset_type);
|
||||
+ ice_ptp_rebuild(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c6e9d77fc59b..780aa242c86b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2655,11 +2655,13 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
+ * ice_ptp_rebuild_owner - Initialize PTP clock owner after reset
|
||||
* @pf: Board private structure
|
||||
- * @reset_type: the reset type being performed
|
||||
+ *
|
||||
+ * Companion function for ice_ptp_rebuild() which handles tasks that only the
|
||||
+ * PTP clock owner instance should perform.
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,32 +2669,21 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
u64 time_diff;
|
||||
int err;
|
||||
|
||||
- if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
- } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
- err = -EINVAL;
|
||||
- dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
- goto pfr;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
- goto err;
|
||||
+ return err;
|
||||
|
||||
/* Acquire the global hardware lock */
|
||||
if (!ice_ptp_lock(hw)) {
|
||||
err = -EBUSY;
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the increment time value to PHY and LAN */
|
||||
err = ice_ptp_write_incval(hw, ice_base_incval(pf));
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the initial Time value to PHY and LAN using the cached PHC
|
||||
@@ -2708,7 +2699,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
err = ice_ptp_write_init(pf, &ts);
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Release the global hardware lock */
|
||||
@@ -2717,11 +2708,39 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_rebuild - Initialize PTP hardware clock support after reset
|
||||
+ * @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
+ */
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ int err;
|
||||
+
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (ice_pf_src_tmr_owned(pf) && reset_type != ICE_RESET_PFR) {
|
||||
+ err = ice_ptp_rebuild_owner(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
@@ -2736,11 +2755,6 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
- /* Restart the PHY timestamping block */
|
||||
- if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
- ice_pf_src_tmr_owned(pf))
|
||||
- ice_ptp_restart_all_phy(pf);
|
||||
-
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 1486a0b3b016..352405a2daf2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -317,7 +317,7 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
@@ -355,8 +355,8 @@ static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
- enum ice_reset_req reset_type)
|
||||
+static inline void ice_ptp_rebuild(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
{
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 1c89a9e26f669bead5ebcac38fa98c20c517769c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:55 -0800
|
||||
Subject: [PATCH 22/36] ice: stop destroying and reinitalizing Tx tracker
|
||||
during reset
|
||||
|
||||
The ice driver currently attempts to destroy and re-initialize the Tx
|
||||
timestamp tracker during the reset flow. The release of the Tx tracker
|
||||
only happened during CORE reset or GLOBAL reset. The ice_ptp_rebuild()
|
||||
function always calls the ice_ptp_init_tx function which will allocate
|
||||
a new tracker data structure, resulting in memory leaks during PF reset.
|
||||
|
||||
Certainly the driver should not be allocating a new tracker without
|
||||
removing the old tracker data, as this results in a memory leak.
|
||||
Additionally, there's no reason to remove the tracker memory during a
|
||||
reset. Remove this logic from the reset and rebuild flow. Instead of
|
||||
releasing the Tx tracker, flush outstanding timestamps just before we
|
||||
reset the PHY timestamp block in ice_ptp_cfg_phy_interrupt().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7a25fe5cd5fb2265065ac6765c53c0a1f1e874d3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 33 +++++++++++++++---------
|
||||
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 780aa242c86b..48ec59fc5d87 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -963,6 +963,22 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_flush_all_tx_tracker - Flush all timestamp trackers on this clock
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called by the clock owner to flush all the Tx timestamp trackers associated
|
||||
+ * with the clock.
|
||||
+ */
|
||||
+static void
|
||||
+ice_ptp_flush_all_tx_tracker(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member)
|
||||
+ ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_release_tx_tracker - Release allocated memory for Tx tracker
|
||||
* @pf: Board private structure
|
||||
@@ -2705,6 +2721,11 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
+ /* Flush software tracking of any outstanding timestamps since we're
|
||||
+ * about to flush the PHY timestamp block.
|
||||
+ */
|
||||
+ ice_ptp_flush_all_tx_tracker(pf);
|
||||
+
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
@@ -2741,18 +2762,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- /* Init Tx structures */
|
||||
- if (ice_is_e810(&pf->hw)) {
|
||||
- err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
- } else {
|
||||
- kthread_init_delayed_work(&ptp->port.ov_work,
|
||||
- ice_ptp_wait_for_offsets);
|
||||
- err = ice_ptp_init_tx_e82x(pf, &ptp->port.tx,
|
||||
- ptp->port.port_num);
|
||||
- }
|
||||
- if (err)
|
||||
- goto err;
|
||||
-
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Start periodic work going */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,457 @@
|
||||
From 6f1d1fa58f58ff3f6ce61ab502bd29227ca1bb3f Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:56 +0100
|
||||
Subject: [PATCH 23/36] ice: Remove and readd netdev during devlink reload
|
||||
|
||||
Recent changes to the devlink reload (commit 9b2348e2d6c9
|
||||
("devlink: warn about existing entities during reload-reinit"))
|
||||
force the drivers to destroy devlink ports during reinit.
|
||||
Adjust ice driver to this requirement, unregister netdvice, destroy
|
||||
devlink port. ice_init_eth() was removed and all the common code
|
||||
between probe and reload was moved to ice_load().
|
||||
|
||||
During devlink reload we can't take devl_lock (it's already taken)
|
||||
and in ice_probe() we have to lock it. Use devl_* variant of the API
|
||||
which does not acquire and release devl_lock. Guard ice_load()
|
||||
with devl_lock only in case of probe.
|
||||
|
||||
Suggested-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 41cc4e53934c30f1cf7745c257154e538c78a1f5)
|
||||
[Adjust ice.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_devlink.c | 68 ++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 186 ++++++-------------
|
||||
3 files changed, 125 insertions(+), 131 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 3278d032a2bd..d3f72f9fbcd7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -978,6 +978,8 @@ int ice_stop(struct net_device *netdev);
|
||||
void ice_service_task_schedule(struct ice_pf *pf);
|
||||
int ice_load(struct ice_pf *pf);
|
||||
void ice_unload(struct ice_pf *pf);
|
||||
+int ice_init_dev(struct ice_pf *pf);
|
||||
+void ice_deinit_dev(struct ice_pf *pf);
|
||||
|
||||
/**
|
||||
* ice_set_rdma_cap - enable RDMA support
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
index 3a2261823d93..43007e3674c4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
@@ -444,6 +444,20 @@ ice_devlink_reload_empr_start(struct ice_pf *pf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_down - unload given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static void ice_devlink_reinit_down(struct ice_pf *pf)
|
||||
+{
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ ice_unload(pf);
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
+ rtnl_unlock();
|
||||
+ ice_deinit_dev(pf);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_down - prepare for reload
|
||||
* @devlink: pointer to the devlink instance to reload
|
||||
@@ -477,7 +491,7 @@ ice_devlink_reload_down(struct devlink *devlink, bool netns_change,
|
||||
"Remove all VFs before doing reinit\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
- ice_unload(pf);
|
||||
+ ice_devlink_reinit_down(pf);
|
||||
return 0;
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
return ice_devlink_reload_empr_start(pf, extack);
|
||||
@@ -1240,6 +1254,45 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_up - do reinit of the given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static int ice_devlink_reinit_up(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+ struct ice_vsi_cfg_params params;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_init_dev(pf);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ params = ice_vsi_to_params(vsi);
|
||||
+ params.flags = ICE_VSI_FLAG_INIT;
|
||||
+
|
||||
+ rtnl_lock();
|
||||
+ err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ rtnl_unlock();
|
||||
+ if (err)
|
||||
+ goto err_vsi_cfg;
|
||||
+
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ err = ice_load(pf);
|
||||
+ if (err)
|
||||
+ goto err_load;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_load:
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(vsi);
|
||||
+ rtnl_unlock();
|
||||
+err_vsi_cfg:
|
||||
+ ice_deinit_dev(pf);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_up - do reload up after reinit
|
||||
* @devlink: pointer to the devlink instance reloading
|
||||
@@ -1260,7 +1313,7 @@ ice_devlink_reload_up(struct devlink *devlink,
|
||||
switch (action) {
|
||||
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
||||
- return ice_load(pf);
|
||||
+ return ice_devlink_reinit_up(pf);
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
|
||||
return ice_devlink_reload_empr_finish(pf, extack);
|
||||
@@ -1540,6 +1593,7 @@ static const struct devlink_port_ops ice_devlink_port_ops = {
|
||||
* @pf: the PF to create a devlink port for
|
||||
*
|
||||
* Create and register a devlink_port for this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*
|
||||
* Return: zero on success or an error code on failure.
|
||||
*/
|
||||
@@ -1552,6 +1606,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
struct device *dev;
|
||||
int err;
|
||||
|
||||
+ devlink = priv_to_devlink(pf);
|
||||
+
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
devlink_port = &pf->devlink_port;
|
||||
@@ -1572,10 +1628,9 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
ice_devlink_set_switch_id(pf, &attrs.switch_id);
|
||||
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
- devlink = priv_to_devlink(pf);
|
||||
|
||||
- err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
- &ice_devlink_port_ops);
|
||||
+ err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
+ &ice_devlink_port_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
|
||||
pf->hw.pf_id, err);
|
||||
@@ -1590,10 +1645,11 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
* @pf: the PF to cleanup
|
||||
*
|
||||
* Unregisters the devlink_port structure associated with this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_devlink_destroy_pf_port(struct ice_pf *pf)
|
||||
{
|
||||
- devlink_port_unregister(&pf->devlink_port);
|
||||
+ devl_port_unregister(&pf->devlink_port);
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index a04dcc89c35d..d3340114297a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -4588,90 +4588,6 @@ static void ice_decfg_netdev(struct ice_vsi *vsi)
|
||||
vsi->netdev = NULL;
|
||||
}
|
||||
|
||||
-static int ice_start_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- int err;
|
||||
-
|
||||
- err = ice_init_mac_fltr(vsi->back);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- err = ice_vsi_open(vsi);
|
||||
- if (err)
|
||||
- ice_fltr_remove_all(vsi);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_stop_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- ice_fltr_remove_all(vsi);
|
||||
- ice_vsi_close(vsi);
|
||||
-}
|
||||
-
|
||||
-static int ice_init_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
- int err;
|
||||
-
|
||||
- if (!vsi)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- /* init channel list */
|
||||
- INIT_LIST_HEAD(&vsi->ch_list);
|
||||
-
|
||||
- err = ice_cfg_netdev(vsi);
|
||||
- if (err)
|
||||
- return err;
|
||||
- /* Setup DCB netlink interface */
|
||||
- ice_dcbnl_setup(vsi);
|
||||
-
|
||||
- err = ice_init_mac_fltr(pf);
|
||||
- if (err)
|
||||
- goto err_init_mac_fltr;
|
||||
-
|
||||
- err = ice_devlink_create_pf_port(pf);
|
||||
- if (err)
|
||||
- goto err_devlink_create_pf_port;
|
||||
-
|
||||
- SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
-
|
||||
- err = ice_register_netdev(vsi);
|
||||
- if (err)
|
||||
- goto err_register_netdev;
|
||||
-
|
||||
- err = ice_tc_indir_block_register(vsi);
|
||||
- if (err)
|
||||
- goto err_tc_indir_block_register;
|
||||
-
|
||||
- ice_napi_add(vsi);
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-err_tc_indir_block_register:
|
||||
- ice_unregister_netdev(vsi);
|
||||
-err_register_netdev:
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
-err_devlink_create_pf_port:
|
||||
-err_init_mac_fltr:
|
||||
- ice_decfg_netdev(vsi);
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_deinit_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
-
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- ice_vsi_close(vsi);
|
||||
- ice_unregister_netdev(vsi);
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
- ice_tc_indir_block_unregister(vsi);
|
||||
- ice_decfg_netdev(vsi);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_wait_for_fw - wait for full FW readiness
|
||||
* @hw: pointer to the hardware structure
|
||||
@@ -4697,7 +4613,7 @@ static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
-static int ice_init_dev(struct ice_pf *pf)
|
||||
+int ice_init_dev(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -4790,7 +4706,7 @@ static int ice_init_dev(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void ice_deinit_dev(struct ice_pf *pf)
|
||||
+void ice_deinit_dev(struct ice_pf *pf)
|
||||
{
|
||||
ice_free_irq_msix_misc(pf);
|
||||
ice_deinit_pf(pf);
|
||||
@@ -5091,31 +5007,47 @@ static void ice_deinit(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_load - load pf by init hw and starting VSI
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
int ice_load(struct ice_pf *pf)
|
||||
{
|
||||
- struct ice_vsi_cfg_params params = {};
|
||||
struct ice_vsi *vsi;
|
||||
int err;
|
||||
|
||||
- err = ice_init_dev(pf);
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
+ vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ /* init channel list */
|
||||
+ INIT_LIST_HEAD(&vsi->ch_list);
|
||||
+
|
||||
+ err = ice_cfg_netdev(vsi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
+ /* Setup DCB netlink interface */
|
||||
+ ice_dcbnl_setup(vsi);
|
||||
|
||||
- params = ice_vsi_to_params(vsi);
|
||||
- params.flags = ICE_VSI_FLAG_INIT;
|
||||
+ err = ice_init_mac_fltr(pf);
|
||||
+ if (err)
|
||||
+ goto err_init_mac_fltr;
|
||||
|
||||
- rtnl_lock();
|
||||
- err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ err = ice_devlink_create_pf_port(pf);
|
||||
if (err)
|
||||
- goto err_vsi_cfg;
|
||||
+ goto err_devlink_create_pf_port;
|
||||
|
||||
- err = ice_start_eth(ice_get_main_vsi(pf));
|
||||
+ SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
+
|
||||
+ err = ice_register_netdev(vsi);
|
||||
+ if (err)
|
||||
+ goto err_register_netdev;
|
||||
+
|
||||
+ err = ice_tc_indir_block_register(vsi);
|
||||
if (err)
|
||||
- goto err_start_eth;
|
||||
- rtnl_unlock();
|
||||
+ goto err_tc_indir_block_register;
|
||||
+
|
||||
+ ice_napi_add(vsi);
|
||||
|
||||
err = ice_init_rdma(pf);
|
||||
if (err)
|
||||
@@ -5129,29 +5061,35 @@ int ice_load(struct ice_pf *pf)
|
||||
return 0;
|
||||
|
||||
err_init_rdma:
|
||||
- ice_vsi_close(ice_get_main_vsi(pf));
|
||||
- rtnl_lock();
|
||||
-err_start_eth:
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
-err_vsi_cfg:
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+err_tc_indir_block_register:
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+err_register_netdev:
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+err_devlink_create_pf_port:
|
||||
+err_init_mac_fltr:
|
||||
+ ice_decfg_netdev(vsi);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_unload - unload pf by stopping VSI and deinit hw
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_unload(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
ice_deinit_features(pf);
|
||||
ice_deinit_rdma(pf);
|
||||
- rtnl_lock();
|
||||
- ice_stop_eth(ice_get_main_vsi(pf));
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+ ice_decfg_netdev(vsi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5249,27 +5187,23 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
|
||||
if (err)
|
||||
goto err_init;
|
||||
|
||||
- err = ice_init_eth(pf);
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ err = ice_load(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
if (err)
|
||||
- goto err_init_eth;
|
||||
-
|
||||
- err = ice_init_rdma(pf);
|
||||
- if (err)
|
||||
- goto err_init_rdma;
|
||||
+ goto err_load;
|
||||
|
||||
err = ice_init_devlink(pf);
|
||||
if (err)
|
||||
goto err_init_devlink;
|
||||
|
||||
- ice_init_features(pf);
|
||||
-
|
||||
return 0;
|
||||
|
||||
err_init_devlink:
|
||||
- ice_deinit_rdma(pf);
|
||||
-err_init_rdma:
|
||||
- ice_deinit_eth(pf);
|
||||
-err_init_eth:
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+err_load:
|
||||
ice_deinit(pf);
|
||||
err_init:
|
||||
pci_disable_device(pdev);
|
||||
@@ -5363,12 +5297,14 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
|
||||
if (!ice_is_safe_mode(pf))
|
||||
ice_remove_arfs(pf);
|
||||
- ice_deinit_features(pf);
|
||||
+
|
||||
ice_deinit_devlink(pf);
|
||||
- ice_deinit_rdma(pf);
|
||||
- ice_deinit_eth(pf);
|
||||
- ice_deinit(pf);
|
||||
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+
|
||||
+ ice_deinit(pf);
|
||||
ice_vsi_release_all(pf);
|
||||
|
||||
ice_setup_mc_magic_wake(pf);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,434 @@
|
||||
From e110839c4d9bfa4c885877a69573f48c008d3edd Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:11 -0800
|
||||
Subject: [PATCH 24/36] ice: remove FW logging code
|
||||
|
||||
The FW logging code doesn't work because there is no way to set
|
||||
cq_ena or uart_ena so remove the code. This code is the original
|
||||
(v1) way of FW logging so it should be replaced with the v2 way.
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1953fc720e603721764f31daae216a2851664167)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 78 -------
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 217 ------------------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 -
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 20 --
|
||||
5 files changed, 319 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 9bacb69ead8c..3b289e6a225b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2032,78 +2032,6 @@ struct ice_aqc_add_rdma_qset_data {
|
||||
struct ice_aqc_add_tx_rdma_qset_entry rdma_qsets[];
|
||||
};
|
||||
|
||||
-/* Configure Firmware Logging Command (indirect 0xFF09)
|
||||
- * Logging Information Read Response (indirect 0xFF10)
|
||||
- * Note: The 0xFF10 command has no input parameters.
|
||||
- */
|
||||
-struct ice_aqc_fw_logging {
|
||||
- u8 log_ctrl;
|
||||
-#define ICE_AQC_FW_LOG_AQ_EN BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_EN BIT(1)
|
||||
- u8 rsvd0;
|
||||
- u8 log_ctrl_valid; /* Not used by 0xFF10 Response */
|
||||
-#define ICE_AQC_FW_LOG_AQ_VALID BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_VALID BIT(1)
|
||||
- u8 rsvd1[5];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
-enum ice_aqc_fw_logging_mod {
|
||||
- ICE_AQC_FW_LOG_ID_GENERAL = 0,
|
||||
- ICE_AQC_FW_LOG_ID_CTRL,
|
||||
- ICE_AQC_FW_LOG_ID_LINK,
|
||||
- ICE_AQC_FW_LOG_ID_LINK_TOPO,
|
||||
- ICE_AQC_FW_LOG_ID_DNL,
|
||||
- ICE_AQC_FW_LOG_ID_I2C,
|
||||
- ICE_AQC_FW_LOG_ID_SDP,
|
||||
- ICE_AQC_FW_LOG_ID_MDIO,
|
||||
- ICE_AQC_FW_LOG_ID_ADMINQ,
|
||||
- ICE_AQC_FW_LOG_ID_HDMA,
|
||||
- ICE_AQC_FW_LOG_ID_LLDP,
|
||||
- ICE_AQC_FW_LOG_ID_DCBX,
|
||||
- ICE_AQC_FW_LOG_ID_DCB,
|
||||
- ICE_AQC_FW_LOG_ID_NETPROXY,
|
||||
- ICE_AQC_FW_LOG_ID_NVM,
|
||||
- ICE_AQC_FW_LOG_ID_AUTH,
|
||||
- ICE_AQC_FW_LOG_ID_VPD,
|
||||
- ICE_AQC_FW_LOG_ID_IOSF,
|
||||
- ICE_AQC_FW_LOG_ID_PARSER,
|
||||
- ICE_AQC_FW_LOG_ID_SW,
|
||||
- ICE_AQC_FW_LOG_ID_SCHEDULER,
|
||||
- ICE_AQC_FW_LOG_ID_TXQ,
|
||||
- ICE_AQC_FW_LOG_ID_RSVD,
|
||||
- ICE_AQC_FW_LOG_ID_POST,
|
||||
- ICE_AQC_FW_LOG_ID_WATCHDOG,
|
||||
- ICE_AQC_FW_LOG_ID_TASK_DISPATCH,
|
||||
- ICE_AQC_FW_LOG_ID_MNG,
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
-};
|
||||
-
|
||||
-/* Defines for both above FW logging command/response buffers */
|
||||
-#define ICE_AQC_FW_LOG_ID_S 0
|
||||
-#define ICE_AQC_FW_LOG_ID_M (0xFFF << ICE_AQC_FW_LOG_ID_S)
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_CONF_SUCCESS 0 /* Used by response */
|
||||
-#define ICE_AQC_FW_LOG_CONF_BAD_INDX BIT(12) /* Used by response */
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_EN_S 12
|
||||
-#define ICE_AQC_FW_LOG_EN_M (0xF << ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_AQC_FW_LOG_INFO_EN BIT(12) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_INIT_EN BIT(13) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_FLOW_EN BIT(14) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_ERR_EN BIT(15) /* Used by command */
|
||||
-
|
||||
-/* Get/Clear FW Log (indirect 0xFF11) */
|
||||
-struct ice_aqc_get_clear_fw_log {
|
||||
- u8 flags;
|
||||
-#define ICE_AQC_FW_LOG_CLEAR BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_MORE_DATA_AVAIL BIT(1)
|
||||
- u8 rsvd1[7];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
/* Download Package (indirect 0x0C40) */
|
||||
/* Also used for Update Package (indirect 0x0C41 and 0x0C42) */
|
||||
struct ice_aqc_download_pkg {
|
||||
@@ -2448,8 +2376,6 @@ struct ice_aq_desc {
|
||||
struct ice_aqc_add_rdma_qset add_rdma_qset;
|
||||
struct ice_aqc_add_get_update_free_vsi vsi_cmd;
|
||||
struct ice_aqc_add_update_free_vsi_resp add_update_free_vsi_res;
|
||||
- struct ice_aqc_fw_logging fw_logging;
|
||||
- struct ice_aqc_get_clear_fw_log get_clear_fw_log;
|
||||
struct ice_aqc_download_pkg download_pkg;
|
||||
struct ice_aqc_set_cgu_input_config set_cgu_input_config;
|
||||
struct ice_aqc_get_cgu_input_config get_cgu_input_config;
|
||||
@@ -2657,10 +2583,6 @@ enum ice_adminq_opc {
|
||||
|
||||
/* Standalone Commands/Events */
|
||||
ice_aqc_opc_event_lan_overflow = 0x1001,
|
||||
-
|
||||
- /* debug commands */
|
||||
- ice_aqc_opc_fw_logging = 0xFF09,
|
||||
- ice_aqc_opc_fw_logging_info = 0xFF10,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index acf6ac00f804..a5c4b7ad6a20 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -897,216 +897,6 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
|
||||
devm_kfree(ice_hw_to_dev(hw), sw);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_fw_log_cfg - get FW logging configuration
|
||||
- * @hw: pointer to the HW struct
|
||||
- */
|
||||
-static int ice_get_fw_log_cfg(struct ice_hw *hw)
|
||||
-{
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *config;
|
||||
- int status;
|
||||
- u16 size;
|
||||
-
|
||||
- size = sizeof(*config) * ICE_AQC_FW_LOG_ID_MAX;
|
||||
- config = kzalloc(size, GFP_KERNEL);
|
||||
- if (!config)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging_info);
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, config, size, NULL);
|
||||
- if (!status) {
|
||||
- u16 i;
|
||||
-
|
||||
- /* Save FW logging information into the HW structure */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 v, m, flgs;
|
||||
-
|
||||
- v = le16_to_cpu(config[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- flgs = (v & ICE_AQC_FW_LOG_EN_M) >> ICE_AQC_FW_LOG_EN_S;
|
||||
-
|
||||
- if (m < ICE_AQC_FW_LOG_ID_MAX)
|
||||
- hw->fw_log.evnts[m].cur = flgs;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- kfree(config);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_cfg_fw_log - configure FW logging
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @enable: enable certain FW logging events if true, disable all if false
|
||||
- *
|
||||
- * This function enables/disables the FW logging via Rx CQ events and a UART
|
||||
- * port based on predetermined configurations. FW logging via the Rx CQ can be
|
||||
- * enabled/disabled for individual PF's. However, FW logging via the UART can
|
||||
- * only be enabled/disabled for all PFs on the same device.
|
||||
- *
|
||||
- * To enable overall FW logging, the "cq_en" and "uart_en" enable bits in
|
||||
- * hw->fw_log need to be set accordingly, e.g. based on user-provided input,
|
||||
- * before initializing the device.
|
||||
- *
|
||||
- * When re/configuring FW logging, callers need to update the "cfg" elements of
|
||||
- * the hw->fw_log.evnts array with the desired logging event configurations for
|
||||
- * modules of interest. When disabling FW logging completely, the callers can
|
||||
- * just pass false in the "enable" parameter. On completion, the function will
|
||||
- * update the "cur" element of the hw->fw_log.evnts array with the resulting
|
||||
- * logging event configurations of the modules that are being re/configured. FW
|
||||
- * logging modules that are not part of a reconfiguration operation retain their
|
||||
- * previous states.
|
||||
- *
|
||||
- * Before resetting the device, it is recommended that the driver disables FW
|
||||
- * logging before shutting down the control queue. When disabling FW logging
|
||||
- * ("enable" = false), the latest configurations of FW logging events stored in
|
||||
- * hw->fw_log.evnts[] are not overridden to allow them to be reconfigured after
|
||||
- * a device reset.
|
||||
- *
|
||||
- * When enabling FW logging to emit log messages via the Rx CQ during the
|
||||
- * device's initialization phase, a mechanism alternative to interrupt handlers
|
||||
- * needs to be used to extract FW log messages from the Rx CQ periodically and
|
||||
- * to prevent the Rx CQ from being full and stalling other types of control
|
||||
- * messages from FW to SW. Interrupts are typically disabled during the device's
|
||||
- * initialization phase.
|
||||
- */
|
||||
-static int ice_cfg_fw_log(struct ice_hw *hw, bool enable)
|
||||
-{
|
||||
- struct ice_aqc_fw_logging *cmd;
|
||||
- u16 i, chgs = 0, len = 0;
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *data = NULL;
|
||||
- u8 actv_evnts = 0;
|
||||
- void *buf = NULL;
|
||||
- int status = 0;
|
||||
-
|
||||
- if (!hw->fw_log.cq_en && !hw->fw_log.uart_en)
|
||||
- return 0;
|
||||
-
|
||||
- /* Disable FW logging only when the control queue is still responsive */
|
||||
- if (!enable &&
|
||||
- (!hw->fw_log.actv_evnts || !ice_check_sq_alive(hw, &hw->adminq)))
|
||||
- return 0;
|
||||
-
|
||||
- /* Get current FW log settings */
|
||||
- status = ice_get_fw_log_cfg(hw);
|
||||
- if (status)
|
||||
- return status;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging);
|
||||
- cmd = &desc.params.fw_logging;
|
||||
-
|
||||
- /* Indicate which controls are valid */
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_AQ_VALID;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_UART_VALID;
|
||||
-
|
||||
- if (enable) {
|
||||
- /* Fill in an array of entries with FW logging modules and
|
||||
- * logging events being reconfigured.
|
||||
- */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 val;
|
||||
-
|
||||
- /* Keep track of enabled event types */
|
||||
- actv_evnts |= hw->fw_log.evnts[i].cfg;
|
||||
-
|
||||
- if (hw->fw_log.evnts[i].cfg == hw->fw_log.evnts[i].cur)
|
||||
- continue;
|
||||
-
|
||||
- if (!data) {
|
||||
- data = devm_kcalloc(ice_hw_to_dev(hw),
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
- sizeof(*data),
|
||||
- GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- val = i << ICE_AQC_FW_LOG_ID_S;
|
||||
- val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
|
||||
- data[chgs++] = cpu_to_le16(val);
|
||||
- }
|
||||
-
|
||||
- /* Only enable FW logging if at least one module is specified.
|
||||
- * If FW logging is currently enabled but all modules are not
|
||||
- * enabled to emit log messages, disable FW logging altogether.
|
||||
- */
|
||||
- if (actv_evnts) {
|
||||
- /* Leave if there is effectively no change */
|
||||
- if (!chgs)
|
||||
- goto out;
|
||||
-
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_AQ_EN;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
|
||||
-
|
||||
- buf = data;
|
||||
- len = sizeof(*data) * chgs;
|
||||
- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, buf, len, NULL);
|
||||
- if (!status) {
|
||||
- /* Update the current configuration to reflect events enabled.
|
||||
- * hw->fw_log.cq_en and hw->fw_log.uart_en indicate if the FW
|
||||
- * logging mode is enabled for the device. They do not reflect
|
||||
- * actual modules being enabled to emit log messages. So, their
|
||||
- * values remain unchanged even when all modules are disabled.
|
||||
- */
|
||||
- u16 cnt = enable ? chgs : (u16)ICE_AQC_FW_LOG_ID_MAX;
|
||||
-
|
||||
- hw->fw_log.actv_evnts = actv_evnts;
|
||||
- for (i = 0; i < cnt; i++) {
|
||||
- u16 v, m;
|
||||
-
|
||||
- if (!enable) {
|
||||
- /* When disabling all FW logging events as part
|
||||
- * of device's de-initialization, the original
|
||||
- * configurations are retained, and can be used
|
||||
- * to reconfigure FW logging later if the device
|
||||
- * is re-initialized.
|
||||
- */
|
||||
- hw->fw_log.evnts[i].cur = 0;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- v = le16_to_cpu(data[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-out:
|
||||
- devm_kfree(ice_hw_to_dev(hw), data);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_output_fw_log
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @desc: pointer to the AQ message descriptor
|
||||
- * @buf: pointer to the buffer accompanying the AQ message
|
||||
- *
|
||||
- * Formats a FW Log message and outputs it via the standard driver logs.
|
||||
- */
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
|
||||
-{
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg Start ]\n");
|
||||
- ice_debug_array(hw, ICE_DBG_FW_LOG, 16, 1, (u8 *)buf,
|
||||
- le16_to_cpu(desc->datalen));
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg End ]\n");
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_get_itr_intrl_gran
|
||||
* @hw: pointer to the HW struct
|
||||
@@ -1164,11 +954,6 @@ int ice_init_hw(struct ice_hw *hw)
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
|
||||
- /* Enable FW logging. Not fatal if this fails. */
|
||||
- status = ice_cfg_fw_log(hw, true);
|
||||
- if (status)
|
||||
- ice_debug(hw, ICE_DBG_INIT, "Failed to enable FW logging.\n");
|
||||
-
|
||||
status = ice_clear_pf_cfg(hw);
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
@@ -1318,8 +1103,6 @@ void ice_deinit_hw(struct ice_hw *hw)
|
||||
ice_free_hw_tbls(hw);
|
||||
mutex_destroy(&hw->tnl_lock);
|
||||
|
||||
- /* Attempt to disable FW logging before shutting down control queues */
|
||||
- ice_cfg_fw_log(hw, false);
|
||||
ice_destroy_all_ctrlq(hw);
|
||||
|
||||
/* Clear VSI contexts if not already cleared */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 7a966a0c224f..d47e5400351f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -199,7 +199,6 @@ ice_aq_cfg_lan_txq(struct ice_hw *hw, struct ice_aqc_cfg_txqs_buf *buf,
|
||||
struct ice_sq_cd *cd);
|
||||
int ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
|
||||
void ice_replay_post(struct ice_hw *hw);
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
|
||||
struct ice_q_ctx *
|
||||
ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
|
||||
int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d3340114297a..e5cc9790969c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1535,9 +1535,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
- case ice_aqc_opc_fw_logging:
|
||||
- ice_output_fw_log(hw, &event.desc, event.msg_buf);
|
||||
- break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index b0f1f4db1d8b..6e1fed0d7384 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -731,24 +731,6 @@ struct ice_switch_info {
|
||||
DECLARE_BITMAP(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS);
|
||||
};
|
||||
|
||||
-/* FW logging configuration */
|
||||
-struct ice_fw_log_evnt {
|
||||
- u8 cfg : 4; /* New event enables to configure */
|
||||
- u8 cur : 4; /* Current/active event enables */
|
||||
-};
|
||||
-
|
||||
-struct ice_fw_log_cfg {
|
||||
- u8 cq_en : 1; /* FW logging is enabled via the control queue */
|
||||
- u8 uart_en : 1; /* FW logging is enabled via UART for all PFs */
|
||||
- u8 actv_evnts; /* Cumulation of currently enabled log events */
|
||||
-
|
||||
-#define ICE_FW_LOG_EVNT_INFO (ICE_AQC_FW_LOG_INFO_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_INIT (ICE_AQC_FW_LOG_INIT_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_FLOW (ICE_AQC_FW_LOG_FLOW_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_ERR (ICE_AQC_FW_LOG_ERR_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
- struct ice_fw_log_evnt evnts[ICE_AQC_FW_LOG_ID_MAX];
|
||||
-};
|
||||
-
|
||||
/* Enum defining the different states of the mailbox snapshot in the
|
||||
* PF-VF mailbox overflow detection algorithm. The snapshot can be in
|
||||
* states:
|
||||
@@ -890,8 +872,6 @@ struct ice_hw {
|
||||
u8 fw_patch; /* firmware patch version */
|
||||
u32 fw_build; /* firmware build number */
|
||||
|
||||
- struct ice_fw_log_cfg fw_log;
|
||||
-
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
* initialization.
|
||||
--
|
||||
2.43.0
|
||||
|
1083
kernel-rt/debian/patches/ice-VDF/0025-ice-configure-FW-logging.patch
Normal file
1083
kernel-rt/debian/patches/ice-VDF/0025-ice-configure-FW-logging.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,281 @@
|
||||
From 189d58473481cf01b493fca4e9dd2ab8380d0ce5 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:13 -0800
|
||||
Subject: [PATCH 26/36] ice: enable FW logging
|
||||
|
||||
Once users have configured the FW logging then allow them to enable it
|
||||
by writing to the 'fwlog/enable' file. The file accepts a boolean value
|
||||
(0 or 1) where 1 means enable FW logging and 0 means disable FW logging.
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Where <value> is 0 or 1.
|
||||
|
||||
The user can read the 'fwlog/enable' file to see whether logging is
|
||||
enabled or not. Reading the actual data is a separate patch. To see the
|
||||
current value then:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 73671c3162c83a689342fd57f00b5f261682e49b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 3 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 98 +++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 67 +++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 2 +
|
||||
4 files changed, 170 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 347e4fed5e0d..11391be4efc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2336,6 +2336,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
};
|
||||
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
+ * Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
@@ -2344,6 +2345,7 @@ struct ice_aqc_fw_log {
|
||||
#define ICE_AQC_FW_LOG_CONF_AQ_EN BIT(1)
|
||||
#define ICE_AQC_FW_LOG_QUERY_REGISTERED BIT(2)
|
||||
#define ICE_AQC_FW_LOG_CONF_SET_VALID BIT(3)
|
||||
+#define ICE_AQC_FW_LOG_AQ_REGISTER BIT(0)
|
||||
#define ICE_AQC_FW_LOG_AQ_QUERY BIT(2)
|
||||
|
||||
u8 rsp_flag;
|
||||
@@ -2662,6 +2664,7 @@ enum ice_adminq_opc {
|
||||
|
||||
/* FW Logging Commands */
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
+ ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3b0d9b214fd1..3dde99969132 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -281,6 +281,101 @@ static const struct file_operations ice_debugfs_nr_messages_fops = {
|
||||
.write = ice_debugfs_nr_messages_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_enable_read - read from 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_enable_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+
|
||||
+ snprintf(buff, sizeof(buff), "%u\n",
|
||||
+ (u16)(hw->fwlog_cfg.options &
|
||||
+ ICE_FWLOG_OPTION_IS_REGISTERED) >> 3);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_enable_write - write into 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_enable_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ bool enable;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 2)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = kstrtobool(user_val, &enable);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+
|
||||
+ ret = ice_fwlog_set(hw, &hw->fwlog_cfg);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ ret = ice_fwlog_register(hw);
|
||||
+ else
|
||||
+ ret = ice_fwlog_unregister(hw);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+enable_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_enable_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_enable_read,
|
||||
+ .write = ice_debugfs_enable_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -332,6 +427,9 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = fw_modules;
|
||||
|
||||
+ debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_enable_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 307e0d04f3fe..25a17cbc1d34 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -63,6 +63,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
kfree(pf->ice_debugfs_pf_fwlog_modules);
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = NULL;
|
||||
+
|
||||
+ status = ice_fwlog_unregister(hw);
|
||||
+ if (status)
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
+ status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,6 +202,8 @@ static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
|
||||
cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
|
||||
+ if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
|
||||
+ cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;
|
||||
|
||||
@@ -226,6 +233,66 @@ int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
return ice_aq_fwlog_get(hw, cfg);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @reg: true to register and false to unregister
|
||||
+ */
|
||||
+static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
|
||||
+{
|
||||
+ struct ice_aq_desc desc;
|
||||
+
|
||||
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);
|
||||
+
|
||||
+ if (reg)
|
||||
+ desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;
|
||||
+
|
||||
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_register - Register the PF for firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * After this call the PF will start to receive firmware logging based on the
|
||||
+ * configuration set in ice_fwlog_set.
|
||||
+ */
|
||||
+int ice_fwlog_register(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, true);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_unregister - Unregister the PF from firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ */
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, false);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_set_supported - Set if FW logging is supported by FW
|
||||
* @hw: pointer to the HW struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 8e68ee02713b..45865558425d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -53,4 +53,6 @@ int ice_fwlog_init(struct ice_hw *hw);
|
||||
void ice_fwlog_deinit(struct ice_hw *hw);
|
||||
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
+int ice_fwlog_register(struct ice_hw *hw);
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,572 @@
|
||||
From a584ea88cfdc8ac3f782be1d5d67fa92c3423290 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:14 -0800
|
||||
Subject: [PATCH 27/36] ice: add ability to read and configure FW log data
|
||||
|
||||
Once logging is enabled the user should read the data from the 'data'
|
||||
file. The data is in the form of a binary blob that can be sent to Intel
|
||||
for decoding. To read the data use a command like:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data > log_data.bin
|
||||
|
||||
If the user wants to clear the FW log data that has been stored in the
|
||||
driver then they can write any value to the 'data' file and that will clear
|
||||
the data. An example is:
|
||||
|
||||
# echo 34 > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data
|
||||
|
||||
In addition to being able to read the data the user can configure how
|
||||
much memory is used to store FW log data. This allows the user to
|
||||
increase/decrease the amount of memory based on the users situation.
|
||||
The data is stored such that if the memory fills up then the oldest data
|
||||
will get overwritten in a circular manner. To change the amount of
|
||||
memory the user can write to the 'log_size' file like this:
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Where <value> is one of 128K, 256K, 512K, 1M, and 2M. The default value
|
||||
is 1M.
|
||||
|
||||
The user can see the current value of 'log_size' by reading the file:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 9d3535e71985beb738c4ad2b772c6f0efdce0202)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 210 ++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 142 ++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 21 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 29 +++
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 1 +
|
||||
6 files changed, 405 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 11391be4efc2..f63b57ff2a3d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2338,6 +2338,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
* Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
+ * FW Log Event (indirect 0xFF33)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
u8 cmd_flags;
|
||||
@@ -2666,6 +2667,7 @@ enum ice_adminq_opc {
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
+ ice_aqc_opc_fw_logs_event = 0xFF33,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3dde99969132..c2bfba6b9ead 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -64,6 +64,17 @@ static const char * const ice_fwlog_level_string[] = {
|
||||
"verbose",
|
||||
};
|
||||
|
||||
+/* the order in this array is important. it matches the ordering of the
|
||||
+ * values in the FW so the index is the same value as in ice_fwlog_level
|
||||
+ */
|
||||
+static const char * const ice_fwlog_log_size[] = {
|
||||
+ "128K",
|
||||
+ "256K",
|
||||
+ "512K",
|
||||
+ "1M",
|
||||
+ "2M",
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_print_module_cfg - print current FW logging module configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -376,6 +387,199 @@ static const struct file_operations ice_debugfs_enable_fops = {
|
||||
.write = ice_debugfs_enable_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_read - read from 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_log_size_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+ int index;
|
||||
+
|
||||
+ index = hw->fwlog_ring.index;
|
||||
+ snprintf(buff, sizeof(buff), "%s\n", ice_fwlog_log_size[index]);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_write - write into 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_log_size_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ ssize_t ret;
|
||||
+ int index;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 5)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ index = sysfs_match_string(ice_fwlog_log_size, user_val);
|
||||
+ if (index < 0) {
|
||||
+ dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n",
|
||||
+ user_val);
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ } else if (hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) {
|
||||
+ dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* free all the buffers and the tracking info and resize */
|
||||
+ ice_fwlog_realloc_rings(hw, index);
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+log_size_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_log_size_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_log_size_read,
|
||||
+ .write = ice_debugfs_log_size_write,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_read - read from 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_data_read(struct file *filp, char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ int data_copied = 0;
|
||||
+ bool done = false;
|
||||
+
|
||||
+ if (ice_fwlog_ring_empty(&hw->fwlog_ring))
|
||||
+ return 0;
|
||||
+
|
||||
+ while (!ice_fwlog_ring_empty(&hw->fwlog_ring) && !done) {
|
||||
+ struct ice_fwlog_data *log;
|
||||
+ u16 cur_buf_len;
|
||||
+
|
||||
+ log = &hw->fwlog_ring.rings[hw->fwlog_ring.head];
|
||||
+ cur_buf_len = log->data_size;
|
||||
+ if (cur_buf_len >= count) {
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_to_user(buffer, log->data, cur_buf_len)) {
|
||||
+ /* if there is an error then bail and return whatever
|
||||
+ * the driver has copied so far
|
||||
+ */
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ data_copied += cur_buf_len;
|
||||
+ buffer += cur_buf_len;
|
||||
+ count -= cur_buf_len;
|
||||
+ *ppos += cur_buf_len;
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+
|
||||
+ return data_copied;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_write - write into 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_data_write(struct file *filp, const char __user *buf, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes */
|
||||
+ if (*ppos != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* any value is allowed to clear the buffer so no need to even look at
|
||||
+ * what the value is
|
||||
+ */
|
||||
+ if (!(hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED)) {
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+ } else {
|
||||
+ dev_info(dev, "Can't clear FW log data while FW log running\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto nr_buffs_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+nr_buffs_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_data_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_data_read,
|
||||
+ .write = ice_debugfs_data_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -430,6 +634,12 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
pf, &ice_debugfs_enable_fops);
|
||||
|
||||
+ debugfs_create_file("log_size", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_log_size_fops);
|
||||
+
|
||||
+ debugfs_create_file("data", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_data_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 25a17cbc1d34..92b5dac481cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -1,10 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2022, Intel Corporation. */
|
||||
|
||||
+#include <linux/vmalloc.h>
|
||||
#include "ice.h"
|
||||
#include "ice_common.h"
|
||||
#include "ice_fwlog.h"
|
||||
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ u16 head, tail;
|
||||
+
|
||||
+ head = rings->head;
|
||||
+ tail = rings->tail;
|
||||
+
|
||||
+ if (head < tail && (tail - head == (rings->size - 1)))
|
||||
+ return true;
|
||||
+ else if (head > tail && (tail == (head - 1)))
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ return rings->head == rings->tail;
|
||||
+}
|
||||
+
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size)
|
||||
+{
|
||||
+ *item = (*item + 1) & (size - 1);
|
||||
+}
|
||||
+
|
||||
+static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i, nr_bytes;
|
||||
+ u8 *mem;
|
||||
+
|
||||
+ nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN;
|
||||
+ mem = vzalloc(nr_bytes);
|
||||
+ if (!mem)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ ring->data_size = ICE_AQ_MAX_BUF_LEN;
|
||||
+ ring->data = mem;
|
||||
+ mem += ICE_AQ_MAX_BUF_LEN;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ /* the first ring is the base memory for the whole range so
|
||||
+ * free it
|
||||
+ */
|
||||
+ if (!i)
|
||||
+ vfree(ring->data);
|
||||
+
|
||||
+ ring->data = NULL;
|
||||
+ ring->data_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n))
|
||||
+/**
|
||||
+ * ice_fwlog_realloc_rings - reallocate the FW log rings
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @index: the new index to use to allocate memory for the log data
|
||||
+ *
|
||||
+ */
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index)
|
||||
+{
|
||||
+ struct ice_fwlog_ring ring;
|
||||
+ int status, ring_size;
|
||||
+
|
||||
+ /* convert the number of bytes into a number of 4K buffers. externally
|
||||
+ * the driver presents the interface to the FW log data as a number of
|
||||
+ * bytes because that's easy for users to understand. internally the
|
||||
+ * driver uses a ring of buffers because the driver doesn't know where
|
||||
+ * the beginning and end of any line of log data is so the driver has
|
||||
+ * to overwrite data as complete blocks. when the data is returned to
|
||||
+ * the user the driver knows that the data is correct and the FW log
|
||||
+ * can be correctly parsed by the tools
|
||||
+ */
|
||||
+ ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN;
|
||||
+ if (ring_size == hw->fwlog_ring.size)
|
||||
+ return;
|
||||
+
|
||||
+ /* allocate space for the new rings and buffers then release the
|
||||
+ * old rings and buffers. that way if we don't have enough
|
||||
+ * memory then we at least have what we had before
|
||||
+ */
|
||||
+ ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL);
|
||||
+ if (!ring.rings)
|
||||
+ return;
|
||||
+
|
||||
+ ring.size = ring_size;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&ring);
|
||||
+ kfree(ring.rings);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+
|
||||
+ hw->fwlog_ring.rings = ring.rings;
|
||||
+ hw->fwlog_ring.size = ring.size;
|
||||
+ hw->fwlog_ring.index = index;
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_init - Initialize FW logging configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -28,6 +146,25 @@ int ice_fwlog_init(struct ice_hw *hw)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
+ hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT,
|
||||
+ sizeof(*hw->fwlog_ring.rings),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!hw->fwlog_ring.rings) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT;
|
||||
+ hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
ice_debugfs_fwlog_init(hw->back);
|
||||
} else {
|
||||
dev_warn(ice_hw_to_dev(hw), "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n");
|
||||
@@ -68,6 +205,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (status)
|
||||
dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
status);
|
||||
+
|
||||
+ if (hw->fwlog_ring.rings) {
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 45865558425d..287e71fa4b86 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -47,6 +47,26 @@ struct ice_fwlog_cfg {
|
||||
u16 log_resolution;
|
||||
};
|
||||
|
||||
+struct ice_fwlog_data {
|
||||
+ u16 data_size;
|
||||
+ u8 *data;
|
||||
+};
|
||||
+
|
||||
+struct ice_fwlog_ring {
|
||||
+ struct ice_fwlog_data *rings;
|
||||
+ u16 index;
|
||||
+ u16 size;
|
||||
+ u16 head;
|
||||
+ u16 tail;
|
||||
+};
|
||||
+
|
||||
+#define ICE_FWLOG_RING_SIZE_INDEX_DFLT 3
|
||||
+#define ICE_FWLOG_RING_SIZE_DFLT 256
|
||||
+#define ICE_FWLOG_RING_SIZE_MAX 512
|
||||
+
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings);
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings);
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size);
|
||||
void ice_fwlog_set_supported(struct ice_hw *hw);
|
||||
bool ice_fwlog_supported(struct ice_hw *hw);
|
||||
int ice_fwlog_init(struct ice_hw *hw);
|
||||
@@ -55,4 +75,5 @@ int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_register(struct ice_hw *hw);
|
||||
int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 614e10ab4159..6c6ca5353f28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1254,6 +1254,32 @@ ice_handle_link_event(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_get_fwlog_data - copy the FW log data from ARQ event
|
||||
+ * @pf: PF that the FW log event is associated with
|
||||
+ * @event: event structure containing FW log data
|
||||
+ */
|
||||
+static void
|
||||
+ice_get_fwlog_data(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
+{
|
||||
+ struct ice_fwlog_data *fwlog;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+
|
||||
+ fwlog = &hw->fwlog_ring.rings[hw->fwlog_ring.tail];
|
||||
+
|
||||
+ memset(fwlog->data, 0, PAGE_SIZE);
|
||||
+ fwlog->data_size = le16_to_cpu(event->desc.datalen);
|
||||
+
|
||||
+ memcpy(fwlog->data, event->msg_buf, fwlog->data_size);
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.tail, hw->fwlog_ring.size);
|
||||
+
|
||||
+ if (ice_fwlog_ring_full(&hw->fwlog_ring)) {
|
||||
+ /* the rings are full so bump the head to create room */
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_aq_prep_for_event - Prepare to wait for an AdminQ event from firmware
|
||||
* @pf: pointer to the PF private structure
|
||||
@@ -1535,6 +1561,9 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
+ case ice_aqc_opc_fw_logs_event:
|
||||
+ ice_get_fwlog_data(pf, &event);
|
||||
+ break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 84bb61aa7409..28e47bb78eaf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -875,6 +875,7 @@ struct ice_hw {
|
||||
|
||||
struct ice_fwlog_cfg fwlog_cfg;
|
||||
bool fwlog_supported; /* does hardware support FW logging? */
|
||||
+ struct ice_fwlog_ring fwlog_ring;
|
||||
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 8a7f6d8b2105c39f236c51c558e21b787c223861 Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:57 +0100
|
||||
Subject: [PATCH 28/36] ice: Fix debugfs with devlink reload
|
||||
|
||||
During devlink reload it is needed to remove debugfs entries
|
||||
correlated with only one PF. ice_debugfs_exit() removes all
|
||||
entries created by ice driver so we can't use it.
|
||||
|
||||
Introduce ice_debugfs_pf_deinit() in order to release PF's
|
||||
debugfs entries. Move ice_debugfs_exit() call to ice_module_exit(),
|
||||
it makes more sense since ice_debugfs_init() is called in
|
||||
ice_module_init() and not in ice_probe().
|
||||
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 500d0df5b4b2394a06b949bab05f7ed0242b9858)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 10 ++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 +--
|
||||
4 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 7966ac61154c..ed1c6cdedeff 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -895,6 +895,7 @@ static inline bool ice_is_adq_active(struct ice_pf *pf)
|
||||
}
|
||||
|
||||
void ice_debugfs_fwlog_init(struct ice_pf *pf);
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf);
|
||||
void ice_debugfs_init(void);
|
||||
void ice_debugfs_exit(void);
|
||||
void ice_pf_fwlog_update_module(struct ice_pf *pf, int log_level, int module);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index c2bfba6b9ead..ba396b22bb7d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -647,6 +647,16 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
kfree(fw_modules);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_pf_deinit - cleanup PF's debugfs
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf)
|
||||
+{
|
||||
+ debugfs_remove_recursive(pf->ice_debugfs_pf);
|
||||
+ pf->ice_debugfs_pf = NULL;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_init - create root directory for debugfs entries
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 92b5dac481cd..4fd15387a7e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -188,6 +188,8 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (hw->bus.func)
|
||||
return;
|
||||
|
||||
+ ice_debugfs_pf_deinit(hw->back);
|
||||
+
|
||||
/* make sure FW logging is disabled to not put the FW in a weird state
|
||||
* for the next driver load
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 6c6ca5353f28..c882c218281a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -5325,8 +5325,6 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
- ice_debugfs_exit();
|
||||
-
|
||||
if (test_bit(ICE_FLAG_SRIOV_ENA, pf->flags)) {
|
||||
set_bit(ICE_VF_RESETS_DISABLED, pf->state);
|
||||
ice_free_vfs(pf);
|
||||
@@ -5823,6 +5821,7 @@ module_init(ice_module_init);
|
||||
static void __exit ice_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ice_driver);
|
||||
+ ice_debugfs_exit();
|
||||
destroy_workqueue(ice_wq);
|
||||
destroy_workqueue(ice_lag_wq);
|
||||
pr_info("module unloaded\n");
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,78 @@
|
||||
From 861015cbb4cf4cb258a1da9e80550fe991be7808 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 16 Feb 2024 14:06:38 -0800
|
||||
Subject: [PATCH 29/36] ice: remove vf->lan_vsi_num field
|
||||
|
||||
The lan_vsi_num field of the VF structure is no longer used for any
|
||||
purpose. Remove it.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1cf94cbfc61bac89cddeb075fbc100ebd3aea81b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_sriov.c | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 +---
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.h | 5 -----
|
||||
3 files changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
index 442162be23ea..3366ac976c44 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
@@ -239,7 +239,6 @@ static struct ice_vsi *ice_vf_vsi_setup(struct ice_vf *vf)
|
||||
}
|
||||
|
||||
vf->lan_vsi_idx = vsi->idx;
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return vsi;
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
index 03b9d7d74851..303fdf8555cf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
@@ -298,7 +298,6 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf)
|
||||
* vf->lan_vsi_idx
|
||||
*/
|
||||
vsi->vsi_num = ice_get_hw_vsi_num(&pf->hw, vsi->idx);
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1299,13 +1298,12 @@ int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_vf_invalidate_vsi - invalidate vsi_idx/vsi_num to remove VSI access
|
||||
+ * ice_vf_invalidate_vsi - invalidate vsi_idx to remove VSI access
|
||||
* @vf: VF to remove access to VSI for
|
||||
*/
|
||||
void ice_vf_invalidate_vsi(struct ice_vf *vf)
|
||||
{
|
||||
vf->lan_vsi_idx = ICE_NO_VSI;
|
||||
- vf->lan_vsi_num = ICE_NO_VSI;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
index 48fea6fa0362..1de07accbc5c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
@@ -110,11 +110,6 @@ struct ice_vf {
|
||||
u8 spoofchk:1;
|
||||
u8 link_forced:1;
|
||||
u8 link_up:1; /* only valid if VF link is forced */
|
||||
- /* VSI indices - actual VSI pointers are maintained in the PF structure
|
||||
- * When assigned, these will be non-zero, because VSI 0 is always
|
||||
- * the main LAN VSI for the PF.
|
||||
- */
|
||||
- u16 lan_vsi_num; /* ID as used by firmware */
|
||||
unsigned int min_tx_rate; /* Minimum Tx bandwidth limit in Mbps */
|
||||
unsigned int max_tx_rate; /* Maximum Tx bandwidth limit in Mbps */
|
||||
DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 6b7fae8669a04943af9f83ef89d39a922ed179fd Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:54 -0800
|
||||
Subject: [PATCH 30/36] ice: rename ice_write_* functions to ice_pack_ctx_*
|
||||
|
||||
In ice_common.c there are 4 functions used for converting the unpacked
|
||||
software Tx and Rx context structure data into the packed format used by
|
||||
hardware. These functions have extremely generic names:
|
||||
|
||||
* ice_write_byte
|
||||
* ice_write_word
|
||||
* ice_write_dword
|
||||
* ice_write_qword
|
||||
|
||||
When I saw these function names my first thought was "write what? to
|
||||
where?". Understanding what these functions do requires looking at the
|
||||
implementation details. The functions take bits from an unpacked structure
|
||||
and copy them into the packed layout used by hardware.
|
||||
|
||||
As part of live migration, we will want functions which perform the inverse
|
||||
operation of reading bits from the packed layout and copying them into the
|
||||
unpacked format. Naming these as "ice_read_byte", etc would be very
|
||||
confusing since they appear to write data.
|
||||
|
||||
In preparation for adding this new inverse operation, rename the existing
|
||||
functions to use the prefix "ice_pack_ctx_". This makes it clear that they
|
||||
perform the bit packing while copying from the unpacked software context
|
||||
structure to the packed hardware context.
|
||||
|
||||
The inverse operations can then neatly be named ice_unpack_ctx_*, clearly
|
||||
indicating they perform the bit unpacking while copying from the packed
|
||||
hardware context to the unpacked software context structure.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1260b45dbe2dbc415f3bc1e841c6c098083bcfb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 56 ++++++++++-----------
|
||||
1 file changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 6dcba0577633..17f60a98c8ed 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4267,13 +4267,13 @@ ice_aq_add_rdma_qsets(struct ice_hw *hw, u8 num_qset_grps,
|
||||
/* End of FW Admin Queue command wrappers */
|
||||
|
||||
/**
|
||||
- * ice_write_byte - write a byte to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_byte - write a byte to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u8 src_byte, dest_byte, mask;
|
||||
u8 *from, *dest;
|
||||
@@ -4306,13 +4306,13 @@ ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_word - write a word to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_word - write a word to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u16 src_word, mask;
|
||||
__le16 dest_word;
|
||||
@@ -4349,13 +4349,13 @@ ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_dword - write a dword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_dword - write a dword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u32 src_dword, mask;
|
||||
__le32 dest_dword;
|
||||
@@ -4400,13 +4400,13 @@ ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_qword - write a qword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_qword - write a qword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u64 src_qword, mask;
|
||||
__le64 dest_qword;
|
||||
@@ -4475,16 +4475,16 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
}
|
||||
switch (ce_info[f].size_of) {
|
||||
case sizeof(u8):
|
||||
- ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
- ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
- ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u64):
|
||||
- ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 619e0e61b39cf051137613459d36c4fe8f435e57 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:55 -0800
|
||||
Subject: [PATCH 31/36] ice: use GENMASK instead of BIT(n) - 1 in pack
|
||||
functions
|
||||
|
||||
The functions used to pack the Tx and Rx context into the hardware format
|
||||
rely on using BIT() and then subtracting 1 to get a bitmask. These
|
||||
functions even have a comment about how x86 machines can't use this method
|
||||
for certain widths because the SHL instructions will not work properly.
|
||||
|
||||
The Linux kernel already provides the GENMASK macro for generating a
|
||||
suitable bitmask. Further, GENMASK is capable of generating the mask
|
||||
including the shift_width. Since width is the total field width, take care
|
||||
to subtract one to get the final bit position.
|
||||
|
||||
Since we now include the shifted bits as part of the mask, shift the source
|
||||
value first before applying the mask.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit a45d1bf516c097bb7ae4983d3128ebf139be952c)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 44 ++++-----------------
|
||||
1 file changed, 8 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 17f60a98c8ed..55a2e264dd69 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4284,14 +4284,11 @@ static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = (u8)(BIT(ce_info->width) - 1);
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
src_byte = *from;
|
||||
- src_byte &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_byte <<= shift_width;
|
||||
+ src_byte &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4324,17 +4321,14 @@ static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_word = *(u16 *)from;
|
||||
- src_word &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_word <<= shift_width;
|
||||
+ src_word &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4367,25 +4361,14 @@ static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 32 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 5 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 32)
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u32)~0;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_dword = *(u32 *)from;
|
||||
- src_dword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_dword <<= shift_width;
|
||||
+ src_dword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4418,25 +4401,14 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 64 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 6 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 64)
|
||||
- mask = BIT_ULL(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u64)~0;
|
||||
+ mask = GENMASK_ULL(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_qword = *(u64 *)from;
|
||||
- src_qword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_qword <<= shift_width;
|
||||
+ src_qword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 6502dd63a7bd436c72d2ee8b328985b93fa7e2a5 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:56 -0800
|
||||
Subject: [PATCH 32/36] ice: cleanup line splitting for context set functions
|
||||
|
||||
The indentation for ice_set_ctx and ice_write_rxq_ctx breaks the function
|
||||
name after the return type. This style of breaking is used a lot throughout
|
||||
the ice driver, even in cases where its not actually helpful for
|
||||
readability. We no longer prefer this style of line splitting in the
|
||||
driver, and new code is avoiding it.
|
||||
|
||||
Normally, I would leave this alone unless the actual function contents or
|
||||
description needed updating. However, a future change is going to add
|
||||
inverse functions for converting packed context to unpacked context
|
||||
structures. To keep this code uniform with the existing set functions, fix
|
||||
up the style to the modern format of keeping the type on the same line.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 979c2c049fbea107ce9f8d31f3ba9dba83ddb0a2)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 12 +++++-------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 10 ++++------
|
||||
2 files changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 55a2e264dd69..59ede77a1473 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -1329,9 +1329,8 @@ static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
|
||||
* it to HW register space and enables the hardware to prefetch descriptors
|
||||
* instead of only fetching them on demand
|
||||
*/
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index)
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index)
|
||||
{
|
||||
u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
|
||||
|
||||
@@ -4427,11 +4426,10 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
* @hw: pointer to the hardware structure
|
||||
* @src_ctx: pointer to a generic non-packed context structure
|
||||
* @dest_ctx: pointer to memory for the packed structure
|
||||
- * @ce_info: a description of the structure to be transformed
|
||||
+ * @ce_info: List of Rx context elements
|
||||
*/
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info)
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
int f;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index d47e5400351f..1c3c29d30815 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -52,9 +52,8 @@ int ice_get_caps(struct ice_hw *hw);
|
||||
|
||||
void ice_set_safe_mode_caps(struct ice_hw *hw);
|
||||
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index);
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index);
|
||||
|
||||
int
|
||||
ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params);
|
||||
@@ -71,9 +70,8 @@ bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);
|
||||
int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
|
||||
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);
|
||||
extern const struct ice_ctx_ele ice_tlan_ctx_info[];
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info);
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info);
|
||||
|
||||
extern struct mutex ice_global_cfg_lock_sw;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,161 @@
|
||||
From 675a8843a0de1411666389eeabeea452161f8cc5 Mon Sep 17 00:00:00 2001
|
||||
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Date: Fri, 23 Feb 2024 17:06:27 +0100
|
||||
Subject: [PATCH 33/36] ice: do not disable Tx queues twice in ice_down()
|
||||
|
||||
ice_down() clears QINT_TQCTL_CAUSE_ENA_M bit twice, which is not
|
||||
necessary. First clearing happens in ice_vsi_dis_irq() and second in
|
||||
ice_vsi_stop_tx_ring() - remove the first one.
|
||||
|
||||
While at it, make ice_vsi_dis_irq() static as ice_down() is the only
|
||||
current caller of it.
|
||||
|
||||
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d5926e01e3739542bb047b77f850d7f641eaa7bc)
|
||||
[Adjust ice_lib.c with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 55 -----------------------
|
||||
drivers/net/ethernet/intel/ice/ice_lib.h | 2 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 44 ++++++++++++++++++
|
||||
3 files changed, 44 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 106ef843f4b5..f23cb9c8e3dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -2877,61 +2877,6 @@ void ice_dis_vsi(struct ice_vsi *vsi, bool locked)
|
||||
}
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
- * @vsi: the VSI being un-configured
|
||||
- */
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
-{
|
||||
- struct ice_pf *pf = vsi->back;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u32 val;
|
||||
- int i;
|
||||
-
|
||||
- /* disable interrupt causation from each queue */
|
||||
- if (vsi->tx_rings) {
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (vsi->tx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->tx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_TQCTL(reg));
|
||||
- val &= ~QINT_TQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_TQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (vsi->rx_rings) {
|
||||
- ice_for_each_rxq(vsi, i) {
|
||||
- if (vsi->rx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->rx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_RQCTL(reg));
|
||||
- val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_RQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* disable each interrupt */
|
||||
- ice_for_each_q_vector(vsi, i) {
|
||||
- if (!vsi->q_vectors[i])
|
||||
- continue;
|
||||
- wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
- }
|
||||
-
|
||||
- ice_flush(hw);
|
||||
-
|
||||
- /* don't call synchronize_irq() for VF's from the host */
|
||||
- if (vsi->type == ICE_VSI_VF)
|
||||
- return;
|
||||
-
|
||||
- ice_for_each_q_vector(vsi, i)
|
||||
- synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_vsi_release - Delete a VSI and free its resources
|
||||
* @vsi: the VSI being removed
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
index f24f5d1e6f9c..dbd0f3409323 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
@@ -110,8 +110,6 @@ void
|
||||
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio,
|
||||
bool ena_ts);
|
||||
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi);
|
||||
-
|
||||
void ice_vsi_free_irq(struct ice_vsi *vsi);
|
||||
|
||||
void ice_vsi_free_rx_rings(struct ice_vsi *vsi);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index c882c218281a..685635a22616 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7023,6 +7023,50 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
+ * @vsi: the VSI being un-configured
|
||||
+ */
|
||||
+static void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
+{
|
||||
+ struct ice_pf *pf = vsi->back;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ /* disable interrupt causation from each Rx queue; Tx queues are
|
||||
+ * handled in ice_vsi_stop_tx_ring()
|
||||
+ */
|
||||
+ if (vsi->rx_rings) {
|
||||
+ ice_for_each_rxq(vsi, i) {
|
||||
+ if (vsi->rx_rings[i]) {
|
||||
+ u16 reg;
|
||||
+
|
||||
+ reg = vsi->rx_rings[i]->reg_idx;
|
||||
+ val = rd32(hw, QINT_RQCTL(reg));
|
||||
+ val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
+ wr32(hw, QINT_RQCTL(reg), val);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* disable each interrupt */
|
||||
+ ice_for_each_q_vector(vsi, i) {
|
||||
+ if (!vsi->q_vectors[i])
|
||||
+ continue;
|
||||
+ wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
+ }
|
||||
+
|
||||
+ ice_flush(hw);
|
||||
+
|
||||
+ /* don't call synchronize_irq() for VF's from the host */
|
||||
+ if (vsi->type == ICE_VSI_VF)
|
||||
+ return;
|
||||
+
|
||||
+ ice_for_each_q_vector(vsi, i)
|
||||
+ synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_down - Shutdown the connection
|
||||
* @vsi: The VSI being stopped
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,274 @@
|
||||
From e53280c20bbe58015a91178268244d5e831276f4 Mon Sep 17 00:00:00 2001
|
||||
From: Milena Olech <milena.olech@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:54 -0700
|
||||
Subject: [PATCH 34/36] ice: Fix improper extts handling
|
||||
|
||||
Extts events are disabled and enabled by the application ts2phc.
|
||||
However, in case where the driver is removed when the application is
|
||||
running, a specific extts event remains enabled and can cause a kernel
|
||||
crash.
|
||||
As a side effect, when the driver is reloaded and application is started
|
||||
again, remaining extts event for the channel from a previous run will
|
||||
keep firing and the message "extts on unexpected channel" might be
|
||||
printed to the user.
|
||||
|
||||
To avoid that, extts events shall be disabled when PTP is released.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Milena Olech <milena.olech@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-2-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 00d3b4f54582d4e4a02cda5886bb336eeab268cc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 105 ++++++++++++++++++-----
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 ++
|
||||
2 files changed, 91 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 48ec59fc5d87..6e06c5d596b9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1603,27 +1603,24 @@ 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.
|
||||
*/
|
||||
-static int
|
||||
-ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
|
||||
- unsigned int extts_flags)
|
||||
+static void 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;
|
||||
-
|
||||
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;
|
||||
@@ -1632,9 +1629,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.
|
||||
@@ -1656,9 +1653,47 @@ 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);
|
||||
|
||||
- return 0;
|
||||
+ if (store)
|
||||
+ memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * 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);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1815,7 +1850,6 @@ 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;
|
||||
@@ -1826,6 +1860,9 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
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)
|
||||
@@ -1853,7 +1890,11 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
|
||||
break;
|
||||
+ }
|
||||
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)
|
||||
@@ -1869,9 +1910,13 @@ 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;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -1889,21 +1934,31 @@ 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.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;
|
||||
+ }
|
||||
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;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -2735,6 +2790,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;
|
||||
}
|
||||
|
||||
@@ -3286,6 +3345,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);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 352405a2daf2..c6469a5a7afb 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -33,6 +33,12 @@ struct ice_perout_channel {
|
||||
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.
|
||||
@@ -226,6 +232,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
|
||||
@@ -249,6 +256,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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 6c24a32820031f9713d0c0cf7ac6f4ead6b58052 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:55 -0700
|
||||
Subject: [PATCH 35/36] ice: Don't process extts if PTP is disabled
|
||||
|
||||
The ice_ptp_extts_event() function can race with ice_ptp_release() and
|
||||
result in a NULL pointer dereference which leads to a kernel panic.
|
||||
|
||||
Panic occurs because the ice_ptp_extts_event() function calls
|
||||
ptp_clock_event() with a NULL pointer. The ice driver has already
|
||||
released the PTP clock by the time the interrupt for the next external
|
||||
timestamp event occurs.
|
||||
|
||||
To fix this, modify the ice_ptp_extts_event() function to check the
|
||||
PTP state and bail early if PTP is not ready.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-3-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 996422e3230e41468f652d754fefd1bdbcd4604e)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 6e06c5d596b9..ceb4ba19c511 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1578,6 +1578,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
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,628 @@
|
||||
From 1ce01cb7cdb0bf4c18a546a62f224c8032d75ebd Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:51 -0700
|
||||
Subject: [PATCH 36/36] ice: Introduce ice_ptp_hw struct
|
||||
|
||||
Create new ice_ptp_hw struct and use it for all HW and PTP-related
|
||||
fields from struct ice_hw.
|
||||
Replace definitions with struct fields, which values are set accordingly
|
||||
to a specific device.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-1-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit d551d075b043821880b8afc0010ef70d050716d0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 24 ++++
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 22 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 134 ++++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 4 +-
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 17 ++-
|
||||
6 files changed, 126 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 59ede77a1473..147004e0170b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -209,6 +209,30 @@ bool ice_is_e810t(struct ice_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_is_e822 - Check if a device is E822 family device
|
||||
+ * @hw: pointer to the hardware structure
|
||||
+ *
|
||||
+ * Return: true if the device is E822 based, false if not.
|
||||
+ */
|
||||
+bool ice_is_e822(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->device_id) {
|
||||
+ case ICE_DEV_ID_E822C_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822C_QSFP:
|
||||
+ case ICE_DEV_ID_E822C_SFP:
|
||||
+ case ICE_DEV_ID_E822C_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822C_SGMII:
|
||||
+ case ICE_DEV_ID_E822L_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822L_SFP:
|
||||
+ case ICE_DEV_ID_E822L_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822L_SGMII:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_is_e823
|
||||
* @hw: pointer to the hardware structure
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 1c3c29d30815..9d38777310e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -245,6 +245,7 @@ void
|
||||
ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat);
|
||||
bool ice_is_e810t(struct ice_hw *hw);
|
||||
+bool ice_is_e822(struct ice_hw *hw);
|
||||
bool ice_is_e823(struct ice_hw *hw);
|
||||
int
|
||||
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ceb4ba19c511..bb1572a353d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -812,7 +812,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
}
|
||||
mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -1026,7 +1026,7 @@ ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static int
|
||||
ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
{
|
||||
- tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
+ tx->block = ICE_GET_QUAD_NUM(port);
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
tx->has_ready_bitmap = 1;
|
||||
@@ -1248,8 +1248,8 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
*/
|
||||
static int ice_ptp_check_tx_fifo(struct ice_ptp_port *port)
|
||||
{
|
||||
- int quad = port->port_num / ICE_PORTS_PER_QUAD;
|
||||
int offs = port->port_num % ICE_PORTS_PER_QUAD;
|
||||
+ int quad = ICE_GET_QUAD_NUM(port->port_num);
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u32 val, phy_sts;
|
||||
@@ -1448,7 +1448,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
- if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
+ if (WARN_ON_ONCE(port >= hw->ptp.num_lports))
|
||||
return;
|
||||
|
||||
ptp_port = &pf->ptp.port;
|
||||
@@ -1458,7 +1458,7 @@ 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;
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
/* Do not reconfigure E810 PHY */
|
||||
return;
|
||||
@@ -1487,7 +1487,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
|
||||
ice_ptp_reset_ts_memory(hw);
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++) {
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) {
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG,
|
||||
&val);
|
||||
if (err)
|
||||
@@ -2038,7 +2038,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
/* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
- if (hw->phy_model == ICE_PHY_E82X)
|
||||
+ if (hw->ptp.phy_model == ICE_PHY_E82X)
|
||||
ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
@@ -2652,7 +2652,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
if (!ice_pf_src_tmr_owned(pf))
|
||||
return;
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -3152,7 +3152,7 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_init(&ptp_port->ps_lock);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3245,7 +3245,7 @@ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
*/
|
||||
static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
{
|
||||
- switch (pf->hw.phy_model) {
|
||||
+ switch (pf->hw.ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
/* E822 based PHY has the clock owner process the interrupt
|
||||
* for all ports.
|
||||
@@ -3281,7 +3281,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ptp->state = ICE_PTP_INITIALIZING;
|
||||
|
||||
- ice_ptp_init_phy_model(hw);
|
||||
+ ice_ptp_init_hw(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 7337e7e710ed..313a72dad813 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -285,18 +285,21 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
|
||||
|
||||
/**
|
||||
* ice_fill_phy_msg_e82x - Fill message data for a PHY register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @port: the port to access
|
||||
* @offset: the register offset
|
||||
*/
|
||||
-static void
|
||||
-ice_fill_phy_msg_e82x(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
+static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 port,
|
||||
+ u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY_E82X;
|
||||
- phy = port / ICE_PORTS_PER_PHY_E82X;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E82X;
|
||||
+ phy_port = port % hw->ptp.ports_per_phy;
|
||||
+ phy = port / hw->ptp.ports_per_phy;
|
||||
+ quadtype = ICE_GET_QUAD_NUM(port) %
|
||||
+ ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -427,7 +430,7 @@ ice_read_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -504,7 +507,7 @@ ice_write_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
@@ -614,24 +617,30 @@ ice_write_64b_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
|
||||
/**
|
||||
* ice_fill_quad_msg_e82x - Fill message data for quad register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @quad: the quad to access
|
||||
* @offset: the register offset
|
||||
*
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * * %0 - OK
|
||||
+ * * %-EINVAL - invalid quad number
|
||||
*/
|
||||
-static int
|
||||
-ice_fill_quad_msg_e82x(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
+static int ice_fill_quad_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 quad,
|
||||
+ u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
+ if (quad >= ICE_GET_QUAD_NUM(hw->ptp.num_lports))
|
||||
return -EINVAL;
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_QUADS_PER_PHY_E82X) == 0)
|
||||
+ if (!(quad % ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy)))
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
@@ -658,7 +667,7 @@ ice_read_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -692,7 +701,7 @@ ice_write_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -813,7 +822,7 @@ static void ice_ptp_reset_ts_memory_e82x(struct ice_hw *hw)
|
||||
{
|
||||
unsigned int quad;
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++)
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++)
|
||||
ice_ptp_reset_ts_memory_quad_e82x(hw, quad);
|
||||
}
|
||||
|
||||
@@ -1110,7 +1119,7 @@ static int ice_ptp_set_vernier_wl(struct ice_hw *hw)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_write_phy_reg_e82x(hw, port, P_REG_WL,
|
||||
@@ -1175,7 +1184,7 @@ ice_ptp_prep_phy_time_e82x(struct ice_hw *hw, u32 time)
|
||||
*/
|
||||
phy_time = (u64)time << 32;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
/* Tx case */
|
||||
err = ice_write_64b_phy_reg_e82x(hw, port,
|
||||
P_REG_TX_TIMER_INC_PRE_L,
|
||||
@@ -1278,7 +1287,7 @@ ice_ptp_prep_phy_adj_e82x(struct ice_hw *hw, s32 adj)
|
||||
else
|
||||
cycles = -(((s64)-adj) << 32);
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_prep_port_adj_e82x(hw, port, cycles);
|
||||
@@ -1304,7 +1313,7 @@ ice_ptp_prep_phy_incval_e82x(struct ice_hw *hw, u64 incval)
|
||||
int err;
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
err = ice_write_40b_phy_reg_e82x(hw, port, P_REG_TIMETUS_L,
|
||||
incval);
|
||||
if (err)
|
||||
@@ -1460,7 +1469,7 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
enum ice_ptp_tmr_cmd cmd;
|
||||
int err;
|
||||
|
||||
@@ -1490,7 +1499,7 @@ ice_ptp_port_cmd_e82x(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_write_port_cmd_e82x(hw, port, cmd);
|
||||
@@ -1603,7 +1612,7 @@ static void ice_phy_cfg_lane_e82x(struct ice_hw *hw, u8 port)
|
||||
return;
|
||||
}
|
||||
|
||||
- quad = port / ICE_PORTS_PER_QUAD;
|
||||
+ quad = ICE_GET_QUAD_NUM(port);
|
||||
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
|
||||
if (err) {
|
||||
@@ -2632,6 +2641,17 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e82x - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e82x(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 8;
|
||||
+}
|
||||
+
|
||||
/* E810 functions
|
||||
*
|
||||
* The following functions operate on the E810 series devices which use
|
||||
@@ -2859,17 +2879,21 @@ static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
|
||||
+ * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
* @hw: pointer to HW struct
|
||||
*
|
||||
- * Enable the timesync PTP functionality for the external PHY connected to
|
||||
- * this function.
|
||||
+ * Perform E810-specific PTP hardware clock initialization steps.
|
||||
+ *
|
||||
+ * Return: 0 on success, other error codes when failed to initialize TimeSync
|
||||
*/
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
+static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
{
|
||||
u8 tmr_idx;
|
||||
int err;
|
||||
|
||||
+ /* Ensure synchronization delay is zero */
|
||||
+ wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
+
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
|
||||
GLTSYN_ENA_TSYN_ENA_M);
|
||||
@@ -2880,21 +2904,6 @@ int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
return err;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
- * @hw: pointer to HW struct
|
||||
- *
|
||||
- * Perform E810-specific PTP hardware clock initialization steps.
|
||||
- */
|
||||
-static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
-{
|
||||
- /* Ensure synchronization delay is zero */
|
||||
- wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
-
|
||||
- /* Initialize the PHY */
|
||||
- return ice_ptp_init_phy_e810(hw);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
|
||||
* @hw: Board private structure
|
||||
@@ -3238,6 +3247,17 @@ int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data)
|
||||
return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e810 - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e810(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E810;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 4;
|
||||
+}
|
||||
+
|
||||
/* Device agnostic functions
|
||||
*
|
||||
* The following functions implement shared behavior common to both E822 and
|
||||
@@ -3295,18 +3315,22 @@ void ice_ptp_unlock(struct ice_hw *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_model - Initialize hw->phy_model based on device type
|
||||
+ * ice_ptp_init_hw - Initialize hw based on device type
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
- * Determine the PHY model for the device, and initialize hw->phy_model
|
||||
+ * Determine the PHY model for the device, and initialize hw
|
||||
* for use by other functions.
|
||||
*/
|
||||
-void ice_ptp_init_phy_model(struct ice_hw *hw)
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
- hw->phy_model = ICE_PHY_E810;
|
||||
+ struct ice_ptp_hw *ptp = &hw->ptp;
|
||||
+
|
||||
+ if (ice_is_e822(hw) || ice_is_e823(hw))
|
||||
+ ice_ptp_init_phy_e82x(ptp);
|
||||
+ else if (ice_is_e810(hw))
|
||||
+ ice_ptp_init_phy_e810(ptp);
|
||||
else
|
||||
- hw->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->phy_model = ICE_PHY_UNSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3327,7 +3351,7 @@ static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
ice_ptp_src_cmd(hw, cmd);
|
||||
|
||||
/* Next, prepare the ports */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_port_cmd_e810(hw, cmd);
|
||||
break;
|
||||
@@ -3379,7 +3403,7 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
|
||||
|
||||
/* PHY timers */
|
||||
/* Fill Rx and Tx ports and send msg to PHY */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
|
||||
break;
|
||||
@@ -3421,7 +3445,7 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_incval_e810(hw, incval);
|
||||
break;
|
||||
@@ -3487,7 +3511,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_adj_e810(hw, adj);
|
||||
break;
|
||||
@@ -3517,7 +3541,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
*/
|
||||
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3545,7 +3569,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_clear_phy_tstamp_e810(hw, block, idx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3606,7 +3630,7 @@ int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
|
||||
*/
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
ice_ptp_reset_ts_memory_e82x(hw);
|
||||
break;
|
||||
@@ -3632,7 +3656,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
/* Clear event err indications for auxiliary pins */
|
||||
(void)rd32(hw, GLTSYN_STAT(src_idx));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_phc_e810(hw);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3655,7 +3679,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
*/
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_get_phy_tx_tstamp_ready_e810(hw, block,
|
||||
tstamp_ready);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 7e8fd369ef7c..d788221eba57 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -211,6 +211,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx);
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw);
|
||||
int ice_ptp_init_phc(struct ice_hw *hw);
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw);
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready);
|
||||
|
||||
/* E822 family functions */
|
||||
@@ -265,7 +266,6 @@ int ice_phy_cfg_tx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
int ice_phy_cfg_rx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
|
||||
/* E810 family functions */
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw);
|
||||
int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
|
||||
int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
|
||||
int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
|
||||
@@ -280,8 +280,6 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
|
||||
u8 *ref_state, u8 *eec_mode, s64 *phase_offset,
|
||||
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);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 28e47bb78eaf..6fc4cd1030d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -807,6 +807,9 @@ struct ice_mbx_data {
|
||||
u16 async_watermark_val;
|
||||
};
|
||||
|
||||
+#define ICE_PORTS_PER_QUAD 4
|
||||
+#define ICE_GET_QUAD_NUM(port) ((port) / ICE_PORTS_PER_QUAD)
|
||||
+
|
||||
/* PHY model */
|
||||
enum ice_phy_model {
|
||||
ICE_PHY_UNSUP = -1,
|
||||
@@ -814,6 +817,12 @@ enum ice_phy_model {
|
||||
ICE_PHY_E82X,
|
||||
};
|
||||
|
||||
+struct ice_ptp_hw {
|
||||
+ enum ice_phy_model phy_model;
|
||||
+ u8 num_lports;
|
||||
+ u8 ports_per_phy;
|
||||
+};
|
||||
+
|
||||
/* Port hardware description */
|
||||
struct ice_hw {
|
||||
u8 __iomem *hw_addr;
|
||||
@@ -835,7 +844,6 @@ 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 */
|
||||
|
||||
@@ -896,12 +904,7 @@ struct ice_hw {
|
||||
/* INTRL granularity in 1 us */
|
||||
u8 intrl_gran;
|
||||
|
||||
-#define ICE_MAX_QUAD 2
|
||||
-#define ICE_QUADS_PER_PHY_E82X 2
|
||||
-#define ICE_PORTS_PER_PHY_E82X 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)
|
||||
+ struct ice_ptp_hw ptp;
|
||||
|
||||
/* Active package version (currently active) */
|
||||
struct ice_pkg_ver active_pkg_ver;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,80 @@
|
||||
From cd12b5c8239993e395436ff9a01b524103aa0641 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:56 -0700
|
||||
Subject: [PATCH] ice: Introduce ice_get_base_incval() helper
|
||||
|
||||
Add a new helper for getting base clock increment value for specific HW.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-6-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 1f374d57c39386520586539641cafc999d0f3ef5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 9 +--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index bb1572a353d0..44b8fc8021cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#define E810_OUT_PROP_DELAY_NS 1
|
||||
|
||||
-#define UNKNOWN_INCVAL_E82X 0x100000000ULL
|
||||
-
|
||||
static const struct ptp_pin_desc ice_pin_desc_e810t[] = {
|
||||
/* name idx func chan */
|
||||
{ "GNSS", GNSS, PTP_PF_EXTTS, 0, { 0, } },
|
||||
@@ -1229,12 +1227,7 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
u64 incval;
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
- incval = ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
- else if (ice_e82x_time_ref(hw) < NUM_ICE_TIME_REF_FREQ)
|
||||
- incval = ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
- else
|
||||
- incval = UNKNOWN_INCVAL_E82X;
|
||||
+ incval = ice_get_base_incval(hw);
|
||||
|
||||
dev_dbg(ice_pf_to_dev(pf), "PTP: using base increment value of 0x%016llx\n",
|
||||
incval);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index d788221eba57..749a3f2d8293 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -283,6 +283,24 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
+/**
|
||||
+ * ice_get_base_incval - Get base clock increment value
|
||||
+ * @hw: pointer to the HW struct
|
||||
+ *
|
||||
+ * Return: base clock increment value for supported PHYs, 0 otherwise
|
||||
+ */
|
||||
+static inline u64 ice_get_base_incval(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
+ return ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
+ case ICE_PHY_E82X:
|
||||
+ return ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
#define ICE_PTP_CLOCK_INDEX_0 0x00
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 437206483113743a4ef40c2f7e14f09705049672 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Mon, 2 Sep 2024 03:18:08 +0000
|
||||
Subject: [PATCH] ice:modify the ice driver version to stx.4
|
||||
|
||||
Change the ice driver min version to stx.4 because we back ported
|
||||
the upstream 36 commits to our code base to support the customer's
|
||||
requirement.
|
||||
|
||||
The ice driver version should be ice-6.6.40-stx.4.
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5807b310bdca..7163d25405f8 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1227,7 +1227,7 @@ uapi-asm-generic:
|
||||
|
||||
# KERNELRELEASE can change from a few different places, meaning version.h
|
||||
# needs to be updated, so this check is forced on all builds
|
||||
-ICE_STX = "-stx.3"
|
||||
+ICE_STX = "-stx.4"
|
||||
I40E_STX = "-stx.0"
|
||||
IAVF_STX = "-stx.0"
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -64,3 +64,41 @@ ice-dpll/0046-dpll-fix-dpll_xa_ref_-_del-for-multiple-registration.patch
|
||||
ice-dpll/0047-ice-modify-the-ice-driver-min-version-to-stx.2.patch
|
||||
ice-mdd/0001-ice-Add-automatic-VF-reset-on-Tx-MDD-events.patch
|
||||
ice-mdd/0002-ice-modify-the-ice-driver-min-version-to-stx.3.patch
|
||||
ice-VDF/0001-ice-Auxbus-devices-driver-for-E822-TS.patch
|
||||
ice-VDF/0002-ice-introduce-ice_pf_src_tmr_owned.patch
|
||||
ice-VDF/0003-ice-Re-enable-timestamping-correctly-after-reset.patch
|
||||
ice-VDF/0004-ice-periodically-kick-Tx-timestamp-interrupt.patch
|
||||
ice-VDF/0005-ice-PTP-Rename-macros-used-for-PHY-QUAD-port-definit.patch
|
||||
ice-VDF/0006-ice-PTP-move-quad-value-check-inside-ice_fill_phy_ms.patch
|
||||
ice-VDF/0007-ice-remove-ptp_tx-ring-parameter-flag.patch
|
||||
ice-VDF/0008-ice-unify-logic-for-programming-PFINT_TSYN_MSK.patch
|
||||
ice-VDF/0009-ice-PTP-Clean-up-timestamp-registers-correctly.patch
|
||||
ice-VDF/0010-ice-Use-PTP-auxbus-for-all-PHYs-restart-in-E822.patch
|
||||
ice-VDF/0011-ice-Rename-E822-to-E82X.patch
|
||||
ice-VDF/0012-ice-Schedule-service-task-in-IRQ-top-half.patch
|
||||
ice-VDF/0013-ice-Enable-SW-interrupt-from-FW-for-LL-TS.patch
|
||||
ice-VDF/0014-ice-PTP-add-clock-domain-number-to-auxiliary-interfa.patch
|
||||
ice-VDF/0015-ice-restore-timestamp-configuration-after-device-res.patch
|
||||
ice-VDF/0016-ice-introduce-PTP-state-machine.patch
|
||||
ice-VDF/0017-ice-pass-reset-type-to-PTP-reset-functions.patch
|
||||
ice-VDF/0018-ice-rename-verify_cached-to-has_ready_bitmap.patch
|
||||
ice-VDF/0019-ice-don-t-check-has_ready_bitmap-in-E810-functions.patch
|
||||
ice-VDF/0020-ice-rename-ice_ptp_tx_cfg_intr.patch
|
||||
ice-VDF/0021-ice-factor-out-ice_ptp_rebuild_owner.patch
|
||||
ice-VDF/0022-ice-stop-destroying-and-reinitalizing-Tx-tracker-dur.patch
|
||||
ice-VDF/0023-ice-Remove-and-readd-netdev-during-devlink-reload.patch
|
||||
ice-VDF/0024-ice-remove-FW-logging-code.patch
|
||||
ice-VDF/0025-ice-configure-FW-logging.patch
|
||||
ice-VDF/0026-ice-enable-FW-logging.patch
|
||||
ice-VDF/0027-ice-add-ability-to-read-and-configure-FW-log-data.patch
|
||||
ice-VDF/0028-ice-Fix-debugfs-with-devlink-reload.patch
|
||||
ice-VDF/0029-ice-remove-vf-lan_vsi_num-field.patch
|
||||
ice-VDF/0030-ice-rename-ice_write_-functions-to-ice_pack_ctx_.patch
|
||||
ice-VDF/0031-ice-use-GENMASK-instead-of-BIT-n-1-in-pack-functions.patch
|
||||
ice-VDF/0032-ice-cleanup-line-splitting-for-context-set-functions.patch
|
||||
ice-VDF/0033-ice-do-not-disable-Tx-queues-twice-in-ice_down.patch
|
||||
ice-VDF/0034-ice-Fix-improper-extts-handling.patch
|
||||
ice-VDF/0035-ice-Don-t-process-extts-if-PTP-is-disabled.patch
|
||||
ice-VDF/0036-ice-Introduce-ice_ptp_hw-struct.patch
|
||||
ice-VDF/0037-ice-Introduce-ice_get_base_incval-helper.patch
|
||||
ice-VDF/0038-ice-modify-the-ice-driver-version-to-stx.4.patch
|
||||
|
@ -0,0 +1,684 @@
|
||||
From ba0d88d4ff54805aac7aec77cc5b05d0df9114da Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:34 +0200
|
||||
Subject: [PATCH 01/36] ice: Auxbus devices & driver for E822 TS
|
||||
|
||||
There is a problem in HW in E822-based devices leading to race
|
||||
condition.
|
||||
It might happen that, in order:
|
||||
- PF0 (which owns the PHC) requests few timestamps,
|
||||
- PF1 requests a timestamp,
|
||||
- interrupt is being triggered and both PF0 and PF1 threads are woken
|
||||
up,
|
||||
- PF0 got one timestamp, still waiting for others so not going to sleep,
|
||||
- PF1 gets it's timestamp, process it and go to sleep,
|
||||
- PF1 requests a timestamp again,
|
||||
- just before PF0 goes to sleep timestamp of PF1 appear,
|
||||
- PF0 finishes all it's timestamps and go to sleep (PF1 also sleeping).
|
||||
That leaves PF1 timestamp memory not read, which lead to blocking the
|
||||
next interrupt from arriving.
|
||||
|
||||
Fix it by adding auxiliary devices and only one driver to handle all the
|
||||
timestamps for all PF's by PHC owner. In the past each PF requested it's
|
||||
own timestamps and process it from the start till the end which causes
|
||||
problem described above. Currently each PF requests the timestamps as
|
||||
before, but the actual reading of the completed timestamps is being done
|
||||
by the PTP auxiliary driver, which is registered by the PF which owns PHC.
|
||||
|
||||
Additionally, the newly introduced auxiliary driver/devices for PTP clock
|
||||
owner will be used for other features in all products (including E810).
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d938a8cca88a5f02f523f95fe3d2d1214f4b4a8d)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 12 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 11 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 393 +++++++++++++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 30 ++
|
||||
5 files changed, 430 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index b9cd0113b859..0a3d76d184ba 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -671,6 +671,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
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 531cc2194741..6756f3d51d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -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)
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8a6acb5a722e..39cb6ee52abe 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,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);
|
||||
}
|
||||
|
||||
@@ -7444,8 +7444,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) {
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 3648d3cccacc..e3012608c9dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -255,6 +255,24 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
return ice_ptp_set_sma_e810t(info, pin, func);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
+ * @pf: The PF pointer to search in
|
||||
+ * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ */
|
||||
+static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Configure the Tx timestamp interrupt */
|
||||
+ val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
+ if (on)
|
||||
+ val |= PFINT_OICR_TSYN_TX_M;
|
||||
+ else
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -263,7 +281,6 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
struct ice_vsi *vsi;
|
||||
- u32 val;
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
@@ -277,13 +294,8 @@ static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
vsi->tx_rings[i]->ptp_tx = on;
|
||||
}
|
||||
|
||||
- /* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
- val |= PFINT_OICR_TSYN_TX_M;
|
||||
- else
|
||||
- val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
+ ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
}
|
||||
@@ -674,9 +686,6 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
int err;
|
||||
u8 idx;
|
||||
|
||||
- if (!tx->init)
|
||||
- return;
|
||||
-
|
||||
ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
pf = ptp_port_to_pf(ptp_port);
|
||||
hw = &pf->hw;
|
||||
@@ -774,6 +783,39 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ mutex_lock(&pf->ptp.ports_owner.lock);
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) {
|
||||
+ struct ice_ptp_tx *tx = &port->tx;
|
||||
+
|
||||
+ if (!tx || !tx->init)
|
||||
+ continue;
|
||||
+
|
||||
+ ice_ptp_process_tx_tstamp(tx);
|
||||
+ }
|
||||
+ mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ /* Read the Tx ready status first */
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (err || tstamp_ready)
|
||||
+ return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
+ }
|
||||
+
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_tx_tstamp - Process Tx timestamps for this function.
|
||||
* @tx: Tx tracking structure to initialize
|
||||
@@ -2448,7 +2490,21 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
*/
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
- return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* This device has the clock owner handle timestamps for it */
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ /* This device handles its own timestamps */
|
||||
+ return ice_ptp_tx_tstamp(&pf->ptp.port.tx);
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* This device handles timestamps for all ports */
|
||||
+ return ice_ptp_tx_tstamp_owner(pf);
|
||||
+ default:
|
||||
+ WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n",
|
||||
+ pf->ptp.tx_interrupt_mode);
|
||||
+ return ICE_TX_TSTAMP_WORK_DONE;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
@@ -2557,6 +2613,187 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the auxiliary PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_aux_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port *aux_port;
|
||||
+ struct ice_ptp *aux_ptp;
|
||||
+
|
||||
+ aux_port = container_of(aux_dev, struct ice_ptp_port, aux_dev);
|
||||
+ aux_ptp = container_of(aux_port, struct ice_ptp, port);
|
||||
+
|
||||
+ return container_of(aux_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_aux_dev_to_owner_pf - Get PF handle for the auxiliary device
|
||||
+ * @aux_dev: auxiliary device to get the PF for
|
||||
+ */
|
||||
+static struct ice_pf *
|
||||
+ice_ptp_aux_dev_to_owner_pf(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_ptp_port_owner *ports_owner;
|
||||
+ struct auxiliary_driver *aux_drv;
|
||||
+ struct ice_ptp *owner_ptp;
|
||||
+
|
||||
+ if (!aux_dev->dev.driver)
|
||||
+ return NULL;
|
||||
+
|
||||
+ aux_drv = to_auxiliary_drv(aux_dev->dev.driver);
|
||||
+ ports_owner = container_of(aux_drv, struct ice_ptp_port_owner,
|
||||
+ aux_driver);
|
||||
+ owner_ptp = container_of(ports_owner, struct ice_ptp, ports_owner);
|
||||
+ return container_of(owner_ptp, struct ice_pf, ptp);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_probe - Probe auxiliary devices
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @id: Auxiliary device ID
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev,
|
||||
+ const struct auxiliary_device_id *id)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ if (WARN_ON(!owner_pf))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_add(&aux_pf->ptp.port.list_member,
|
||||
+ &owner_pf->ptp.ports_owner.ports);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_remove - Remove auxiliary devices from the bus
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ struct ice_pf *owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev);
|
||||
+
|
||||
+ mutex_lock(&owner_pf->ptp.ports_owner.lock);
|
||||
+ list_del(&aux_pf->ptp.port.list_member);
|
||||
+ mutex_unlock(&owner_pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_shutdown
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static void ice_ptp_auxbus_shutdown(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_suspend
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ * @state: power management state indicator
|
||||
+ */
|
||||
+static int
|
||||
+ice_ptp_auxbus_suspend(struct auxiliary_device *aux_dev, pm_message_t state)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_resume
|
||||
+ * @aux_dev: PF's auxiliary device
|
||||
+ */
|
||||
+static int ice_ptp_auxbus_resume(struct auxiliary_device *aux_dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbus driver must be satisfied */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_auxbus_create_id_table - Create auxiliary device ID table
|
||||
+ * @pf: Board private structure
|
||||
+ * @name: auxiliary bus driver name
|
||||
+ */
|
||||
+static struct auxiliary_device_id *
|
||||
+ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name)
|
||||
+{
|
||||
+ struct auxiliary_device_id *ids;
|
||||
+
|
||||
+ /* Second id left empty to terminate the array */
|
||||
+ ids = devm_kcalloc(ice_pf_to_dev(pf), 2,
|
||||
+ sizeof(struct auxiliary_device_id), GFP_KERNEL);
|
||||
+ if (!ids)
|
||||
+ return NULL;
|
||||
+
|
||||
+ snprintf(ids[0].name, sizeof(ids[0].name), "ice.%s", name);
|
||||
+
|
||||
+ return ids;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_register_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+ aux_driver = &ptp->ports_owner.aux_driver;
|
||||
+ INIT_LIST_HEAD(&ptp->ports_owner.ports);
|
||||
+ mutex_init(&ptp->ports_owner.lock);
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_driver->name = name;
|
||||
+ aux_driver->shutdown = ice_ptp_auxbus_shutdown;
|
||||
+ aux_driver->suspend = ice_ptp_auxbus_suspend;
|
||||
+ aux_driver->remove = ice_ptp_auxbus_remove;
|
||||
+ aux_driver->resume = ice_ptp_auxbus_resume;
|
||||
+ aux_driver->probe = ice_ptp_auxbus_probe;
|
||||
+ aux_driver->id_table = ice_ptp_auxbus_create_id_table(pf, name);
|
||||
+ if (!aux_driver->id_table)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = auxiliary_driver_register(aux_driver);
|
||||
+ if (err) {
|
||||
+ devm_kfree(dev, aux_driver->id_table);
|
||||
+ dev_err(dev, "Failed registering aux_driver, name <%s>\n",
|
||||
+ name);
|
||||
+ }
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver;
|
||||
+
|
||||
+ auxiliary_driver_unregister(aux_driver);
|
||||
+ devm_kfree(ice_pf_to_dev(pf), aux_driver->id_table);
|
||||
+
|
||||
+ mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -2635,7 +2872,15 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (!ice_is_e810(hw)) {
|
||||
+ if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
+ /* The clock owner for this device type handles the timestamp
|
||||
+ * interrupt for all ports.
|
||||
+ */
|
||||
+ ice_ptp_configure_tx_tstamp(pf, true);
|
||||
+
|
||||
+ /* React on all quads interrupts for E82x */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2650,8 +2895,16 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Store the PTP clock index for other PFs */
|
||||
ice_set_ptp_clock_index(pf);
|
||||
|
||||
- return 0;
|
||||
+ err = ice_ptp_register_auxbus_driver(pf);
|
||||
+ if (err) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
+ goto err_aux;
|
||||
+ }
|
||||
|
||||
+ return 0;
|
||||
+err_aux:
|
||||
+ ice_clear_ptp_clock_index(pf);
|
||||
+ ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
err_exit:
|
||||
@@ -2701,6 +2954,13 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
+ /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
+ * neither on own quad nor on others
|
||||
+ */
|
||||
+ if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ ice_ptp_configure_tx_tstamp(pf, false);
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -2711,6 +2971,101 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_release_auxbus_device
|
||||
+ * @dev: device that utilizes the auxbus
|
||||
+ */
|
||||
+static void ice_ptp_release_auxbus_device(struct device *dev)
|
||||
+{
|
||||
+ /* Doing nothing here, but handle to auxbux device must be satisfied */
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_create_auxbus_device - Create PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static int ice_ptp_create_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_ptp *ptp;
|
||||
+ struct device *dev;
|
||||
+ char *name;
|
||||
+ int err;
|
||||
+ u32 id;
|
||||
+
|
||||
+ ptp = &pf->ptp;
|
||||
+ id = ptp->port.port_num;
|
||||
+ dev = ice_pf_to_dev(pf);
|
||||
+
|
||||
+ aux_dev = &ptp->port.aux_dev;
|
||||
+
|
||||
+ name = devm_kasprintf(dev, GFP_KERNEL, "ptp_aux_dev_%u_%u_clk%u",
|
||||
+ pf->pdev->bus->number, PCI_SLOT(pf->pdev->devfn),
|
||||
+ ice_get_ptp_src_clock_index(&pf->hw));
|
||||
+
|
||||
+ aux_dev->name = name;
|
||||
+ aux_dev->id = id;
|
||||
+ aux_dev->dev.release = ice_ptp_release_auxbus_device;
|
||||
+ aux_dev->dev.parent = dev;
|
||||
+
|
||||
+ err = auxiliary_device_init(aux_dev);
|
||||
+ if (err)
|
||||
+ goto aux_err;
|
||||
+
|
||||
+ err = auxiliary_device_add(aux_dev);
|
||||
+ if (err) {
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+ goto aux_err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+aux_err:
|
||||
+ dev_err(dev, "Failed to create PTP auxiliary bus device <%s>\n", name);
|
||||
+ devm_kfree(dev, name);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev;
|
||||
+
|
||||
+ auxiliary_device_delete(aux_dev);
|
||||
+ auxiliary_device_uninit(aux_dev);
|
||||
+
|
||||
+ memset(aux_dev, 0, sizeof(*aux_dev));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_init_tx_interrupt_mode - Initialize device Tx interrupt mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Initialize the Tx timestamp interrupt mode for this device. For most device
|
||||
+ * types, each PF processes the interrupt and manages its own timestamps. For
|
||||
+ * E822-based devices, only the clock owner processes the timestamps. Other
|
||||
+ * PFs disable the interrupt and do not process their own timestamps.
|
||||
+ */
|
||||
+static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ switch (pf->hw.phy_model) {
|
||||
+ case ICE_PHY_E822:
|
||||
+ /* E822 based PHY has the clock owner process the interrupt
|
||||
+ * for all ports.
|
||||
+ */
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL;
|
||||
+ else
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_NONE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* other PHY types handle their own Tx interrupt */
|
||||
+ pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_SELF;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_init - Initialize PTP hardware clock support
|
||||
* @pf: Board private structure
|
||||
@@ -2731,6 +3086,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
+ ice_ptp_init_tx_interrupt_mode(pf);
|
||||
+
|
||||
/* If this function owns the clock hardware, it must allocate and
|
||||
* configure the PTP clock device to represent it.
|
||||
*/
|
||||
@@ -2753,6 +3110,10 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
+ if (err)
|
||||
+ goto err;
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "PTP init successful\n");
|
||||
return;
|
||||
|
||||
@@ -2781,6 +3142,8 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_cfg_timestamp(pf, false);
|
||||
|
||||
+ ice_ptp_remove_auxbus_device(pf);
|
||||
+
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
@@ -2804,5 +3167,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 995a57019ba7..d94c22329df0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,95 @@
|
||||
From f6af978ef435067b4c9f5ff5e159f8b65d969268 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 8 Sep 2023 14:37:14 -0700
|
||||
Subject: [PATCH 02/36] ice: introduce ice_pf_src_tmr_owned
|
||||
|
||||
Add ice_pf_src_tmr_owned() macro to check the function capability bit
|
||||
indicating if the current function owns the PTP hardware clock. This is
|
||||
slightly shorter than the more verbose access via
|
||||
hw.func_caps.ts_func_info.src_tmr_owned. Use this where possible rather
|
||||
than open coding its equivalent.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 42d40bb21e332151da6fb689bf7d4af8195866ed)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 6 +++---
|
||||
4 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 0a3d76d184ba..54a98c4032b7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -197,6 +197,8 @@ extern const char ice_drv_ver[];
|
||||
|
||||
#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_PHY_RCLK,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 632091487413..106ef843f4b5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -4010,7 +4010,7 @@ void ice_init_feature_support(struct ice_pf *pf)
|
||||
if (ice_is_phy_rclk_in_netlist(&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_in_netlist(&pf->hw))
|
||||
ice_set_feature_support(pf, ICE_F_CGU);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 39cb6ee52abe..e957529b3fd6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3200,7 +3200,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 |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index e3012608c9dd..b1951357ba9f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -448,7 +448,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;
|
||||
@@ -2538,7 +2538,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);
|
||||
@@ -3091,7 +3091,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* 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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 3c155fbf8e2a0546302a01cc06e8ece18468148e Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:42 -0800
|
||||
Subject: [PATCH 03/36] ice: Re-enable timestamping correctly after reset
|
||||
|
||||
During reset, TX_TSYN interrupt should be processed as it may process
|
||||
timestamps in brief moments before and after reset.
|
||||
Timestamping should be enabled on VSIs at the end of reset procedure.
|
||||
On ice_get_phy_tx_tstamp_ready error, interrupt should not be rearmed
|
||||
because error only happens on resets.
|
||||
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1cc5b6eaad92d69fe4d84bbee5c12ee297d56296)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 19 ++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index e957529b3fd6..d2f3b4374d14 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3190,7 +3190,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 && ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b1951357ba9f..92459589f6ce 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -809,7 +809,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
- if (err || tstamp_ready)
|
||||
+ if (err)
|
||||
+ break;
|
||||
+ else if (tstamp_ready)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
}
|
||||
|
||||
@@ -2535,12 +2537,10 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
+ !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- goto reset_ts;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
goto err;
|
||||
@@ -2584,10 +2584,6 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-reset_ts:
|
||||
- /* Restart the PHY timestamping block */
|
||||
- ice_ptp_reset_phy_timestamping(pf);
|
||||
-
|
||||
pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
@@ -2603,6 +2599,11 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
+ /* Restart the PHY timestamping block */
|
||||
+ if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
+ ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,121 @@
|
||||
From 214f06259ade960e3790b62f96bc1b75e5b76e79 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 1 Dec 2023 10:08:43 -0800
|
||||
Subject: [PATCH 04/36] ice: periodically kick Tx timestamp interrupt
|
||||
|
||||
The E822 hardware for Tx timestamping keeps track of how many
|
||||
outstanding timestamps are still in the PHY memory block. It will not
|
||||
generate a new interrupt to the MAC until all of the timestamps in the
|
||||
region have been read.
|
||||
|
||||
If somehow all the available data is not read, but the driver has exited
|
||||
its interrupt routine already, the PHY will not generate a new interrupt
|
||||
even if new timestamp data is captured. Because no interrupt is
|
||||
generated, the driver never processes the timestamp data. This state
|
||||
results in a permanent failure for all future Tx timestamps.
|
||||
|
||||
It is not clear how the driver and hardware could enter this state.
|
||||
However, if it does, there is currently no recovery mechanism.
|
||||
|
||||
Add a recovery mechanism via the periodic PTP work thread which invokes
|
||||
ice_ptp_periodic_work(). Introduce a new check,
|
||||
ice_ptp_maybe_trigger_tx_interrupt() which checks the PHY timestamp
|
||||
ready bitmask. If any bits are set, trigger a software interrupt by
|
||||
writing to PFINT_OICR.
|
||||
|
||||
Once triggered, the main timestamp processing thread will read through
|
||||
the PHY data and clear the outstanding timestamp data. Once cleared, new
|
||||
data should trigger interrupts as expected.
|
||||
|
||||
This should allow recovery from such a state rather than leaving the
|
||||
device in a state where we cannot process Tx timestamps.
|
||||
|
||||
It is possible that this function checks for timestamp data
|
||||
simultaneously with the interrupt, and it might trigger additional
|
||||
unnecessary interrupts. This will cause a small amount of additional
|
||||
processing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Andrii Staikov <andrii.staikov@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 712e876371f8350c446a33577cf4a0aedcd4742a)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 50 ++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 92459589f6ce..0d6c7215e0c1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2509,6 +2509,54 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_maybe_trigger_tx_interrupt - Trigger Tx timstamp interrupt
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * The device PHY issues Tx timestamp interrupts to the driver for processing
|
||||
+ * timestamp data from the PHY. It will not interrupt again until all
|
||||
+ * current timestamp data is read. In rare circumstances, it is possible that
|
||||
+ * the driver fails to read all outstanding data.
|
||||
+ *
|
||||
+ * To avoid getting permanently stuck, periodically check if the PHY has
|
||||
+ * outstanding timestamp data. If so, trigger an interrupt from software to
|
||||
+ * process this data.
|
||||
+ */
|
||||
+static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool trigger_oicr = false;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (ice_is_e810(hw))
|
||||
+ return;
|
||||
+
|
||||
+ if (!ice_pf_src_tmr_owned(pf))
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ u64 tstamp_ready;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready);
|
||||
+ if (!err && tstamp_ready) {
|
||||
+ trigger_oicr = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (trigger_oicr) {
|
||||
+ /* Trigger a software interrupt, to ensure this data
|
||||
+ * gets processed.
|
||||
+ */
|
||||
+ dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
|
||||
+
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
{
|
||||
struct ice_ptp *ptp = container_of(work, struct ice_ptp, work.work);
|
||||
@@ -2520,6 +2568,8 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
|
||||
+ ice_ptp_maybe_trigger_tx_interrupt(pf);
|
||||
+
|
||||
/* Run twice a second or reschedule if phc update failed */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work,
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,81 @@
|
||||
From c25fc364d599195403ed9ba51ef8fa6ed3b642ff Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:44 -0700
|
||||
Subject: [PATCH 05/36] ice: PTP: Rename macros used for PHY/QUAD port
|
||||
definitions
|
||||
|
||||
The ice_fill_phy_msg_e822 function uses several macros to specify the
|
||||
correct address when sending a sideband message to the PHY block in
|
||||
hardware.
|
||||
|
||||
The names of these macros are fairly generic and confusing. Future
|
||||
development is going to extend the driver to support new hardware families
|
||||
which have different relationships between PHY and QUAD. Rename the macros
|
||||
for clarity and to indicate that they are E822 specific. This also matches
|
||||
closer to the hardware specification in the data sheet.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 64fd7de2469dd52a7f1517ce95ae22fcb391a8a1)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 8 ++++----
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 14 +++++++-------
|
||||
2 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index a299af39a7c4..03c4aa995e8d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -294,9 +294,9 @@ ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY;
|
||||
- phy = port / ICE_PORTS_PER_PHY;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_NUM_QUAD_TYPE;
|
||||
+ phy_port = port % ICE_PORTS_PER_PHY_E822;
|
||||
+ phy = port / ICE_PORTS_PER_PHY_E822;
|
||||
+ quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E822;
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -628,7 +628,7 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_NUM_QUAD_TYPE) == 0)
|
||||
+ if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 4cd131546aa9..bb5d8b681bc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -909,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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 13f48f4c94ad4d317e7c7ccaa188a11850a8aa32 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:45 -0700
|
||||
Subject: [PATCH 06/36] ice: PTP: move quad value check inside
|
||||
ice_fill_phy_msg_e822
|
||||
|
||||
The callers of ice_fill_phy_msg_e822 check for whether the quad number is
|
||||
within the expected range. Move this check inside the ice_fill_phy_msg_e822
|
||||
function instead of duplicating it twice.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit dd84744cf5ea967c8d53aae6b6a45703dbc5c5c4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 19 ++++++++++++-------
|
||||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 03c4aa995e8d..e024b88ce32b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -621,11 +621,14 @@ ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
*/
|
||||
-static void
|
||||
+static int
|
||||
ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
+ if (quad >= ICE_MAX_QUAD)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
|
||||
@@ -635,6 +638,8 @@ ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
|
||||
msg->msg_addr_low = lower_16_bits(addr);
|
||||
msg->msg_addr_high = upper_16_bits(addr);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,10 +658,10 @@ ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -687,10 +692,10 @@ ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
- return -EINVAL;
|
||||
+ err = ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
- ice_fill_quad_msg_e822(&msg, quad, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,97 @@
|
||||
From 7dae9333af82f6c9e2db1940c3a10ae38dabea7b Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:55 -0800
|
||||
Subject: [PATCH 07/36] ice: remove ptp_tx ring parameter flag
|
||||
|
||||
Before performing a Tx timestamp in ice_stamp(), the driver checks a ptp_tx
|
||||
ring variable to see if timestamping is enabled on that ring. This value is
|
||||
set for all rings whenever userspace configures Tx timestamping.
|
||||
|
||||
Ostensibly this was done to avoid wasting cycles checking other fields when
|
||||
timestamping has not been enabled. However, for Tx timestamps we already
|
||||
get an individual per-SKB flag indicating whether userspace wants to
|
||||
request a timestamp on that packet. We do not gain much by also having
|
||||
a separate flag to check for whether timestamping was enabled.
|
||||
|
||||
In fact, the driver currently fails to restore the field after a PF reset.
|
||||
Because of this, if a PF reset occurs, timestamps will be disabled.
|
||||
|
||||
Since this flag doesn't add value in the hotpath, remove it and always
|
||||
provide a timestamp if the SKB flag has been set.
|
||||
|
||||
A following change will fix the reset path to properly restore user
|
||||
timestamping configuration completely.
|
||||
|
||||
This went unnoticed for some time because one of the most common
|
||||
applications using Tx timestamps, ptp4l, will reconfigure the socket as
|
||||
part of its fault recovery logic.
|
||||
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 0ffb08b1a45bd6b7694e01da0e1d9e3e788418fb)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 14 --------------
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.c | 3 ---
|
||||
drivers/net/ethernet/intel/ice/ice_txrx.h | 1 -
|
||||
3 files changed, 18 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 0d6c7215e0c1..c03153bdb7c3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -280,20 +280,6 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- struct ice_vsi *vsi;
|
||||
- u16 i;
|
||||
-
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- /* Set the timestamp enable flag for all the Tx rings */
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (!vsi->tx_rings[i])
|
||||
- continue;
|
||||
- vsi->tx_rings[i]->ptp_tx = on;
|
||||
- }
|
||||
-
|
||||
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
ice_ptp_configure_tx_tstamp(pf, on);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
index 24c914015973..9170a3e8f088 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
@@ -2305,9 +2305,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb,
|
||||
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
|
||||
return;
|
||||
|
||||
- if (!tx_ring->ptp_tx)
|
||||
- return;
|
||||
-
|
||||
/* Tx timestamps cannot be sampled when doing TSO */
|
||||
if (first->tx_flags & ICE_TX_FLAGS_TSO)
|
||||
return;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
index 407d4c320097..b28b9826bbcd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
@@ -381,7 +381,6 @@ struct ice_tx_ring {
|
||||
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
|
||||
u8 flags;
|
||||
u8 dcb_tc; /* Traffic class of ring */
|
||||
- u8 ptp_tx;
|
||||
} ____cacheline_internodealigned_in_smp;
|
||||
|
||||
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,160 @@
|
||||
From 99007ca6255e2c35256bd97fa141705d301eb934 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:56 -0800
|
||||
Subject: [PATCH 08/36] ice: unify logic for programming PFINT_TSYN_MSK
|
||||
|
||||
Commit d938a8cca88a ("ice: Auxbus devices & driver for E822 TS") modified
|
||||
how Tx timestamps are handled for E822 devices. On these devices, only the
|
||||
clock owner handles reading the Tx timestamp data from firmware. To do
|
||||
this, the PFINT_TSYN_MSK register is modified from the default value to one
|
||||
which enables reacting to a Tx timestamp on all PHY ports.
|
||||
|
||||
The driver currently programs PFINT_TSYN_MSK in different places depending
|
||||
on whether the port is the clock owner or not. For the clock owner, the
|
||||
PFINT_TSYN_MSK value is programmed during ice_ptp_init_owner just before
|
||||
calling ice_ptp_tx_ena_intr to program the PHY ports.
|
||||
|
||||
For the non-clock owner ports, the PFINT_TSYN_MSK is programmed during
|
||||
ice_ptp_init_port.
|
||||
|
||||
If a large enough device reset occurs, the PFINT_TSYN_MSK register will be
|
||||
reset to the default value in which only the PHY associated directly with
|
||||
the PF will cause the Tx timestamp interrupt to trigger.
|
||||
|
||||
The driver lacks logic to reprogram the PFINT_TSYN_MSK register after a
|
||||
device reset. For the E822 device, this results in the PF no longer
|
||||
responding to interrupts for other ports. This results in failure to
|
||||
deliver Tx timestamps to user space applications.
|
||||
|
||||
Rename ice_ptp_configure_tx_tstamp to ice_ptp_cfg_tx_interrupt, and unify
|
||||
the logic for programming PFINT_TSYN_MSK and PFINT_OICR_ENA into one place.
|
||||
This function will program both registers according to the combination of
|
||||
user configuration and device requirements.
|
||||
|
||||
This ensures that PFINT_TSYN_MSK is always restored when we configure the
|
||||
Tx timestamp interrupt.
|
||||
|
||||
Fixes: d938a8cca88a ("ice: Auxbus devices & driver for E822 TS")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7d606a1e2d0575b6c3a2600f43f90d1e409f9661)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 60 ++++++++++++++----------
|
||||
1 file changed, 34 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c03153bdb7c3..b0bba866e8a2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -256,21 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamp interrupt is enabled or disabled
|
||||
+ * ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Program the device to respond appropriately to the Tx timestamp interrupt
|
||||
+ * cause.
|
||||
*/
|
||||
-static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
+static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable;
|
||||
u32 val;
|
||||
|
||||
+ switch (pf->ptp.tx_interrupt_mode) {
|
||||
+ case ICE_PTP_TX_INTERRUPT_ALL:
|
||||
+ /* React to interrupts across all quads. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
+ enable = true;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_NONE:
|
||||
+ /* Do not react to interrupts on any quad. */
|
||||
+ wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
+ enable = false;
|
||||
+ break;
|
||||
+ case ICE_PTP_TX_INTERRUPT_SELF:
|
||||
+ default:
|
||||
+ enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Configure the Tx timestamp interrupt */
|
||||
- val = rd32(&pf->hw, PFINT_OICR_ENA);
|
||||
- if (on)
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ if (enable)
|
||||
val |= PFINT_OICR_TSYN_TX_M;
|
||||
else
|
||||
val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
- wr32(&pf->hw, PFINT_OICR_ENA, val);
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,10 +301,9 @@ static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
*/
|
||||
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
{
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
|
||||
- ice_ptp_configure_tx_tstamp(pf, on);
|
||||
-
|
||||
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2909,15 +2929,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
- if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
|
||||
- /* The clock owner for this device type handles the timestamp
|
||||
- * interrupt for all ports.
|
||||
- */
|
||||
- ice_ptp_configure_tx_tstamp(pf, true);
|
||||
-
|
||||
- /* React on all quads interrupts for E82x */
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
|
||||
-
|
||||
+ if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
if (err)
|
||||
@@ -2991,13 +3003,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E822:
|
||||
- /* Non-owner PFs don't react to any interrupts on E82x,
|
||||
- * neither on own quad nor on others
|
||||
- */
|
||||
- if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
- ice_ptp_configure_tx_tstamp(pf, false);
|
||||
- wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
|
||||
- }
|
||||
kthread_init_delayed_work(&ptp_port->ov_work,
|
||||
ice_ptp_wait_for_offsets);
|
||||
|
||||
@@ -3142,6 +3147,9 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Start the PHY timestamping block */
|
||||
ice_ptp_reset_phy_timestamping(pf);
|
||||
|
||||
+ /* Configure initial Tx interrupt settings */
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,147 @@
|
||||
From e5a65377977e338a8f7baf92892481acf1c62403 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 26 Jul 2023 11:27:43 -0700
|
||||
Subject: [PATCH 09/36] ice: PTP: Clean up timestamp registers correctly
|
||||
|
||||
E822 PHY TS registers should not be written and the only way to clean up
|
||||
them is to reset QUAD memory.
|
||||
|
||||
To ensure that the status bit for the timestamp index is cleared, ensure
|
||||
that ice_clear_phy_tstamp implementations first read the timestamp out.
|
||||
Implementations which can write the register continue to do so.
|
||||
|
||||
Add a note to indicate this function should only be called on timestamps
|
||||
which have their valid bit set. Update the dynamic debug messages to
|
||||
reflect the actual action taken.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit be65a1a33bdee3912daac50aa6c5270ec9c37010)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 70 +++++++++++++--------
|
||||
1 file changed, 45 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index e024b88ce32b..cd28430cfdda 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -759,29 +759,32 @@ ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
|
||||
* @quad: the quad to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the PHY quad block that is
|
||||
- * shared between the internal PHYs on the E822 devices.
|
||||
+ * Read the timestamp out of the quad to clear its timestamp status bit from
|
||||
+ * the PHY quad block that is shared between the internal PHYs of the E822
|
||||
+ * devices.
|
||||
+ *
|
||||
+ * Note that unlike E810, software cannot directly write to the quad memory
|
||||
+ * bank registers. E822 relies on the ice_get_phy_tx_tstamp_ready() function
|
||||
+ * to determine which timestamps are valid. Reading a timestamp auto-clears
|
||||
+ * the valid bit.
|
||||
+ *
|
||||
+ * To directly clear the contents of the timestamp block entirely, discarding
|
||||
+ * all timestamp data at once, software should instead use
|
||||
+ * ice_ptp_reset_ts_memory_quad_e822().
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int
|
||||
ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
|
||||
{
|
||||
- u16 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
- lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
- hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
|
||||
- if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- err = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
|
||||
+ err = ice_read_phy_tstamp_e822(hw, quad, idx, &unused_tstamp);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for quad %u, idx %u, err %d\n",
|
||||
+ quad, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2816,28 +2819,39 @@ ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
|
||||
* @lport: the lport to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block of the
|
||||
- * external PHY on the E810 device.
|
||||
+ * Read the timestamp and then forcibly overwrite its value to clear the valid
|
||||
+ * bit from the timestamp block of the external PHY on the E810 device.
|
||||
+ *
|
||||
+ * This function should only be called on an idx whose bit is set according to
|
||||
+ * ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
{
|
||||
u32 lo_addr, hi_addr;
|
||||
+ u64 unused_tstamp;
|
||||
int err;
|
||||
|
||||
+ err = ice_read_phy_tstamp_e810(hw, lport, idx, &unused_tstamp);
|
||||
+ if (err) {
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to read the timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
|
||||
hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, lo_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ice_write_phy_reg_e810(hw, hi_addr, 0);
|
||||
if (err) {
|
||||
- ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n",
|
||||
- err);
|
||||
+ ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register for lport %u, idx %u, err %d\n",
|
||||
+ lport, idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3519,9 +3533,15 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
* @block: the block to read from
|
||||
* @idx: the timestamp index to reset
|
||||
*
|
||||
- * Clear a timestamp, resetting its valid bit, from the timestamp block. For
|
||||
- * E822 devices, the block is the quad to clear from. For E810 devices, the
|
||||
- * block is the logical port to clear from.
|
||||
+ * Clear a timestamp from the timestamp block, discarding its value without
|
||||
+ * returning it. This resets the memory status bit for the timestamp index
|
||||
+ * allowing it to be reused for another timestamp in the future.
|
||||
+ *
|
||||
+ * For E822 devices, the block number is the PHY quad to clear from. For E810
|
||||
+ * devices, the block number is the logical port to clear from.
|
||||
+ *
|
||||
+ * This function must only be called on a timestamp index whose valid bit is
|
||||
+ * set according to ice_get_phy_tx_tstamp_ready().
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,65 @@
|
||||
From e2a74a0a7dd399b0ee2ddd4889c609dedb85bfb5 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:35 +0200
|
||||
Subject: [PATCH 10/36] ice: Use PTP auxbus for all PHYs restart in E822
|
||||
|
||||
The E822 (and other devices based on the same PHY) is having issue while
|
||||
setting the PHC timer - the PHY timers are drifting from the PHC. After
|
||||
such a set all PHYs need to be restarted and resynchronised - do it
|
||||
using auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit af3c5c8748e6d286d4f2dd9800f9d27f29b8e2ef)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 24 +++++++++++++++++++++---
|
||||
1 file changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index b0bba866e8a2..42eb1418eb90 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1496,6 +1496,24 @@ static void ice_ptp_reset_phy_timestamping(struct ice_pf *pf)
|
||||
ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_restart_all_phy - Restart all PHYs to recalibrate timestamping
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+static void ice_ptp_restart_all_phy(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct list_head *entry;
|
||||
+
|
||||
+ list_for_each(entry, &pf->ptp.ports_owner.ports) {
|
||||
+ struct ice_ptp_port *port = list_entry(entry,
|
||||
+ struct ice_ptp_port,
|
||||
+ list_member);
|
||||
+
|
||||
+ if (port->link_up)
|
||||
+ ice_ptp_port_phy_restart(port);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_adjfine - Adjust clock increment rate
|
||||
* @info: the driver's PTP info structure
|
||||
@@ -1933,9 +1951,9 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
/* Reenable periodic outputs */
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
- /* Recalibrate and re-enable timestamp block */
|
||||
- if (pf->ptp.port.link_up)
|
||||
- ice_ptp_port_phy_restart(&pf->ptp.port);
|
||||
+ /* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
+ if (hw->phy_model == ICE_PHY_E822)
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err);
|
||||
--
|
||||
2.43.0
|
||||
|
2177
kernel-std/debian/patches/ice-VDF/0011-ice-Rename-E822-to-E82X.patch
Normal file
2177
kernel-std/debian/patches/ice-VDF/0011-ice-Rename-E822-to-E82X.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,104 @@
|
||||
From 3b37119a08ffe4be182ade746a6b1fe3bcf65921 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:22 +0100
|
||||
Subject: [PATCH 12/36] ice: Schedule service task in IRQ top half
|
||||
|
||||
Schedule service task and EXTTS in the top half to avoid bottom half
|
||||
scheduling if possible, which significantly reduces timestamping delay.
|
||||
|
||||
Co-developed-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 00d50001444ef5c75c8ab476a6674708f3ff613b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 20 +++++++++++---------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 54a98c4032b7..efe78d5e4da1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -517,7 +517,6 @@ enum ice_pf_flags {
|
||||
};
|
||||
|
||||
enum ice_misc_thread_tasks {
|
||||
- ICE_MISC_THREAD_EXTTS_EVENT,
|
||||
ICE_MISC_THREAD_TX_TSTAMP,
|
||||
ICE_MISC_THREAD_NBITS /* must be last */
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d2f3b4374d14..2acaa17a12bf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3109,6 +3109,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
{
|
||||
struct ice_pf *pf = (struct ice_pf *)data;
|
||||
+ irqreturn_t ret = IRQ_HANDLED;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct device *dev;
|
||||
u32 oicr, ena_mask;
|
||||
@@ -3190,8 +3191,10 @@ 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 (ice_ptp_pf_handles_tx_interrupt(pf))
|
||||
+ if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
+ ret = IRQ_WAKE_THREAD;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (oicr & PFINT_OICR_TSYN_EVNT_M) {
|
||||
@@ -3207,7 +3210,7 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
GLTSYN_STAT_EVENT1_M |
|
||||
GLTSYN_STAT_EVENT2_M);
|
||||
|
||||
- set_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread);
|
||||
+ ice_ptp_extts_event(pf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,8 +3233,11 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
|
||||
set_bit(ICE_PFR_REQ, pf->state);
|
||||
}
|
||||
}
|
||||
+ ice_service_task_schedule(pf);
|
||||
+ if (ret == IRQ_HANDLED)
|
||||
+ ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
- return IRQ_WAKE_THREAD;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3247,12 +3253,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
hw = &pf->hw;
|
||||
|
||||
if (ice_is_reset_in_progress(pf->state))
|
||||
- return IRQ_HANDLED;
|
||||
-
|
||||
- ice_service_task_schedule(pf);
|
||||
-
|
||||
- if (test_and_clear_bit(ICE_MISC_THREAD_EXTTS_EVENT, pf->misc_thread))
|
||||
- ice_ptp_extts_event(pf);
|
||||
+ goto skip_irq;
|
||||
|
||||
if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) {
|
||||
/* Process outstanding Tx timestamps. If there is more work,
|
||||
@@ -3264,6 +3265,7 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
+skip_irq:
|
||||
ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,660 @@
|
||||
From c4ab92eb3ee89178a012702f2a98477d683fad31 Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Wed, 29 Nov 2023 13:40:23 +0100
|
||||
Subject: [PATCH 13/36] ice: Enable SW interrupt from FW for LL TS
|
||||
|
||||
Introduce new capability - Low Latency Timestamping with Interrupt.
|
||||
On supported devices, driver can request a single timestamp from FW
|
||||
without polling the register afterwards. Instead, FW can issue
|
||||
a dedicated interrupt when the timestamp was read from the PHY register
|
||||
and its value is available to read from the register.
|
||||
This eliminates the need of bottom half scheduling, which results in
|
||||
minimal delay for timestamping.
|
||||
|
||||
For this mode, allocate TS indices sequentially, so that timestamps are
|
||||
always completed in FIFO manner.
|
||||
|
||||
Co-developed-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Signed-off-by: Yochai Hagvi <yochai.hagvi@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 82e71b226e0ef770d7bc143701c8b4960b4eb3d5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 3 +
|
||||
.../net/ethernet/intel/ice/ice_hw_autogen.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 120 +++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 ++++++++++++++++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 9 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 2 +
|
||||
8 files changed, 274 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index efe78d5e4da1..ee42a504c2f4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -594,6 +594,7 @@ struct ice_pf {
|
||||
u32 hw_csum_rx_error;
|
||||
u32 oicr_err_reg;
|
||||
struct msi_map oicr_irq; /* Other interrupt cause MSIX vector */
|
||||
+ struct msi_map ll_ts_irq; /* LL_TS interrupt MSIX vector */
|
||||
u16 max_pf_txqs; /* Total Tx queues PF wide */
|
||||
u16 max_pf_rxqs; /* Total Rx queues PF wide */
|
||||
u16 num_lan_msix; /* Total MSIX vectors for base driver */
|
||||
@@ -618,6 +619,7 @@ struct ice_pf {
|
||||
unsigned long tx_timeout_last_recovery;
|
||||
u32 tx_timeout_recovery_level;
|
||||
char int_name[ICE_INT_NAME_STR_LEN];
|
||||
+ char int_name_ll_ts[ICE_INT_NAME_STR_LEN];
|
||||
struct auxiliary_device *adev;
|
||||
int aux_idx;
|
||||
u32 sw_int_count;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 7674267a2d90..acf6ac00f804 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -2624,6 +2624,7 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
|
||||
|
||||
info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0);
|
||||
+ info->ts_ll_int_read = ((number & ICE_TS_LL_TX_TS_INT_READ_M) != 0);
|
||||
|
||||
info->ena_ports = logical_id;
|
||||
info->tmr_own_map = phys_id;
|
||||
@@ -2644,6 +2645,8 @@ ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
|
||||
info->tmr1_ena);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_read = %u\n",
|
||||
info->ts_ll_read);
|
||||
+ ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_int_read = %u\n",
|
||||
+ info->ts_ll_int_read);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n",
|
||||
info->ena_ports);
|
||||
ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
index 6756f3d51d14..fa730bca7f15 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
|
||||
@@ -200,6 +200,8 @@
|
||||
#define GLINT_VECT2FUNC_PF_NUM_M ICE_M(0x7, 12)
|
||||
#define GLINT_VECT2FUNC_IS_PF_S 16
|
||||
#define GLINT_VECT2FUNC_IS_PF_M BIT(16)
|
||||
+#define PFINT_ALLOC 0x001D2600
|
||||
+#define PFINT_ALLOC_FIRST ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL 0x0016C800
|
||||
#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
|
||||
#define PFINT_FW_CTL_ITR_INDX_S 11
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 2acaa17a12bf..9163a72368b3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -3071,6 +3071,7 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp)
|
||||
static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ u32 pf_intr_start_offset;
|
||||
u32 val;
|
||||
|
||||
/* Disable anti-spoof detection interrupt to prevent spurious event
|
||||
@@ -3099,6 +3100,47 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
|
||||
/* SW_ITR_IDX = 0, but don't change INTENA */
|
||||
wr32(hw, GLINT_DYN_CTL(pf->oicr_irq.index),
|
||||
GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ return;
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ll_ts_intr - ll_ts interrupt handler
|
||||
+ * @irq: interrupt number
|
||||
+ * @data: pointer to a q_vector
|
||||
+ */
|
||||
+static irqreturn_t ice_ll_ts_intr(int __always_unused irq, void *data)
|
||||
+{
|
||||
+ struct ice_pf *pf = data;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct ice_ptp_tx *tx;
|
||||
+ unsigned long flags;
|
||||
+ struct ice_hw *hw;
|
||||
+ u32 val;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ hw = &pf->hw;
|
||||
+ tx = &pf->ptp.port.tx;
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ ice_ptp_complete_tx_single_tstamp(tx);
|
||||
+
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+
|
||||
+ val = GLINT_DYN_CTL_INTENA_M | GLINT_DYN_CTL_CLEARPBA_M |
|
||||
+ (ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S);
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ wr32(hw, GLINT_DYN_CTL(pf->ll_ts_irq.index + pf_intr_start_offset),
|
||||
+ val);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3191,7 +3233,19 @@ 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 (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
+ if (ice_pf_state_is_nominal(pf) &&
|
||||
+ pf->hw.dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ struct ice_ptp_tx *tx = &pf->ptp.port.tx;
|
||||
+ unsigned long flags;
|
||||
+ u8 idx;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
+ idx = find_next_bit_wrap(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx != tx->len)
|
||||
+ ice_ptp_req_tx_single_tstamp(tx, idx);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
+ } else if (ice_ptp_pf_handles_tx_interrupt(pf)) {
|
||||
set_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread);
|
||||
ret = IRQ_WAKE_THREAD;
|
||||
}
|
||||
@@ -3295,6 +3349,20 @@ static void ice_dis_ctrlq_interrupts(struct ice_hw *hw)
|
||||
ice_flush(hw);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_free_irq_msix_ll_ts- Unroll ll_ts vector setup
|
||||
+ * @pf: board private structure
|
||||
+ */
|
||||
+static void ice_free_irq_msix_ll_ts(struct ice_pf *pf)
|
||||
+{
|
||||
+ int irq_num = pf->ll_ts_irq.virq;
|
||||
+
|
||||
+ synchronize_irq(irq_num);
|
||||
+ devm_free_irq(ice_pf_to_dev(pf), irq_num, pf);
|
||||
+
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_free_irq_msix_misc - Unroll misc vector setup
|
||||
* @pf: board private structure
|
||||
@@ -3314,6 +3382,8 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
|
||||
devm_free_irq(ice_pf_to_dev(pf), misc_irq_num, pf);
|
||||
|
||||
ice_free_irq(pf, pf->oicr_irq);
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ ice_free_irq_msix_ll_ts(pf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3339,10 +3409,12 @@ static void ice_ena_ctrlq_interrupts(struct ice_hw *hw, u16 reg_idx)
|
||||
PFINT_MBX_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, PFINT_MBX_CTL, val);
|
||||
|
||||
- /* This enables Sideband queue Interrupt causes */
|
||||
- val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
- PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
- wr32(hw, PFINT_SB_CTL, val);
|
||||
+ if (!hw->dev_caps.ts_dev_info.ts_ll_int_read) {
|
||||
+ /* enable Sideband queue Interrupt causes */
|
||||
+ val = ((reg_idx & PFINT_SB_CTL_MSIX_INDX_M) |
|
||||
+ PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
+ wr32(hw, PFINT_SB_CTL, val);
|
||||
+ }
|
||||
|
||||
ice_flush(hw);
|
||||
}
|
||||
@@ -3359,13 +3431,17 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
- struct msi_map oicr_irq;
|
||||
+ u32 pf_intr_start_offset;
|
||||
+ struct msi_map irq;
|
||||
int err = 0;
|
||||
|
||||
if (!pf->int_name[0])
|
||||
snprintf(pf->int_name, sizeof(pf->int_name) - 1, "%s-%s:misc",
|
||||
dev_driver_string(dev), dev_name(dev));
|
||||
|
||||
+ if (!pf->int_name_ll_ts[0])
|
||||
+ snprintf(pf->int_name_ll_ts, sizeof(pf->int_name_ll_ts) - 1,
|
||||
+ "%s-%s:ll_ts", dev_driver_string(dev), dev_name(dev));
|
||||
/* Do not request IRQ but do enable OICR interrupt since settings are
|
||||
* lost during reset. Note that this function is called only during
|
||||
* rebuild path and not while reset is in progress.
|
||||
@@ -3374,11 +3450,11 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
goto skip_req_irq;
|
||||
|
||||
/* reserve one vector in irq_tracker for misc interrupts */
|
||||
- oicr_irq = ice_alloc_irq(pf, false);
|
||||
- if (oicr_irq.index < 0)
|
||||
- return oicr_irq.index;
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
|
||||
- pf->oicr_irq = oicr_irq;
|
||||
+ pf->oicr_irq = irq;
|
||||
err = devm_request_threaded_irq(dev, pf->oicr_irq.virq, ice_misc_intr,
|
||||
ice_misc_intr_thread_fn, 0,
|
||||
pf->int_name, pf);
|
||||
@@ -3389,10 +3465,34 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
+ /* reserve one vector in irq_tracker for ll_ts interrupt */
|
||||
+ if (!pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ goto skip_req_irq;
|
||||
+
|
||||
+ irq = ice_alloc_irq(pf, false);
|
||||
+ if (irq.index < 0)
|
||||
+ return irq.index;
|
||||
+
|
||||
+ pf->ll_ts_irq = irq;
|
||||
+ err = devm_request_irq(dev, pf->ll_ts_irq.virq, ice_ll_ts_intr, 0,
|
||||
+ pf->int_name_ll_ts, pf);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "devm_request_irq for %s failed: %d\n",
|
||||
+ pf->int_name_ll_ts, err);
|
||||
+ ice_free_irq(pf, pf->ll_ts_irq);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
skip_req_irq:
|
||||
ice_ena_misc_vector(pf);
|
||||
|
||||
ice_ena_ctrlq_interrupts(hw, pf->oicr_irq.index);
|
||||
+ /* This enables LL TS interrupt */
|
||||
+ pf_intr_start_offset = rd32(hw, PFINT_ALLOC) & PFINT_ALLOC_FIRST;
|
||||
+ if (pf->hw.dev_caps.ts_dev_info.ts_ll_int_read)
|
||||
+ wr32(hw, PFINT_SB_CTL,
|
||||
+ ((pf->ll_ts_irq.index + pf_intr_start_offset) &
|
||||
+ PFINT_SB_CTL_MSIX_INDX_M) | PFINT_SB_CTL_CAUSE_ENA_M);
|
||||
wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_irq.index),
|
||||
ITR_REG_ALIGN(ICE_ITR_8K) >> ICE_ITR_GRAN_S);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 2e6e1fc84d11..75038d826f71 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -634,6 +634,119 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
return tx->init && !tx->calibrating;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_req_tx_single_tstamp - Request Tx timestamp for a port from FW
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ * @idx: index of the timestamp to request
|
||||
+ */
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+
|
||||
+ if (!tx->init)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ /* Drop packets which have waited for more than 2 seconds */
|
||||
+ if (time_is_before_jiffies(tx->tstamps[idx].start + 2 * HZ)) {
|
||||
+ /* Count the number of Tx timestamps that timed out */
|
||||
+ pf->ptp.tx_hwtstamp_timeouts++;
|
||||
+
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_req, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ /* Write TS index to read to the PF register so the FW can read it */
|
||||
+ wr32(&pf->hw, PF_SB_ATQBAL,
|
||||
+ TS_LL_READ_TS_INTR | FIELD_PREP(TS_LL_READ_TS_IDX, idx) |
|
||||
+ TS_LL_READ_TS);
|
||||
+ tx->last_ll_ts_idx_read = idx;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_complete_tx_single_tstamp - Complete Tx timestamp for a port
|
||||
+ * @tx: the PTP Tx timestamp tracker
|
||||
+ */
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
+{
|
||||
+ struct skb_shared_hwtstamps shhwtstamps = {};
|
||||
+ u8 idx = tx->last_ll_ts_idx_read;
|
||||
+ struct ice_ptp_port *ptp_port;
|
||||
+ u64 raw_tstamp, tstamp;
|
||||
+ bool drop_ts = false;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct ice_pf *pf;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (!tx->init || tx->last_ll_ts_idx_read < 0)
|
||||
+ return;
|
||||
+
|
||||
+ ptp_port = container_of(tx, struct ice_ptp_port, tx);
|
||||
+ pf = ptp_port_to_pf(ptp_port);
|
||||
+
|
||||
+ ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx);
|
||||
+
|
||||
+ val = rd32(&pf->hw, PF_SB_ATQBAL);
|
||||
+
|
||||
+ /* When the bit is cleared, the TS is ready in the register */
|
||||
+ if (val & TS_LL_READ_TS) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to get the Tx tstamp - FW not ready");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* High 8 bit value of the TS is on the bits 16:23 */
|
||||
+ raw_tstamp = FIELD_GET(TS_LL_READ_TS_HIGH, val);
|
||||
+ raw_tstamp <<= 32;
|
||||
+
|
||||
+ /* Read the low 32 bit value */
|
||||
+ raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
+
|
||||
+ /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
+ * verify that the timestamp value is different from the last cached
|
||||
+ * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
+ * been captured by hardware.
|
||||
+ */
|
||||
+ if (!drop_ts && tx->verify_cached &&
|
||||
+ raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ return;
|
||||
+
|
||||
+ if (tx->verify_cached && raw_tstamp)
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ clear_bit(idx, tx->in_use);
|
||||
+ skb = tx->tstamps[idx].skb;
|
||||
+ tx->tstamps[idx].skb = NULL;
|
||||
+ if (test_and_clear_bit(idx, tx->stale))
|
||||
+ drop_ts = true;
|
||||
+
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ if (drop_ts) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Extend the timestamp using cached PHC time */
|
||||
+ tstamp = ice_ptp_extend_40b_ts(pf, raw_tstamp);
|
||||
+ if (tstamp) {
|
||||
+ shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
|
||||
+ ice_trace(tx_tstamp_complete, skb, idx);
|
||||
+ }
|
||||
+
|
||||
+ skb_tstamp_tx(skb, &shhwtstamps);
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_process_tx_tstamp - Process Tx timestamps for a port
|
||||
* @tx: the PTP Tx timestamp tracker
|
||||
@@ -685,6 +798,7 @@ ice_ptp_is_tx_tracker_up(struct ice_ptp_tx *tx)
|
||||
static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_ptp_port *ptp_port;
|
||||
+ unsigned long flags;
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u64 tstamp_ready;
|
||||
@@ -756,7 +870,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
drop_ts = true;
|
||||
|
||||
skip_ts_read:
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
if (tx->verify_cached && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
@@ -764,7 +878,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
if (test_and_clear_bit(idx, tx->stale))
|
||||
drop_ts = true;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* It is unlikely but possible that the SKB will have been
|
||||
* flushed at this point due to link change or teardown.
|
||||
@@ -834,6 +948,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
{
|
||||
bool more_timestamps;
|
||||
+ unsigned long flags;
|
||||
|
||||
if (!tx->init)
|
||||
return ICE_TX_TSTAMP_WORK_DONE;
|
||||
@@ -842,9 +957,9 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
ice_ptp_process_tx_tstamp(tx);
|
||||
|
||||
/* Check if there are outstanding Tx timestamps */
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
if (more_timestamps)
|
||||
return ICE_TX_TSTAMP_WORK_PENDING;
|
||||
@@ -881,6 +996,7 @@ ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx)
|
||||
tx->in_use = in_use;
|
||||
tx->stale = stale;
|
||||
tx->init = 1;
|
||||
+ tx->last_ll_ts_idx_read = -1;
|
||||
|
||||
spin_lock_init(&tx->lock);
|
||||
|
||||
@@ -898,6 +1014,7 @@ static void
|
||||
ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
u8 idx;
|
||||
@@ -921,12 +1038,12 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
if (!hw->reset_ongoing && (tstamp_ready & BIT_ULL(phy_idx)))
|
||||
ice_clear_phy_tstamp(hw, tx->block, phy_idx);
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
clear_bit(idx, tx->in_use);
|
||||
clear_bit(idx, tx->stale);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* Count the number of Tx timestamps flushed */
|
||||
pf->ptp.tx_hwtstamp_flushed++;
|
||||
@@ -950,9 +1067,11 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
bitmap_or(tx->stale, tx->stale, tx->in_use, tx->len);
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -965,9 +1084,11 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
static void
|
||||
ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
{
|
||||
- spin_lock(&tx->lock);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
tx->init = 0;
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* wait for potentially outstanding interrupt to complete */
|
||||
synchronize_irq(pf->oicr_irq.virq);
|
||||
@@ -1367,6 +1488,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
struct ice_pf *pf = ptp_port_to_pf(ptp_port);
|
||||
u8 port = ptp_port->port_num;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
+ unsigned long flags;
|
||||
int err;
|
||||
|
||||
if (ice_is_e810(hw))
|
||||
@@ -1380,9 +1502,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
kthread_cancel_delayed_work_sync(&ptp_port->ov_work);
|
||||
|
||||
/* temporarily disable Tx timestamps while calibrating PHY offset */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = true;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx_fifo_busy_cnt = 0;
|
||||
|
||||
/* Start the PHY timer in Vernier mode */
|
||||
@@ -1391,9 +1513,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||
goto out_unlock;
|
||||
|
||||
/* Enable Tx timestamps right away */
|
||||
- spin_lock(&ptp_port->tx.lock);
|
||||
+ spin_lock_irqsave(&ptp_port->tx.lock, flags);
|
||||
ptp_port->tx.calibrating = false;
|
||||
- spin_unlock(&ptp_port->tx.lock);
|
||||
+ spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
|
||||
|
||||
kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work, 0);
|
||||
|
||||
@@ -2471,18 +2593,23 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
*/
|
||||
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
{
|
||||
+ unsigned long flags;
|
||||
u8 idx;
|
||||
|
||||
- spin_lock(&tx->lock);
|
||||
+ spin_lock_irqsave(&tx->lock, flags);
|
||||
|
||||
/* Check that this tracker is accepting new timestamp requests */
|
||||
if (!ice_ptp_is_tx_tracker_up(tx)) {
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find and set the first available index */
|
||||
- idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+ idx = find_next_zero_bit(tx->in_use, tx->len,
|
||||
+ tx->last_ll_ts_idx_read + 1);
|
||||
+ if (idx == tx->len)
|
||||
+ idx = find_first_zero_bit(tx->in_use, tx->len);
|
||||
+
|
||||
if (idx < tx->len) {
|
||||
/* We got a valid index that no other thread could have set. Store
|
||||
* a reference to the skb and the start time to allow discarding old
|
||||
@@ -2496,7 +2623,7 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
ice_trace(tx_tstamp_request, skb, idx);
|
||||
}
|
||||
|
||||
- spin_unlock(&tx->lock);
|
||||
+ spin_unlock_irqrestore(&tx->lock, flags);
|
||||
|
||||
/* return the appropriate PHY timestamp register index, -1 if no
|
||||
* indexes were available.
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index a3ae008a3539..64679d3d2c49 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -131,6 +131,7 @@ enum ice_tx_tstamp_work {
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
* @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
spinlock_t lock; /* lock protecting in_use bitmap */
|
||||
@@ -143,6 +144,7 @@ struct ice_ptp_tx {
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
u8 verify_cached : 1;
|
||||
+ s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
/* Quad and port information for initializing timestamp blocks */
|
||||
@@ -296,6 +298,8 @@ 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);
|
||||
+void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx);
|
||||
+void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx);
|
||||
enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
|
||||
void
|
||||
@@ -330,6 +334,11 @@ ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static inline void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx)
|
||||
+{ }
|
||||
+
|
||||
+static inline void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { }
|
||||
+
|
||||
static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
{
|
||||
return true;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 0cc285614c72..7e8fd369ef7c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -509,6 +509,7 @@ int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
#define TS_LL_READ_RETRIES 200
|
||||
#define TS_LL_READ_TS_HIGH GENMASK(23, 16)
|
||||
#define TS_LL_READ_TS_IDX GENMASK(29, 24)
|
||||
+#define TS_LL_READ_TS_INTR BIT(30)
|
||||
#define TS_LL_READ_TS BIT(31)
|
||||
|
||||
/* Internal PHY timestamp address */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index f8b658386552..b0f1f4db1d8b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -350,6 +350,7 @@ struct ice_ts_func_info {
|
||||
#define ICE_TS_TMR0_ENA_M BIT(25)
|
||||
#define ICE_TS_TMR1_ENA_M BIT(26)
|
||||
#define ICE_TS_LL_TX_TS_READ_M BIT(28)
|
||||
+#define ICE_TS_LL_TX_TS_INT_READ_M BIT(29)
|
||||
|
||||
struct ice_ts_dev_info {
|
||||
/* Device specific info */
|
||||
@@ -363,6 +364,7 @@ struct ice_ts_dev_info {
|
||||
u8 tmr0_ena;
|
||||
u8 tmr1_ena;
|
||||
u8 ts_ll_read;
|
||||
+ u8 ts_ll_int_read;
|
||||
};
|
||||
|
||||
/* Function specific capabilities */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,310 @@
|
||||
From f267daca86600496d536f85c4d1945558b982427 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Michalik <michal.michalik@intel.com>
|
||||
Date: Thu, 27 Jul 2023 15:50:36 +0200
|
||||
Subject: [PATCH 14/36] ice: PTP: add clock domain number to auxiliary
|
||||
interface
|
||||
|
||||
The PHC clock id used to be moved between PFs using FW admin queue
|
||||
shared parameters - move the implementation to auxiliary bus.
|
||||
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Michal Michalik <michal.michalik@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit fcd2c1e3139a27766ef263bd2011195dbc8a79f5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 5 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 163 +++---------------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 11 +-
|
||||
4 files changed, 34 insertions(+), 147 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 353ac55bdb9d..9bacb69ead8c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2360,11 +2360,6 @@ struct ice_aqc_driver_shared_params {
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 456cf4785c74..057453d589d5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3286,7 +3286,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);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 75038d826f71..a2d0da7dfe83 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -345,131 +345,6 @@ void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
ice_set_rx_tstamp(pf, ena);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_ptp_clock_index - Get the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Determine the clock index of the PTP clock associated with this device. If
|
||||
- * this is the PF controlling the clock, just use the local access to the
|
||||
- * clock device pointer.
|
||||
- *
|
||||
- * Otherwise, read from the driver shared parameters to determine the clock
|
||||
- * index value.
|
||||
- *
|
||||
- * Returns: the index of the PTP clock associated with this device, or -1 if
|
||||
- * there is no associated clock.
|
||||
- */
|
||||
-int ice_get_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- /* Use the ptp_clock structure if we're the main PF */
|
||||
- if (pf->ptp.clock)
|
||||
- return ptp_clock_index(pf->ptp.clock);
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_get_driver_param(hw, param_idx, &value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to read PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* The PTP clock index is an integer, and will be between 0 and
|
||||
- * INT_MAX. The highest bit of the driver shared parameter is used to
|
||||
- * indicate whether or not the currently stored clock index is valid.
|
||||
- */
|
||||
- if (!(value & PTP_SHARED_CLK_IDX_VALID))
|
||||
- return -1;
|
||||
-
|
||||
- return value & ~PTP_SHARED_CLK_IDX_VALID;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_set_ptp_clock_index - Set the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Set the PTP clock index for this device into the shared driver parameters,
|
||||
- * so that other PFs associated with this device can read it.
|
||||
- *
|
||||
- * If the PF is unable to store the clock index, it will log an error, but
|
||||
- * will continue operating PTP.
|
||||
- */
|
||||
-static void ice_set_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- u32 value;
|
||||
- int err;
|
||||
-
|
||||
- if (!pf->ptp.clock)
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- value = (u32)ptp_clock_index(pf->ptp.clock);
|
||||
- if (value > INT_MAX) {
|
||||
- dev_err(dev, "PTP Clock index is too large to store\n");
|
||||
- return;
|
||||
- }
|
||||
- value |= PTP_SHARED_CLK_IDX_VALID;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, value, NULL);
|
||||
- if (err) {
|
||||
- dev_err(dev, "Failed to set PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_clear_ptp_clock_index - Clear the PTP clock index
|
||||
- * @pf: the PF pointer
|
||||
- *
|
||||
- * Clear the PTP clock index for this device. Must be called when
|
||||
- * unregistering the PTP clock, in order to ensure other PFs stop reporting
|
||||
- * a clock object that no longer exists.
|
||||
- */
|
||||
-static void ice_clear_ptp_clock_index(struct ice_pf *pf)
|
||||
-{
|
||||
- struct device *dev = ice_pf_to_dev(pf);
|
||||
- enum ice_aqc_driver_params param_idx;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u8 tmr_idx;
|
||||
- int err;
|
||||
-
|
||||
- /* Do not clear the index if we don't own the timer */
|
||||
- if (!ice_pf_src_tmr_owned(pf))
|
||||
- return;
|
||||
-
|
||||
- tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc;
|
||||
- if (!tmr_idx)
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR0;
|
||||
- else
|
||||
- param_idx = ICE_AQC_DRIVER_PARAM_CLK_IDX_TMR1;
|
||||
-
|
||||
- err = ice_aq_set_driver_param(hw, param_idx, 0, NULL);
|
||||
- if (err) {
|
||||
- dev_dbg(dev, "Failed to clear PTP clock index parameter, err %d aq_err %s\n",
|
||||
- err, ice_aq_str(hw->adminq.sq_last_status));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_read_src_clk_reg - Read the source clock register
|
||||
* @pf: Board private structure
|
||||
@@ -2564,7 +2439,6 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
|
||||
static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
{
|
||||
struct ptp_clock_info *info;
|
||||
- struct ptp_clock *clock;
|
||||
struct device *dev;
|
||||
|
||||
/* No need to create a clock device if we already have one */
|
||||
@@ -2577,11 +2451,11 @@ static long ice_ptp_create_clock(struct ice_pf *pf)
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
/* Attempt to register the clock before enabling the hardware. */
|
||||
- clock = ptp_clock_register(info, dev);
|
||||
- if (IS_ERR(clock))
|
||||
- return PTR_ERR(clock);
|
||||
-
|
||||
- pf->ptp.clock = clock;
|
||||
+ pf->ptp.clock = ptp_clock_register(info, dev);
|
||||
+ if (IS_ERR(pf->ptp.clock)) {
|
||||
+ dev_err(ice_pf_to_dev(pf), "Failed to register PTP clock device");
|
||||
+ return PTR_ERR(pf->ptp.clock);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2996,6 +2870,28 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf)
|
||||
mutex_destroy(&pf->ptp.ports_owner.lock);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_clock_index - Get the PTP clock index for this device
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Returns: the PTP clock index associated with this PF, or -1 if no PTP clock
|
||||
+ * is associated.
|
||||
+ */
|
||||
+int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct auxiliary_device *aux_dev;
|
||||
+ struct ice_pf *owner_pf;
|
||||
+ struct ptp_clock *clock;
|
||||
+
|
||||
+ aux_dev = &pf->ptp.port.aux_dev;
|
||||
+ owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev);
|
||||
+ if (!owner_pf)
|
||||
+ return -1;
|
||||
+ clock = owner_pf->ptp.clock;
|
||||
+
|
||||
+ return clock ? ptp_clock_index(clock) : -1;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
@@ -3086,9 +2982,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err_clk;
|
||||
|
||||
- /* Store the PTP clock index for other PFs */
|
||||
- ice_set_ptp_clock_index(pf);
|
||||
-
|
||||
err = ice_ptp_register_auxbus_driver(pf);
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver");
|
||||
@@ -3097,7 +2990,6 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
return 0;
|
||||
err_aux:
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
err_clk:
|
||||
pf->ptp.clock = NULL;
|
||||
@@ -3353,7 +3245,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
/* Disable periodic outputs */
|
||||
ice_ptp_disable_all_clkout(pf);
|
||||
|
||||
- ice_clear_ptp_clock_index(pf);
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 64679d3d2c49..95ebd7a048ec 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -290,11 +290,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);
|
||||
@@ -322,10 +322,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
|
||||
@@ -353,5 +349,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_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,266 @@
|
||||
From eb63973adae478fdcc324f5490d6803646f0cc76 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 21 Nov 2023 13:12:57 -0800
|
||||
Subject: [PATCH 15/36] ice: restore timestamp configuration after device reset
|
||||
|
||||
The driver calls ice_ptp_cfg_timestamp() during ice_ptp_prepare_for_reset()
|
||||
to disable timestamping while the device is resetting. This operation
|
||||
destroys the user requested configuration. While the driver does call
|
||||
ice_ptp_cfg_timestamp in ice_rebuild() to restore some hardware settings
|
||||
after a reset, it unconditionally passes true or false, resulting in
|
||||
failure to restore previous user space configuration.
|
||||
|
||||
This results in a device reset forcibly disabling timestamp configuration
|
||||
regardless of current user settings.
|
||||
|
||||
This was not detected previously due to a quirk of the LinuxPTP ptp4l
|
||||
application. If ptp4l detects a missing timestamp, it enters a fault state
|
||||
and performs recovery logic which includes executing SIOCSHWTSTAMP again,
|
||||
restoring the now accidentally cleared configuration.
|
||||
|
||||
Not every application does this, and for these applications, timestamps
|
||||
will mysteriously stop after a PF reset, without being restored until an
|
||||
application restart.
|
||||
|
||||
Fix this by replacing ice_ptp_cfg_timestamp() with two new functions:
|
||||
|
||||
1) ice_ptp_disable_timestamp_mode() which unconditionally disables the
|
||||
timestamping logic in ice_ptp_prepare_for_reset() and ice_ptp_release()
|
||||
|
||||
2) ice_ptp_restore_timestamp_mode() which calls
|
||||
ice_ptp_restore_tx_interrupt() to restore Tx timestamping configuration,
|
||||
calls ice_set_rx_tstamp() to restore Rx timestamping configuration, and
|
||||
issues an immediate TSYN_TX interrupt to ensure that timestamps which
|
||||
may have occurred during the device reset get processed.
|
||||
|
||||
Modify the ice_ptp_set_timestamp_mode to directly save the user
|
||||
configuration and then call ice_ptp_restore_timestamp_mode. This way, reset
|
||||
no longer destroys the saved user configuration.
|
||||
|
||||
This obsoletes the ice_set_tx_tstamp() function which can now be safely
|
||||
removed.
|
||||
|
||||
With this change, all devices should now restore Tx and Rx timestamping
|
||||
functionality correctly after a PF reset without application intervention.
|
||||
|
||||
Fixes: 77a781155a65 ("ice: enable receive hardware timestamping")
|
||||
Fixes: ea9b847cda64 ("ice: enable transmit timestamps for E810 devices")
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7758017911a4f2578d54c318e8fe77bcb5899054)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 12 +---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 74 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 5 +-
|
||||
3 files changed, 51 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 9163a72368b3..8cfb923198e9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7545,15 +7545,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err_vsi_rebuild;
|
||||
}
|
||||
|
||||
- /* configure PTP timestamping after VSI rebuild */
|
||||
- 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) {
|
||||
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
|
||||
@@ -7605,6 +7596,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_plug_aux_dev(pf);
|
||||
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
|
||||
ice_lag_rebuild(pf);
|
||||
+
|
||||
+ /* Restore timestamp mode settings after VSI rebuild */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
return;
|
||||
|
||||
err_vsi_rebuild:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a2d0da7dfe83..8fc6905b0f79 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -294,18 +294,6 @@ static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
|
||||
wr32(hw, PFINT_OICR_ENA, val);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_set_tx_tstamp - Enable or disable Tx timestamping
|
||||
- * @pf: The PF pointer to search in
|
||||
- * @on: bool value for whether timestamps are enabled or disabled
|
||||
- */
|
||||
-static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
|
||||
-{
|
||||
- pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||
-
|
||||
- ice_ptp_cfg_tx_interrupt(pf);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_set_rx_tstamp - Enable or disable Rx timestamping
|
||||
* @pf: The PF pointer to search in
|
||||
@@ -317,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
u16 i;
|
||||
|
||||
vsi = ice_get_main_vsi(pf);
|
||||
- if (!vsi)
|
||||
+ if (!vsi || !vsi->rx_rings)
|
||||
return;
|
||||
|
||||
/* Set the timestamp flag for all the Rx rings */
|
||||
@@ -326,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
|
||||
continue;
|
||||
vsi->rx_rings[i]->ptp_rx = on;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_disable_timestamp_mode - Disable current timestamp mode
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called during preparation for reset to temporarily disable timestamping on
|
||||
+ * the device. Called during remove to disable timestamping while cleaning up
|
||||
+ * driver resources.
|
||||
+ */
|
||||
+static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = rd32(hw, PFINT_OICR_ENA);
|
||||
+ val &= ~PFINT_OICR_TSYN_TX_M;
|
||||
+ wr32(hw, PFINT_OICR_ENA, val);
|
||||
|
||||
- pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
|
||||
- HWTSTAMP_FILTER_NONE;
|
||||
+ ice_set_rx_tstamp(pf, false);
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
|
||||
+ * ice_ptp_restore_timestamp_mode - Restore timestamp configuration
|
||||
* @pf: Board private structure
|
||||
- * @ena: bool value to enable or disable time stamp
|
||||
*
|
||||
- * This function will configure timestamping during PTP initialization
|
||||
- * and deinitialization
|
||||
+ * Called at the end of rebuild to restore timestamp configuration after
|
||||
+ * a device reset.
|
||||
*/
|
||||
-void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
|
||||
+void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
|
||||
{
|
||||
- ice_set_tx_tstamp(pf, ena);
|
||||
- ice_set_rx_tstamp(pf, ena);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ bool enable_rx;
|
||||
+
|
||||
+ ice_ptp_cfg_tx_interrupt(pf);
|
||||
+
|
||||
+ enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL;
|
||||
+ ice_set_rx_tstamp(pf, enable_rx);
|
||||
+
|
||||
+ /* Trigger an immediate software interrupt to ensure that timestamps
|
||||
+ * which occurred during reset are handled now.
|
||||
+ */
|
||||
+ wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
|
||||
+ ice_flush(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2152,10 +2167,10 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
{
|
||||
switch (config->tx_type) {
|
||||
case HWTSTAMP_TX_OFF:
|
||||
- ice_set_tx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
|
||||
break;
|
||||
case HWTSTAMP_TX_ON:
|
||||
- ice_set_tx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
@@ -2163,7 +2178,7 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
|
||||
switch (config->rx_filter) {
|
||||
case HWTSTAMP_FILTER_NONE:
|
||||
- ice_set_rx_tstamp(pf, false);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
@@ -2179,12 +2194,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_NTP_ALL:
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
- ice_set_rx_tstamp(pf, true);
|
||||
+ pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
+ /* Immediately update the device timestamping mode */
|
||||
+ ice_ptp_restore_timestamp_mode(pf);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2904,7 +2922,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
@@ -3222,7 +3240,7 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_cfg_timestamp(pf, false);
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
ice_ptp_remove_auxbus_device(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 95ebd7a048ec..130e6d2ae9a5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -294,7 +294,7 @@ 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);
|
||||
+void ice_ptp_restore_timestamp_mode(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);
|
||||
@@ -321,8 +321,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
-static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
|
||||
-
|
||||
+static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { }
|
||||
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
|
||||
static inline s8
|
||||
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,316 @@
|
||||
From 5c6115d27a377927d6392b3bfbe9739188c8153c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:49 -0800
|
||||
Subject: [PATCH 16/36] ice: introduce PTP state machine
|
||||
|
||||
Add PTP state machine so that the driver can correctly identify PTP
|
||||
state around resets.
|
||||
When the driver got information about ungraceful reset, PTP was not
|
||||
prepared for reset and it returned error. When this situation occurs,
|
||||
prepare PTP before rebuilding its structures.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 8293e4cb2ff54b1ec4f7206dcb74c908f62a3fb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_ethtool.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 110 +++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 10 ++
|
||||
4 files changed, 74 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index ee42a504c2f4..3278d032a2bd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -492,7 +492,6 @@ enum ice_pf_flags {
|
||||
ICE_FLAG_DCB_ENA,
|
||||
ICE_FLAG_FD_ENA,
|
||||
ICE_FLAG_PTP_SUPPORTED, /* PTP is supported by NVM */
|
||||
- ICE_FLAG_PTP, /* PTP is enabled by software */
|
||||
ICE_FLAG_ADV_FEATURES,
|
||||
ICE_FLAG_TC_MQPRIO, /* support for Multi queue TC */
|
||||
ICE_FLAG_CLS_FLOWER,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
index 057453d589d5..9e949c493c38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
|
||||
@@ -3276,7 +3276,7 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
|
||||
struct ice_pf *pf = ice_netdev_to_pf(dev);
|
||||
|
||||
/* only report timestamping if PTP is enabled */
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return ethtool_op_get_ts_info(dev, info);
|
||||
|
||||
info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 8fc6905b0f79..36c81c5ee83b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1430,7 +1430,7 @@ 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))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
@@ -2148,7 +2148,7 @@ int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
{
|
||||
struct hwtstamp_config *config;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EIO;
|
||||
|
||||
config = &pf->ptp.tstamp_config;
|
||||
@@ -2218,7 +2218,7 @@ int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||
struct hwtstamp_config config;
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return -EAGAIN;
|
||||
|
||||
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
|
||||
@@ -2606,7 +2606,7 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
struct ice_pf *pf = container_of(ptp, struct ice_pf, ptp);
|
||||
int err;
|
||||
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
err = ice_ptp_update_cached_phctime(pf);
|
||||
@@ -2618,6 +2618,42 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
msecs_to_jiffies(err ? 10 : 500));
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
+ * @pf: Board private structure
|
||||
+ */
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ u8 src_tmr;
|
||||
+
|
||||
+ if (ptp->state != ICE_PTP_READY)
|
||||
+ return;
|
||||
+
|
||||
+ ptp->state = ICE_PTP_RESETTING;
|
||||
+
|
||||
+ /* Disable timestamping for both Tx and Rx */
|
||||
+ ice_ptp_disable_timestamp_mode(pf);
|
||||
+
|
||||
+ kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
+
|
||||
+ if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ return;
|
||||
+
|
||||
+ ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
+
|
||||
+ /* Disable periodic outputs */
|
||||
+ ice_ptp_disable_all_clkout(pf);
|
||||
+
|
||||
+ src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
+
|
||||
+ /* Disable source clock */
|
||||
+ wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
+
|
||||
+ /* Acquire PHC and system timer to restore after reset */
|
||||
+ ptp->reset_time = ktime_get_real_ns();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
@@ -2630,6 +2666,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
int err, itr = 1;
|
||||
u64 time_diff;
|
||||
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
!ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
@@ -2690,7 +2734,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Restart the PHY timestamping block */
|
||||
if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
@@ -2704,6 +2748,7 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
return;
|
||||
|
||||
err:
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -2910,39 +2955,6 @@ int ice_ptp_clock_index(struct ice_pf *pf)
|
||||
return clock ? ptp_clock_index(clock) : -1;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
- * @pf: Board private structure
|
||||
- */
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_ptp *ptp = &pf->ptp;
|
||||
- u8 src_tmr;
|
||||
-
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
- /* Disable timestamping for both Tx and Rx */
|
||||
- ice_ptp_disable_timestamp_mode(pf);
|
||||
-
|
||||
- kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
-
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
- return;
|
||||
-
|
||||
- ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
-
|
||||
- /* Disable periodic outputs */
|
||||
- ice_ptp_disable_all_clkout(pf);
|
||||
-
|
||||
- src_tmr = ice_get_ptp_src_clock_index(&pf->hw);
|
||||
-
|
||||
- /* Disable source clock */
|
||||
- wr32(&pf->hw, GLTSYN_ENA(src_tmr), (u32)~GLTSYN_ENA_TSYN_ENA_M);
|
||||
-
|
||||
- /* Acquire PHC and system timer to restore after reset */
|
||||
- ptp->reset_time = ktime_get_real_ns();
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_init_owner - Initialize PTP_1588_CLOCK device
|
||||
* @pf: Board private structure
|
||||
@@ -3181,6 +3193,8 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err;
|
||||
|
||||
+ ptp->state = ICE_PTP_INITIALIZING;
|
||||
+
|
||||
ice_ptp_init_phy_model(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
@@ -3205,12 +3219,13 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
/* Configure initial Tx interrupt settings */
|
||||
ice_ptp_cfg_tx_interrupt(pf);
|
||||
|
||||
- set_bit(ICE_FLAG_PTP, pf->flags);
|
||||
- err = ice_ptp_init_work(pf, ptp);
|
||||
+ err = ice_ptp_create_auxbus_device(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
- err = ice_ptp_create_auxbus_device(pf);
|
||||
+ ptp->state = ICE_PTP_READY;
|
||||
+
|
||||
+ err = ice_ptp_init_work(pf, ptp);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
@@ -3223,7 +3238,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
ptp_clock_unregister(ptp->clock);
|
||||
pf->ptp.clock = NULL;
|
||||
}
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
+ ptp->state = ICE_PTP_ERROR;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP failed %d\n", err);
|
||||
}
|
||||
|
||||
@@ -3236,9 +3251,11 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
*/
|
||||
void ice_ptp_release(struct ice_pf *pf)
|
||||
{
|
||||
- if (!test_bit(ICE_FLAG_PTP, pf->flags))
|
||||
+ if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
+ pf->ptp.state = ICE_PTP_UNINIT;
|
||||
+
|
||||
/* Disable timestamping for both Tx and Rx */
|
||||
ice_ptp_disable_timestamp_mode(pf);
|
||||
|
||||
@@ -3246,8 +3263,6 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
|
||||
- clear_bit(ICE_FLAG_PTP, pf->flags);
|
||||
-
|
||||
kthread_cancel_delayed_work_sync(&pf->ptp.work);
|
||||
|
||||
ice_ptp_port_phy_stop(&pf->ptp.port);
|
||||
@@ -3257,6 +3272,9 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
pf->ptp.kworker = NULL;
|
||||
}
|
||||
|
||||
+ if (ice_pf_src_tmr_owned(pf))
|
||||
+ ice_ptp_unregister_auxbus_driver(pf);
|
||||
+
|
||||
if (!pf->ptp.clock)
|
||||
return;
|
||||
|
||||
@@ -3266,7 +3284,5 @@ void ice_ptp_release(struct ice_pf *pf)
|
||||
ptp_clock_unregister(pf->ptp.clock);
|
||||
pf->ptp.clock = NULL;
|
||||
|
||||
- ice_ptp_unregister_auxbus_driver(pf);
|
||||
-
|
||||
dev_info(ice_pf_to_dev(pf), "Removed PTP clock\n");
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 130e6d2ae9a5..e3cc69692405 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -203,8 +203,17 @@ struct ice_ptp_port_owner {
|
||||
|
||||
#define GLTSYN_TGT_H_IDX_MAX 4
|
||||
|
||||
+enum ice_ptp_state {
|
||||
+ ICE_PTP_UNINIT = 0,
|
||||
+ ICE_PTP_INITIALIZING,
|
||||
+ ICE_PTP_READY,
|
||||
+ ICE_PTP_RESETTING,
|
||||
+ ICE_PTP_ERROR,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK
|
||||
+ * @state: current state of PTP state machine
|
||||
* @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
|
||||
@@ -227,6 +236,7 @@ struct ice_ptp_port_owner {
|
||||
* @late_cached_phc_updates: number of times cached PHC update is late
|
||||
*/
|
||||
struct ice_ptp {
|
||||
+ enum ice_ptp_state state;
|
||||
enum ice_ptp_tx_interrupt tx_interrupt_mode;
|
||||
struct ice_ptp_port port;
|
||||
struct ice_ptp_port_owner ports_owner;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 68d481b41ee5c177a1376fb82a98c09c148d982a Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:50 -0800
|
||||
Subject: [PATCH 17/36] ice: pass reset type to PTP reset functions
|
||||
|
||||
The ice_ptp_prepare_for_reset() and ice_ptp_reset() functions currently
|
||||
check the pf->flags ICE_FLAG_PFR_REQ bit to determine if the current
|
||||
reset is a PF reset or not.
|
||||
|
||||
This is problematic, because it is possible that a PF reset and a higher
|
||||
level reset (CORE reset, GLOBAL reset, EMP reset) are requested
|
||||
simultaneously. In that case, the driver performs the highest level
|
||||
reset requested. However, the ICE_FLAG_PFR_REQ flag will still be set.
|
||||
|
||||
The main driver reset functions take an enum ice_reset_req indicating
|
||||
which reset is actually being performed. Pass this data into the PTP
|
||||
functions and rely on this instead of relying on the driver flags.
|
||||
|
||||
This ensures that the PTP code performs the proper level of reset that
|
||||
the driver is actually undergoing.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit c75d5e675a8542274fa0f7e52f3c4db1d4859a0c)
|
||||
[Adjust the ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 4 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 13 +++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 17 +++++++++++++----
|
||||
3 files changed, 22 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 8cfb923198e9..d5321410f2d7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -615,7 +615,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
ice_pf_dis_all_vsi(pf, false);
|
||||
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_exit(pf);
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf);
|
||||
+ ice_ptp_reset(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 36c81c5ee83b..20d1d22235d3 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2621,8 +2621,9 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
|
||||
/**
|
||||
* ice_ptp_prepare_for_reset - Prepare PTP for reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
u8 src_tmr;
|
||||
@@ -2637,7 +2638,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
|
||||
kthread_cancel_delayed_work_sync(&ptp->work);
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state))
|
||||
+ if (reset_type == ICE_RESET_PFR)
|
||||
return;
|
||||
|
||||
ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
|
||||
@@ -2657,8 +2658,9 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
* @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf)
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,15 +2669,14 @@ void ice_ptp_reset(struct ice_pf *pf)
|
||||
u64 time_diff;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf);
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
} else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
err = -EINVAL;
|
||||
dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (test_bit(ICE_PFR_REQ, pf->state) ||
|
||||
- !ice_pf_src_tmr_owned(pf))
|
||||
+ if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
goto pfr;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index e3cc69692405..cd74712a17a1 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -315,8 +315,9 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf);
|
||||
-void ice_ptp_prepare_for_reset(struct ice_pf *pf);
|
||||
+void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
void ice_ptp_release(struct ice_pf *pf);
|
||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
|
||||
@@ -351,8 +352,16 @@ static inline bool ice_ptp_process_ts(struct ice_pf *pf)
|
||||
static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf) { }
|
||||
-static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { }
|
||||
+
|
||||
+static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
+{
|
||||
+}
|
||||
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
||||
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)
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,119 @@
|
||||
From 084497314e63f3d92178bc44500a27a277abc378 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:51 -0800
|
||||
Subject: [PATCH 18/36] ice: rename verify_cached to has_ready_bitmap
|
||||
|
||||
The tx->verify_cached flag is used to inform the Tx timestamp tracking
|
||||
code whether it needs to verify the cached Tx timestamp value against
|
||||
a previous captured value. This is necessary on E810 hardware which does
|
||||
not have a Tx timestamp ready bitmap.
|
||||
|
||||
In addition, we currently rely on the fact that the
|
||||
ice_get_phy_tx_tstamp_ready() function returns all 1s for E810 hardware.
|
||||
Instead of introducing a brand new flag, rename and verify_cached to
|
||||
has_ready_bitmap, inverting the relevant checks.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 3f2216e8dbce04da5376ea7df410541f7b687cb0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 +++++---
|
||||
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 20d1d22235d3..a8c6b83579e6 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -606,11 +606,11 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
* timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
* been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -751,7 +751,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* from the last cached timestamp. If it is not, skip this for
|
||||
* now assuming it hasn't yet been captured by hardware.
|
||||
*/
|
||||
- if (!drop_ts && tx->verify_cached &&
|
||||
+ if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
continue;
|
||||
|
||||
@@ -761,7 +761,7 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
|
||||
skip_ts_read:
|
||||
spin_lock_irqsave(&tx->lock, flags);
|
||||
- if (tx->verify_cached && raw_tstamp)
|
||||
+ if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
@@ -1014,7 +1014,7 @@ ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
- tx->verify_cached = 0;
|
||||
+ tx->has_ready_bitmap = 1;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
* verify new timestamps against cached copy of the last read
|
||||
* timestamp.
|
||||
*/
|
||||
- tx->verify_cached = 1;
|
||||
+ tx->has_ready_bitmap = 0;
|
||||
|
||||
return ice_ptp_alloc_tx_tracker(tx);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index cd74712a17a1..1486a0b3b016 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -100,7 +100,7 @@ struct ice_perout_channel {
|
||||
* the last timestamp we read for a given index. If the current timestamp
|
||||
* value is the same as the cached value, we assume a new timestamp hasn't
|
||||
* been captured. This avoids reporting stale timestamps to the stack. This is
|
||||
- * only done if the verify_cached flag is set in ice_ptp_tx structure.
|
||||
+ * only done if the has_ready_bitmap flag is not set in ice_ptp_tx structure.
|
||||
*/
|
||||
struct ice_tx_tstamp {
|
||||
struct sk_buff *skb;
|
||||
@@ -130,7 +130,9 @@ enum ice_tx_tstamp_work {
|
||||
* @init: if true, the tracker is initialized;
|
||||
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
|
||||
* window, timestamps are temporarily disabled.
|
||||
- * @verify_cached: if true, verify new timestamp differs from last read value
|
||||
+ * @has_ready_bitmap: if true, the hardware has a valid Tx timestamp ready
|
||||
+ * bitmap register. If false, fall back to verifying new
|
||||
+ * timestamp values against previously cached copy.
|
||||
* @last_ll_ts_idx_read: index of the last LL TS read by the FW
|
||||
*/
|
||||
struct ice_ptp_tx {
|
||||
@@ -143,7 +145,7 @@ struct ice_ptp_tx {
|
||||
u8 len;
|
||||
u8 init : 1;
|
||||
u8 calibrating : 1;
|
||||
- u8 verify_cached : 1;
|
||||
+ u8 has_ready_bitmap : 1;
|
||||
s8 last_ll_ts_idx_read;
|
||||
};
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,77 @@
|
||||
From 375bced6b51243a8c8708204dd32960d076d5b83 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:52 -0800
|
||||
Subject: [PATCH 19/36] ice: don't check has_ready_bitmap in E810 functions
|
||||
|
||||
E810 hardware does not have a Tx timestamp ready bitmap. Don't check
|
||||
has_ready_bitmap in E810-specific functions.
|
||||
Add has_ready_bitmap check in ice_ptp_process_tx_tstamp() to stop
|
||||
relying on the fact that ice_get_phy_tx_tstamp_ready() returns all 1s.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit fea82915fca626eaa83f36d8a23194e8593ef4b4)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 23 +++++++++++------------
|
||||
1 file changed, 11 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index a8c6b83579e6..ddc2dd0b2a28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -601,17 +601,13 @@ void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx)
|
||||
/* Read the low 32 bit value */
|
||||
raw_tstamp |= (u64)rd32(&pf->hw, PF_SB_ATQBAH);
|
||||
|
||||
- /* For PHYs which don't implement a proper timestamp ready bitmap,
|
||||
- * verify that the timestamp value is different from the last cached
|
||||
- * timestamp. If it is not, skip this for now assuming it hasn't yet
|
||||
- * been captured by hardware.
|
||||
+ /* Devices using this interface always verify the timestamp differs
|
||||
+ * relative to the last cached timestamp value.
|
||||
*/
|
||||
- if (!drop_ts && !tx->has_ready_bitmap &&
|
||||
- raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
+ if (raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
return;
|
||||
|
||||
- if (!tx->has_ready_bitmap && raw_tstamp)
|
||||
- tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
+ tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
@@ -701,9 +697,11 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
hw = &pf->hw;
|
||||
|
||||
/* Read the Tx ready status first */
|
||||
- err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
- if (err)
|
||||
- return;
|
||||
+ if (tx->has_ready_bitmap) {
|
||||
+ err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
|
||||
+ if (err)
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* Drop packets if the link went down */
|
||||
link_up = ptp_port->link_up;
|
||||
@@ -731,7 +729,8 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
|
||||
* If we do not, the hardware logic for generating a new
|
||||
* interrupt can get stuck on some devices.
|
||||
*/
|
||||
- if (!(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
+ if (tx->has_ready_bitmap &&
|
||||
+ !(tstamp_ready & BIT_ULL(phy_idx))) {
|
||||
if (drop_ts)
|
||||
goto skip_ts_read;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,88 @@
|
||||
From a5318a3a04ed9535ab18ef0f0537b3d33862bee9 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:53 -0800
|
||||
Subject: [PATCH 20/36] ice: rename ice_ptp_tx_cfg_intr
|
||||
|
||||
The ice_ptp_tx_cfg_intr() function sends a control queue message to
|
||||
configure the PHY timestamp interrupt block. This is a very similar name
|
||||
to a function which is used to configure the MAC Other Interrupt Cause
|
||||
Enable register.
|
||||
|
||||
Rename this function to ice_ptp_cfg_phy_interrupt in order to make it
|
||||
more obvious to the reader what action it performs, and distinguish it
|
||||
from other similarly named functions.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 1abefdca85e8664374f53c7bc80d5f5f827ce711)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ddc2dd0b2a28..c6e9d77fc59b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1455,14 +1455,14 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_tx_ena_intr - Enable or disable the Tx timestamp interrupt
|
||||
+ * ice_ptp_cfg_phy_interrupt - Configure PHY interrupt settings
|
||||
* @pf: PF private structure
|
||||
* @ena: bool value to enable or disable interrupt
|
||||
* @threshold: Minimum number of packets at which intr is triggered
|
||||
*
|
||||
* Utility function to enable or disable Tx timestamp interrupt and threshold
|
||||
*/
|
||||
-static int ice_ptp_tx_ena_intr(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
+static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
int err = 0;
|
||||
@@ -2664,8 +2664,8 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
u64 time_diff;
|
||||
+ int err;
|
||||
|
||||
if (ptp->state == ICE_PTP_READY) {
|
||||
ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
@@ -2716,7 +2716,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
@@ -2967,7 +2967,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
struct timespec64 ts;
|
||||
- int err, itr = 1;
|
||||
+ int err;
|
||||
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err) {
|
||||
@@ -3002,7 +3002,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
||||
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
- err = ice_ptp_tx_ena_intr(pf, true, itr);
|
||||
+ err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,191 @@
|
||||
From 9411c5b82a7196b9712488631fd14e67e2d919fa Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:54 -0800
|
||||
Subject: [PATCH 21/36] ice: factor out ice_ptp_rebuild_owner()
|
||||
|
||||
The ice_ptp_reset() function uses a goto to skip past clock owner
|
||||
operations if performing a PF reset or if the device is not the clock
|
||||
owner. This is a bit confusing. Factor this out into
|
||||
ice_ptp_rebuild_owner() instead.
|
||||
|
||||
The ice_ptp_reset() function is called by ice_rebuild() to restore PTP
|
||||
functionality after a device reset. Follow the convention set by the
|
||||
ice_main.c file and rename this function to ice_ptp_rebuild(), in the
|
||||
same way that we have ice_prepare_for_reset() and
|
||||
ice_ptp_prepare_for_reset().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 803bef817807d2d36c930dada20c96fffae0dd19)
|
||||
[Adjust ice_ptp.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 62 ++++++++++++++---------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 6 +--
|
||||
3 files changed, 42 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d5321410f2d7..a04dcc89c35d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7533,7 +7533,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
* fail.
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
|
||||
- ice_ptp_reset(pf, reset_type);
|
||||
+ ice_ptp_rebuild(pf, reset_type);
|
||||
|
||||
if (ice_is_feature_supported(pf, ICE_F_GNSS))
|
||||
ice_gnss_init(pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index c6e9d77fc59b..780aa242c86b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -2655,11 +2655,13 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_reset - Initialize PTP hardware clock support after reset
|
||||
+ * ice_ptp_rebuild_owner - Initialize PTP clock owner after reset
|
||||
* @pf: Board private structure
|
||||
- * @reset_type: the reset type being performed
|
||||
+ *
|
||||
+ * Companion function for ice_ptp_rebuild() which handles tasks that only the
|
||||
+ * PTP clock owner instance should perform.
|
||||
*/
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_ptp *ptp = &pf->ptp;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -2667,32 +2669,21 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
u64 time_diff;
|
||||
int err;
|
||||
|
||||
- if (ptp->state == ICE_PTP_READY) {
|
||||
- ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
- } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
- err = -EINVAL;
|
||||
- dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- if (reset_type == ICE_RESET_PFR || !ice_pf_src_tmr_owned(pf))
|
||||
- goto pfr;
|
||||
-
|
||||
err = ice_ptp_init_phc(hw);
|
||||
if (err)
|
||||
- goto err;
|
||||
+ return err;
|
||||
|
||||
/* Acquire the global hardware lock */
|
||||
if (!ice_ptp_lock(hw)) {
|
||||
err = -EBUSY;
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the increment time value to PHY and LAN */
|
||||
err = ice_ptp_write_incval(hw, ice_base_incval(pf));
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Write the initial Time value to PHY and LAN using the cached PHC
|
||||
@@ -2708,7 +2699,7 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
err = ice_ptp_write_init(pf, &ts);
|
||||
if (err) {
|
||||
ice_ptp_unlock(hw);
|
||||
- goto err;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/* Release the global hardware lock */
|
||||
@@ -2717,11 +2708,39 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ ice_ptp_restart_all_phy(pf);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_ptp_rebuild - Initialize PTP hardware clock support after reset
|
||||
+ * @pf: Board private structure
|
||||
+ * @reset_type: the reset type being performed
|
||||
+ */
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
+{
|
||||
+ struct ice_ptp *ptp = &pf->ptp;
|
||||
+ int err;
|
||||
+
|
||||
+ if (ptp->state == ICE_PTP_READY) {
|
||||
+ ice_ptp_prepare_for_reset(pf, reset_type);
|
||||
+ } else if (ptp->state != ICE_PTP_RESETTING) {
|
||||
+ err = -EINVAL;
|
||||
+ dev_err(ice_pf_to_dev(pf), "PTP was not initialized\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (ice_pf_src_tmr_owned(pf) && reset_type != ICE_RESET_PFR) {
|
||||
+ err = ice_ptp_rebuild_owner(pf);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
|
||||
-pfr:
|
||||
/* Init Tx structures */
|
||||
if (ice_is_e810(&pf->hw)) {
|
||||
err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
@@ -2736,11 +2755,6 @@ void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
- /* Restart the PHY timestamping block */
|
||||
- if (!test_bit(ICE_PFR_REQ, pf->state) &&
|
||||
- ice_pf_src_tmr_owned(pf))
|
||||
- ice_ptp_restart_all_phy(pf);
|
||||
-
|
||||
/* Start periodic work going */
|
||||
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 1486a0b3b016..352405a2daf2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -317,7 +317,7 @@ enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf);
|
||||
void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
|
||||
-void ice_ptp_reset(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
+void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type);
|
||||
void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||
enum ice_reset_req reset_type);
|
||||
void ice_ptp_init(struct ice_pf *pf);
|
||||
@@ -355,8 +355,8 @@ static inline void
|
||||
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
|
||||
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
|
||||
|
||||
-static inline void ice_ptp_reset(struct ice_pf *pf,
|
||||
- enum ice_reset_req reset_type)
|
||||
+static inline void ice_ptp_rebuild(struct ice_pf *pf,
|
||||
+ enum ice_reset_req reset_type)
|
||||
{
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 1c89a9e26f669bead5ebcac38fa98c20c517769c Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Thu, 25 Jan 2024 13:57:55 -0800
|
||||
Subject: [PATCH 22/36] ice: stop destroying and reinitalizing Tx tracker
|
||||
during reset
|
||||
|
||||
The ice driver currently attempts to destroy and re-initialize the Tx
|
||||
timestamp tracker during the reset flow. The release of the Tx tracker
|
||||
only happened during CORE reset or GLOBAL reset. The ice_ptp_rebuild()
|
||||
function always calls the ice_ptp_init_tx function which will allocate
|
||||
a new tracker data structure, resulting in memory leaks during PF reset.
|
||||
|
||||
Certainly the driver should not be allocating a new tracker without
|
||||
removing the old tracker data, as this results in a memory leak.
|
||||
Additionally, there's no reason to remove the tracker memory during a
|
||||
reset. Remove this logic from the reset and rebuild flow. Instead of
|
||||
releasing the Tx tracker, flush outstanding timestamps just before we
|
||||
reset the PHY timestamp block in ice_ptp_cfg_phy_interrupt().
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
(cherry picked from commit 7a25fe5cd5fb2265065ac6765c53c0a1f1e874d3)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 33 +++++++++++++++---------
|
||||
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 780aa242c86b..48ec59fc5d87 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -963,6 +963,22 @@ ice_ptp_mark_tx_tracker_stale(struct ice_ptp_tx *tx)
|
||||
spin_unlock_irqrestore(&tx->lock, flags);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_flush_all_tx_tracker - Flush all timestamp trackers on this clock
|
||||
+ * @pf: Board private structure
|
||||
+ *
|
||||
+ * Called by the clock owner to flush all the Tx timestamp trackers associated
|
||||
+ * with the clock.
|
||||
+ */
|
||||
+static void
|
||||
+ice_ptp_flush_all_tx_tracker(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_ptp_port *port;
|
||||
+
|
||||
+ list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member)
|
||||
+ ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_ptp_release_tx_tracker - Release allocated memory for Tx tracker
|
||||
* @pf: Board private structure
|
||||
@@ -2705,6 +2721,11 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
||||
/* Release the global hardware lock */
|
||||
ice_ptp_unlock(hw);
|
||||
|
||||
+ /* Flush software tracking of any outstanding timestamps since we're
|
||||
+ * about to flush the PHY timestamp block.
|
||||
+ */
|
||||
+ ice_ptp_flush_all_tx_tracker(pf);
|
||||
+
|
||||
if (!ice_is_e810(hw)) {
|
||||
/* Enable quad interrupts */
|
||||
err = ice_ptp_cfg_phy_interrupt(pf, true, 1);
|
||||
@@ -2741,18 +2762,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- /* Init Tx structures */
|
||||
- if (ice_is_e810(&pf->hw)) {
|
||||
- err = ice_ptp_init_tx_e810(pf, &ptp->port.tx);
|
||||
- } else {
|
||||
- kthread_init_delayed_work(&ptp->port.ov_work,
|
||||
- ice_ptp_wait_for_offsets);
|
||||
- err = ice_ptp_init_tx_e82x(pf, &ptp->port.tx,
|
||||
- ptp->port.port_num);
|
||||
- }
|
||||
- if (err)
|
||||
- goto err;
|
||||
-
|
||||
ptp->state = ICE_PTP_READY;
|
||||
|
||||
/* Start periodic work going */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,457 @@
|
||||
From 6f1d1fa58f58ff3f6ce61ab502bd29227ca1bb3f Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:56 +0100
|
||||
Subject: [PATCH 23/36] ice: Remove and readd netdev during devlink reload
|
||||
|
||||
Recent changes to the devlink reload (commit 9b2348e2d6c9
|
||||
("devlink: warn about existing entities during reload-reinit"))
|
||||
force the drivers to destroy devlink ports during reinit.
|
||||
Adjust ice driver to this requirement, unregister netdvice, destroy
|
||||
devlink port. ice_init_eth() was removed and all the common code
|
||||
between probe and reload was moved to ice_load().
|
||||
|
||||
During devlink reload we can't take devl_lock (it's already taken)
|
||||
and in ice_probe() we have to lock it. Use devl_* variant of the API
|
||||
which does not acquire and release devl_lock. Guard ice_load()
|
||||
with devl_lock only in case of probe.
|
||||
|
||||
Suggested-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 41cc4e53934c30f1cf7745c257154e538c78a1f5)
|
||||
[Adjust ice.h with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_devlink.c | 68 ++++++-
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 186 ++++++-------------
|
||||
3 files changed, 125 insertions(+), 131 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 3278d032a2bd..d3f72f9fbcd7 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -978,6 +978,8 @@ int ice_stop(struct net_device *netdev);
|
||||
void ice_service_task_schedule(struct ice_pf *pf);
|
||||
int ice_load(struct ice_pf *pf);
|
||||
void ice_unload(struct ice_pf *pf);
|
||||
+int ice_init_dev(struct ice_pf *pf);
|
||||
+void ice_deinit_dev(struct ice_pf *pf);
|
||||
|
||||
/**
|
||||
* ice_set_rdma_cap - enable RDMA support
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
index 3a2261823d93..43007e3674c4 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
|
||||
@@ -444,6 +444,20 @@ ice_devlink_reload_empr_start(struct ice_pf *pf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_down - unload given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static void ice_devlink_reinit_down(struct ice_pf *pf)
|
||||
+{
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ ice_unload(pf);
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
+ rtnl_unlock();
|
||||
+ ice_deinit_dev(pf);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_down - prepare for reload
|
||||
* @devlink: pointer to the devlink instance to reload
|
||||
@@ -477,7 +491,7 @@ ice_devlink_reload_down(struct devlink *devlink, bool netns_change,
|
||||
"Remove all VFs before doing reinit\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
- ice_unload(pf);
|
||||
+ ice_devlink_reinit_down(pf);
|
||||
return 0;
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
return ice_devlink_reload_empr_start(pf, extack);
|
||||
@@ -1240,6 +1254,45 @@ static int ice_devlink_set_parent(struct devlink_rate *devlink_rate,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_devlink_reinit_up - do reinit of the given PF
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+static int ice_devlink_reinit_up(struct ice_pf *pf)
|
||||
+{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+ struct ice_vsi_cfg_params params;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ice_init_dev(pf);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ params = ice_vsi_to_params(vsi);
|
||||
+ params.flags = ICE_VSI_FLAG_INIT;
|
||||
+
|
||||
+ rtnl_lock();
|
||||
+ err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ rtnl_unlock();
|
||||
+ if (err)
|
||||
+ goto err_vsi_cfg;
|
||||
+
|
||||
+ /* No need to take devl_lock, it's already taken by devlink API */
|
||||
+ err = ice_load(pf);
|
||||
+ if (err)
|
||||
+ goto err_load;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_load:
|
||||
+ rtnl_lock();
|
||||
+ ice_vsi_decfg(vsi);
|
||||
+ rtnl_unlock();
|
||||
+err_vsi_cfg:
|
||||
+ ice_deinit_dev(pf);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_devlink_reload_up - do reload up after reinit
|
||||
* @devlink: pointer to the devlink instance reloading
|
||||
@@ -1260,7 +1313,7 @@ ice_devlink_reload_up(struct devlink *devlink,
|
||||
switch (action) {
|
||||
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
||||
- return ice_load(pf);
|
||||
+ return ice_devlink_reinit_up(pf);
|
||||
case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
|
||||
return ice_devlink_reload_empr_finish(pf, extack);
|
||||
@@ -1540,6 +1593,7 @@ static const struct devlink_port_ops ice_devlink_port_ops = {
|
||||
* @pf: the PF to create a devlink port for
|
||||
*
|
||||
* Create and register a devlink_port for this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*
|
||||
* Return: zero on success or an error code on failure.
|
||||
*/
|
||||
@@ -1552,6 +1606,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
struct device *dev;
|
||||
int err;
|
||||
|
||||
+ devlink = priv_to_devlink(pf);
|
||||
+
|
||||
dev = ice_pf_to_dev(pf);
|
||||
|
||||
devlink_port = &pf->devlink_port;
|
||||
@@ -1572,10 +1628,9 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
ice_devlink_set_switch_id(pf, &attrs.switch_id);
|
||||
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
- devlink = priv_to_devlink(pf);
|
||||
|
||||
- err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
- &ice_devlink_port_ops);
|
||||
+ err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
|
||||
+ &ice_devlink_port_ops);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
|
||||
pf->hw.pf_id, err);
|
||||
@@ -1590,10 +1645,11 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
|
||||
* @pf: the PF to cleanup
|
||||
*
|
||||
* Unregisters the devlink_port structure associated with this PF.
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_devlink_destroy_pf_port(struct ice_pf *pf)
|
||||
{
|
||||
- devlink_port_unregister(&pf->devlink_port);
|
||||
+ devl_port_unregister(&pf->devlink_port);
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index a04dcc89c35d..d3340114297a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -4588,90 +4588,6 @@ static void ice_decfg_netdev(struct ice_vsi *vsi)
|
||||
vsi->netdev = NULL;
|
||||
}
|
||||
|
||||
-static int ice_start_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- int err;
|
||||
-
|
||||
- err = ice_init_mac_fltr(vsi->back);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- err = ice_vsi_open(vsi);
|
||||
- if (err)
|
||||
- ice_fltr_remove_all(vsi);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_stop_eth(struct ice_vsi *vsi)
|
||||
-{
|
||||
- ice_fltr_remove_all(vsi);
|
||||
- ice_vsi_close(vsi);
|
||||
-}
|
||||
-
|
||||
-static int ice_init_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
- int err;
|
||||
-
|
||||
- if (!vsi)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- /* init channel list */
|
||||
- INIT_LIST_HEAD(&vsi->ch_list);
|
||||
-
|
||||
- err = ice_cfg_netdev(vsi);
|
||||
- if (err)
|
||||
- return err;
|
||||
- /* Setup DCB netlink interface */
|
||||
- ice_dcbnl_setup(vsi);
|
||||
-
|
||||
- err = ice_init_mac_fltr(pf);
|
||||
- if (err)
|
||||
- goto err_init_mac_fltr;
|
||||
-
|
||||
- err = ice_devlink_create_pf_port(pf);
|
||||
- if (err)
|
||||
- goto err_devlink_create_pf_port;
|
||||
-
|
||||
- SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
-
|
||||
- err = ice_register_netdev(vsi);
|
||||
- if (err)
|
||||
- goto err_register_netdev;
|
||||
-
|
||||
- err = ice_tc_indir_block_register(vsi);
|
||||
- if (err)
|
||||
- goto err_tc_indir_block_register;
|
||||
-
|
||||
- ice_napi_add(vsi);
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-err_tc_indir_block_register:
|
||||
- ice_unregister_netdev(vsi);
|
||||
-err_register_netdev:
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
-err_devlink_create_pf_port:
|
||||
-err_init_mac_fltr:
|
||||
- ice_decfg_netdev(vsi);
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static void ice_deinit_eth(struct ice_pf *pf)
|
||||
-{
|
||||
- struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
-
|
||||
- if (!vsi)
|
||||
- return;
|
||||
-
|
||||
- ice_vsi_close(vsi);
|
||||
- ice_unregister_netdev(vsi);
|
||||
- ice_devlink_destroy_pf_port(pf);
|
||||
- ice_tc_indir_block_unregister(vsi);
|
||||
- ice_decfg_netdev(vsi);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_wait_for_fw - wait for full FW readiness
|
||||
* @hw: pointer to the hardware structure
|
||||
@@ -4697,7 +4613,7 @@ static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
-static int ice_init_dev(struct ice_pf *pf)
|
||||
+int ice_init_dev(struct ice_pf *pf)
|
||||
{
|
||||
struct device *dev = ice_pf_to_dev(pf);
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
@@ -4790,7 +4706,7 @@ static int ice_init_dev(struct ice_pf *pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void ice_deinit_dev(struct ice_pf *pf)
|
||||
+void ice_deinit_dev(struct ice_pf *pf)
|
||||
{
|
||||
ice_free_irq_msix_misc(pf);
|
||||
ice_deinit_pf(pf);
|
||||
@@ -5091,31 +5007,47 @@ static void ice_deinit(struct ice_pf *pf)
|
||||
/**
|
||||
* ice_load - load pf by init hw and starting VSI
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
int ice_load(struct ice_pf *pf)
|
||||
{
|
||||
- struct ice_vsi_cfg_params params = {};
|
||||
struct ice_vsi *vsi;
|
||||
int err;
|
||||
|
||||
- err = ice_init_dev(pf);
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
+ vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ /* init channel list */
|
||||
+ INIT_LIST_HEAD(&vsi->ch_list);
|
||||
+
|
||||
+ err = ice_cfg_netdev(vsi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- vsi = ice_get_main_vsi(pf);
|
||||
+ /* Setup DCB netlink interface */
|
||||
+ ice_dcbnl_setup(vsi);
|
||||
|
||||
- params = ice_vsi_to_params(vsi);
|
||||
- params.flags = ICE_VSI_FLAG_INIT;
|
||||
+ err = ice_init_mac_fltr(pf);
|
||||
+ if (err)
|
||||
+ goto err_init_mac_fltr;
|
||||
|
||||
- rtnl_lock();
|
||||
- err = ice_vsi_cfg(vsi, ¶ms);
|
||||
+ err = ice_devlink_create_pf_port(pf);
|
||||
if (err)
|
||||
- goto err_vsi_cfg;
|
||||
+ goto err_devlink_create_pf_port;
|
||||
|
||||
- err = ice_start_eth(ice_get_main_vsi(pf));
|
||||
+ SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
|
||||
+
|
||||
+ err = ice_register_netdev(vsi);
|
||||
+ if (err)
|
||||
+ goto err_register_netdev;
|
||||
+
|
||||
+ err = ice_tc_indir_block_register(vsi);
|
||||
if (err)
|
||||
- goto err_start_eth;
|
||||
- rtnl_unlock();
|
||||
+ goto err_tc_indir_block_register;
|
||||
+
|
||||
+ ice_napi_add(vsi);
|
||||
|
||||
err = ice_init_rdma(pf);
|
||||
if (err)
|
||||
@@ -5129,29 +5061,35 @@ int ice_load(struct ice_pf *pf)
|
||||
return 0;
|
||||
|
||||
err_init_rdma:
|
||||
- ice_vsi_close(ice_get_main_vsi(pf));
|
||||
- rtnl_lock();
|
||||
-err_start_eth:
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
-err_vsi_cfg:
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+err_tc_indir_block_register:
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+err_register_netdev:
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+err_devlink_create_pf_port:
|
||||
+err_init_mac_fltr:
|
||||
+ ice_decfg_netdev(vsi);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_unload - unload pf by stopping VSI and deinit hw
|
||||
* @pf: pointer to the pf instance
|
||||
+ *
|
||||
+ * This function has to be called under devl_lock.
|
||||
*/
|
||||
void ice_unload(struct ice_pf *pf)
|
||||
{
|
||||
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
|
||||
+
|
||||
+ devl_assert_locked(priv_to_devlink(pf));
|
||||
+
|
||||
ice_deinit_features(pf);
|
||||
ice_deinit_rdma(pf);
|
||||
- rtnl_lock();
|
||||
- ice_stop_eth(ice_get_main_vsi(pf));
|
||||
- ice_vsi_decfg(ice_get_main_vsi(pf));
|
||||
- rtnl_unlock();
|
||||
- ice_deinit_dev(pf);
|
||||
+ ice_tc_indir_block_unregister(vsi);
|
||||
+ ice_unregister_netdev(vsi);
|
||||
+ ice_devlink_destroy_pf_port(pf);
|
||||
+ ice_decfg_netdev(vsi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5249,27 +5187,23 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
|
||||
if (err)
|
||||
goto err_init;
|
||||
|
||||
- err = ice_init_eth(pf);
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ err = ice_load(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
if (err)
|
||||
- goto err_init_eth;
|
||||
-
|
||||
- err = ice_init_rdma(pf);
|
||||
- if (err)
|
||||
- goto err_init_rdma;
|
||||
+ goto err_load;
|
||||
|
||||
err = ice_init_devlink(pf);
|
||||
if (err)
|
||||
goto err_init_devlink;
|
||||
|
||||
- ice_init_features(pf);
|
||||
-
|
||||
return 0;
|
||||
|
||||
err_init_devlink:
|
||||
- ice_deinit_rdma(pf);
|
||||
-err_init_rdma:
|
||||
- ice_deinit_eth(pf);
|
||||
-err_init_eth:
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+err_load:
|
||||
ice_deinit(pf);
|
||||
err_init:
|
||||
pci_disable_device(pdev);
|
||||
@@ -5363,12 +5297,14 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
|
||||
if (!ice_is_safe_mode(pf))
|
||||
ice_remove_arfs(pf);
|
||||
- ice_deinit_features(pf);
|
||||
+
|
||||
ice_deinit_devlink(pf);
|
||||
- ice_deinit_rdma(pf);
|
||||
- ice_deinit_eth(pf);
|
||||
- ice_deinit(pf);
|
||||
|
||||
+ devl_lock(priv_to_devlink(pf));
|
||||
+ ice_unload(pf);
|
||||
+ devl_unlock(priv_to_devlink(pf));
|
||||
+
|
||||
+ ice_deinit(pf);
|
||||
ice_vsi_release_all(pf);
|
||||
|
||||
ice_setup_mc_magic_wake(pf);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,434 @@
|
||||
From e110839c4d9bfa4c885877a69573f48c008d3edd Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:11 -0800
|
||||
Subject: [PATCH 24/36] ice: remove FW logging code
|
||||
|
||||
The FW logging code doesn't work because there is no way to set
|
||||
cq_ena or uart_ena so remove the code. This code is the original
|
||||
(v1) way of FW logging so it should be replaced with the v2 way.
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1953fc720e603721764f31daae216a2851664167)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 78 -------
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 217 ------------------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 -
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 20 --
|
||||
5 files changed, 319 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 9bacb69ead8c..3b289e6a225b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2032,78 +2032,6 @@ struct ice_aqc_add_rdma_qset_data {
|
||||
struct ice_aqc_add_tx_rdma_qset_entry rdma_qsets[];
|
||||
};
|
||||
|
||||
-/* Configure Firmware Logging Command (indirect 0xFF09)
|
||||
- * Logging Information Read Response (indirect 0xFF10)
|
||||
- * Note: The 0xFF10 command has no input parameters.
|
||||
- */
|
||||
-struct ice_aqc_fw_logging {
|
||||
- u8 log_ctrl;
|
||||
-#define ICE_AQC_FW_LOG_AQ_EN BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_EN BIT(1)
|
||||
- u8 rsvd0;
|
||||
- u8 log_ctrl_valid; /* Not used by 0xFF10 Response */
|
||||
-#define ICE_AQC_FW_LOG_AQ_VALID BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_UART_VALID BIT(1)
|
||||
- u8 rsvd1[5];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
-enum ice_aqc_fw_logging_mod {
|
||||
- ICE_AQC_FW_LOG_ID_GENERAL = 0,
|
||||
- ICE_AQC_FW_LOG_ID_CTRL,
|
||||
- ICE_AQC_FW_LOG_ID_LINK,
|
||||
- ICE_AQC_FW_LOG_ID_LINK_TOPO,
|
||||
- ICE_AQC_FW_LOG_ID_DNL,
|
||||
- ICE_AQC_FW_LOG_ID_I2C,
|
||||
- ICE_AQC_FW_LOG_ID_SDP,
|
||||
- ICE_AQC_FW_LOG_ID_MDIO,
|
||||
- ICE_AQC_FW_LOG_ID_ADMINQ,
|
||||
- ICE_AQC_FW_LOG_ID_HDMA,
|
||||
- ICE_AQC_FW_LOG_ID_LLDP,
|
||||
- ICE_AQC_FW_LOG_ID_DCBX,
|
||||
- ICE_AQC_FW_LOG_ID_DCB,
|
||||
- ICE_AQC_FW_LOG_ID_NETPROXY,
|
||||
- ICE_AQC_FW_LOG_ID_NVM,
|
||||
- ICE_AQC_FW_LOG_ID_AUTH,
|
||||
- ICE_AQC_FW_LOG_ID_VPD,
|
||||
- ICE_AQC_FW_LOG_ID_IOSF,
|
||||
- ICE_AQC_FW_LOG_ID_PARSER,
|
||||
- ICE_AQC_FW_LOG_ID_SW,
|
||||
- ICE_AQC_FW_LOG_ID_SCHEDULER,
|
||||
- ICE_AQC_FW_LOG_ID_TXQ,
|
||||
- ICE_AQC_FW_LOG_ID_RSVD,
|
||||
- ICE_AQC_FW_LOG_ID_POST,
|
||||
- ICE_AQC_FW_LOG_ID_WATCHDOG,
|
||||
- ICE_AQC_FW_LOG_ID_TASK_DISPATCH,
|
||||
- ICE_AQC_FW_LOG_ID_MNG,
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
-};
|
||||
-
|
||||
-/* Defines for both above FW logging command/response buffers */
|
||||
-#define ICE_AQC_FW_LOG_ID_S 0
|
||||
-#define ICE_AQC_FW_LOG_ID_M (0xFFF << ICE_AQC_FW_LOG_ID_S)
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_CONF_SUCCESS 0 /* Used by response */
|
||||
-#define ICE_AQC_FW_LOG_CONF_BAD_INDX BIT(12) /* Used by response */
|
||||
-
|
||||
-#define ICE_AQC_FW_LOG_EN_S 12
|
||||
-#define ICE_AQC_FW_LOG_EN_M (0xF << ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_AQC_FW_LOG_INFO_EN BIT(12) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_INIT_EN BIT(13) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_FLOW_EN BIT(14) /* Used by command */
|
||||
-#define ICE_AQC_FW_LOG_ERR_EN BIT(15) /* Used by command */
|
||||
-
|
||||
-/* Get/Clear FW Log (indirect 0xFF11) */
|
||||
-struct ice_aqc_get_clear_fw_log {
|
||||
- u8 flags;
|
||||
-#define ICE_AQC_FW_LOG_CLEAR BIT(0)
|
||||
-#define ICE_AQC_FW_LOG_MORE_DATA_AVAIL BIT(1)
|
||||
- u8 rsvd1[7];
|
||||
- __le32 addr_high;
|
||||
- __le32 addr_low;
|
||||
-};
|
||||
-
|
||||
/* Download Package (indirect 0x0C40) */
|
||||
/* Also used for Update Package (indirect 0x0C41 and 0x0C42) */
|
||||
struct ice_aqc_download_pkg {
|
||||
@@ -2448,8 +2376,6 @@ struct ice_aq_desc {
|
||||
struct ice_aqc_add_rdma_qset add_rdma_qset;
|
||||
struct ice_aqc_add_get_update_free_vsi vsi_cmd;
|
||||
struct ice_aqc_add_update_free_vsi_resp add_update_free_vsi_res;
|
||||
- struct ice_aqc_fw_logging fw_logging;
|
||||
- struct ice_aqc_get_clear_fw_log get_clear_fw_log;
|
||||
struct ice_aqc_download_pkg download_pkg;
|
||||
struct ice_aqc_set_cgu_input_config set_cgu_input_config;
|
||||
struct ice_aqc_get_cgu_input_config get_cgu_input_config;
|
||||
@@ -2657,10 +2583,6 @@ enum ice_adminq_opc {
|
||||
|
||||
/* Standalone Commands/Events */
|
||||
ice_aqc_opc_event_lan_overflow = 0x1001,
|
||||
-
|
||||
- /* debug commands */
|
||||
- ice_aqc_opc_fw_logging = 0xFF09,
|
||||
- ice_aqc_opc_fw_logging_info = 0xFF10,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index acf6ac00f804..a5c4b7ad6a20 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -897,216 +897,6 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
|
||||
devm_kfree(ice_hw_to_dev(hw), sw);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_get_fw_log_cfg - get FW logging configuration
|
||||
- * @hw: pointer to the HW struct
|
||||
- */
|
||||
-static int ice_get_fw_log_cfg(struct ice_hw *hw)
|
||||
-{
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *config;
|
||||
- int status;
|
||||
- u16 size;
|
||||
-
|
||||
- size = sizeof(*config) * ICE_AQC_FW_LOG_ID_MAX;
|
||||
- config = kzalloc(size, GFP_KERNEL);
|
||||
- if (!config)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging_info);
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, config, size, NULL);
|
||||
- if (!status) {
|
||||
- u16 i;
|
||||
-
|
||||
- /* Save FW logging information into the HW structure */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 v, m, flgs;
|
||||
-
|
||||
- v = le16_to_cpu(config[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- flgs = (v & ICE_AQC_FW_LOG_EN_M) >> ICE_AQC_FW_LOG_EN_S;
|
||||
-
|
||||
- if (m < ICE_AQC_FW_LOG_ID_MAX)
|
||||
- hw->fw_log.evnts[m].cur = flgs;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- kfree(config);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_cfg_fw_log - configure FW logging
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @enable: enable certain FW logging events if true, disable all if false
|
||||
- *
|
||||
- * This function enables/disables the FW logging via Rx CQ events and a UART
|
||||
- * port based on predetermined configurations. FW logging via the Rx CQ can be
|
||||
- * enabled/disabled for individual PF's. However, FW logging via the UART can
|
||||
- * only be enabled/disabled for all PFs on the same device.
|
||||
- *
|
||||
- * To enable overall FW logging, the "cq_en" and "uart_en" enable bits in
|
||||
- * hw->fw_log need to be set accordingly, e.g. based on user-provided input,
|
||||
- * before initializing the device.
|
||||
- *
|
||||
- * When re/configuring FW logging, callers need to update the "cfg" elements of
|
||||
- * the hw->fw_log.evnts array with the desired logging event configurations for
|
||||
- * modules of interest. When disabling FW logging completely, the callers can
|
||||
- * just pass false in the "enable" parameter. On completion, the function will
|
||||
- * update the "cur" element of the hw->fw_log.evnts array with the resulting
|
||||
- * logging event configurations of the modules that are being re/configured. FW
|
||||
- * logging modules that are not part of a reconfiguration operation retain their
|
||||
- * previous states.
|
||||
- *
|
||||
- * Before resetting the device, it is recommended that the driver disables FW
|
||||
- * logging before shutting down the control queue. When disabling FW logging
|
||||
- * ("enable" = false), the latest configurations of FW logging events stored in
|
||||
- * hw->fw_log.evnts[] are not overridden to allow them to be reconfigured after
|
||||
- * a device reset.
|
||||
- *
|
||||
- * When enabling FW logging to emit log messages via the Rx CQ during the
|
||||
- * device's initialization phase, a mechanism alternative to interrupt handlers
|
||||
- * needs to be used to extract FW log messages from the Rx CQ periodically and
|
||||
- * to prevent the Rx CQ from being full and stalling other types of control
|
||||
- * messages from FW to SW. Interrupts are typically disabled during the device's
|
||||
- * initialization phase.
|
||||
- */
|
||||
-static int ice_cfg_fw_log(struct ice_hw *hw, bool enable)
|
||||
-{
|
||||
- struct ice_aqc_fw_logging *cmd;
|
||||
- u16 i, chgs = 0, len = 0;
|
||||
- struct ice_aq_desc desc;
|
||||
- __le16 *data = NULL;
|
||||
- u8 actv_evnts = 0;
|
||||
- void *buf = NULL;
|
||||
- int status = 0;
|
||||
-
|
||||
- if (!hw->fw_log.cq_en && !hw->fw_log.uart_en)
|
||||
- return 0;
|
||||
-
|
||||
- /* Disable FW logging only when the control queue is still responsive */
|
||||
- if (!enable &&
|
||||
- (!hw->fw_log.actv_evnts || !ice_check_sq_alive(hw, &hw->adminq)))
|
||||
- return 0;
|
||||
-
|
||||
- /* Get current FW log settings */
|
||||
- status = ice_get_fw_log_cfg(hw);
|
||||
- if (status)
|
||||
- return status;
|
||||
-
|
||||
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging);
|
||||
- cmd = &desc.params.fw_logging;
|
||||
-
|
||||
- /* Indicate which controls are valid */
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_AQ_VALID;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_UART_VALID;
|
||||
-
|
||||
- if (enable) {
|
||||
- /* Fill in an array of entries with FW logging modules and
|
||||
- * logging events being reconfigured.
|
||||
- */
|
||||
- for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
|
||||
- u16 val;
|
||||
-
|
||||
- /* Keep track of enabled event types */
|
||||
- actv_evnts |= hw->fw_log.evnts[i].cfg;
|
||||
-
|
||||
- if (hw->fw_log.evnts[i].cfg == hw->fw_log.evnts[i].cur)
|
||||
- continue;
|
||||
-
|
||||
- if (!data) {
|
||||
- data = devm_kcalloc(ice_hw_to_dev(hw),
|
||||
- ICE_AQC_FW_LOG_ID_MAX,
|
||||
- sizeof(*data),
|
||||
- GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
-
|
||||
- val = i << ICE_AQC_FW_LOG_ID_S;
|
||||
- val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
|
||||
- data[chgs++] = cpu_to_le16(val);
|
||||
- }
|
||||
-
|
||||
- /* Only enable FW logging if at least one module is specified.
|
||||
- * If FW logging is currently enabled but all modules are not
|
||||
- * enabled to emit log messages, disable FW logging altogether.
|
||||
- */
|
||||
- if (actv_evnts) {
|
||||
- /* Leave if there is effectively no change */
|
||||
- if (!chgs)
|
||||
- goto out;
|
||||
-
|
||||
- if (hw->fw_log.cq_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_AQ_EN;
|
||||
-
|
||||
- if (hw->fw_log.uart_en)
|
||||
- cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
|
||||
-
|
||||
- buf = data;
|
||||
- len = sizeof(*data) * chgs;
|
||||
- desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- status = ice_aq_send_cmd(hw, &desc, buf, len, NULL);
|
||||
- if (!status) {
|
||||
- /* Update the current configuration to reflect events enabled.
|
||||
- * hw->fw_log.cq_en and hw->fw_log.uart_en indicate if the FW
|
||||
- * logging mode is enabled for the device. They do not reflect
|
||||
- * actual modules being enabled to emit log messages. So, their
|
||||
- * values remain unchanged even when all modules are disabled.
|
||||
- */
|
||||
- u16 cnt = enable ? chgs : (u16)ICE_AQC_FW_LOG_ID_MAX;
|
||||
-
|
||||
- hw->fw_log.actv_evnts = actv_evnts;
|
||||
- for (i = 0; i < cnt; i++) {
|
||||
- u16 v, m;
|
||||
-
|
||||
- if (!enable) {
|
||||
- /* When disabling all FW logging events as part
|
||||
- * of device's de-initialization, the original
|
||||
- * configurations are retained, and can be used
|
||||
- * to reconfigure FW logging later if the device
|
||||
- * is re-initialized.
|
||||
- */
|
||||
- hw->fw_log.evnts[i].cur = 0;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- v = le16_to_cpu(data[i]);
|
||||
- m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
|
||||
- hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-out:
|
||||
- devm_kfree(ice_hw_to_dev(hw), data);
|
||||
-
|
||||
- return status;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * ice_output_fw_log
|
||||
- * @hw: pointer to the HW struct
|
||||
- * @desc: pointer to the AQ message descriptor
|
||||
- * @buf: pointer to the buffer accompanying the AQ message
|
||||
- *
|
||||
- * Formats a FW Log message and outputs it via the standard driver logs.
|
||||
- */
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
|
||||
-{
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg Start ]\n");
|
||||
- ice_debug_array(hw, ICE_DBG_FW_LOG, 16, 1, (u8 *)buf,
|
||||
- le16_to_cpu(desc->datalen));
|
||||
- ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg End ]\n");
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_get_itr_intrl_gran
|
||||
* @hw: pointer to the HW struct
|
||||
@@ -1164,11 +954,6 @@ int ice_init_hw(struct ice_hw *hw)
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
|
||||
- /* Enable FW logging. Not fatal if this fails. */
|
||||
- status = ice_cfg_fw_log(hw, true);
|
||||
- if (status)
|
||||
- ice_debug(hw, ICE_DBG_INIT, "Failed to enable FW logging.\n");
|
||||
-
|
||||
status = ice_clear_pf_cfg(hw);
|
||||
if (status)
|
||||
goto err_unroll_cqinit;
|
||||
@@ -1318,8 +1103,6 @@ void ice_deinit_hw(struct ice_hw *hw)
|
||||
ice_free_hw_tbls(hw);
|
||||
mutex_destroy(&hw->tnl_lock);
|
||||
|
||||
- /* Attempt to disable FW logging before shutting down control queues */
|
||||
- ice_cfg_fw_log(hw, false);
|
||||
ice_destroy_all_ctrlq(hw);
|
||||
|
||||
/* Clear VSI contexts if not already cleared */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 7a966a0c224f..d47e5400351f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -199,7 +199,6 @@ ice_aq_cfg_lan_txq(struct ice_hw *hw, struct ice_aqc_cfg_txqs_buf *buf,
|
||||
struct ice_sq_cd *cd);
|
||||
int ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
|
||||
void ice_replay_post(struct ice_hw *hw);
|
||||
-void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
|
||||
struct ice_q_ctx *
|
||||
ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
|
||||
int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index d3340114297a..e5cc9790969c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1535,9 +1535,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
- case ice_aqc_opc_fw_logging:
|
||||
- ice_output_fw_log(hw, &event.desc, event.msg_buf);
|
||||
- break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index b0f1f4db1d8b..6e1fed0d7384 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -731,24 +731,6 @@ struct ice_switch_info {
|
||||
DECLARE_BITMAP(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS);
|
||||
};
|
||||
|
||||
-/* FW logging configuration */
|
||||
-struct ice_fw_log_evnt {
|
||||
- u8 cfg : 4; /* New event enables to configure */
|
||||
- u8 cur : 4; /* Current/active event enables */
|
||||
-};
|
||||
-
|
||||
-struct ice_fw_log_cfg {
|
||||
- u8 cq_en : 1; /* FW logging is enabled via the control queue */
|
||||
- u8 uart_en : 1; /* FW logging is enabled via UART for all PFs */
|
||||
- u8 actv_evnts; /* Cumulation of currently enabled log events */
|
||||
-
|
||||
-#define ICE_FW_LOG_EVNT_INFO (ICE_AQC_FW_LOG_INFO_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_INIT (ICE_AQC_FW_LOG_INIT_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_FLOW (ICE_AQC_FW_LOG_FLOW_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
-#define ICE_FW_LOG_EVNT_ERR (ICE_AQC_FW_LOG_ERR_EN >> ICE_AQC_FW_LOG_EN_S)
|
||||
- struct ice_fw_log_evnt evnts[ICE_AQC_FW_LOG_ID_MAX];
|
||||
-};
|
||||
-
|
||||
/* Enum defining the different states of the mailbox snapshot in the
|
||||
* PF-VF mailbox overflow detection algorithm. The snapshot can be in
|
||||
* states:
|
||||
@@ -890,8 +872,6 @@ struct ice_hw {
|
||||
u8 fw_patch; /* firmware patch version */
|
||||
u32 fw_build; /* firmware build number */
|
||||
|
||||
- struct ice_fw_log_cfg fw_log;
|
||||
-
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
* initialization.
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,281 @@
|
||||
From 189d58473481cf01b493fca4e9dd2ab8380d0ce5 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:13 -0800
|
||||
Subject: [PATCH 26/36] ice: enable FW logging
|
||||
|
||||
Once users have configured the FW logging then allow them to enable it
|
||||
by writing to the 'fwlog/enable' file. The file accepts a boolean value
|
||||
(0 or 1) where 1 means enable FW logging and 0 means disable FW logging.
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Where <value> is 0 or 1.
|
||||
|
||||
The user can read the 'fwlog/enable' file to see whether logging is
|
||||
enabled or not. Reading the actual data is a separate patch. To see the
|
||||
current value then:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/enable
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 73671c3162c83a689342fd57f00b5f261682e49b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 3 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 98 +++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 67 +++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 2 +
|
||||
4 files changed, 170 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 347e4fed5e0d..11391be4efc2 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2336,6 +2336,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
};
|
||||
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
+ * Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
@@ -2344,6 +2345,7 @@ struct ice_aqc_fw_log {
|
||||
#define ICE_AQC_FW_LOG_CONF_AQ_EN BIT(1)
|
||||
#define ICE_AQC_FW_LOG_QUERY_REGISTERED BIT(2)
|
||||
#define ICE_AQC_FW_LOG_CONF_SET_VALID BIT(3)
|
||||
+#define ICE_AQC_FW_LOG_AQ_REGISTER BIT(0)
|
||||
#define ICE_AQC_FW_LOG_AQ_QUERY BIT(2)
|
||||
|
||||
u8 rsp_flag;
|
||||
@@ -2662,6 +2664,7 @@ enum ice_adminq_opc {
|
||||
|
||||
/* FW Logging Commands */
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
+ ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
};
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3b0d9b214fd1..3dde99969132 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -281,6 +281,101 @@ static const struct file_operations ice_debugfs_nr_messages_fops = {
|
||||
.write = ice_debugfs_nr_messages_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_enable_read - read from 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_enable_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+
|
||||
+ snprintf(buff, sizeof(buff), "%u\n",
|
||||
+ (u16)(hw->fwlog_cfg.options &
|
||||
+ ICE_FWLOG_OPTION_IS_REGISTERED) >> 3);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_enable_write - write into 'enable' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_enable_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ bool enable;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 2)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = kstrtobool(user_val, &enable);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
+
|
||||
+ ret = ice_fwlog_set(hw, &hw->fwlog_cfg);
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ if (enable)
|
||||
+ ret = ice_fwlog_register(hw);
|
||||
+ else
|
||||
+ ret = ice_fwlog_unregister(hw);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto enable_write_error;
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+enable_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_enable_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_enable_read,
|
||||
+ .write = ice_debugfs_enable_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -332,6 +427,9 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = fw_modules;
|
||||
|
||||
+ debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_enable_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 307e0d04f3fe..25a17cbc1d34 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -63,6 +63,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
kfree(pf->ice_debugfs_pf_fwlog_modules);
|
||||
|
||||
pf->ice_debugfs_pf_fwlog_modules = NULL;
|
||||
+
|
||||
+ status = ice_fwlog_unregister(hw);
|
||||
+ if (status)
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
+ status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,6 +202,8 @@ static int ice_aq_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
cfg->options |= ICE_FWLOG_OPTION_ARQ_ENA;
|
||||
if (cmd->cmd_flags & ICE_AQC_FW_LOG_CONF_UART_EN)
|
||||
cfg->options |= ICE_FWLOG_OPTION_UART_ENA;
|
||||
+ if (cmd->cmd_flags & ICE_AQC_FW_LOG_QUERY_REGISTERED)
|
||||
+ cfg->options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
|
||||
fw_modules = (struct ice_aqc_fw_log_cfg_resp *)buf;
|
||||
|
||||
@@ -226,6 +233,66 @@ int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg)
|
||||
return ice_aq_fwlog_get(hw, cfg);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_aq_fwlog_register - Register PF for firmware logging events (0xFF31)
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @reg: true to register and false to unregister
|
||||
+ */
|
||||
+static int ice_aq_fwlog_register(struct ice_hw *hw, bool reg)
|
||||
+{
|
||||
+ struct ice_aq_desc desc;
|
||||
+
|
||||
+ ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logs_register);
|
||||
+
|
||||
+ if (reg)
|
||||
+ desc.params.fw_log.cmd_flags = ICE_AQC_FW_LOG_AQ_REGISTER;
|
||||
+
|
||||
+ return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_register - Register the PF for firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * After this call the PF will start to receive firmware logging based on the
|
||||
+ * configuration set in ice_fwlog_set.
|
||||
+ */
|
||||
+int ice_fwlog_register(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, true);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to register for firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_fwlog_unregister - Unregister the PF from firmware logging
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ */
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ if (!ice_fwlog_supported(hw))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ status = ice_aq_fwlog_register(hw, false);
|
||||
+ if (status)
|
||||
+ ice_debug(hw, ICE_DBG_FW_LOG, "Failed to unregister from firmware logging events over ARQ\n");
|
||||
+ else
|
||||
+ hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_IS_REGISTERED;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_set_supported - Set if FW logging is supported by FW
|
||||
* @hw: pointer to the HW struct
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 8e68ee02713b..45865558425d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -53,4 +53,6 @@ int ice_fwlog_init(struct ice_hw *hw);
|
||||
void ice_fwlog_deinit(struct ice_hw *hw);
|
||||
int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
+int ice_fwlog_register(struct ice_hw *hw);
|
||||
+int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,572 @@
|
||||
From a584ea88cfdc8ac3f782be1d5d67fa92c3423290 Mon Sep 17 00:00:00 2001
|
||||
From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Date: Tue, 12 Dec 2023 21:07:14 -0800
|
||||
Subject: [PATCH 27/36] ice: add ability to read and configure FW log data
|
||||
|
||||
Once logging is enabled the user should read the data from the 'data'
|
||||
file. The data is in the form of a binary blob that can be sent to Intel
|
||||
for decoding. To read the data use a command like:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data > log_data.bin
|
||||
|
||||
If the user wants to clear the FW log data that has been stored in the
|
||||
driver then they can write any value to the 'data' file and that will clear
|
||||
the data. An example is:
|
||||
|
||||
# echo 34 > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/data
|
||||
|
||||
In addition to being able to read the data the user can configure how
|
||||
much memory is used to store FW log data. This allows the user to
|
||||
increase/decrease the amount of memory based on the users situation.
|
||||
The data is stored such that if the memory fills up then the oldest data
|
||||
will get overwritten in a circular manner. To change the amount of
|
||||
memory the user can write to the 'log_size' file like this:
|
||||
|
||||
# echo <value> > /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Where <value> is one of 128K, 256K, 512K, 1M, and 2M. The default value
|
||||
is 1M.
|
||||
|
||||
The user can see the current value of 'log_size' by reading the file:
|
||||
|
||||
# cat /sys/kernel/debug/ice/0000\:18\:00.0/fwlog/log_size
|
||||
|
||||
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 9d3535e71985beb738c4ad2b772c6f0efdce0202)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 2 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 210 ++++++++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 142 ++++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.h | 21 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 29 +++
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 1 +
|
||||
6 files changed, 405 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
index 11391be4efc2..f63b57ff2a3d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
|
||||
@@ -2338,6 +2338,7 @@ enum ice_aqc_fw_logging_mod {
|
||||
/* Set FW Logging configuration (indirect 0xFF30)
|
||||
* Register for FW Logging (indirect 0xFF31)
|
||||
* Query FW Logging (indirect 0xFF32)
|
||||
+ * FW Log Event (indirect 0xFF33)
|
||||
*/
|
||||
struct ice_aqc_fw_log {
|
||||
u8 cmd_flags;
|
||||
@@ -2666,6 +2667,7 @@ enum ice_adminq_opc {
|
||||
ice_aqc_opc_fw_logs_config = 0xFF30,
|
||||
ice_aqc_opc_fw_logs_register = 0xFF31,
|
||||
ice_aqc_opc_fw_logs_query = 0xFF32,
|
||||
+ ice_aqc_opc_fw_logs_event = 0xFF33,
|
||||
};
|
||||
|
||||
#endif /* _ICE_ADMINQ_CMD_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index 3dde99969132..c2bfba6b9ead 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -64,6 +64,17 @@ static const char * const ice_fwlog_level_string[] = {
|
||||
"verbose",
|
||||
};
|
||||
|
||||
+/* the order in this array is important. it matches the ordering of the
|
||||
+ * values in the FW so the index is the same value as in ice_fwlog_level
|
||||
+ */
|
||||
+static const char * const ice_fwlog_log_size[] = {
|
||||
+ "128K",
|
||||
+ "256K",
|
||||
+ "512K",
|
||||
+ "1M",
|
||||
+ "2M",
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_print_module_cfg - print current FW logging module configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -376,6 +387,199 @@ static const struct file_operations ice_debugfs_enable_fops = {
|
||||
.write = ice_debugfs_enable_write,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_read - read from 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_log_size_read(struct file *filp,
|
||||
+ char __user *buffer, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char buff[32] = {};
|
||||
+ int index;
|
||||
+
|
||||
+ index = hw->fwlog_ring.index;
|
||||
+ snprintf(buff, sizeof(buff), "%s\n", ice_fwlog_log_size[index]);
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_log_size_write - write into 'log_size' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_log_size_write(struct file *filp, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ char user_val[8], *cmd_buf;
|
||||
+ ssize_t ret;
|
||||
+ int index;
|
||||
+
|
||||
+ /* don't allow partial writes or invalid input */
|
||||
+ if (*ppos != 0 || count > 5)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cmd_buf = memdup_user(buf, count);
|
||||
+ if (IS_ERR(cmd_buf))
|
||||
+ return PTR_ERR(cmd_buf);
|
||||
+
|
||||
+ ret = sscanf(cmd_buf, "%s", user_val);
|
||||
+ if (ret != 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ index = sysfs_match_string(ice_fwlog_log_size, user_val);
|
||||
+ if (index < 0) {
|
||||
+ dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n",
|
||||
+ user_val);
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ } else if (hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) {
|
||||
+ dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto log_size_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* free all the buffers and the tracking info and resize */
|
||||
+ ice_fwlog_realloc_rings(hw, index);
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+log_size_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_log_size_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_log_size_read,
|
||||
+ .write = ice_debugfs_log_size_write,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_read - read from 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buffer: where to write the data for the user to read
|
||||
+ * @count: the size of the user's buffer
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t ice_debugfs_data_read(struct file *filp, char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ int data_copied = 0;
|
||||
+ bool done = false;
|
||||
+
|
||||
+ if (ice_fwlog_ring_empty(&hw->fwlog_ring))
|
||||
+ return 0;
|
||||
+
|
||||
+ while (!ice_fwlog_ring_empty(&hw->fwlog_ring) && !done) {
|
||||
+ struct ice_fwlog_data *log;
|
||||
+ u16 cur_buf_len;
|
||||
+
|
||||
+ log = &hw->fwlog_ring.rings[hw->fwlog_ring.head];
|
||||
+ cur_buf_len = log->data_size;
|
||||
+ if (cur_buf_len >= count) {
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_to_user(buffer, log->data, cur_buf_len)) {
|
||||
+ /* if there is an error then bail and return whatever
|
||||
+ * the driver has copied so far
|
||||
+ */
|
||||
+ done = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ data_copied += cur_buf_len;
|
||||
+ buffer += cur_buf_len;
|
||||
+ count -= cur_buf_len;
|
||||
+ *ppos += cur_buf_len;
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+
|
||||
+ return data_copied;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ice_debugfs_data_write - write into 'data' file
|
||||
+ * @filp: the opened file
|
||||
+ * @buf: where to find the user's data
|
||||
+ * @count: the length of the user's data
|
||||
+ * @ppos: file position offset
|
||||
+ */
|
||||
+static ssize_t
|
||||
+ice_debugfs_data_write(struct file *filp, const char __user *buf, size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_pf *pf = filp->private_data;
|
||||
+ struct device *dev = ice_pf_to_dev(pf);
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ /* don't allow partial writes */
|
||||
+ if (*ppos != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* any value is allowed to clear the buffer so no need to even look at
|
||||
+ * what the value is
|
||||
+ */
|
||||
+ if (!(hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED)) {
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+ } else {
|
||||
+ dev_info(dev, "Can't clear FW log data while FW log running\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto nr_buffs_write_error;
|
||||
+ }
|
||||
+
|
||||
+ /* if we get here, nothing went wrong; return count since we didn't
|
||||
+ * really write anything
|
||||
+ */
|
||||
+ ret = (ssize_t)count;
|
||||
+
|
||||
+nr_buffs_write_error:
|
||||
+ /* This function always consumes all of the written input, or produces
|
||||
+ * an error. Check and enforce this. Otherwise, the write operation
|
||||
+ * won't complete properly.
|
||||
+ */
|
||||
+ if (WARN_ON(ret != (ssize_t)count && ret >= 0))
|
||||
+ ret = -EIO;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_debugfs_data_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = ice_debugfs_data_read,
|
||||
+ .write = ice_debugfs_data_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_fwlog_init - setup the debugfs directory
|
||||
* @pf: the ice that is starting up
|
||||
@@ -430,6 +634,12 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
pf, &ice_debugfs_enable_fops);
|
||||
|
||||
+ debugfs_create_file("log_size", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_log_size_fops);
|
||||
+
|
||||
+ debugfs_create_file("data", 0600, pf->ice_debugfs_pf_fwlog,
|
||||
+ pf, &ice_debugfs_data_fops);
|
||||
+
|
||||
return;
|
||||
|
||||
err_create_module_files:
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 25a17cbc1d34..92b5dac481cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -1,10 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2022, Intel Corporation. */
|
||||
|
||||
+#include <linux/vmalloc.h>
|
||||
#include "ice.h"
|
||||
#include "ice_common.h"
|
||||
#include "ice_fwlog.h"
|
||||
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ u16 head, tail;
|
||||
+
|
||||
+ head = rings->head;
|
||||
+ tail = rings->tail;
|
||||
+
|
||||
+ if (head < tail && (tail - head == (rings->size - 1)))
|
||||
+ return true;
|
||||
+ else if (head > tail && (tail == (head - 1)))
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ return rings->head == rings->tail;
|
||||
+}
|
||||
+
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size)
|
||||
+{
|
||||
+ *item = (*item + 1) & (size - 1);
|
||||
+}
|
||||
+
|
||||
+static int ice_fwlog_alloc_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i, nr_bytes;
|
||||
+ u8 *mem;
|
||||
+
|
||||
+ nr_bytes = rings->size * ICE_AQ_MAX_BUF_LEN;
|
||||
+ mem = vzalloc(nr_bytes);
|
||||
+ if (!mem)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ ring->data_size = ICE_AQ_MAX_BUF_LEN;
|
||||
+ ring->data = mem;
|
||||
+ mem += ICE_AQ_MAX_BUF_LEN;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ice_fwlog_free_ring_buffs(struct ice_fwlog_ring *rings)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < rings->size; i++) {
|
||||
+ struct ice_fwlog_data *ring = &rings->rings[i];
|
||||
+
|
||||
+ /* the first ring is the base memory for the whole range so
|
||||
+ * free it
|
||||
+ */
|
||||
+ if (!i)
|
||||
+ vfree(ring->data);
|
||||
+
|
||||
+ ring->data = NULL;
|
||||
+ ring->data_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define ICE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n))
|
||||
+/**
|
||||
+ * ice_fwlog_realloc_rings - reallocate the FW log rings
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ * @index: the new index to use to allocate memory for the log data
|
||||
+ *
|
||||
+ */
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index)
|
||||
+{
|
||||
+ struct ice_fwlog_ring ring;
|
||||
+ int status, ring_size;
|
||||
+
|
||||
+ /* convert the number of bytes into a number of 4K buffers. externally
|
||||
+ * the driver presents the interface to the FW log data as a number of
|
||||
+ * bytes because that's easy for users to understand. internally the
|
||||
+ * driver uses a ring of buffers because the driver doesn't know where
|
||||
+ * the beginning and end of any line of log data is so the driver has
|
||||
+ * to overwrite data as complete blocks. when the data is returned to
|
||||
+ * the user the driver knows that the data is correct and the FW log
|
||||
+ * can be correctly parsed by the tools
|
||||
+ */
|
||||
+ ring_size = ICE_FWLOG_INDEX_TO_BYTES(index) / ICE_AQ_MAX_BUF_LEN;
|
||||
+ if (ring_size == hw->fwlog_ring.size)
|
||||
+ return;
|
||||
+
|
||||
+ /* allocate space for the new rings and buffers then release the
|
||||
+ * old rings and buffers. that way if we don't have enough
|
||||
+ * memory then we at least have what we had before
|
||||
+ */
|
||||
+ ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL);
|
||||
+ if (!ring.rings)
|
||||
+ return;
|
||||
+
|
||||
+ ring.size = ring_size;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&ring);
|
||||
+ kfree(ring.rings);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+
|
||||
+ hw->fwlog_ring.rings = ring.rings;
|
||||
+ hw->fwlog_ring.size = ring.size;
|
||||
+ hw->fwlog_ring.index = index;
|
||||
+ hw->fwlog_ring.head = 0;
|
||||
+ hw->fwlog_ring.tail = 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_fwlog_init - Initialize FW logging configuration
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -28,6 +146,25 @@ int ice_fwlog_init(struct ice_hw *hw)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
+ hw->fwlog_ring.rings = kcalloc(ICE_FWLOG_RING_SIZE_DFLT,
|
||||
+ sizeof(*hw->fwlog_ring.rings),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!hw->fwlog_ring.rings) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log rings\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ hw->fwlog_ring.size = ICE_FWLOG_RING_SIZE_DFLT;
|
||||
+ hw->fwlog_ring.index = ICE_FWLOG_RING_SIZE_INDEX_DFLT;
|
||||
+
|
||||
+ status = ice_fwlog_alloc_ring_buffs(&hw->fwlog_ring);
|
||||
+ if (status) {
|
||||
+ dev_warn(ice_hw_to_dev(hw), "Unable to allocate memory for FW log ring data buffers\n");
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
ice_debugfs_fwlog_init(hw->back);
|
||||
} else {
|
||||
dev_warn(ice_hw_to_dev(hw), "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n");
|
||||
@@ -68,6 +205,11 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (status)
|
||||
dev_warn(ice_hw_to_dev(hw), "Unable to unregister FW logging, status: %d\n",
|
||||
status);
|
||||
+
|
||||
+ if (hw->fwlog_ring.rings) {
|
||||
+ ice_fwlog_free_ring_buffs(&hw->fwlog_ring);
|
||||
+ kfree(hw->fwlog_ring.rings);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.h b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
index 45865558425d..287e71fa4b86 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.h
|
||||
@@ -47,6 +47,26 @@ struct ice_fwlog_cfg {
|
||||
u16 log_resolution;
|
||||
};
|
||||
|
||||
+struct ice_fwlog_data {
|
||||
+ u16 data_size;
|
||||
+ u8 *data;
|
||||
+};
|
||||
+
|
||||
+struct ice_fwlog_ring {
|
||||
+ struct ice_fwlog_data *rings;
|
||||
+ u16 index;
|
||||
+ u16 size;
|
||||
+ u16 head;
|
||||
+ u16 tail;
|
||||
+};
|
||||
+
|
||||
+#define ICE_FWLOG_RING_SIZE_INDEX_DFLT 3
|
||||
+#define ICE_FWLOG_RING_SIZE_DFLT 256
|
||||
+#define ICE_FWLOG_RING_SIZE_MAX 512
|
||||
+
|
||||
+bool ice_fwlog_ring_full(struct ice_fwlog_ring *rings);
|
||||
+bool ice_fwlog_ring_empty(struct ice_fwlog_ring *rings);
|
||||
+void ice_fwlog_ring_increment(u16 *item, u16 size);
|
||||
void ice_fwlog_set_supported(struct ice_hw *hw);
|
||||
bool ice_fwlog_supported(struct ice_hw *hw);
|
||||
int ice_fwlog_init(struct ice_hw *hw);
|
||||
@@ -55,4 +75,5 @@ int ice_fwlog_set(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_get(struct ice_hw *hw, struct ice_fwlog_cfg *cfg);
|
||||
int ice_fwlog_register(struct ice_hw *hw);
|
||||
int ice_fwlog_unregister(struct ice_hw *hw);
|
||||
+void ice_fwlog_realloc_rings(struct ice_hw *hw, int index);
|
||||
#endif /* _ICE_FWLOG_H_ */
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 614e10ab4159..6c6ca5353f28 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -1254,6 +1254,32 @@ ice_handle_link_event(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
return status;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_get_fwlog_data - copy the FW log data from ARQ event
|
||||
+ * @pf: PF that the FW log event is associated with
|
||||
+ * @event: event structure containing FW log data
|
||||
+ */
|
||||
+static void
|
||||
+ice_get_fwlog_data(struct ice_pf *pf, struct ice_rq_event_info *event)
|
||||
+{
|
||||
+ struct ice_fwlog_data *fwlog;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+
|
||||
+ fwlog = &hw->fwlog_ring.rings[hw->fwlog_ring.tail];
|
||||
+
|
||||
+ memset(fwlog->data, 0, PAGE_SIZE);
|
||||
+ fwlog->data_size = le16_to_cpu(event->desc.datalen);
|
||||
+
|
||||
+ memcpy(fwlog->data, event->msg_buf, fwlog->data_size);
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.tail, hw->fwlog_ring.size);
|
||||
+
|
||||
+ if (ice_fwlog_ring_full(&hw->fwlog_ring)) {
|
||||
+ /* the rings are full so bump the head to create room */
|
||||
+ ice_fwlog_ring_increment(&hw->fwlog_ring.head,
|
||||
+ hw->fwlog_ring.size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_aq_prep_for_event - Prepare to wait for an AdminQ event from firmware
|
||||
* @pf: pointer to the PF private structure
|
||||
@@ -1535,6 +1561,9 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
|
||||
|
||||
ice_vc_process_vf_msg(pf, &event, &data);
|
||||
break;
|
||||
+ case ice_aqc_opc_fw_logs_event:
|
||||
+ ice_get_fwlog_data(pf, &event);
|
||||
+ break;
|
||||
case ice_aqc_opc_lldp_set_mib_change:
|
||||
ice_dcb_process_lldp_set_mib_change(pf, &event);
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 84bb61aa7409..28e47bb78eaf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -875,6 +875,7 @@ struct ice_hw {
|
||||
|
||||
struct ice_fwlog_cfg fwlog_cfg;
|
||||
bool fwlog_supported; /* does hardware support FW logging? */
|
||||
+ struct ice_fwlog_ring fwlog_ring;
|
||||
|
||||
/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
|
||||
* register. Used for determining the ITR/INTRL granularity during
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 8a7f6d8b2105c39f236c51c558e21b787c223861 Mon Sep 17 00:00:00 2001
|
||||
From: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Date: Mon, 5 Feb 2024 14:03:57 +0100
|
||||
Subject: [PATCH 28/36] ice: Fix debugfs with devlink reload
|
||||
|
||||
During devlink reload it is needed to remove debugfs entries
|
||||
correlated with only one PF. ice_debugfs_exit() removes all
|
||||
entries created by ice driver so we can't use it.
|
||||
|
||||
Introduce ice_debugfs_pf_deinit() in order to release PF's
|
||||
debugfs entries. Move ice_debugfs_exit() call to ice_module_exit(),
|
||||
it makes more sense since ice_debugfs_init() is called in
|
||||
ice_module_init() and not in ice_probe().
|
||||
|
||||
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 500d0df5b4b2394a06b949bab05f7ed0242b9858)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_debugfs.c | 10 ++++++++++
|
||||
drivers/net/ethernet/intel/ice/ice_fwlog.c | 2 ++
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 3 +--
|
||||
4 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
|
||||
index 7966ac61154c..ed1c6cdedeff 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice.h
|
||||
@@ -895,6 +895,7 @@ static inline bool ice_is_adq_active(struct ice_pf *pf)
|
||||
}
|
||||
|
||||
void ice_debugfs_fwlog_init(struct ice_pf *pf);
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf);
|
||||
void ice_debugfs_init(void);
|
||||
void ice_debugfs_exit(void);
|
||||
void ice_pf_fwlog_update_module(struct ice_pf *pf, int log_level, int module);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index c2bfba6b9ead..ba396b22bb7d 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -647,6 +647,16 @@ void ice_debugfs_fwlog_init(struct ice_pf *pf)
|
||||
kfree(fw_modules);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_debugfs_pf_deinit - cleanup PF's debugfs
|
||||
+ * @pf: pointer to the PF struct
|
||||
+ */
|
||||
+void ice_debugfs_pf_deinit(struct ice_pf *pf)
|
||||
+{
|
||||
+ debugfs_remove_recursive(pf->ice_debugfs_pf);
|
||||
+ pf->ice_debugfs_pf = NULL;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_debugfs_init - create root directory for debugfs entries
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_fwlog.c b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
index 92b5dac481cd..4fd15387a7e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_fwlog.c
|
||||
@@ -188,6 +188,8 @@ void ice_fwlog_deinit(struct ice_hw *hw)
|
||||
if (hw->bus.func)
|
||||
return;
|
||||
|
||||
+ ice_debugfs_pf_deinit(hw->back);
|
||||
+
|
||||
/* make sure FW logging is disabled to not put the FW in a weird state
|
||||
* for the next driver load
|
||||
*/
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index 6c6ca5353f28..c882c218281a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -5325,8 +5325,6 @@ static void ice_remove(struct pci_dev *pdev)
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
- ice_debugfs_exit();
|
||||
-
|
||||
if (test_bit(ICE_FLAG_SRIOV_ENA, pf->flags)) {
|
||||
set_bit(ICE_VF_RESETS_DISABLED, pf->state);
|
||||
ice_free_vfs(pf);
|
||||
@@ -5823,6 +5821,7 @@ module_init(ice_module_init);
|
||||
static void __exit ice_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ice_driver);
|
||||
+ ice_debugfs_exit();
|
||||
destroy_workqueue(ice_wq);
|
||||
destroy_workqueue(ice_lag_wq);
|
||||
pr_info("module unloaded\n");
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,78 @@
|
||||
From 861015cbb4cf4cb258a1da9e80550fe991be7808 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Fri, 16 Feb 2024 14:06:38 -0800
|
||||
Subject: [PATCH 29/36] ice: remove vf->lan_vsi_num field
|
||||
|
||||
The lan_vsi_num field of the VF structure is no longer used for any
|
||||
purpose. Remove it.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1cf94cbfc61bac89cddeb075fbc100ebd3aea81b)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_sriov.c | 1 -
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 +---
|
||||
drivers/net/ethernet/intel/ice/ice_vf_lib.h | 5 -----
|
||||
3 files changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
index 442162be23ea..3366ac976c44 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
|
||||
@@ -239,7 +239,6 @@ static struct ice_vsi *ice_vf_vsi_setup(struct ice_vf *vf)
|
||||
}
|
||||
|
||||
vf->lan_vsi_idx = vsi->idx;
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return vsi;
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
index 03b9d7d74851..303fdf8555cf 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
@@ -298,7 +298,6 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf)
|
||||
* vf->lan_vsi_idx
|
||||
*/
|
||||
vsi->vsi_num = ice_get_hw_vsi_num(&pf->hw, vsi->idx);
|
||||
- vf->lan_vsi_num = vsi->vsi_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1299,13 +1298,12 @@ int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_vf_invalidate_vsi - invalidate vsi_idx/vsi_num to remove VSI access
|
||||
+ * ice_vf_invalidate_vsi - invalidate vsi_idx to remove VSI access
|
||||
* @vf: VF to remove access to VSI for
|
||||
*/
|
||||
void ice_vf_invalidate_vsi(struct ice_vf *vf)
|
||||
{
|
||||
vf->lan_vsi_idx = ICE_NO_VSI;
|
||||
- vf->lan_vsi_num = ICE_NO_VSI;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
index 48fea6fa0362..1de07accbc5c 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
|
||||
@@ -110,11 +110,6 @@ struct ice_vf {
|
||||
u8 spoofchk:1;
|
||||
u8 link_forced:1;
|
||||
u8 link_up:1; /* only valid if VF link is forced */
|
||||
- /* VSI indices - actual VSI pointers are maintained in the PF structure
|
||||
- * When assigned, these will be non-zero, because VSI 0 is always
|
||||
- * the main LAN VSI for the PF.
|
||||
- */
|
||||
- u16 lan_vsi_num; /* ID as used by firmware */
|
||||
unsigned int min_tx_rate; /* Minimum Tx bandwidth limit in Mbps */
|
||||
unsigned int max_tx_rate; /* Maximum Tx bandwidth limit in Mbps */
|
||||
DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,150 @@
|
||||
From 6b7fae8669a04943af9f83ef89d39a922ed179fd Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:54 -0800
|
||||
Subject: [PATCH 30/36] ice: rename ice_write_* functions to ice_pack_ctx_*
|
||||
|
||||
In ice_common.c there are 4 functions used for converting the unpacked
|
||||
software Tx and Rx context structure data into the packed format used by
|
||||
hardware. These functions have extremely generic names:
|
||||
|
||||
* ice_write_byte
|
||||
* ice_write_word
|
||||
* ice_write_dword
|
||||
* ice_write_qword
|
||||
|
||||
When I saw these function names my first thought was "write what? to
|
||||
where?". Understanding what these functions do requires looking at the
|
||||
implementation details. The functions take bits from an unpacked structure
|
||||
and copy them into the packed layout used by hardware.
|
||||
|
||||
As part of live migration, we will want functions which perform the inverse
|
||||
operation of reading bits from the packed layout and copying them into the
|
||||
unpacked format. Naming these as "ice_read_byte", etc would be very
|
||||
confusing since they appear to write data.
|
||||
|
||||
In preparation for adding this new inverse operation, rename the existing
|
||||
functions to use the prefix "ice_pack_ctx_". This makes it clear that they
|
||||
perform the bit packing while copying from the unpacked software context
|
||||
structure to the packed hardware context.
|
||||
|
||||
The inverse operations can then neatly be named ice_unpack_ctx_*, clearly
|
||||
indicating they perform the bit unpacking while copying from the packed
|
||||
hardware context to the unpacked software context structure.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 1260b45dbe2dbc415f3bc1e841c6c098083bcfb8)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 56 ++++++++++-----------
|
||||
1 file changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 6dcba0577633..17f60a98c8ed 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4267,13 +4267,13 @@ ice_aq_add_rdma_qsets(struct ice_hw *hw, u8 num_qset_grps,
|
||||
/* End of FW Admin Queue command wrappers */
|
||||
|
||||
/**
|
||||
- * ice_write_byte - write a byte to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_byte - write a byte to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u8 src_byte, dest_byte, mask;
|
||||
u8 *from, *dest;
|
||||
@@ -4306,13 +4306,13 @@ ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_word - write a word to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_word - write a word to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u16 src_word, mask;
|
||||
__le16 dest_word;
|
||||
@@ -4349,13 +4349,13 @@ ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_dword - write a dword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_dword - write a dword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u32 src_dword, mask;
|
||||
__le32 dest_dword;
|
||||
@@ -4400,13 +4400,13 @@ ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_write_qword - write a qword to a packed context structure
|
||||
- * @src_ctx: the context structure to read from
|
||||
- * @dest_ctx: the context to be written to
|
||||
- * @ce_info: a description of the struct to be filled
|
||||
+ * ice_pack_ctx_qword - write a qword to a packed context structure
|
||||
+ * @src_ctx: unpacked source context structure
|
||||
+ * @dest_ctx: packed destination context data
|
||||
+ * @ce_info: context element description
|
||||
*/
|
||||
-static void
|
||||
-ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
|
||||
+static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
u64 src_qword, mask;
|
||||
__le64 dest_qword;
|
||||
@@ -4475,16 +4475,16 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
}
|
||||
switch (ce_info[f].size_of) {
|
||||
case sizeof(u8):
|
||||
- ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_byte(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u16):
|
||||
- ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_word(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u32):
|
||||
- ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_dword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
case sizeof(u64):
|
||||
- ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
+ ice_pack_ctx_qword(src_ctx, dest_ctx, &ce_info[f]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 619e0e61b39cf051137613459d36c4fe8f435e57 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:55 -0800
|
||||
Subject: [PATCH 31/36] ice: use GENMASK instead of BIT(n) - 1 in pack
|
||||
functions
|
||||
|
||||
The functions used to pack the Tx and Rx context into the hardware format
|
||||
rely on using BIT() and then subtracting 1 to get a bitmask. These
|
||||
functions even have a comment about how x86 machines can't use this method
|
||||
for certain widths because the SHL instructions will not work properly.
|
||||
|
||||
The Linux kernel already provides the GENMASK macro for generating a
|
||||
suitable bitmask. Further, GENMASK is capable of generating the mask
|
||||
including the shift_width. Since width is the total field width, take care
|
||||
to subtract one to get the final bit position.
|
||||
|
||||
Since we now include the shifted bits as part of the mask, shift the source
|
||||
value first before applying the mask.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit a45d1bf516c097bb7ae4983d3128ebf139be952c)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 44 ++++-----------------
|
||||
1 file changed, 8 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 17f60a98c8ed..55a2e264dd69 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -4284,14 +4284,11 @@ static void ice_pack_ctx_byte(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = (u8)(BIT(ce_info->width) - 1);
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
src_byte = *from;
|
||||
- src_byte &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_byte <<= shift_width;
|
||||
+ src_byte &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4324,17 +4321,14 @@ static void ice_pack_ctx_word(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_word = *(u16 *)from;
|
||||
- src_word &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_word <<= shift_width;
|
||||
+ src_word &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4367,25 +4361,14 @@ static void ice_pack_ctx_dword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 32 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 5 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 32)
|
||||
- mask = BIT(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u32)~0;
|
||||
+ mask = GENMASK(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_dword = *(u32 *)from;
|
||||
- src_dword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_dword <<= shift_width;
|
||||
+ src_dword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
@@ -4418,25 +4401,14 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
|
||||
/* prepare the bits and mask */
|
||||
shift_width = ce_info->lsb % 8;
|
||||
-
|
||||
- /* if the field width is exactly 64 on an x86 machine, then the shift
|
||||
- * operation will not work because the SHL instructions count is masked
|
||||
- * to 6 bits so the shift will do nothing
|
||||
- */
|
||||
- if (ce_info->width < 64)
|
||||
- mask = BIT_ULL(ce_info->width) - 1;
|
||||
- else
|
||||
- mask = (u64)~0;
|
||||
+ mask = GENMASK_ULL(ce_info->width - 1 + shift_width, shift_width);
|
||||
|
||||
/* don't swizzle the bits until after the mask because the mask bits
|
||||
* will be in a different bit position on big endian machines
|
||||
*/
|
||||
src_qword = *(u64 *)from;
|
||||
- src_qword &= mask;
|
||||
-
|
||||
- /* shift to correct alignment */
|
||||
- mask <<= shift_width;
|
||||
src_qword <<= shift_width;
|
||||
+ src_qword &= mask;
|
||||
|
||||
/* get the current bits from the target bit string */
|
||||
dest = dest_ctx + (ce_info->lsb / 8);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 6502dd63a7bd436c72d2ee8b328985b93fa7e2a5 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Mon, 26 Feb 2024 16:14:56 -0800
|
||||
Subject: [PATCH 32/36] ice: cleanup line splitting for context set functions
|
||||
|
||||
The indentation for ice_set_ctx and ice_write_rxq_ctx breaks the function
|
||||
name after the return type. This style of breaking is used a lot throughout
|
||||
the ice driver, even in cases where its not actually helpful for
|
||||
readability. We no longer prefer this style of line splitting in the
|
||||
driver, and new code is avoiding it.
|
||||
|
||||
Normally, I would leave this alone unless the actual function contents or
|
||||
description needed updating. However, a future change is going to add
|
||||
inverse functions for converting packed context to unpacked context
|
||||
structures. To keep this code uniform with the existing set functions, fix
|
||||
up the style to the modern format of keeping the type on the same line.
|
||||
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit 979c2c049fbea107ce9f8d31f3ba9dba83ddb0a2)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 12 +++++-------
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 10 ++++------
|
||||
2 files changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 55a2e264dd69..59ede77a1473 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -1329,9 +1329,8 @@ static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
|
||||
* it to HW register space and enables the hardware to prefetch descriptors
|
||||
* instead of only fetching them on demand
|
||||
*/
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index)
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index)
|
||||
{
|
||||
u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
|
||||
|
||||
@@ -4427,11 +4426,10 @@ static void ice_pack_ctx_qword(u8 *src_ctx, u8 *dest_ctx,
|
||||
* @hw: pointer to the hardware structure
|
||||
* @src_ctx: pointer to a generic non-packed context structure
|
||||
* @dest_ctx: pointer to memory for the packed structure
|
||||
- * @ce_info: a description of the structure to be transformed
|
||||
+ * @ce_info: List of Rx context elements
|
||||
*/
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info)
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info)
|
||||
{
|
||||
int f;
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index d47e5400351f..1c3c29d30815 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -52,9 +52,8 @@ int ice_get_caps(struct ice_hw *hw);
|
||||
|
||||
void ice_set_safe_mode_caps(struct ice_hw *hw);
|
||||
|
||||
-int
|
||||
-ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
- u32 rxq_index);
|
||||
+int ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
|
||||
+ u32 rxq_index);
|
||||
|
||||
int
|
||||
ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params);
|
||||
@@ -71,9 +70,8 @@ bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);
|
||||
int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);
|
||||
void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);
|
||||
extern const struct ice_ctx_ele ice_tlan_ctx_info[];
|
||||
-int
|
||||
-ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
- const struct ice_ctx_ele *ce_info);
|
||||
+int ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
|
||||
+ const struct ice_ctx_ele *ce_info);
|
||||
|
||||
extern struct mutex ice_global_cfg_lock_sw;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,161 @@
|
||||
From 675a8843a0de1411666389eeabeea452161f8cc5 Mon Sep 17 00:00:00 2001
|
||||
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Date: Fri, 23 Feb 2024 17:06:27 +0100
|
||||
Subject: [PATCH 33/36] ice: do not disable Tx queues twice in ice_down()
|
||||
|
||||
ice_down() clears QINT_TQCTL_CAUSE_ENA_M bit twice, which is not
|
||||
necessary. First clearing happens in ice_vsi_dis_irq() and second in
|
||||
ice_vsi_stop_tx_ring() - remove the first one.
|
||||
|
||||
While at it, make ice_vsi_dis_irq() static as ice_down() is the only
|
||||
current caller of it.
|
||||
|
||||
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
(cherry picked from commit d5926e01e3739542bb047b77f850d7f641eaa7bc)
|
||||
[Adjust ice_lib.c with the context change.]
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_lib.c | 55 -----------------------
|
||||
drivers/net/ethernet/intel/ice/ice_lib.h | 2 -
|
||||
drivers/net/ethernet/intel/ice/ice_main.c | 44 ++++++++++++++++++
|
||||
3 files changed, 44 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 106ef843f4b5..f23cb9c8e3dd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -2877,61 +2877,6 @@ void ice_dis_vsi(struct ice_vsi *vsi, bool locked)
|
||||
}
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
- * @vsi: the VSI being un-configured
|
||||
- */
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
-{
|
||||
- struct ice_pf *pf = vsi->back;
|
||||
- struct ice_hw *hw = &pf->hw;
|
||||
- u32 val;
|
||||
- int i;
|
||||
-
|
||||
- /* disable interrupt causation from each queue */
|
||||
- if (vsi->tx_rings) {
|
||||
- ice_for_each_txq(vsi, i) {
|
||||
- if (vsi->tx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->tx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_TQCTL(reg));
|
||||
- val &= ~QINT_TQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_TQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (vsi->rx_rings) {
|
||||
- ice_for_each_rxq(vsi, i) {
|
||||
- if (vsi->rx_rings[i]) {
|
||||
- u16 reg;
|
||||
-
|
||||
- reg = vsi->rx_rings[i]->reg_idx;
|
||||
- val = rd32(hw, QINT_RQCTL(reg));
|
||||
- val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
- wr32(hw, QINT_RQCTL(reg), val);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* disable each interrupt */
|
||||
- ice_for_each_q_vector(vsi, i) {
|
||||
- if (!vsi->q_vectors[i])
|
||||
- continue;
|
||||
- wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
- }
|
||||
-
|
||||
- ice_flush(hw);
|
||||
-
|
||||
- /* don't call synchronize_irq() for VF's from the host */
|
||||
- if (vsi->type == ICE_VSI_VF)
|
||||
- return;
|
||||
-
|
||||
- ice_for_each_q_vector(vsi, i)
|
||||
- synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_vsi_release - Delete a VSI and free its resources
|
||||
* @vsi: the VSI being removed
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
index f24f5d1e6f9c..dbd0f3409323 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
@@ -110,8 +110,6 @@ void
|
||||
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio,
|
||||
bool ena_ts);
|
||||
|
||||
-void ice_vsi_dis_irq(struct ice_vsi *vsi);
|
||||
-
|
||||
void ice_vsi_free_irq(struct ice_vsi *vsi);
|
||||
|
||||
void ice_vsi_free_rx_rings(struct ice_vsi *vsi);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
index c882c218281a..685635a22616 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
||||
@@ -7023,6 +7023,50 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_vsi_dis_irq - Mask off queue interrupt generation on the VSI
|
||||
+ * @vsi: the VSI being un-configured
|
||||
+ */
|
||||
+static void ice_vsi_dis_irq(struct ice_vsi *vsi)
|
||||
+{
|
||||
+ struct ice_pf *pf = vsi->back;
|
||||
+ struct ice_hw *hw = &pf->hw;
|
||||
+ u32 val;
|
||||
+ int i;
|
||||
+
|
||||
+ /* disable interrupt causation from each Rx queue; Tx queues are
|
||||
+ * handled in ice_vsi_stop_tx_ring()
|
||||
+ */
|
||||
+ if (vsi->rx_rings) {
|
||||
+ ice_for_each_rxq(vsi, i) {
|
||||
+ if (vsi->rx_rings[i]) {
|
||||
+ u16 reg;
|
||||
+
|
||||
+ reg = vsi->rx_rings[i]->reg_idx;
|
||||
+ val = rd32(hw, QINT_RQCTL(reg));
|
||||
+ val &= ~QINT_RQCTL_CAUSE_ENA_M;
|
||||
+ wr32(hw, QINT_RQCTL(reg), val);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* disable each interrupt */
|
||||
+ ice_for_each_q_vector(vsi, i) {
|
||||
+ if (!vsi->q_vectors[i])
|
||||
+ continue;
|
||||
+ wr32(hw, GLINT_DYN_CTL(vsi->q_vectors[i]->reg_idx), 0);
|
||||
+ }
|
||||
+
|
||||
+ ice_flush(hw);
|
||||
+
|
||||
+ /* don't call synchronize_irq() for VF's from the host */
|
||||
+ if (vsi->type == ICE_VSI_VF)
|
||||
+ return;
|
||||
+
|
||||
+ ice_for_each_q_vector(vsi, i)
|
||||
+ synchronize_irq(vsi->q_vectors[i]->irq.virq);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_down - Shutdown the connection
|
||||
* @vsi: The VSI being stopped
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,274 @@
|
||||
From e53280c20bbe58015a91178268244d5e831276f4 Mon Sep 17 00:00:00 2001
|
||||
From: Milena Olech <milena.olech@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:54 -0700
|
||||
Subject: [PATCH 34/36] ice: Fix improper extts handling
|
||||
|
||||
Extts events are disabled and enabled by the application ts2phc.
|
||||
However, in case where the driver is removed when the application is
|
||||
running, a specific extts event remains enabled and can cause a kernel
|
||||
crash.
|
||||
As a side effect, when the driver is reloaded and application is started
|
||||
again, remaining extts event for the channel from a previous run will
|
||||
keep firing and the message "extts on unexpected channel" might be
|
||||
printed to the user.
|
||||
|
||||
To avoid that, extts events shall be disabled when PTP is released.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Milena Olech <milena.olech@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-2-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 00d3b4f54582d4e4a02cda5886bb336eeab268cc)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 105 ++++++++++++++++++-----
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.h | 8 ++
|
||||
2 files changed, 91 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 48ec59fc5d87..6e06c5d596b9 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1603,27 +1603,24 @@ 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.
|
||||
*/
|
||||
-static int
|
||||
-ice_ptp_cfg_extts(struct ice_pf *pf, bool ena, unsigned int chan, u32 gpio_pin,
|
||||
- unsigned int extts_flags)
|
||||
+static void 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;
|
||||
-
|
||||
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;
|
||||
@@ -1632,9 +1629,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.
|
||||
@@ -1656,9 +1653,47 @@ 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);
|
||||
|
||||
- return 0;
|
||||
+ if (store)
|
||||
+ memcpy(&pf->ptp.extts_channels[chan], config, sizeof(*config));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * 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);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1815,7 +1850,6 @@ 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;
|
||||
@@ -1826,6 +1860,9 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
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)
|
||||
@@ -1853,7 +1890,11 @@ ice_ptp_gpio_enable_e810(struct ptp_clock_info *info,
|
||||
|
||||
err = ice_ptp_cfg_clkout(pf, chan, &clk_cfg, true);
|
||||
break;
|
||||
+ }
|
||||
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)
|
||||
@@ -1869,9 +1910,13 @@ 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;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, chan, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -1889,21 +1934,31 @@ 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.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;
|
||||
+ }
|
||||
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;
|
||||
+
|
||||
+ ice_ptp_cfg_extts(pf, rq->extts.index, &extts_cfg, true);
|
||||
+ return 0;
|
||||
+ }
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -2735,6 +2790,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;
|
||||
}
|
||||
|
||||
@@ -3286,6 +3345,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);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
index 352405a2daf2..c6469a5a7afb 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.h
|
||||
@@ -33,6 +33,12 @@ struct ice_perout_channel {
|
||||
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.
|
||||
@@ -226,6 +232,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
|
||||
@@ -249,6 +256,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;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 6c24a32820031f9713d0c0cf7ac6f4ead6b58052 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 2 Jul 2024 10:14:55 -0700
|
||||
Subject: [PATCH 35/36] ice: Don't process extts if PTP is disabled
|
||||
|
||||
The ice_ptp_extts_event() function can race with ice_ptp_release() and
|
||||
result in a NULL pointer dereference which leads to a kernel panic.
|
||||
|
||||
Panic occurs because the ice_ptp_extts_event() function calls
|
||||
ptp_clock_event() with a NULL pointer. The ice driver has already
|
||||
released the PTP clock by the time the interrupt for the next external
|
||||
timestamp event occurs.
|
||||
|
||||
To fix this, modify the ice_ptp_extts_event() function to check the
|
||||
PTP state and bail early if PTP is not ready.
|
||||
|
||||
Fixes: 172db5f91d5f ("ice: add support for auxiliary input/output pins")
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
|
||||
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
|
||||
Link: https://patch.msgid.link/20240702171459.2606611-3-anthony.l.nguyen@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 996422e3230e41468f652d754fefd1bdbcd4604e)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index 6e06c5d596b9..ceb4ba19c511 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -1578,6 +1578,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
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,628 @@
|
||||
From 1ce01cb7cdb0bf4c18a546a62f224c8032d75ebd Mon Sep 17 00:00:00 2001
|
||||
From: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:51 -0700
|
||||
Subject: [PATCH 36/36] ice: Introduce ice_ptp_hw struct
|
||||
|
||||
Create new ice_ptp_hw struct and use it for all HW and PTP-related
|
||||
fields from struct ice_hw.
|
||||
Replace definitions with struct fields, which values are set accordingly
|
||||
to a specific device.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-1-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit d551d075b043821880b8afc0010ef70d050716d0)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_common.c | 24 ++++
|
||||
drivers/net/ethernet/intel/ice/ice_common.h | 1 +
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 22 ++--
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 134 ++++++++++++--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 4 +-
|
||||
drivers/net/ethernet/intel/ice/ice_type.h | 17 ++-
|
||||
6 files changed, 126 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
index 59ede77a1473..147004e0170b 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
|
||||
@@ -209,6 +209,30 @@ bool ice_is_e810t(struct ice_hw *hw)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_is_e822 - Check if a device is E822 family device
|
||||
+ * @hw: pointer to the hardware structure
|
||||
+ *
|
||||
+ * Return: true if the device is E822 based, false if not.
|
||||
+ */
|
||||
+bool ice_is_e822(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->device_id) {
|
||||
+ case ICE_DEV_ID_E822C_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822C_QSFP:
|
||||
+ case ICE_DEV_ID_E822C_SFP:
|
||||
+ case ICE_DEV_ID_E822C_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822C_SGMII:
|
||||
+ case ICE_DEV_ID_E822L_BACKPLANE:
|
||||
+ case ICE_DEV_ID_E822L_SFP:
|
||||
+ case ICE_DEV_ID_E822L_10G_BASE_T:
|
||||
+ case ICE_DEV_ID_E822L_SGMII:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ice_is_e823
|
||||
* @hw: pointer to the hardware structure
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
index 1c3c29d30815..9d38777310e5 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
|
||||
@@ -245,6 +245,7 @@ void
|
||||
ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat);
|
||||
bool ice_is_e810t(struct ice_hw *hw);
|
||||
+bool ice_is_e822(struct ice_hw *hw);
|
||||
bool ice_is_e823(struct ice_hw *hw);
|
||||
int
|
||||
ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index ceb4ba19c511..bb1572a353d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -812,7 +812,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
|
||||
}
|
||||
mutex_unlock(&pf->ptp.ports_owner.lock);
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -1026,7 +1026,7 @@ ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
|
||||
static int
|
||||
ice_ptp_init_tx_e82x(struct ice_pf *pf, struct ice_ptp_tx *tx, u8 port)
|
||||
{
|
||||
- tx->block = port / ICE_PORTS_PER_QUAD;
|
||||
+ tx->block = ICE_GET_QUAD_NUM(port);
|
||||
tx->offset = (port % ICE_PORTS_PER_QUAD) * INDEX_PER_PORT_E82X;
|
||||
tx->len = INDEX_PER_PORT_E82X;
|
||||
tx->has_ready_bitmap = 1;
|
||||
@@ -1248,8 +1248,8 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
*/
|
||||
static int ice_ptp_check_tx_fifo(struct ice_ptp_port *port)
|
||||
{
|
||||
- int quad = port->port_num / ICE_PORTS_PER_QUAD;
|
||||
int offs = port->port_num % ICE_PORTS_PER_QUAD;
|
||||
+ int quad = ICE_GET_QUAD_NUM(port->port_num);
|
||||
struct ice_pf *pf;
|
||||
struct ice_hw *hw;
|
||||
u32 val, phy_sts;
|
||||
@@ -1448,7 +1448,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||
if (pf->ptp.state != ICE_PTP_READY)
|
||||
return;
|
||||
|
||||
- if (WARN_ON_ONCE(port >= ICE_NUM_EXTERNAL_PORTS))
|
||||
+ if (WARN_ON_ONCE(port >= hw->ptp.num_lports))
|
||||
return;
|
||||
|
||||
ptp_port = &pf->ptp.port;
|
||||
@@ -1458,7 +1458,7 @@ 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;
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
/* Do not reconfigure E810 PHY */
|
||||
return;
|
||||
@@ -1487,7 +1487,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
|
||||
|
||||
ice_ptp_reset_ts_memory(hw);
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++) {
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) {
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG,
|
||||
&val);
|
||||
if (err)
|
||||
@@ -2038,7 +2038,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)
|
||||
ice_ptp_enable_all_clkout(pf);
|
||||
|
||||
/* Recalibrate and re-enable timestamp blocks for E822/E823 */
|
||||
- if (hw->phy_model == ICE_PHY_E82X)
|
||||
+ if (hw->ptp.phy_model == ICE_PHY_E82X)
|
||||
ice_ptp_restart_all_phy(pf);
|
||||
exit:
|
||||
if (err) {
|
||||
@@ -2652,7 +2652,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
|
||||
if (!ice_pf_src_tmr_owned(pf))
|
||||
return;
|
||||
|
||||
- for (i = 0; i < ICE_MAX_QUAD; i++) {
|
||||
+ for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) {
|
||||
u64 tstamp_ready;
|
||||
int err;
|
||||
|
||||
@@ -3152,7 +3152,7 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
|
||||
|
||||
mutex_init(&ptp_port->ps_lock);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3245,7 +3245,7 @@ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf)
|
||||
*/
|
||||
static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
|
||||
{
|
||||
- switch (pf->hw.phy_model) {
|
||||
+ switch (pf->hw.ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
/* E822 based PHY has the clock owner process the interrupt
|
||||
* for all ports.
|
||||
@@ -3281,7 +3281,7 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||
|
||||
ptp->state = ICE_PTP_INITIALIZING;
|
||||
|
||||
- ice_ptp_init_phy_model(hw);
|
||||
+ ice_ptp_init_hw(hw);
|
||||
|
||||
ice_ptp_init_tx_interrupt_mode(pf);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
index 7337e7e710ed..313a72dad813 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
|
||||
@@ -285,18 +285,21 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
|
||||
|
||||
/**
|
||||
* ice_fill_phy_msg_e82x - Fill message data for a PHY register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @port: the port to access
|
||||
* @offset: the register offset
|
||||
*/
|
||||
-static void
|
||||
-ice_fill_phy_msg_e82x(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
|
||||
+static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 port,
|
||||
+ u16 offset)
|
||||
{
|
||||
int phy_port, phy, quadtype;
|
||||
|
||||
- phy_port = port % ICE_PORTS_PER_PHY_E82X;
|
||||
- phy = port / ICE_PORTS_PER_PHY_E82X;
|
||||
- quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E82X;
|
||||
+ phy_port = port % hw->ptp.ports_per_phy;
|
||||
+ phy = port / hw->ptp.ports_per_phy;
|
||||
+ quadtype = ICE_GET_QUAD_NUM(port) %
|
||||
+ ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
||||
|
||||
if (quadtype == 0) {
|
||||
msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
|
||||
@@ -427,7 +430,7 @@ ice_read_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_rd;
|
||||
|
||||
err = ice_sbq_rw_reg(hw, &msg);
|
||||
@@ -504,7 +507,7 @@ ice_write_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- ice_fill_phy_msg_e82x(&msg, port, offset);
|
||||
+ ice_fill_phy_msg_e82x(hw, &msg, port, offset);
|
||||
msg.opcode = ice_sbq_msg_wr;
|
||||
msg.data = val;
|
||||
|
||||
@@ -614,24 +617,30 @@ ice_write_64b_phy_reg_e82x(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
|
||||
|
||||
/**
|
||||
* ice_fill_quad_msg_e82x - Fill message data for quad register access
|
||||
+ * @hw: pointer to the HW struct
|
||||
* @msg: the PHY message buffer to fill in
|
||||
* @quad: the quad to access
|
||||
* @offset: the register offset
|
||||
*
|
||||
* Fill a message buffer for accessing a register in a quad shared between
|
||||
* multiple PHYs.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * * %0 - OK
|
||||
+ * * %-EINVAL - invalid quad number
|
||||
*/
|
||||
-static int
|
||||
-ice_fill_quad_msg_e82x(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
|
||||
+static int ice_fill_quad_msg_e82x(struct ice_hw *hw,
|
||||
+ struct ice_sbq_msg_input *msg, u8 quad,
|
||||
+ u16 offset)
|
||||
{
|
||||
u32 addr;
|
||||
|
||||
- if (quad >= ICE_MAX_QUAD)
|
||||
+ if (quad >= ICE_GET_QUAD_NUM(hw->ptp.num_lports))
|
||||
return -EINVAL;
|
||||
|
||||
msg->dest_dev = rmn_0;
|
||||
|
||||
- if ((quad % ICE_QUADS_PER_PHY_E82X) == 0)
|
||||
+ if (!(quad % ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy)))
|
||||
addr = Q_0_BASE + offset;
|
||||
else
|
||||
addr = Q_1_BASE + offset;
|
||||
@@ -658,7 +667,7 @@ ice_read_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -692,7 +701,7 @@ ice_write_quad_reg_e82x(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
|
||||
struct ice_sbq_msg_input msg = {0};
|
||||
int err;
|
||||
|
||||
- err = ice_fill_quad_msg_e82x(&msg, quad, offset);
|
||||
+ err = ice_fill_quad_msg_e82x(hw, &msg, quad, offset);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -813,7 +822,7 @@ static void ice_ptp_reset_ts_memory_e82x(struct ice_hw *hw)
|
||||
{
|
||||
unsigned int quad;
|
||||
|
||||
- for (quad = 0; quad < ICE_MAX_QUAD; quad++)
|
||||
+ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++)
|
||||
ice_ptp_reset_ts_memory_quad_e82x(hw, quad);
|
||||
}
|
||||
|
||||
@@ -1110,7 +1119,7 @@ static int ice_ptp_set_vernier_wl(struct ice_hw *hw)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_write_phy_reg_e82x(hw, port, P_REG_WL,
|
||||
@@ -1175,7 +1184,7 @@ ice_ptp_prep_phy_time_e82x(struct ice_hw *hw, u32 time)
|
||||
*/
|
||||
phy_time = (u64)time << 32;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
/* Tx case */
|
||||
err = ice_write_64b_phy_reg_e82x(hw, port,
|
||||
P_REG_TX_TIMER_INC_PRE_L,
|
||||
@@ -1278,7 +1287,7 @@ ice_ptp_prep_phy_adj_e82x(struct ice_hw *hw, s32 adj)
|
||||
else
|
||||
cycles = -(((s64)-adj) << 32);
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_prep_port_adj_e82x(hw, port, cycles);
|
||||
@@ -1304,7 +1313,7 @@ ice_ptp_prep_phy_incval_e82x(struct ice_hw *hw, u64 incval)
|
||||
int err;
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
err = ice_write_40b_phy_reg_e82x(hw, port, P_REG_TIMETUS_L,
|
||||
incval);
|
||||
if (err)
|
||||
@@ -1460,7 +1469,7 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port,
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
enum ice_ptp_tmr_cmd cmd;
|
||||
int err;
|
||||
|
||||
@@ -1490,7 +1499,7 @@ ice_ptp_port_cmd_e82x(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
- for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
|
||||
+ for (port = 0; port < hw->ptp.num_lports; port++) {
|
||||
int err;
|
||||
|
||||
err = ice_ptp_write_port_cmd_e82x(hw, port, cmd);
|
||||
@@ -1603,7 +1612,7 @@ static void ice_phy_cfg_lane_e82x(struct ice_hw *hw, u8 port)
|
||||
return;
|
||||
}
|
||||
|
||||
- quad = port / ICE_PORTS_PER_QUAD;
|
||||
+ quad = ICE_GET_QUAD_NUM(port);
|
||||
|
||||
err = ice_read_quad_reg_e82x(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
|
||||
if (err) {
|
||||
@@ -2632,6 +2641,17 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e82x - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e82x(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 8;
|
||||
+}
|
||||
+
|
||||
/* E810 functions
|
||||
*
|
||||
* The following functions operate on the E810 series devices which use
|
||||
@@ -2859,17 +2879,21 @@ static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
|
||||
+ * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
* @hw: pointer to HW struct
|
||||
*
|
||||
- * Enable the timesync PTP functionality for the external PHY connected to
|
||||
- * this function.
|
||||
+ * Perform E810-specific PTP hardware clock initialization steps.
|
||||
+ *
|
||||
+ * Return: 0 on success, other error codes when failed to initialize TimeSync
|
||||
*/
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
+static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
{
|
||||
u8 tmr_idx;
|
||||
int err;
|
||||
|
||||
+ /* Ensure synchronization delay is zero */
|
||||
+ wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
+
|
||||
tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
|
||||
err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
|
||||
GLTSYN_ENA_TSYN_ENA_M);
|
||||
@@ -2880,21 +2904,6 @@ int ice_ptp_init_phy_e810(struct ice_hw *hw)
|
||||
return err;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
|
||||
- * @hw: pointer to HW struct
|
||||
- *
|
||||
- * Perform E810-specific PTP hardware clock initialization steps.
|
||||
- */
|
||||
-static int ice_ptp_init_phc_e810(struct ice_hw *hw)
|
||||
-{
|
||||
- /* Ensure synchronization delay is zero */
|
||||
- wr32(hw, GLTSYN_SYNC_DLAY, 0);
|
||||
-
|
||||
- /* Initialize the PHY */
|
||||
- return ice_ptp_init_phy_e810(hw);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
|
||||
* @hw: Board private structure
|
||||
@@ -3238,6 +3247,17 @@ int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data)
|
||||
return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ice_ptp_init_phy_e810 - initialize PHY parameters
|
||||
+ * @ptp: pointer to the PTP HW struct
|
||||
+ */
|
||||
+static void ice_ptp_init_phy_e810(struct ice_ptp_hw *ptp)
|
||||
+{
|
||||
+ ptp->phy_model = ICE_PHY_E810;
|
||||
+ ptp->num_lports = 8;
|
||||
+ ptp->ports_per_phy = 4;
|
||||
+}
|
||||
+
|
||||
/* Device agnostic functions
|
||||
*
|
||||
* The following functions implement shared behavior common to both E822 and
|
||||
@@ -3295,18 +3315,22 @@ void ice_ptp_unlock(struct ice_hw *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
- * ice_ptp_init_phy_model - Initialize hw->phy_model based on device type
|
||||
+ * ice_ptp_init_hw - Initialize hw based on device type
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
- * Determine the PHY model for the device, and initialize hw->phy_model
|
||||
+ * Determine the PHY model for the device, and initialize hw
|
||||
* for use by other functions.
|
||||
*/
|
||||
-void ice_ptp_init_phy_model(struct ice_hw *hw)
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw)
|
||||
{
|
||||
- if (ice_is_e810(hw))
|
||||
- hw->phy_model = ICE_PHY_E810;
|
||||
+ struct ice_ptp_hw *ptp = &hw->ptp;
|
||||
+
|
||||
+ if (ice_is_e822(hw) || ice_is_e823(hw))
|
||||
+ ice_ptp_init_phy_e82x(ptp);
|
||||
+ else if (ice_is_e810(hw))
|
||||
+ ice_ptp_init_phy_e810(ptp);
|
||||
else
|
||||
- hw->phy_model = ICE_PHY_E82X;
|
||||
+ ptp->phy_model = ICE_PHY_UNSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3327,7 +3351,7 @@ static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
|
||||
ice_ptp_src_cmd(hw, cmd);
|
||||
|
||||
/* Next, prepare the ports */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_port_cmd_e810(hw, cmd);
|
||||
break;
|
||||
@@ -3379,7 +3403,7 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time)
|
||||
|
||||
/* PHY timers */
|
||||
/* Fill Rx and Tx ports and send msg to PHY */
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
|
||||
break;
|
||||
@@ -3421,7 +3445,7 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_incval_e810(hw, incval);
|
||||
break;
|
||||
@@ -3487,7 +3511,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
|
||||
wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
err = ice_ptp_prep_phy_adj_e810(hw, adj);
|
||||
break;
|
||||
@@ -3517,7 +3541,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
|
||||
*/
|
||||
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3545,7 +3569,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
|
||||
*/
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_clear_phy_tstamp_e810(hw, block, idx);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3606,7 +3630,7 @@ int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx)
|
||||
*/
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E82X:
|
||||
ice_ptp_reset_ts_memory_e82x(hw);
|
||||
break;
|
||||
@@ -3632,7 +3656,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
/* Clear event err indications for auxiliary pins */
|
||||
(void)rd32(hw, GLTSYN_STAT(src_idx));
|
||||
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_ptp_init_phc_e810(hw);
|
||||
case ICE_PHY_E82X:
|
||||
@@ -3655,7 +3679,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
||||
*/
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready)
|
||||
{
|
||||
- switch (hw->phy_model) {
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
case ICE_PHY_E810:
|
||||
return ice_get_phy_tx_tstamp_ready_e810(hw, block,
|
||||
tstamp_ready);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index 7e8fd369ef7c..d788221eba57 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -211,6 +211,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
|
||||
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx);
|
||||
void ice_ptp_reset_ts_memory(struct ice_hw *hw);
|
||||
int ice_ptp_init_phc(struct ice_hw *hw);
|
||||
+void ice_ptp_init_hw(struct ice_hw *hw);
|
||||
int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready);
|
||||
|
||||
/* E822 family functions */
|
||||
@@ -265,7 +266,6 @@ int ice_phy_cfg_tx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
int ice_phy_cfg_rx_offset_e82x(struct ice_hw *hw, u8 port);
|
||||
|
||||
/* E810 family functions */
|
||||
-int ice_ptp_init_phy_e810(struct ice_hw *hw);
|
||||
int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
|
||||
int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
|
||||
int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
|
||||
@@ -280,8 +280,6 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx,
|
||||
u8 *ref_state, u8 *eec_mode, s64 *phase_offset,
|
||||
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);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
index 28e47bb78eaf..6fc4cd1030d0 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
|
||||
@@ -807,6 +807,9 @@ struct ice_mbx_data {
|
||||
u16 async_watermark_val;
|
||||
};
|
||||
|
||||
+#define ICE_PORTS_PER_QUAD 4
|
||||
+#define ICE_GET_QUAD_NUM(port) ((port) / ICE_PORTS_PER_QUAD)
|
||||
+
|
||||
/* PHY model */
|
||||
enum ice_phy_model {
|
||||
ICE_PHY_UNSUP = -1,
|
||||
@@ -814,6 +817,12 @@ enum ice_phy_model {
|
||||
ICE_PHY_E82X,
|
||||
};
|
||||
|
||||
+struct ice_ptp_hw {
|
||||
+ enum ice_phy_model phy_model;
|
||||
+ u8 num_lports;
|
||||
+ u8 ports_per_phy;
|
||||
+};
|
||||
+
|
||||
/* Port hardware description */
|
||||
struct ice_hw {
|
||||
u8 __iomem *hw_addr;
|
||||
@@ -835,7 +844,6 @@ 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 */
|
||||
|
||||
@@ -896,12 +904,7 @@ struct ice_hw {
|
||||
/* INTRL granularity in 1 us */
|
||||
u8 intrl_gran;
|
||||
|
||||
-#define ICE_MAX_QUAD 2
|
||||
-#define ICE_QUADS_PER_PHY_E82X 2
|
||||
-#define ICE_PORTS_PER_PHY_E82X 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)
|
||||
+ struct ice_ptp_hw ptp;
|
||||
|
||||
/* Active package version (currently active) */
|
||||
struct ice_pkg_ver active_pkg_ver;
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,80 @@
|
||||
From cd12b5c8239993e395436ff9a01b524103aa0641 Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Date: Tue, 28 May 2024 16:03:56 -0700
|
||||
Subject: [PATCH] ice: Introduce ice_get_base_incval() helper
|
||||
|
||||
Add a new helper for getting base clock increment value for specific HW.
|
||||
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
||||
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
|
||||
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
|
||||
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
|
||||
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-6-c082739bb6f6@intel.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit 1f374d57c39386520586539641cafc999d0f3ef5)
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
drivers/net/ethernet/intel/ice/ice_ptp.c | 9 +--------
|
||||
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
index bb1572a353d0..44b8fc8021cd 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#define E810_OUT_PROP_DELAY_NS 1
|
||||
|
||||
-#define UNKNOWN_INCVAL_E82X 0x100000000ULL
|
||||
-
|
||||
static const struct ptp_pin_desc ice_pin_desc_e810t[] = {
|
||||
/* name idx func chan */
|
||||
{ "GNSS", GNSS, PTP_PF_EXTTS, 0, { 0, } },
|
||||
@@ -1229,12 +1227,7 @@ static u64 ice_base_incval(struct ice_pf *pf)
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
u64 incval;
|
||||
|
||||
- if (ice_is_e810(hw))
|
||||
- incval = ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
- else if (ice_e82x_time_ref(hw) < NUM_ICE_TIME_REF_FREQ)
|
||||
- incval = ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
- else
|
||||
- incval = UNKNOWN_INCVAL_E82X;
|
||||
+ incval = ice_get_base_incval(hw);
|
||||
|
||||
dev_dbg(ice_pf_to_dev(pf), "PTP: using base increment value of 0x%016llx\n",
|
||||
incval);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
index d788221eba57..749a3f2d8293 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
|
||||
@@ -283,6 +283,24 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num);
|
||||
int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id,
|
||||
unsigned long *caps);
|
||||
|
||||
+/**
|
||||
+ * ice_get_base_incval - Get base clock increment value
|
||||
+ * @hw: pointer to the HW struct
|
||||
+ *
|
||||
+ * Return: base clock increment value for supported PHYs, 0 otherwise
|
||||
+ */
|
||||
+static inline u64 ice_get_base_incval(struct ice_hw *hw)
|
||||
+{
|
||||
+ switch (hw->ptp.phy_model) {
|
||||
+ case ICE_PHY_E810:
|
||||
+ return ICE_PTP_NOMINAL_INCVAL_E810;
|
||||
+ case ICE_PHY_E82X:
|
||||
+ return ice_e82x_nominal_incval(ice_e82x_time_ref(hw));
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#define PFTSYN_SEM_BYTES 4
|
||||
|
||||
#define ICE_PTP_CLOCK_INDEX_0 0x00
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 437206483113743a4ef40c2f7e14f09705049672 Mon Sep 17 00:00:00 2001
|
||||
From: Jiping Ma <jiping.ma2@windriver.com>
|
||||
Date: Mon, 2 Sep 2024 03:18:08 +0000
|
||||
Subject: [PATCH] ice:modify the ice driver version to stx.4
|
||||
|
||||
Change the ice driver min version to stx.4 because we back ported
|
||||
the upstream 36 commits to our code base to support the customer's
|
||||
requirement.
|
||||
|
||||
The ice driver version should be ice-6.6.40-stx.4.
|
||||
|
||||
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5807b310bdca..7163d25405f8 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1227,7 +1227,7 @@ uapi-asm-generic:
|
||||
|
||||
# KERNELRELEASE can change from a few different places, meaning version.h
|
||||
# needs to be updated, so this check is forced on all builds
|
||||
-ICE_STX = "-stx.3"
|
||||
+ICE_STX = "-stx.4"
|
||||
I40E_STX = "-stx.0"
|
||||
IAVF_STX = "-stx.0"
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -64,3 +64,41 @@ ice-dpll/0046-dpll-fix-dpll_xa_ref_-_del-for-multiple-registration.patch
|
||||
ice-dpll/0047-ice-modify-the-ice-driver-min-version-to-stx.2.patch
|
||||
ice-mdd/0001-ice-Add-automatic-VF-reset-on-Tx-MDD-events.patch
|
||||
ice-mdd/0002-ice-modify-the-ice-driver-min-version-to-stx.3.patch
|
||||
ice-VDF/0001-ice-Auxbus-devices-driver-for-E822-TS.patch
|
||||
ice-VDF/0002-ice-introduce-ice_pf_src_tmr_owned.patch
|
||||
ice-VDF/0003-ice-Re-enable-timestamping-correctly-after-reset.patch
|
||||
ice-VDF/0004-ice-periodically-kick-Tx-timestamp-interrupt.patch
|
||||
ice-VDF/0005-ice-PTP-Rename-macros-used-for-PHY-QUAD-port-definit.patch
|
||||
ice-VDF/0006-ice-PTP-move-quad-value-check-inside-ice_fill_phy_ms.patch
|
||||
ice-VDF/0007-ice-remove-ptp_tx-ring-parameter-flag.patch
|
||||
ice-VDF/0008-ice-unify-logic-for-programming-PFINT_TSYN_MSK.patch
|
||||
ice-VDF/0009-ice-PTP-Clean-up-timestamp-registers-correctly.patch
|
||||
ice-VDF/0010-ice-Use-PTP-auxbus-for-all-PHYs-restart-in-E822.patch
|
||||
ice-VDF/0011-ice-Rename-E822-to-E82X.patch
|
||||
ice-VDF/0012-ice-Schedule-service-task-in-IRQ-top-half.patch
|
||||
ice-VDF/0013-ice-Enable-SW-interrupt-from-FW-for-LL-TS.patch
|
||||
ice-VDF/0014-ice-PTP-add-clock-domain-number-to-auxiliary-interfa.patch
|
||||
ice-VDF/0015-ice-restore-timestamp-configuration-after-device-res.patch
|
||||
ice-VDF/0016-ice-introduce-PTP-state-machine.patch
|
||||
ice-VDF/0017-ice-pass-reset-type-to-PTP-reset-functions.patch
|
||||
ice-VDF/0018-ice-rename-verify_cached-to-has_ready_bitmap.patch
|
||||
ice-VDF/0019-ice-don-t-check-has_ready_bitmap-in-E810-functions.patch
|
||||
ice-VDF/0020-ice-rename-ice_ptp_tx_cfg_intr.patch
|
||||
ice-VDF/0021-ice-factor-out-ice_ptp_rebuild_owner.patch
|
||||
ice-VDF/0022-ice-stop-destroying-and-reinitalizing-Tx-tracker-dur.patch
|
||||
ice-VDF/0023-ice-Remove-and-readd-netdev-during-devlink-reload.patch
|
||||
ice-VDF/0024-ice-remove-FW-logging-code.patch
|
||||
ice-VDF/0025-ice-configure-FW-logging.patch
|
||||
ice-VDF/0026-ice-enable-FW-logging.patch
|
||||
ice-VDF/0027-ice-add-ability-to-read-and-configure-FW-log-data.patch
|
||||
ice-VDF/0028-ice-Fix-debugfs-with-devlink-reload.patch
|
||||
ice-VDF/0029-ice-remove-vf-lan_vsi_num-field.patch
|
||||
ice-VDF/0030-ice-rename-ice_write_-functions-to-ice_pack_ctx_.patch
|
||||
ice-VDF/0031-ice-use-GENMASK-instead-of-BIT-n-1-in-pack-functions.patch
|
||||
ice-VDF/0032-ice-cleanup-line-splitting-for-context-set-functions.patch
|
||||
ice-VDF/0033-ice-do-not-disable-Tx-queues-twice-in-ice_down.patch
|
||||
ice-VDF/0034-ice-Fix-improper-extts-handling.patch
|
||||
ice-VDF/0035-ice-Don-t-process-extts-if-PTP-is-disabled.patch
|
||||
ice-VDF/0036-ice-Introduce-ice_ptp_hw-struct.patch
|
||||
ice-VDF/0037-ice-Introduce-ice_get_base_incval-helper.patch
|
||||
ice-VDF/0038-ice-modify-the-ice-driver-version-to-stx.4.patch
|
||||
|
Loading…
x
Reference in New Issue
Block a user