Re: [Intel-wired-lan] [PATCH iwl-net] ice: ensure periodic output start time is in the future

2025-03-13 Thread Rinitha, SX
> -Original Message-
> From: Intel-wired-lan  On Behalf Of Jacob 
> Keller
> Sent: 20 February 2025 03:43
> To: Nguyen, Anthony L ; Kitszel, Przemyslaw 
> ; Kubalewski, Arkadiusz 
> ; Kolacinski, Karol 
> 
Cc: intel-wired-...@lists.osuosl.org; net...@vger.kernel.org; Keller, Jacob E 

> Subject: [Intel-wired-lan] [PATCH iwl-net] ice: ensure periodic output start 
> time is in the future
>
> From: Karol Kolacinski 
>
> On E800 series hardware, if the start time for a periodic output signal is 
> programmed into GLTSYN_TGT_H and GLTSYN_TGT_L registers, the hardware logic 
> locks up and the periodic output signal never starts. Any future attempt to 
> reprogram the clock function is futile as the hardware will not reset until a 
> power on.
>
> The ice_ptp_cfg_perout function has logic to prevent this, as it checks if 
> the requested start time is in the past. If so, a new start time is 
> calculated by rounding up.
>
> Since commit d755a7e129a5 ("ice: Cache perout/extts requests and check 
> flags"), the rounding is done to the nearest multiple of the clock period, 
> rather than to a full second. This is more accurate, since it ensures the 
> signal matches the user request precisely.
>
> Unfortunately, there is a race condition with this rounding logic. If the 
> current time is close to the multiple of the period, we could calculate a 
> target time that is extremely soon. It takes time for the software to program 
> the registers, during which time this requested start time could become a 
> start time in the past. If that happens, the periodic output signal will lock 
> up.
>
> For large enough periods, or for the logic prior to the mentioned commit, 
> this is unlikely. However, with the new logic rounding to the period and with 
> a small enough period, this becomes inevitable.
>
> For example, attempting to enable a 10MHz signal requires a period of 100 
> nanoseconds. This means in the *best* case, we have 99 nanoseconds to program 
> the clock output. This is essentially impossible, and thus such a small 
> period practically guarantees that the clock output function will lock up.
>
> To fix this, add some slop to the clock time used to check if the start time 
> is in the past. Because it is not critical that output signals start 
> immediately, but it *is* critical that we do not brick the function, 0.5 
> seconds is selected. > This does mean that any requested output will be 
> delayed by at least 0.5 seconds.
>
> This slop is applied before rounding, so that we always round up to the 
> nearest multiple of the period that is at least 0.5 seconds in the future, 
> ensuring a minimum of 0.5 seconds to program the clock output registers.
>
> Finally, to ensure that the hardware registers programming the clock output 
> complete in a timely manner, add a write flush to the end of 
> ice_ptp_write_perout. This ensures we don't risk any issue with PCIe 
> transaction batching.
>
> Strictly speaking, this fixes a race condition all the way back at the 
> initial implementation of periodic output programming, as it is theoretically 
> possible to trigger this bug even on the old logic when always rounding to a 
> full second. However, the window is narrow, and the code has been refactored 
> heavily since then, making a direct backport not apply cleanly.
>
> Fixes: d755a7e129a5 ("ice: Cache perout/extts requests and check flags")
> Signed-off-by: Karol Kolacinski 
> Signed-off-by: Jacob Keller 
> ---
> drivers/net/ethernet/intel/ice/ice_ptp.c | 6 --
> 1 file changed, 4 insertions(+), 2 deletions(-)
>

Tested-by: Rinitha S  (A Contingent worker at Intel)


[Intel-wired-lan] [PATCH iwl-next v8 00/15] ixgbe: Add basic devlink support

2025-03-13 Thread Jedrzej Jagielski
Create devlink specific directory for more convenient future feature
development.

Flashing and reloading are supported only by E610 devices.

Introduce basic FW/NVM validation since devlink reload introduces
possibility of runtime NVM update. Check FW API version, FW recovery mode
and FW rollback mode. Introduce minimal recovery probe to let user to
reload the faulty FW when recovery mode is detected.

This series is based on the series introducing initial E610 device
support:
https://lore.kernel.org/intel-wired-lan/20241205084450.4651-1-piotr.kwapulin...@intel.com/
---
v3: introduce to the series additional patch touching devlink/dev.c
v4: introduce to the series additional patch changing netdev allocation
---
Andrii Staikov (1):
  ixgbe: add support for FW rollback mode

Jedrzej Jagielski (10):
  devlink: add value check to devlink_info_version_put()
  ixgbe: add initial devlink support
  ixgbe: add handler for devlink .info_get()
  ixgbe: add .info_get extension specific for E610 devices
  ixgbe: add E610 functions getting PBA and FW ver info
  ixgbe: extend .info_get with() stored versions
  ixgbe: add device flash update via devlink
  ixgbe: add support for devlink reload
  ixgbe: add FW API version check
  ixgbe: add E610 implementation of FW recovery mode

Przemek Kitszel (1):
  ixgbe: wrap netdev_priv() usage

Slawomir Mrozowicz (3):
  ixgbe: add E610 functions for acquiring flash data
  ixgbe: read the OROM version information
  ixgbe: read the netlist version information

 Documentation/networking/devlink/index.rst|1 +
 Documentation/networking/devlink/ixgbe.rst|  110 ++
 drivers/net/ethernet/intel/Kconfig|2 +
 drivers/net/ethernet/intel/ixgbe/Makefile |3 +-
 .../ethernet/intel/ixgbe/devlink/devlink.c|  585 +++
 .../ethernet/intel/ixgbe/devlink/devlink.h|   10 +
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |   21 +
 .../net/ethernet/intel/ixgbe/ixgbe_82598.c|1 +
 .../net/ethernet/intel/ixgbe/ixgbe_82599.c|1 +
 .../net/ethernet/intel/ixgbe/ixgbe_common.c   |1 +
 .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c   |   56 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 1515 +++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h |   16 +
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  |   86 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c |   12 +-
 .../ethernet/intel/ixgbe/ixgbe_fw_update.c|  707 
 .../ethernet/intel/ixgbe/ixgbe_fw_update.h|   12 +
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c|   10 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  269 ++-
 .../net/ethernet/intel/ixgbe/ixgbe_sriov.c|   16 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h |5 +
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  161 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c |1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c |1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c  |2 +-
 net/devlink/dev.c |2 +-
 26 files changed, 3364 insertions(+), 242 deletions(-)
 create mode 100644 Documentation/networking/devlink/ixgbe.rst
 create mode 100644 drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/devlink/devlink.h
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.h


base-commit: 0a5f2afff8673e66160725b8ec8310f47c74f8b9
-- 
2.31.1



[Intel-wired-lan] [PATCH iwl-next v8 11/15] ixgbe: add device flash update via devlink

2025-03-13 Thread Jedrzej Jagielski
Use the pldmfw library to implement device flash update for
the Intel ixgbe networking device driver specifically for E610 devices.
This support uses the devlink flash update interface.

Using the pldmfw library, the provided firmware file will be scanned for
the three major components, "fw.undi" for the Option ROM, "fw.mgmt" for
the main NVM module containing the primary device firmware, and
"fw.netlist" containing the netlist module.

The flash is separated into two banks, the active bank containing the
running firmware, and the inactive bank which we use for update. Each
module is updated in a staged process. First, the inactive bank is
erased, preparing the device for update. Second, the contents of the
component are copied to the inactive portion of the flash. After all
components are updated, the driver signals the device to switch the
active bank during the next EMP reset.

With this implementation, basic flash update for the E610 hardware is
supported.

Reviewed-by: Jacob Keller 
Tested-by: Bharath R 
Co-developed-by: Slawomir Mrozowicz 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Co-developed-by: Stefan Wegrzyn 
Signed-off-by: Stefan Wegrzyn 
Signed-off-by: Jedrzej Jagielski 
---
v5: fix caps->nvm_unified_update assignment
v8: fix doc
---
 Documentation/networking/devlink/ixgbe.rst|  27 +
 drivers/net/ethernet/intel/Kconfig|   1 +
 drivers/net/ethernet/intel/ixgbe/Makefile |   2 +-
 .../ethernet/intel/ixgbe/devlink/devlink.c|   4 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 210 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h |  11 +
 .../ethernet/intel/ixgbe/ixgbe_fw_update.c| 668 ++
 .../ethernet/intel/ixgbe/ixgbe_fw_update.h|  12 +
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  64 ++
 9 files changed, 998 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.h

diff --git a/Documentation/networking/devlink/ixgbe.rst 
b/Documentation/networking/devlink/ixgbe.rst
index a41073a62776..aa4eab95b3d5 100644
--- a/Documentation/networking/devlink/ixgbe.rst
+++ b/Documentation/networking/devlink/ixgbe.rst
@@ -64,3 +64,30 @@ The ``ixgbe`` driver reports the following versions
   - running
   - 0xee16ced7
   - The first 4 bytes of the hash of the netlist module contents.
+
+Flash Update
+
+
+The ``ixgbe`` driver implements support for flash update using the
+``devlink-flash`` interface. It supports updating the device flash using a
+combined flash image that contains the ``fw.mgmt``, ``fw.undi``, and
+``fw.netlist`` components.
+
+.. list-table:: List of supported overwrite modes
+   :widths: 5 95
+
+   * - Bits
+ - Behavior
+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
+ - Do not preserve settings stored in the flash components being
+   updated. This includes overwriting the port configuration that
+   determines the number of physical functions the device will
+   initialize with.
+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS`` and 
``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
+ - Do not preserve either settings or identifiers. Overwrite everything
+   in the flash with the contents from the provided image, without
+   performing any preservation. This includes overwriting device
+   identifying fields such as the MAC address, Vital product Data (VPD) 
area,
+   and device serial number. It is expected that this combination be used 
with an
+   image customized for the specific device.
+
diff --git a/drivers/net/ethernet/intel/Kconfig 
b/drivers/net/ethernet/intel/Kconfig
index 3366738c57c8..8fecb8a4e249 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -148,6 +148,7 @@ config IXGBE
depends on PTP_1588_CLOCK_OPTIONAL
select MDIO
select NET_DEVLINK
+   select PLDMFW
select PHYLIB
help
  This driver supports Intel(R) 10GbE PCI Express family of
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile 
b/drivers/net/ethernet/intel/ixgbe/Makefile
index 11f37140c0a3..ce447540d146 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o
 ixgbe-y := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \
-   ixgbe_xsk.o ixgbe_e610.o devlink/devlink.o
+   ixgbe_xsk.o ixgbe_e610.o devlink/devlink.o ixgbe_fw_update.o
 
 ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
   ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 6b45846f0ddd..2ffe59a8881

[Intel-wired-lan] [PATCH iwl-next v8 05/15] ixgbe: add E610 functions for acquiring flash data

2025-03-13 Thread Jedrzej Jagielski
From: Slawomir Mrozowicz 

Read NVM related info from the flash.

Add several helper functions used to access the flash data,
find memory banks, calculate offsets, calculate the flash size.

Reviewed-by: Przemek Kitszel 
Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Co-developed-by: Jedrzej Jagielski 
Signed-off-by: Jedrzej Jagielski 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 509 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   4 +
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  40 +-
 4 files changed, 552 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index 683c668672d6..3654b7e32cc8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -2264,6 +2264,513 @@ int ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw)
return err;
 }
 
+/**
+ * ixgbe_discover_flash_size - Discover the available flash size
+ * @hw: pointer to the HW struct
+ *
+ * The device flash could be up to 16MB in size. However, it is possible that
+ * the actual size is smaller. Use bisection to determine the accessible size
+ * of flash memory.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_discover_flash_size(struct ixgbe_hw *hw)
+{
+   u32 min_size = 0, max_size = IXGBE_ACI_NVM_MAX_OFFSET + 1;
+   int err;
+
+   err = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
+   if (err)
+   return err;
+
+   while ((max_size - min_size) > 1) {
+   u32 offset = (max_size + min_size) / 2;
+   u32 len = 1;
+   u8 data;
+
+   err = ixgbe_read_flat_nvm(hw, offset, &len, &data, false);
+   if (err == -EIO &&
+   hw->aci.last_status == IXGBE_ACI_RC_EINVAL) {
+   err = 0;
+   max_size = offset;
+   } else if (!err) {
+   min_size = offset;
+   } else {
+   /* an unexpected error occurred */
+   goto err_read_flat_nvm;
+   }
+   }
+
+   hw->flash.flash_size = max_size;
+
+err_read_flat_nvm:
+   ixgbe_release_nvm(hw);
+
+   return err;
+}
+
+/**
+ * ixgbe_read_sr_base_address - Read the value of a Shadow RAM pointer word
+ * @hw: pointer to the HW structure
+ * @offset: the word offset of the Shadow RAM word to read
+ * @pointer: pointer value read from Shadow RAM
+ *
+ * Read the given Shadow RAM word, and convert it to a pointer value specified
+ * in bytes. This function assumes the specified offset is a valid pointer
+ * word.
+ *
+ * Each pointer word specifies whether it is stored in word size or 4KB
+ * sector size by using the highest bit. The reported pointer value will be in
+ * bytes, intended for flat NVM reads.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_read_sr_base_address(struct ixgbe_hw *hw, u16 offset,
+ u32 *pointer)
+{
+   u16 value;
+   int err;
+
+   err = ixgbe_read_ee_aci_e610(hw, offset, &value);
+   if (err)
+   return err;
+
+   /* Determine if the pointer is in 4KB or word units */
+   if (value & IXGBE_SR_NVM_PTR_4KB_UNITS)
+   *pointer = (value & ~IXGBE_SR_NVM_PTR_4KB_UNITS) * SZ_4K;
+   else
+   *pointer = value * sizeof(u16);
+
+   return 0;
+}
+
+/**
+ * ixgbe_read_sr_area_size - Read an area size from a Shadow RAM word
+ * @hw: pointer to the HW structure
+ * @offset: the word offset of the Shadow RAM to read
+ * @size: size value read from the Shadow RAM
+ *
+ * Read the given Shadow RAM word, and convert it to an area size value
+ * specified in bytes. This function assumes the specified offset is a valid
+ * area size word.
+ *
+ * Each area size word is specified in 4KB sector units. This function reports
+ * the size in bytes, intended for flat NVM reads.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_read_sr_area_size(struct ixgbe_hw *hw, u16 offset, u32 *size)
+{
+   u16 value;
+   int err;
+
+   err = ixgbe_read_ee_aci_e610(hw, offset, &value);
+   if (err)
+   return err;
+
+   /* Area sizes are always specified in 4KB units */
+   *size = value * SZ_4K;
+
+   return 0;
+}
+
+/**
+ * ixgbe_determine_active_flash_banks - Discover active bank for each module
+ * @hw: pointer to the HW struct
+ *
+ * Read the Shadow RAM control word and determine which banks are active for
+ * the NVM, OROM, and Netlist modules. Also read and calculate the associated
+ * pointer and size. These values are then cached into the ixgbe_flash_info
+ * structure for later use in order to calculate the correct offset to read

[Intel-wired-lan] [PATCH iwl-next v8 07/15] ixgbe: read the netlist version information

2025-03-13 Thread Jedrzej Jagielski
From: Slawomir Mrozowicz 

Add functions reading the netlist version info and use them
as a part of the setting NVM info procedure.

Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Signed-off-by: Jedrzej Jagielski 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 112 ++
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  33 ++
 2 files changed, 145 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index bad4bc04bb66..b34570b244d9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -2582,6 +2582,33 @@ static int ixgbe_read_nvm_module(struct ixgbe_hw *hw,
return err;
 }
 
+/**
+ * ixgbe_read_netlist_module - Read data from the netlist module area
+ * @hw: pointer to the HW structure
+ * @bank: whether to read from the active or inactive module
+ * @offset: offset into the netlist to read from
+ * @data: storage for returned word value
+ *
+ * Read a word from the specified netlist bank.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_read_netlist_module(struct ixgbe_hw *hw,
+enum ixgbe_bank_select bank,
+u32 offset, u16 *data)
+{
+   __le16 data_local;
+   int err;
+
+   err = ixgbe_read_flash_module(hw, bank, IXGBE_E610_SR_NETLIST_BANK_PTR,
+ offset * sizeof(data_local),
+ (u8 *)&data_local, sizeof(data_local));
+   if (!err)
+   *data = le16_to_cpu(data_local);
+
+   return err;
+}
+
 /**
  * ixgbe_read_orom_module - Read from the active Option ROM module
  * @hw: pointer to the HW structure
@@ -2887,6 +2914,86 @@ static int ixgbe_get_nvm_ver_info(struct ixgbe_hw *hw,
return 0;
 }
 
+/**
+ * ixgbe_get_netlist_info - Read the netlist version information
+ * @hw: pointer to the HW struct
+ * @bank: whether to read from the active or inactive flash bank
+ * @netlist: pointer to netlist version info structure
+ *
+ * Get the netlist version information from the requested bank. Reads the Link
+ * Topology section to find the Netlist ID block and extract the relevant
+ * information into the netlist version structure.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_get_netlist_info(struct ixgbe_hw *hw,
+ enum ixgbe_bank_select bank,
+ struct ixgbe_netlist_info *netlist)
+{
+   u16 module_id, length, node_count, i;
+   u16 *id_blk;
+   int err;
+
+   err = ixgbe_read_netlist_module(hw, bank, IXGBE_NETLIST_TYPE_OFFSET,
+   &module_id);
+   if (err)
+   return err;
+
+   if (module_id != IXGBE_NETLIST_LINK_TOPO_MOD_ID)
+   return -EIO;
+
+   err = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_MODULE_LEN,
+   &length);
+   if (err)
+   return err;
+
+   /* Sanity check that we have at least enough words to store the
+* netlist ID block.
+*/
+   if (length < IXGBE_NETLIST_ID_BLK_SIZE)
+   return -EIO;
+
+   err = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_NODE_COUNT,
+   &node_count);
+   if (err)
+   return err;
+
+   node_count &= IXGBE_LINK_TOPO_NODE_COUNT_M;
+
+   id_blk = kcalloc(IXGBE_NETLIST_ID_BLK_SIZE, sizeof(*id_blk), 
GFP_KERNEL);
+   if (!id_blk)
+   return -ENOMEM;
+
+   /* Read out the entire Netlist ID Block at once. */
+   err = ixgbe_read_flash_module(hw, bank, IXGBE_E610_SR_NETLIST_BANK_PTR,
+ IXGBE_NETLIST_ID_BLK_OFFSET(node_count) *
+ sizeof(*id_blk), (u8 *)id_blk,
+ IXGBE_NETLIST_ID_BLK_SIZE *
+ sizeof(*id_blk));
+   if (err)
+   goto free_id_blk;
+
+   for (i = 0; i < IXGBE_NETLIST_ID_BLK_SIZE; i++)
+   id_blk[i] = le16_to_cpu(((__le16 *)id_blk)[i]);
+
+   netlist->major = id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH] << 16 |
+id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW];
+   netlist->minor = id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH] << 16 |
+id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW];
+   netlist->type = id_blk[IXGBE_NETLIST_ID_BLK_TYPE_HIGH] << 16 |
+   id_blk[IXGBE_NETLIST_ID_BLK_TYPE_LOW];
+   netlist->rev = id_blk[IXGBE_NETLIST_ID_BLK_REV_HIGH] << 16 |
+  id_blk[IXGBE_NETLIST_ID_BLK_REV_LOW];
+   netlist->cust_ver = id_blk[IXGBE_NETLIST_ID_BLK_CUST_VER];
+   /* Read the left m

[Intel-wired-lan] [PATCH iwl-next v8 01/15] devlink: add value check to devlink_info_version_put()

2025-03-13 Thread Jedrzej Jagielski
Prevent from proceeding if there's nothing to print.

Suggested-by: Przemek Kitszel 
Reviewed-by: Jiri Pirko 
Reviewed-by: Kalesh AP 
Tested-by: Bharath R 
Signed-off-by: Jedrzej Jagielski 
---
 net/devlink/dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index d6e3db300acb..02602704bdea 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c
@@ -775,7 +775,7 @@ static int devlink_info_version_put(struct devlink_info_req 
*req, int attr,
req->version_cb(version_name, version_type,
req->version_cb_priv);
 
-   if (!req->msg)
+   if (!req->msg || !*version_value)
return 0;
 
nest = nla_nest_start_noflag(req->msg, attr);
-- 
2.31.1



[Intel-wired-lan] [PATCH iwl-next v8 02/15] ixgbe: wrap netdev_priv() usage

2025-03-13 Thread Jedrzej Jagielski
From: Przemek Kitszel 

Wrap use of netdev_priv() in order to change the allocator of the device
private structure from alloc_etherdev_mq() to the devlink in next commit.

All but one netdev_priv() calls in the whole driver are replaced, the
remaining one is called on MACVLAN (so not ixgbe) device.

Signed-off-by: Przemek Kitszel 
Tested-by: Bharath R 
Signed-off-by: Jedrzej Jagielski 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |  5 ++
 .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c   | 56 +++---
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  | 74 +--
 drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 12 +--
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c| 10 +--
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 74 +--
 .../net/ethernet/intel/ixgbe/ixgbe_sriov.c| 16 ++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c  |  2 +-
 8 files changed, 127 insertions(+), 122 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index e6a380d4929b..0efd6da874a5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -830,6 +830,11 @@ struct ixgbe_adapter {
spinlock_t vfs_lock;
 };
 
+static inline struct ixgbe_adapter *ixgbe_from_netdev(struct net_device 
*netdev)
+{
+   return netdev_priv(netdev);
+}
+
 static inline int ixgbe_determine_xdp_q_idx(int cpu)
 {
if (static_key_enabled(&ixgbe_xdp_locking_key))
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index 19d6b6fa8fb3..3dd5a16a14df 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -118,14 +118,14 @@ static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter 
*adapter, int tc_max)
 
 static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
 }
 
 static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
/* Fail command if not in CEE mode */
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
@@ -142,7 +142,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, 
u8 state)
 static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
 u8 *perm_addr)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
int i, j;
 
memset(perm_addr, 0xff, MAX_ADDR_LEN);
@@ -167,7 +167,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device 
*netdev, int tc,
 u8 prio, u8 bwg_id, u8 bw_pct,
 u8 up_map)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
if (prio != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio;
@@ -184,7 +184,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device 
*netdev, int tc,
 static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int 
bwg_id,
  u8 bw_pct)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
 }
@@ -193,7 +193,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device 
*netdev, int tc,
 u8 prio, u8 bwg_id, u8 bw_pct,
 u8 up_map)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
if (prio != DCB_ATTR_VALUE_UNDEFINED)
adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio;
@@ -210,7 +210,7 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device 
*netdev, int tc,
 static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int 
bwg_id,
  u8 bw_pct)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
 
adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
 }
@@ -219,7 +219,7 @@ static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device 
*netdev, int tc,
 u8 *prio, u8 *bwg_id, u8 *bw_pct,
 u8 *up_map)
 {
-   struct ixgbe_adapter *adapter = netdev_priv(netdev);
+   struct ixgbe_adapter *adapter = ixgbe_from_netdev(netd

[Intel-wired-lan] [PATCH iwl-next v8 03/15] ixgbe: add initial devlink support

2025-03-13 Thread Jedrzej Jagielski
Add an initial support for devlink interface to ixgbe driver.

Similarly to i40e driver the implementation doesn't enable
devlink to manage device-wide configuration. Devlink instance
is created for each physical function of PCIe device.

Create separate directory for devlink related ixgbe files
and use naming scheme similar to the one used in the ice driver.

Add a stub for Documentation, to be extended by further patches.

Change struct ixgbe_adapter allocation to be done by devlink (Przemek),
as suggested by Jiri.

Reviewed-by: Mateusz Polchlopek 
Co-developed-by: Przemek Kitszel 
Signed-off-by: Przemek Kitszel 
Tested-by: Bharath R 
Signed-off-by: Jedrzej Jagielski 
---
v2: fix error path in probe; minor tweaks
v4: alloc ixgbe_adapter by devlink
---

 Documentation/networking/devlink/index.rst|  1 +
 Documentation/networking/devlink/ixgbe.rst|  8 ++
 drivers/net/ethernet/intel/Kconfig|  1 +
 drivers/net/ethernet/intel/ixgbe/Makefile |  3 +-
 .../ethernet/intel/ixgbe/devlink/devlink.c| 77 +++
 .../ethernet/intel/ixgbe/devlink/devlink.h| 10 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  | 12 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 30 +++-
 8 files changed, 138 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/networking/devlink/ixgbe.rst
 create mode 100644 drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/devlink/devlink.h

diff --git a/Documentation/networking/devlink/index.rst 
b/Documentation/networking/devlink/index.rst
index 948c8c44e233..8319f43b5933 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -84,6 +84,7 @@ parameters, info versions, and other features it supports.
i40e
ionic
ice
+   ixgbe
mlx4
mlx5
mlxsw
diff --git a/Documentation/networking/devlink/ixgbe.rst 
b/Documentation/networking/devlink/ixgbe.rst
new file mode 100644
index ..c04ac51c6d85
--- /dev/null
+++ b/Documentation/networking/devlink/ixgbe.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+ixgbe devlink support
+=
+
+This document describes the devlink features implemented by the ``ixgbe``
+device driver.
diff --git a/drivers/net/ethernet/intel/Kconfig 
b/drivers/net/ethernet/intel/Kconfig
index 5579fb9bfd55..3366738c57c8 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -147,6 +147,7 @@ config IXGBE
depends on PCI
depends on PTP_1588_CLOCK_OPTIONAL
select MDIO
+   select NET_DEVLINK
select PHYLIB
help
  This driver supports Intel(R) 10GbE PCI Express family of
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile 
b/drivers/net/ethernet/intel/ixgbe/Makefile
index b456d102655a..11f37140c0a3 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -4,12 +4,13 @@
 # Makefile for the Intel(R) 10GbE PCI Express ethernet driver
 #
 
+subdir-ccflags-y += -I$(src)
 obj-$(CONFIG_IXGBE) += ixgbe.o
 
 ixgbe-y := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \
-   ixgbe_xsk.o ixgbe_e610.o
+   ixgbe_xsk.o ixgbe_e610.o devlink/devlink.o
 
 ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
   ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
new file mode 100644
index ..6c3452cf5d7d
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025, Intel Corporation. */
+
+#include "ixgbe.h"
+#include "devlink.h"
+
+static const struct devlink_ops ixgbe_devlink_ops = {
+};
+
+/**
+ * ixgbe_allocate_devlink - Allocate devlink instance
+ * @dev: device to allocate devlink for
+ *
+ * Allocate a devlink instance for this physical function.
+ *
+ * Return: pointer to the device adapter structure on success,
+ * ERR_PTR(-ENOMEM) when allocation failed.
+ */
+struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev)
+{
+   struct ixgbe_adapter *adapter;
+   struct devlink *devlink;
+
+   devlink = devlink_alloc(&ixgbe_devlink_ops, sizeof(*adapter), dev);
+   if (!devlink)
+   return ERR_PTR(-ENOMEM);
+
+   adapter = devlink_priv(devlink);
+   adapter->devlink = devlink;
+
+   return adapter;
+}
+
+/**
+ * ixgbe_devlink_set_switch_id - Set unique switch ID based on PCI DSN
+ * @adapter: pointer to the device adapter structure
+ * @ppid: struct with switch id information
+ */
+static void ixgbe_devlink_set_switch_id(struct ixgbe_adapter *adapter,
+   struct netd

[Intel-wired-lan] [PATCH iwl-next v8 12/15] ixgbe: add support for devlink reload

2025-03-13 Thread Jedrzej Jagielski
The E610 adapters contain an embedded chip with firmware which can be
updated using devlink flash. The firmware which runs on this chip is
referred to as the Embedded Management Processor firmware (EMP
firmware).

Activating the new firmware image currently requires that the system be
rebooted. This is not ideal as rebooting the system can cause unwanted
downtime.

The EMP firmware itself can be reloaded by issuing a special update
to the device called an Embedded Management Processor reset (EMP
reset). This reset causes the device to reset and reload the EMP
firmware.

Implement support for devlink reload with the "fw_activate" flag. This
allows user space to request the firmware be activated immediately.

Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Co-developed-by: Slawomir Mrozowicz 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Co-developed-by: Stefan Wegrzyn 
Signed-off-by: Stefan Wegrzyn 
Signed-off-by: Jedrzej Jagielski 
---
v6: fix doc
---
 Documentation/networking/devlink/ixgbe.rst|  17 +++
 .../ethernet/intel/ixgbe/devlink/devlink.c| 112 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |   4 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c |  18 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h |   1 +
 .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c  |  12 ++
 .../ethernet/intel/ixgbe/ixgbe_fw_update.c|  37 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   5 +-
 8 files changed, 199 insertions(+), 7 deletions(-)

diff --git a/Documentation/networking/devlink/ixgbe.rst 
b/Documentation/networking/devlink/ixgbe.rst
index aa4eab95b3d5..31aef3793845 100644
--- a/Documentation/networking/devlink/ixgbe.rst
+++ b/Documentation/networking/devlink/ixgbe.rst
@@ -91,3 +91,20 @@ combined flash image that contains the ``fw.mgmt``, 
``fw.undi``, and
and device serial number. It is expected that this combination be used 
with an
image customized for the specific device.
 
+Reload
+==
+
+The ``ixgbe`` driver supports activating new firmware after a flash update
+using ``DEVLINK_CMD_RELOAD`` with the ``DEVLINK_RELOAD_ACTION_FW_ACTIVATE``
+action.
+
+.. code:: shell
+
+$ devlink dev reload pci/:01:00.0 reload action fw_activate
+
+The new firmware is activated by issuing a device specific Embedded
+Management Processor reset which requests the device to reset and reload the
+EMP firmware image.
+
+The driver does not currently support reloading the driver via
+``DEVLINK_RELOAD_ACTION_DRIVER_REINIT``.
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 2ffe59a88811..391d53503627 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -352,6 +352,9 @@ static int ixgbe_devlink_info_get(struct devlink *devlink,
if (!ctx)
return -ENOMEM;
 
+   if (hw->mac.type == ixgbe_mac_e610)
+   ixgbe_refresh_fw_version(adapter);
+
ixgbe_info_get_dsn(adapter, ctx);
err = devlink_info_serial_number_put(req, ctx->buf);
if (err)
@@ -393,11 +396,120 @@ static int ixgbe_devlink_info_get(struct devlink 
*devlink,
return err;
 }
 
+/**
+ * ixgbe_devlink_reload_empr_start - Start EMP reset to activate new firmware
+ * @devlink: pointer to the devlink instance to reload
+ * @netns_change: if true, the network namespace is changing
+ * @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE
+ * @limit: limits on what reload should do, such as not resetting
+ * @extack: netlink extended ACK structure
+ *
+ * Allow user to activate new Embedded Management Processor firmware by
+ * issuing device specific EMP reset. Called in response to
+ * a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE.
+ *
+ * Note that teardown and rebuild of the driver state happens automatically as
+ * part of an interrupt and watchdog task. This is because all physical
+ * functions on the device must be able to reset when an EMP reset occurs from
+ * any source.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_devlink_reload_empr_start(struct devlink *devlink,
+  bool netns_change,
+  enum devlink_reload_action action,
+  enum devlink_reload_limit limit,
+  struct netlink_ext_ack *extack)
+{
+   struct ixgbe_adapter *adapter = devlink_priv(devlink);
+   struct ixgbe_hw *hw = &adapter->hw;
+   u8 pending;
+   int err;
+
+   if (hw->mac.type != ixgbe_mac_e610)
+   return -EOPNOTSUPP;
+
+   err = ixgbe_get_pending_updates(adapter, &pending, extack);
+   if (err)
+   return err;
+
+   /* Pending is a bitmask of which flash banks have a pending update,
+* incl

[Intel-wired-lan] [PATCH iwl-next v8 13/15] ixgbe: add FW API version check

2025-03-13 Thread Jedrzej Jagielski
Add E610 specific function checking whether the FW API version
is compatible with the driver expectations.

The major API version should be less than or equal to the expected
API version. If not the driver won't be fully operational.

Check the minor version, and if it is more than two versions lesser
or greater than the expected version, print a message indicating
that the NVM or driver should be updated respectively.

Reviewed-by: Mateusz Polchlopek 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Signed-off-by: Jedrzej Jagielski 
---
v5: add get_fw_ver
---
 .../ethernet/intel/ixgbe/devlink/devlink.c|  2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |  1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c |  1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 34 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h |  1 +
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  4 +++
 6 files changed, 43 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 391d53503627..87ec2dea5862 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -499,6 +499,8 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink 
*devlink,
 
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
 
+   adapter->flags2 &= ~IXGBE_FLAG2_API_MISMATCH;
+
return 0;
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 83d4d7368cda..2246997bc9fb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -671,6 +671,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_PHY_FW_LOAD_FAILED BIT(20)
 #define IXGBE_FLAG2_NO_MEDIA   BIT(21)
 #define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED  BIT(22)
+#define IXGBE_FLAG2_API_MISMATCH   BIT(23)
 
/* Tx fast path data */
int num_tx_queues;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index e6b35792fdee..5aa66534aa75 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -3877,6 +3877,7 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
.led_off= ixgbe_led_off_generic,
.init_led_link_act  = ixgbe_init_led_link_act_generic,
.reset_hw   = ixgbe_reset_hw_e610,
+   .get_fw_ver = ixgbe_aci_get_fw_ver,
.get_media_type = ixgbe_get_media_type_e610,
.setup_link = ixgbe_setup_link_e610,
.get_link_capabilities  = ixgbe_get_link_capabilities_e610,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 9892d3f41620..de74132f9001 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8361,6 +8361,34 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter 
*adapter)
rtnl_unlock();
 }
 
+static int ixgbe_check_fw_api_mismatch(struct ixgbe_adapter *adapter)
+{
+   struct ixgbe_hw *hw = &adapter->hw;
+
+   if (hw->mac.type != ixgbe_mac_e610)
+   return 0;
+
+   if (hw->mac.ops.get_fw_ver && hw->mac.ops.get_fw_ver(hw))
+   return 0;
+
+   if (hw->api_maj_ver > IXGBE_FW_API_VER_MAJOR) {
+   e_dev_err("The driver for the device stopped because the NVM 
image is newer than expected. You must install the most recent version of the 
network driver.\n");
+
+   adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH;
+   return -EOPNOTSUPP;
+   } else if (hw->api_maj_ver == IXGBE_FW_API_VER_MAJOR &&
+  hw->api_min_ver > IXGBE_FW_API_VER_MINOR + 
IXGBE_FW_API_VER_DIFF_ALLOWED) {
+   e_dev_info("The driver for the device detected a newer version 
of the NVM image than expected. Please install the most recent version of the 
network driver.\n");
+   adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH;
+   } else if (hw->api_maj_ver < IXGBE_FW_API_VER_MAJOR ||
+  hw->api_min_ver < IXGBE_FW_API_VER_MINOR - 
IXGBE_FW_API_VER_DIFF_ALLOWED) {
+   e_dev_info("The driver for the device detected an older version 
of the NVM image than expected. Please update the NVM image.\n");
+   adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH;
+   }
+
+   return 0;
+}
+
 /**
  * ixgbe_check_fw_error - Check firmware for errors
  * @adapter: the adapter private structure
@@ -8371,6 +8399,7 @@ static bool ixgbe_check_fw_error(struct ixgbe_adapter 
*adapter)
 {
struct ixgbe_hw *hw = &adapter->hw;
u32 fwsm;
+   int err;
 
/* read fwsm.ext_err_ind register and log errors */
fwsm = IXGBE_READ

[Intel-wired-lan] [PATCH iwl-next v8 15/15] ixgbe: add support for FW rollback mode

2025-03-13 Thread Jedrzej Jagielski
From: Andrii Staikov 

The driver should detect whether the device entered FW rollback
mode and then notify user with the dedicated message including
FW and NVM versions.

Even if the driver detected rollback mode, this should not result
in an probe error and the normal flow proceeds.

FW tries to rollback to “old” operational FW located in the
inactive NVM bank in cases when newly loaded FW exhibits faulty
behavior. If something goes wrong during boot the FW may switch
into rollback mode in an attempt to avoid recovery mode and stay
operational. After rollback is successful, the banks are swapped,
and the “rollback” bank becomes the active bank for the next reset.

Reviewed-by: Mateusz Polchlopek 
Signed-off-by: Andrii Staikov 
Signed-off-by: Jedrzej Jagielski 
---
 .../ethernet/intel/ixgbe/devlink/devlink.c|  3 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe.h  |  1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 33 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 26 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h |  2 ++
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  1 +
 6 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 87ec2dea5862..88335912bd6f 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -499,7 +499,8 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink 
*devlink,
 
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
 
-   adapter->flags2 &= ~IXGBE_FLAG2_API_MISMATCH;
+   adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH |
+IXGBE_FLAG2_FW_ROLLBACK);
 
return 0;
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 2246997bc9fb..23c2e2c2649c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -672,6 +672,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_NO_MEDIA   BIT(21)
 #define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED  BIT(22)
 #define IXGBE_FLAG2_API_MISMATCH   BIT(23)
+#define IXGBE_FLAG2_FW_ROLLBACKBIT(24)
 
/* Tx fast path data */
int num_tx_queues;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index 84b015e2dac2..bc1a5775a3a0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -1831,6 +1831,22 @@ static bool ixgbe_fw_recovery_mode_e610(struct ixgbe_hw 
*hw)
return !!(fwsm & IXGBE_GL_MNG_FWSM_RECOVERY_M);
 }
 
+/**
+ * ixgbe_fw_rollback_mode_e610 - Check FW NVM rollback mode
+ * @hw: pointer to hardware structure
+ *
+ * Check FW NVM rollback mode by reading the value of
+ * the dedicated register.
+ *
+ * Return: true if FW is in rollback mode, otherwise false.
+ */
+static bool ixgbe_fw_rollback_mode_e610(struct ixgbe_hw *hw)
+{
+   u32 fwsm = IXGBE_READ_REG(hw, IXGBE_GL_MNG_FWSM);
+
+   return !!(fwsm & IXGBE_GL_MNG_FWSM_ROLLBACK_M);
+}
+
 /**
  * ixgbe_init_phy_ops_e610 - PHY specific init
  * @hw: pointer to hardware structure
@@ -3163,6 +3179,21 @@ int ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, 
struct ixgbe_nvm_info *nvm)
return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm);
 }
 
+/**
+ * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank
+ * @hw: pointer to the HW structure
+ * @nvm: storage for Option ROM version information
+ *
+ * Reads the NVM EETRACK ID, Map version, and security revision of the
+ * active NVM bank.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info 
*nvm)
+{
+   return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm);
+}
+
 /**
  * ixgbe_get_netlist_info - Read the netlist version information
  * @hw: pointer to the HW struct
@@ -3897,6 +3928,8 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
.get_media_type = ixgbe_get_media_type_e610,
.setup_link = ixgbe_setup_link_e610,
.fw_recovery_mode   = ixgbe_fw_recovery_mode_e610,
+   .fw_rollback_mode   = ixgbe_fw_rollback_mode_e610,
+   .get_nvm_ver= ixgbe_get_active_nvm_ver,
.get_link_capabilities  = ixgbe_get_link_capabilities_e610,
.get_bus_info   = ixgbe_get_bus_info_generic,
.acquire_swfw_sync  = ixgbe_acquire_swfw_sync_X540,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 5c9de1fafd28..ce73a47ce00a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8420,6 +

[Intel-wired-lan] [PATCH iwl-next v8 06/15] ixgbe: read the OROM version information

2025-03-13 Thread Jedrzej Jagielski
From: Slawomir Mrozowicz 

Add functions reading the OROM version info and use them
as a part of the setting NVM info procedure.

Reviewed-by: Mateusz Polchlopek 
Reviewed-by: Przemek Kitszel 
Tested-by: Bharath R 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Signed-off-by: Jedrzej Jagielski 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 172 ++
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  15 ++
 2 files changed, 187 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index 3654b7e32cc8..bad4bc04bb66 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -2582,6 +2582,35 @@ static int ixgbe_read_nvm_module(struct ixgbe_hw *hw,
return err;
 }
 
+/**
+ * ixgbe_read_orom_module - Read from the active Option ROM module
+ * @hw: pointer to the HW structure
+ * @bank: whether to read from active or inactive OROM module
+ * @offset: offset into the OROM module to read, in words
+ * @data: storage for returned word value
+ *
+ * Read the specified word from the active Option ROM module of the flash.
+ * Note that unlike the NVM module, the CSS data is stored at the end of the
+ * module instead of at the beginning.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_read_orom_module(struct ixgbe_hw *hw,
+ enum ixgbe_bank_select bank,
+ u32 offset, u16 *data)
+{
+   __le16 data_local;
+   int err;
+
+   err = ixgbe_read_flash_module(hw, bank, IXGBE_E610_SR_1ST_OROM_BANK_PTR,
+ offset * sizeof(data_local),
+ (u8 *)&data_local, sizeof(data_local));
+   if (!err)
+   *data = le16_to_cpu(data_local);
+
+   return err;
+}
+
 /**
  * ixgbe_get_nvm_css_hdr_len - Read the CSS header length
  * @hw: pointer to the HW struct
@@ -2678,6 +2707,143 @@ static int ixgbe_get_nvm_srev(struct ixgbe_hw *hw,
return 0;
 }
 
+/**
+ * ixgbe_get_orom_civd_data - Get the combo version information from Option ROM
+ * @hw: pointer to the HW struct
+ * @bank: whether to read from the active or inactive flash module
+ * @civd: storage for the Option ROM CIVD data.
+ *
+ * Searches through the Option ROM flash contents to locate the CIVD data for
+ * the image.
+ *
+ * Return: the exit code of the operation.
+ */
+static int
+ixgbe_get_orom_civd_data(struct ixgbe_hw *hw, enum ixgbe_bank_select bank,
+struct ixgbe_orom_civd_info *civd)
+{
+   struct ixgbe_orom_civd_info tmp;
+   u32 offset;
+   int err;
+
+   /* The CIVD section is located in the Option ROM aligned to 512 bytes.
+* The first 4 bytes must contain the ASCII characters "$CIV".
+* A simple modulo 256 sum of all of the bytes of the structure must
+* equal 0.
+*/
+   for (offset = 0; (offset + SZ_512) <= hw->flash.banks.orom_size;
+offset += SZ_512) {
+   u8 sum = 0;
+   u32 i;
+
+   err = ixgbe_read_flash_module(hw, bank,
+ IXGBE_E610_SR_1ST_OROM_BANK_PTR,
+ offset,
+ (u8 *)&tmp, sizeof(tmp));
+   if (err)
+   return err;
+
+   /* Skip forward until we find a matching signature */
+   if (memcmp(IXGBE_OROM_CIV_SIGNATURE, tmp.signature,
+  sizeof(tmp.signature)))
+   continue;
+
+   /* Verify that the simple checksum is zero */
+   for (i = 0; i < sizeof(tmp); i++)
+   sum += ((u8 *)&tmp)[i];
+
+   if (sum)
+   return -EDOM;
+
+   *civd = tmp;
+   return 0;
+   }
+
+   return -ENODATA;
+}
+
+/**
+ * ixgbe_get_orom_srev - Read the security revision from the OROM CSS header
+ * @hw: pointer to the HW struct
+ * @bank: whether to read from active or inactive flash module
+ * @srev: storage for security revision
+ *
+ * Read the security revision out of the CSS header of the active OROM module
+ * bank.
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_get_orom_srev(struct ixgbe_hw *hw,
+  enum ixgbe_bank_select bank,
+  u32 *srev)
+{
+   u32 orom_size_word = hw->flash.banks.orom_size / 2;
+   u32 css_start, hdr_len;
+   u16 srev_l, srev_h;
+   int err;
+
+   err = ixgbe_get_nvm_css_hdr_len(hw, bank, &hdr_len);
+   if (err)
+   return err;
+
+   if (orom_size_word < hdr_len)
+   return -EINVAL;
+
+   /* Calculate how far into the Option ROM the CSS header starts. Note
+* that ixgbe_r

[Intel-wired-lan] [PATCH iwl-next v8 14/15] ixgbe: add E610 implementation of FW recovery mode

2025-03-13 Thread Jedrzej Jagielski
Add E610 implementation of fw_recovery_mode MAC operation.

In case of E610 information about recovery mode is obtained
from FW_MODES field in IXGBE_GL_MNG_FWSM register (0x000B6134).

Introduce recovery specific probing flow and init only
vital features.

User should be able to perform NVM update using devlink
once FW error is detected in order to load a healthy img.

Reviewed-by: Mateusz Polchlopek 
Co-developed-by: Stefan Wegrzyn 
Signed-off-by: Stefan Wegrzyn 
Signed-off-by: Jedrzej Jagielski 
---
v7: unregister mdiobus before unregistering netdev
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 17 
 .../ethernet/intel/ixgbe/ixgbe_fw_update.c| 14 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 94 +--
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|  3 +
 4 files changed, 117 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index 5aa66534aa75..84b015e2dac2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -1815,6 +1815,22 @@ void ixgbe_disable_rx_e610(struct ixgbe_hw *hw)
}
 }
 
+/**
+ * ixgbe_fw_recovery_mode_e610 - Check FW NVM recovery mode
+ * @hw: pointer to hardware structure
+ *
+ * Check FW NVM recovery mode by reading the value of
+ * the dedicated register.
+ *
+ * Return: true if FW is in recovery mode, otherwise false.
+ */
+static bool ixgbe_fw_recovery_mode_e610(struct ixgbe_hw *hw)
+{
+   u32 fwsm = IXGBE_READ_REG(hw, IXGBE_GL_MNG_FWSM);
+
+   return !!(fwsm & IXGBE_GL_MNG_FWSM_RECOVERY_M);
+}
+
 /**
  * ixgbe_init_phy_ops_e610 - PHY specific init
  * @hw: pointer to hardware structure
@@ -3880,6 +3896,7 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
.get_fw_ver = ixgbe_aci_get_fw_ver,
.get_media_type = ixgbe_get_media_type_e610,
.setup_link = ixgbe_setup_link_e610,
+   .fw_recovery_mode   = ixgbe_fw_recovery_mode_e610,
.get_link_capabilities  = ixgbe_get_link_capabilities_e610,
.get_bus_info   = ixgbe_get_bus_info_generic,
.acquire_swfw_sync  = ixgbe_acquire_swfw_sync_X540,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c
index 052d5b3fb371..39f106e39be6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c
@@ -73,6 +73,8 @@ static int ixgbe_check_component_response(struct 
ixgbe_adapter *adapter,
  u8 response, u8 code,
  struct netlink_ext_ack *extack)
 {
+   struct ixgbe_hw *hw = &adapter->hw;
+
switch (response) {
case IXGBE_ACI_NVM_PASS_COMP_CAN_BE_UPDATED:
/* Firmware indicated this update is good to proceed. */
@@ -84,6 +86,11 @@ static int ixgbe_check_component_response(struct 
ixgbe_adapter *adapter,
case IXGBE_ACI_NVM_PASS_COMP_CAN_NOT_BE_UPDATED:
NL_SET_ERR_MSG_MOD(extack, "Firmware has rejected updating.");
break;
+   case IXGBE_ACI_NVM_PASS_COMP_PARTIAL_CHECK:
+   if (hw->mac.ops.fw_recovery_mode &&
+   hw->mac.ops.fw_recovery_mode(hw))
+   return 0;
+   break;
}
 
switch (code) {
@@ -653,7 +660,12 @@ int ixgbe_flash_pldm_image(struct devlink *devlink,
return -EOPNOTSUPP;
}
 
-   if (!hw->dev_caps.common_cap.nvm_unified_update) {
+   /* Cannot get caps in recovery mode, so lack of nvm_unified_update bit
+* cannot lead to error
+*/
+   if (!hw->dev_caps.common_cap.nvm_unified_update &&
+   (hw->mac.ops.fw_recovery_mode &&
+!hw->mac.ops.fw_recovery_mode(hw))) {
NL_SET_ERR_MSG_MOD(extack,
   "Current firmware does not support unified 
update");
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index de74132f9001..5c9de1fafd28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8423,6 +8423,18 @@ static bool ixgbe_check_fw_error(struct ixgbe_adapter 
*adapter)
return false;
 }
 
+static void ixgbe_recovery_service_task(struct work_struct *work)
+{
+   struct ixgbe_adapter *adapter = container_of(work,
+struct ixgbe_adapter,
+service_task);
+
+   ixgbe_handle_fw_event(adapter);
+   ixgbe_service_event_complete(adapter);
+
+   mod_timer(&adapter->service_timer, jiffies + msecs_to_jiffies(100));
+}
+
 /**
  * ixgbe_service_task - manages and runs subtas

[Intel-wired-lan] [PATCH iwl-next v8 04/15] ixgbe: add handler for devlink .info_get()

2025-03-13 Thread Jedrzej Jagielski
Provide devlink .info_get() callback implementation to allow the
driver to report detailed version information. The following info
is reported:

 "serial_number" -> The PCI DSN of the adapter
 "fw.bundle_id" -> Unique identifier for the combined flash image
 "fw.undi" -> Version of the Option ROM containing the UEFI driver
 "board.id" -> The PBA ID string

Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Signed-off-by: Jedrzej Jagielski 
---
v2: zero the ctx buff when chance it won't be filled out
v4: use devlink_priv()
v6: fix devlink_*_put() labels
---
 Documentation/networking/devlink/ixgbe.rst|  32 ++
 .../ethernet/intel/ixgbe/devlink/devlink.c| 101 ++
 2 files changed, 133 insertions(+)

diff --git a/Documentation/networking/devlink/ixgbe.rst 
b/Documentation/networking/devlink/ixgbe.rst
index c04ac51c6d85..b63645de37e8 100644
--- a/Documentation/networking/devlink/ixgbe.rst
+++ b/Documentation/networking/devlink/ixgbe.rst
@@ -6,3 +6,35 @@ ixgbe devlink support
 
 This document describes the devlink features implemented by the ``ixgbe``
 device driver.
+
+Info versions
+=
+
+The ``ixgbe`` driver reports the following versions
+
+.. list-table:: devlink info versions implemented
+:widths: 5 5 5 90
+
+* - Name
+  - Type
+  - Example
+  - Description
+* - ``board.id``
+  - fixed
+  - H49289-000
+  - The Product Board Assembly (PBA) identifier of the board.
+* - ``fw.undi``
+  - running
+  - 1.1937.0
+  - Version of the Option ROM containing the UEFI driver. The version is
+reported in ``major.minor.patch`` format. The major version is
+incremented whenever a major breaking change occurs, or when the
+minor version would overflow. The minor version is incremented for
+non-breaking changes and reset to 1 when the major version is
+incremented. The patch version is normally 0 but is incremented when
+a fix is delivered as a patch against an older base Option ROM.
+* - ``fw.bundle_id``
+  - running
+  - 0x8d0d
+  - Unique identifier of the firmware image file that was loaded onto
+the device. Also referred to as the EETRACK identifier of the NVM.
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 6c3452cf5d7d..d91252da4a61 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -4,7 +4,108 @@
 #include "ixgbe.h"
 #include "devlink.h"
 
+struct ixgbe_info_ctx {
+   char buf[128];
+};
+
+static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
+  struct ixgbe_info_ctx *ctx)
+{
+   u8 dsn[8];
+
+   /* Copy the DSN into an array in Big Endian format */
+   put_unaligned_be64(pci_get_dsn(adapter->pdev), dsn);
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
+}
+
+static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
+  struct ixgbe_info_ctx *ctx)
+{
+   struct ixgbe_hw *hw = &adapter->hw;
+   struct ixgbe_nvm_version nvm_ver;
+
+   ctx->buf[0] = '\0';
+
+   ixgbe_get_oem_prod_version(hw, &nvm_ver);
+   if (nvm_ver.oem_valid) {
+   snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",
+nvm_ver.oem_major, nvm_ver.oem_minor,
+nvm_ver.oem_release);
+
+   return;
+   }
+
+   ixgbe_get_orom_version(hw, &nvm_ver);
+   if (nvm_ver.or_valid)
+   snprintf(ctx->buf, sizeof(ctx->buf), "%d.%d.%d",
+nvm_ver.or_major, nvm_ver.or_build, nvm_ver.or_patch);
+}
+
+static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
+  struct ixgbe_info_ctx *ctx)
+{
+   struct ixgbe_hw *hw = &adapter->hw;
+   struct ixgbe_nvm_version nvm_ver;
+
+   ixgbe_get_oem_prod_version(hw, &nvm_ver);
+
+   /* No ETRACK version for OEM */
+   if (nvm_ver.oem_valid) {
+   ctx->buf[0] = '\0';
+   return;
+   }
+
+   ixgbe_get_etk_id(hw, &nvm_ver);
+   snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id);
+}
+
+static int ixgbe_devlink_info_get(struct devlink *devlink,
+ struct devlink_info_req *req,
+ struct netlink_ext_ack *extack)
+{
+   struct ixgbe_adapter *adapter = devlink_priv(devlink);
+   struct ixgbe_hw *hw = &adapter->hw;
+   struct ixgbe_info_ctx *ctx;
+   int err;
+
+   ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+   if (!ctx)
+   return -ENOMEM;
+
+   ixgbe_info_get_dsn(adapter, ctx);
+   err = devlink_info_serial_number_put(req, ctx->buf);
+   if (err)
+   goto free_ctx;
+
+   err = ixgbe_read_pba_string_generic(hw, ctx->buf, sizeof(ctx->buf));
+   if (err)
+   goto free

[Intel-wired-lan] [PATCH iwl-next v8 09/15] ixgbe: add E610 functions getting PBA and FW ver info

2025-03-13 Thread Jedrzej Jagielski
Introduce 2 E610 specific callbacks implementations:
-ixgbe_start_hw_e610() which expands the regular .start_hw callback with
getting FW version information
-ixgbe_read_pba_string_e610() which gets Product Board Assembly string

Extend EEPROM ops with new .read_pba_string in order to distinguish
generic one and the E610 one.

Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Co-developed-by: Stefan Wegrzyn 
Signed-off-by: Stefan Wegrzyn 
Signed-off-by: Jedrzej Jagielski 
---
v7: add .init_params() callback implementation
---
 .../ethernet/intel/ixgbe/devlink/devlink.c|   2 +-
 .../net/ethernet/intel/ixgbe/ixgbe_82598.c|   1 +
 .../net/ethernet/intel/ixgbe/ixgbe_82599.c|   1 +
 .../net/ethernet/intel/ixgbe/ixgbe_common.c   |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 184 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h |   2 +
 .../ethernet/intel/ixgbe/ixgbe_type_e610.h|   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c |   1 +
 10 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 365310a6910d..8f44c3dee0b5 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -198,7 +198,7 @@ static int ixgbe_devlink_info_get(struct devlink *devlink,
if (err)
goto free_ctx;
 
-   err = ixgbe_read_pba_string_generic(hw, ctx->buf, sizeof(ctx->buf));
+   err = hw->eeprom.ops.read_pba_string(hw, ctx->buf, sizeof(ctx->buf));
if (err)
goto free_ctx;
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 4aaaea3b5f8f..444da982593f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1169,6 +1169,7 @@ static const struct ixgbe_eeprom_operations 
eeprom_ops_82598 = {
.calc_checksum  = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum  = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum= &ixgbe_update_eeprom_checksum_generic,
+   .read_pba_string= &ixgbe_read_pba_string_generic,
 };
 
 static const struct ixgbe_phy_operations phy_ops_82598 = {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index 964988b4d58b..d5b1b974b4a3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -2230,6 +2230,7 @@ static const struct ixgbe_eeprom_operations 
eeprom_ops_82599 = {
.calc_checksum  = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum  = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum= &ixgbe_update_eeprom_checksum_generic,
+   .read_pba_string= &ixgbe_read_pba_string_generic,
 };
 
 static const struct ixgbe_phy_operations phy_ops_82599 = {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 7beaf6ea57f9..5784d5d1896e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -332,6 +332,7 @@ int ixgbe_start_hw_generic(struct ixgbe_hw *hw)
  * Devices in the second generation:
  * 82599
  * X540
+ * E610
  **/
 int ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
 {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
index b34570b244d9..457d1f4b8784 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
@@ -343,6 +343,41 @@ void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc 
*desc, u16 opcode)
desc->flags = cpu_to_le16(IXGBE_ACI_FLAG_SI);
 }
 
+/**
+ * ixgbe_aci_get_fw_ver - Get the firmware version
+ * @hw: pointer to the HW struct
+ *
+ * Get the firmware version using ACI command (0x0001).
+ *
+ * Return: the exit code of the operation.
+ */
+static int ixgbe_aci_get_fw_ver(struct ixgbe_hw *hw)
+{
+   struct ixgbe_aci_cmd_get_ver *resp;
+   struct ixgbe_aci_desc desc;
+   int err;
+
+   resp = &desc.params.get_ver;
+
+   ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_ver);
+
+   err = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
+
+   if (!err) {
+   hw->fw_branch = resp->fw_branch;
+   hw->fw_maj_ver = resp->fw_major;
+   hw->fw_min_ver = resp->fw_minor;
+   hw->fw_patch = resp->fw_patch;
+   hw->fw_build = le32_to_cpu(resp->fw_build);
+   hw->api_branch = resp->api_branch;
+   hw->api_maj_ver = resp->api_major;
+   hw->api_min_ver = resp->api_minor;
+   

[Intel-wired-lan] [PATCH iwl-net v4 1/1] e1000e: change k1 configuration on MTP and later platforms

2025-03-13 Thread Vitaly Lifshits
Starting from Meteor Lake, the Kumeran interface between the integrated
MAC and the I219 PHY works at a different frequency. This causes sporadic
MDI errors when accessing the PHY, and in rare circumstances could lead
to packet corruption.

To overcome this, introduce minor changes to the Kumeran idle
state (K1) parameters during device initialization. Hardware reset
reverts this configuration, therefore it needs to be applied in a few
places.

Fixes: cc23f4f0b6b9 ("e1000e: Add support for Meteor Lake")
Signed-off-by: Vitaly Lifshits 
---
v4: fix a typo
v3: refactor code to avoid edge case errors
v2: address community comments
v1: initial version
---
 drivers/net/ethernet/intel/e1000e/defines.h |  3 +
 drivers/net/ethernet/intel/e1000e/ich8lan.c | 80 +++--
 drivers/net/ethernet/intel/e1000e/ich8lan.h |  4 ++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/defines.h 
b/drivers/net/ethernet/intel/e1000e/defines.h
index 5e2cfa73f889..8294a7c4f122 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -803,4 +803,7 @@
 /* SerDes Control */
 #define E1000_GEN_POLL_TIMEOUT  640
 
+#define E1000_FEXTNVM12_PHYPD_CTRL_MASK0x00C0
+#define E1000_FEXTNVM12_PHYPD_CTRL_P1  0x0080
+
 #endif /* _E1000_DEFINES_H_ */
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c 
b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 2f9655cf5dd9..364378133526 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -285,6 +285,45 @@ static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw 
*hw)
}
 }
 
+/**
+ * e1000_reconfigure_k1_exit_timeout - reconfigure K1 exit timeout to
+ * align to MTP and later platform requirements.
+ * @hw: pointer to the HW structure
+ *
+ * Context: PHY semaphore must be held by caller.
+ * Return: 0 on success, negative on failure
+ */
+static s32 e1000_reconfigure_k1_exit_timeout(struct e1000_hw *hw)
+{
+   u16 phy_timeout;
+   u32 fextnvm12;
+   s32 ret_val;
+
+   if (hw->mac.type < e1000_pch_mtp)
+   return 0;
+
+   /* Change Kumeran K1 power down state from P0s to P1 */
+   fextnvm12 = er32(FEXTNVM12);
+   fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
+   fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
+   ew32(FEXTNVM12, fextnvm12);
+
+   /* Wait for the interface the settle */
+   usleep_range(1000, 1100);
+
+   /* Change K1 exit timeout */
+   ret_val = e1e_rphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+ &phy_timeout);
+   if (ret_val)
+   return ret_val;
+
+   phy_timeout &= ~I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK;
+   phy_timeout |= 0xF00;
+
+   return e1e_wphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+ phy_timeout);
+}
+
 /**
  *  e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
  *  @hw: pointer to the HW structure
@@ -327,15 +366,22 @@ static s32 e1000_init_phy_workarounds_pchlan(struct 
e1000_hw *hw)
 * LANPHYPC Value bit to force the interconnect to PCIe mode.
 */
switch (hw->mac.type) {
+   case e1000_pch_mtp:
+   case e1000_pch_lnp:
+   case e1000_pch_ptp:
+   case e1000_pch_nvp:
+   /* At this point the PHY might be inaccessible so don't
+* propagate the failure
+*/
+   if (e1000_reconfigure_k1_exit_timeout(hw))
+   e_dbg("Failed to reconfigure K1 exit timeout\n");
+
+   fallthrough;
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
-   case e1000_pch_mtp:
-   case e1000_pch_lnp:
-   case e1000_pch_ptp:
-   case e1000_pch_nvp:
if (e1000_phy_is_accessible_pchlan(hw))
break;
 
@@ -419,8 +465,20 @@ static s32 e1000_init_phy_workarounds_pchlan(struct 
e1000_hw *hw)
 *  the PHY is in.
 */
ret_val = hw->phy.ops.check_reset_block(hw);
-   if (ret_val)
+   if (ret_val) {
e_err("ME blocked access to PHY after reset\n");
+   goto out;
+   }
+
+   if (hw->mac.type >= e1000_pch_mtp) {
+   ret_val = hw->phy.ops.acquire(hw);
+   if (ret_val) {
+   e_err("Failed to reconfigure K1 exit 
timeout\n");
+   goto out;
+   }
+   ret_val = e1000_reconfigure_k1_exit_timeout(hw);
+   hw->phy.ops.release(hw);
+   }
}
 
 out:
@@ -4888,6 +4946,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
u16 i;
 
e1000_initialize_hw_bits_ich8lan(hw);
+   if (hw->m

Re: [Intel-wired-lan] [PATCH net v2 2/5] renesas: reject PTP_STRICT_FLAGS as unsupported

2025-03-13 Thread Niklas Söderlund
Hi Jacob,

Thanks for your work.

On 2025-03-12 15:15:51 -0700, Jacob Keller wrote:
> The ravb_ptp_extts() function checks the flags coming from the
> PTP_EXTTS_REQUEST ioctl, to ensure that future flags are not accepted on
> accident.
> 
> This was updated to 'honor' the PTP_STRICT_FLAGS in commit 6138e687c7b6
> ("ptp: Introduce strict checking of external time stamp options.").
> However, the driver does not *actually* validate the flags.
> 
> I originally fixed this driver to reject future flags in commit
> 592025a03b34 ("renesas: reject unsupported external timestamp flags"). It
> is still unclear whether this hardware timestamps the rising, falling, or
> both edges of the input signal.
> 
> Accepting requests with PTP_STRICT_FLAGS is a bug, as this could lead to
> users mistakenly assuming a request with PTP_RISING_EDGE actually
> timestamps the rising edge only.
> 
> Reject requests with PTP_STRICT_FLAGS (and hence all PTP_EXTTS_REQUEST2
> requests) until someone with access to the datasheet or hardware knowledge
> can confirm the timestamping behavior and update this driver.
> 
> Fixes: 6138e687c7b6 ("ptp: Introduce strict checking of external time stamp 
> options.")
> Signed-off-by: Jacob Keller 

Reviewed-by: Niklas Söderlund 

> ---
>  drivers/net/ethernet/renesas/ravb_ptp.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c 
> b/drivers/net/ethernet/renesas/ravb_ptp.c
> index 
> 6e4ef7af27bf31ab2aad8e06a65e0ede6046e3c0..b4365906669f3bd40953813e263aeaafd2e1eb70
>  100644
> --- a/drivers/net/ethernet/renesas/ravb_ptp.c
> +++ b/drivers/net/ethernet/renesas/ravb_ptp.c
> @@ -179,8 +179,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
>   /* Reject requests with unsupported flags */
>   if (req->flags & ~(PTP_ENABLE_FEATURE |
>  PTP_RISING_EDGE |
> -PTP_FALLING_EDGE |
> -PTP_STRICT_FLAGS))
> +PTP_FALLING_EDGE))
>   return -EOPNOTSUPP;
>  
>   if (req->index)
> 
> -- 
> 2.48.1.397.gec9d649cc640
> 

-- 
Kind Regards,
Niklas Söderlund


[Intel-wired-lan] [PATCH iwl-next] igc: enable HW vlan tag insertion/stripping by default

2025-03-13 Thread Rui Salvaterra
This is enabled by default in other Intel drivers I've checked (e1000, e1000e,
iavf, igb and ice). Fixes an out-of-the-box performance issue when running
OpenWrt on typical mini-PCs with igc-supported Ethernet controllers and 802.1Q
VLAN configurations, as ethtool isn't part of the default packages and sane
defaults are expected.

In my specific case, with an Intel N100-based machine with four I226-V Ethernet
controllers, my upload performance increased from under 30 Mb/s to the expected
~1 Gb/s.

Signed-off-by: Rui Salvaterra 
---
 drivers/net/ethernet/intel/igc/igc_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/intel/igc/igc_main.c 
b/drivers/net/ethernet/intel/igc/igc_main.c
index 84307bb7313e..1cb9ce8aa743 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -7049,6 +7049,9 @@ static int igc_probe(struct pci_dev *pdev,
netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
   NETDEV_XDP_ACT_XSK_ZEROCOPY;
 
+   /* enable HW vlan tag insertion/stripping by default */
+   netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
+
/* MTU range: 68 - 9216 */
netdev->min_mtu = ETH_MIN_MTU;
netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
-- 
2.48.1



[Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 Earliest TxTime First Offload support

2025-03-13 Thread Paul Greenwalt
E830 supports Earliest TxTime First (ETF) hardware offload, which is
configured via the ETF Qdisc (see tc-etf(8)). ETF introduces a new Tx flow
mechanism that utilizes a timestamp ring (tstamp_ring) alongside the
standard Tx ring. This timestamp ring is used to indicate when hardware
will transmit a packet.

The allocation and initialization of the timestamp ring occur when the
feature is enabled via tc-etf. Since the timestamp ring and Tx ring are
tightly coupled, both must be configured simultaneously.

To support ETF, the following flags are introduced:

 - ICE_F_TXTIME: Device feature flag set for E830 NICs, indicating ETF
   support.
 - ICE_FLAG_TXTIME: PF-level flag indicating whether ETF is enabled on any
   Tx queue. It is checked during ring allocation to determine if timestamp
   rings should be allocated and is also referenced when modifying queue
   count via ethtool -G.
 - ICE_TX_FLAGS_TXTIME: Per-ring flag set when ETF is enabled and cleared
   when disabled for a specific Tx queue. It helps determine ETF status
   when transmitting timestamped packets and is used by ice_is_txtime_ena()
   to check if ETF is enabled on any Tx queue.

Due to a hardware issue that can result in a malicious driver detection
event, additional timestamp descriptors are required when wrapping the
timestamp ring. Up to 64 additional timestamp descriptors are reserved,
reducing the available Tx descriptors.

To accommodate this, ICE_MAX_NUM_DESC_BY_MAC is introduced, defining:

 - E830: Maximum Tx descriptor length of 8096 (8K - 32 - 64 for timestamp
   fetch descriptors).
 - E810 and E82X: Maximum Tx descriptor length of 8160 (8K - 32) .

Reviewed-by: Aleksandr Loktionov 
Co-developed-by: Alice Michael 
Signed-off-by: Alice Michael 
Signed-off-by: Paul Greenwalt 
---
Changelog:
v2->v3:
 - Fix const compiler warning.
 - Fix spelling error in function header.
 - Fix Changelog verions number.
v1->v2:
 - Resolve patch apply isue.
 - Fixes RCT, zero struct initialization, move bailout condition to top
   of function, removed unnecessary newlines, and added use of
   str_enable_disable.
v1: 
https://patchwork.ozlabs.org/project/intel-wired-lan/patch/20250227111333.30675-1-paul.greenw...@intel.com/
---
 drivers/net/ethernet/intel/ice/ice.h  |   9 +-
 .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  53 +
 drivers/net/ethernet/intel/ice/ice_base.c | 212 +++---
 drivers/net/ethernet/intel/ice/ice_base.h |   1 +
 drivers/net/ethernet/intel/ice/ice_common.c   | 118 ++
 drivers/net/ethernet/intel/ice/ice_common.h   |  10 +
 drivers/net/ethernet/intel/ice/ice_ethtool.c  |  61 -
 .../net/ethernet/intel/ice/ice_hw_autogen.h   |   3 +
 .../net/ethernet/intel/ice/ice_lan_tx_rx.h|  42 
 drivers/net/ethernet/intel/ice/ice_lib.c  |  45 +++-
 drivers/net/ethernet/intel/ice/ice_main.c | 174 +-
 drivers/net/ethernet/intel/ice/ice_txrx.c | 129 ++-
 drivers/net/ethernet/intel/ice/ice_txrx.h |   4 +
 drivers/net/ethernet/intel/ice/ice_txrx_lib.h |  14 ++
 drivers/net/ethernet/intel/ice/ice_virtchnl.c |   2 +-
 15 files changed, 823 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h 
b/drivers/net/ethernet/intel/ice/ice.h
index 2694951a0b1d..43a34e3fa762 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -83,7 +83,11 @@
 #define ICE_BAR0   0
 #define ICE_REQ_DESC_MULTIPLE  32
 #define ICE_MIN_NUM_DESC   64
-#define ICE_MAX_NUM_DESC   8160
+#define ICE_MAX_NUM_DESC_E810  8160
+#define ICE_MAX_NUM_DESC_E830  8096
+#define ICE_MAX_NUM_DESC_BY_MAC(hw) ((hw)->mac_type == ICE_MAC_E830 ? \
+ICE_MAX_NUM_DESC_E830 : \
+ICE_MAX_NUM_DESC_E810)
 #define ICE_DFLT_MIN_RX_DESC   512
 #define ICE_DFLT_NUM_TX_DESC   256
 #define ICE_DFLT_NUM_RX_DESC   2048
@@ -201,6 +205,7 @@ enum ice_feature {
ICE_F_SMA_CTRL,
ICE_F_CGU,
ICE_F_GNSS,
+   ICE_F_TXTIME,
ICE_F_GCS,
ICE_F_ROCE_LAG,
ICE_F_SRIOV_LAG,
@@ -332,6 +337,7 @@ struct ice_vsi {
struct ice_pf *back; /* back pointer to PF */
struct ice_rx_ring **rx_rings;   /* Rx ring array */
struct ice_tx_ring **tx_rings;   /* Tx ring array */
+   struct ice_tx_ring **tstamp_rings; /* Time stamp ring array */
struct ice_q_vector **q_vectors; /* q_vector array */
 
irqreturn_t (*irq_handler)(int irq, void *data);
@@ -516,6 +522,7 @@ enum ice_pf_flags {
ICE_FLAG_GNSS,  /* GNSS successfully initialized */
ICE_FLAG_DPLL,  /* SyncE/PTP dplls initialized */
ICE_FLAG_LLDP_AQ_FLTR,
+   ICE_FLAG_TXTIME,
ICE_PF_FLAGS_NBITS  /* must be last */
 };
 
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h 
b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index bdee499f991a..2eaa4ab8e791 100644
-

Re: [Intel-wired-lan] [PATCH iwl-next v3] igc: Change Tx mode for MQPRIO offloading

2025-03-13 Thread Vladimir Oltean
On Tue, Mar 11, 2025 at 04:03:57PM +0800, Abdul Rahim, Faizal wrote:
> On 7/3/2025 11:02 pm, Vladimir Oltean wrote:
> > How do you and Faizal plan to serialize your changes on these flags?
> > You delete IGC_FLAG_TSN_LEGACY_ENABLED and he adds
> > IGC_FLAG_TSN_PREEMPT_ENABLED.
> 
> From what I’ve experienced before, when there’s a conflict like this, the
> Intel maintainer handles it and gets both authors to review the resolution
> (this has happened to both of us before) before they proceed to submit the
> patch.
> 
> But if one patch gets merged first, the other person can just rebase and
> submit a new version ?

Yes, rebasing after the other's patch is merged works just fine. I was
asking if you had decided which one should go in first just to avoid any
ambiguity, but if the answer is 'any', that is also fine.


Re: [Intel-wired-lan] [PATCH net-next 08/16] idpf: make complq cleaning dependent on scheduling mode

2025-03-13 Thread Alexander Lobakin
From: Maciej Fijalkowski 
Date: Fri, 7 Mar 2025 12:11:05 +0100

> On Wed, Mar 05, 2025 at 05:21:24PM +0100, Alexander Lobakin wrote:
>> From: Michal Kubiak 
>>
>> Extend completion queue cleaning function to support queue-based
>> scheduling mode needed for XDP queues.
>> Add 4-byte descriptor for queue-based scheduling mode and
>> perform some refactoring to extract the common code for
>> both scheduling modes.

TBH it's not needed at all as the cleaning logic for XDP queues is in
xdp.c and doesn't depend on the regular Tx. Previously, the same
functions were used for both, but then we rewrote stuff and I forgot
to toss it off =\

I only need to add 4-byte completion descriptors and allocation
depending on the queue type. Regular skb functions don't use queue-based
mode, XDP path doesn't use flow-based mode.

Thanks,
Olek


Re: [Intel-wired-lan] [PATCH net-next 10/16] idpf: add support for nointerrupt queues

2025-03-13 Thread Alexander Lobakin
From: Maciej Fijalkowski 
Date: Fri, 7 Mar 2025 13:10:29 +0100

> On Wed, Mar 05, 2025 at 05:21:26PM +0100, Alexander Lobakin wrote:
>> Currently, queues are associated 1:1 with interrupt vectors as it's
>> assumed queues are always interrupt-driven.
>> In order to use a queue without an interrupt, idpf still needs to have
>> a vector assigned to it to flush descriptors. This vector can be global
>> and only one for the whole vport to handle all its noirq queues.
>> Always request one excessive vector and configure it in non-interrupt
>> mode right away when creating vport, so that it can be used later by
>> queues when needed.
> 
> Description sort of miss the purpose of this commit, you don't ever
> mention that your design choice for XDP Tx queues is to have them
> irq-less.

Because this is not directly related to XDP and maybe some time later
more code could make use of noirq queues, who knows :>

But I'll mention why this is needed, ok.

> 
>>
>> Co-developed-by: Michal Kubiak 
>> Signed-off-by: Michal Kubiak 
>> Signed-off-by: Alexander Lobakin 
>> ---
>>  drivers/net/ethernet/intel/idpf/idpf.h|  8 +++
>>  drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  4 ++
>>  drivers/net/ethernet/intel/idpf/idpf_dev.c| 11 +++-
>>  drivers/net/ethernet/intel/idpf/idpf_lib.c|  2 +-
>>  drivers/net/ethernet/intel/idpf/idpf_txrx.c   |  8 +++
>>  drivers/net/ethernet/intel/idpf/idpf_vf_dev.c | 11 +++-
>>  .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 53 +--
>>  7 files changed, 79 insertions(+), 18 deletions(-)

Thanks,
Olek


Re: [Intel-wired-lan] [PATCH net-next 09/16] idpf: remove SW marker handling from NAPI

2025-03-13 Thread Alexander Lobakin
From: Maciej Fijalkowski 
Date: Fri, 7 Mar 2025 12:42:10 +0100

> On Wed, Mar 05, 2025 at 05:21:25PM +0100, Alexander Lobakin wrote:
>> From: Michal Kubiak 
>>
>> SW marker descriptors on completion queues are used only when a queue
>> is about to be destroyed. It's far from hotpath and handling it in the
>> hotpath NAPI poll makes no sense.

[...]

>> +/**
>> + * idpf_wait_for_sw_marker_completion - wait for SW marker of disabled Tx 
>> queue
>> + * @txq: disabled Tx queue
>> + */
>> +void idpf_wait_for_sw_marker_completion(struct idpf_tx_queue *txq)
>> +{
>> +struct idpf_compl_queue *complq = txq->txq_grp->complq;
>> +struct idpf_splitq_4b_tx_compl_desc *tx_desc;
>> +s16 ntc = complq->next_to_clean;
>> +unsigned long timeout;
>> +bool flow, gen_flag;
>> +u32 pos = ntc;
>> +
>> +if (!idpf_queue_has(SW_MARKER, txq))
>> +return;
>> +
>> +flow = idpf_queue_has(FLOW_SCH_EN, complq);
>> +gen_flag = idpf_queue_has(GEN_CHK, complq);
>> +
>> +timeout = jiffies + msecs_to_jiffies(IDPF_WAIT_FOR_MARKER_TIMEO);
>> +tx_desc = flow ? &complq->comp[pos].common : &complq->comp_4b[pos];
>> +ntc -= complq->desc_count;
> 
> could we stop this logic? it was introduced back in the days as comparison
> against 0 for wrap case was faster, here as you said it doesn't have much
> in common with hot path.

+1

> 
>> +
>> +do {
>> +struct idpf_tx_queue *tx_q;
>> +int ctype;
>> +
>> +ctype = idpf_parse_compl_desc(tx_desc, complq, &tx_q,
>> +  gen_flag);
>> +if (ctype == IDPF_TXD_COMPLT_SW_MARKER) {
>> +idpf_queue_clear(SW_MARKER, tx_q);
>> +if (txq == tx_q)
>> +break;
>> +} else if (ctype == -ENODATA) {
>> +usleep_range(500, 1000);
>> +continue;
>> +}
>> +
>> +pos++;
>> +ntc++;
>> +if (unlikely(!ntc)) {
>> +ntc -= complq->desc_count;
>> +pos = 0;
>> +gen_flag = !gen_flag;
>> +}
>> +
>> +tx_desc = flow ? &complq->comp[pos].common :
>> +  &complq->comp_4b[pos];
>> +prefetch(tx_desc);
>> +} while (time_before(jiffies, timeout));
> 
> what if timeout expires and you didn't find the marker desc? why do you

Then we'll print "failed to receive marker" and that's it. Usually that
happens only if HW went out for cigarettes and won't come back until
a full power cycle. In that case, timeout prevents the kernel from hanging.

> need timer? couldn't you scan the whole ring instead?

Queue destroy marker is always the last written descriptor, there's no
point in scanning the whole ring.
The marker arrives as the CP receives the virtchnl message, queues the
queue (lol) for destroying and sends the marker. This may take up to
several msecs, but you never know.
So you anyway need a loop with some sane sleeps (here it's 500-1000 usec
and it usually takes 2-3 iterations).

> 
>> +
>> +idpf_tx_update_complq_indexes(complq, ntc, gen_flag);
>> +}

Thanks,
Olek


[Intel-wired-lan] [PATCH v9 iwl-next 04/10] idpf: negotiate PTP capabilities and get PTP clock

2025-03-13 Thread Milena Olech
PTP capabilities are negotiated using virtchnl command. Add get
capabilities function, direct access to read the PTP clock time and
direct access to read the cross timestamp - system time and PTP clock
time. Set initial PTP capabilities exposed to the stack.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Willem de Bruijn 
Tested-by: Willem de Bruijn 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
v1 -> v2: change the size of access fields in ptp struct,
remove CONFIG_PCIE_PTM dependency

 drivers/net/ethernet/intel/idpf/Makefile  |   2 +
 drivers/net/ethernet/intel/idpf/idpf.h|   2 +
 drivers/net/ethernet/intel/idpf/idpf_dev.c|  14 +
 .../ethernet/intel/idpf/idpf_lan_pf_regs.h|   4 +
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 263 ++
 drivers/net/ethernet/intel/idpf/idpf_ptp.h|  89 ++
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   |  95 +++
 7 files changed, 469 insertions(+)
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c

diff --git a/drivers/net/ethernet/intel/idpf/Makefile 
b/drivers/net/ethernet/intel/idpf/Makefile
index 1f38a9d7125c..83ac5e296382 100644
--- a/drivers/net/ethernet/intel/idpf/Makefile
+++ b/drivers/net/ethernet/intel/idpf/Makefile
@@ -17,4 +17,6 @@ idpf-y := \
idpf_vf_dev.o
 
 idpf-$(CONFIG_IDPF_SINGLEQ)+= idpf_singleq_txrx.o
+
 idpf-$(CONFIG_PTP_1588_CLOCK)  += idpf_ptp.o
+idpf-$(CONFIG_PTP_1588_CLOCK)  += idpf_virtchnl_ptp.o
diff --git a/drivers/net/ethernet/intel/idpf/idpf.h 
b/drivers/net/ethernet/intel/idpf/idpf.h
index 2e8b14dd9d96..d5d5064d313b 100644
--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -189,6 +189,7 @@ struct idpf_vport_max_q {
  * @mb_intr_reg_init: Mailbox interrupt register initialization
  * @reset_reg_init: Reset register initialization
  * @trigger_reset: Trigger a reset to occur
+ * @ptp_reg_init: PTP register initialization
  */
 struct idpf_reg_ops {
void (*ctlq_reg_init)(struct idpf_ctlq_create_info *cq);
@@ -197,6 +198,7 @@ struct idpf_reg_ops {
void (*reset_reg_init)(struct idpf_adapter *adapter);
void (*trigger_reset)(struct idpf_adapter *adapter,
  enum idpf_flags trig_cause);
+   void (*ptp_reg_init)(const struct idpf_adapter *adapter);
 };
 
 /**
diff --git a/drivers/net/ethernet/intel/idpf/idpf_dev.c 
b/drivers/net/ethernet/intel/idpf/idpf_dev.c
index 41e4bd49402a..3fae81f1f988 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_dev.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_dev.c
@@ -4,6 +4,7 @@
 #include "idpf.h"
 #include "idpf_lan_pf_regs.h"
 #include "idpf_virtchnl.h"
+#include "idpf_ptp.h"
 
 #define IDPF_PF_ITR_IDX_SPACING0x4
 
@@ -148,6 +149,18 @@ static void idpf_trigger_reset(struct idpf_adapter 
*adapter,
   idpf_get_reg_addr(adapter, PFGEN_CTRL));
 }
 
+/**
+ * idpf_ptp_reg_init - Initialize required registers
+ * @adapter: Driver specific private structure
+ *
+ * Set the bits required for enabling shtime and cmd execution
+ */
+static void idpf_ptp_reg_init(const struct idpf_adapter *adapter)
+{
+   adapter->ptp->cmd.shtime_enable_mask = PF_GLTSYN_CMD_SYNC_SHTIME_EN_M;
+   adapter->ptp->cmd.exec_cmd_mask = PF_GLTSYN_CMD_SYNC_EXEC_CMD_M;
+}
+
 /**
  * idpf_reg_ops_init - Initialize register API function pointers
  * @adapter: Driver specific private structure
@@ -159,6 +172,7 @@ static void idpf_reg_ops_init(struct idpf_adapter *adapter)
adapter->dev_ops.reg_ops.mb_intr_reg_init = idpf_mb_intr_reg_init;
adapter->dev_ops.reg_ops.reset_reg_init = idpf_reset_reg_init;
adapter->dev_ops.reg_ops.trigger_reset = idpf_trigger_reset;
+   adapter->dev_ops.reg_ops.ptp_reg_init = idpf_ptp_reg_init;
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/idpf/idpf_lan_pf_regs.h 
b/drivers/net/ethernet/intel/idpf/idpf_lan_pf_regs.h
index 24edb8a6ec2e..cc9aa2b6a14a 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_lan_pf_regs.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_lan_pf_regs.h
@@ -53,6 +53,10 @@
 #define PF_FW_ATQH_ATQH_M  GENMASK(9, 0)
 #define PF_FW_ATQT (PF_FW_BASE + 0x24)
 
+/* Timesync registers */
+#define PF_GLTSYN_CMD_SYNC_EXEC_CMD_M  GENMASK(1, 0)
+#define PF_GLTSYN_CMD_SYNC_SHTIME_EN_M BIT(2)
+
 /* Interrupts */
 #define PF_GLINT_BASE  0x0890
 #define PF_GLINT_DYN_CTL(_INT) (PF_GLINT_BASE + ((_INT) * 0x1000))
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index 1ac6367f5989..12caeaf4c1a1 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -4,6 +4,258 @@
 #include "idpf.h"
 #include "idpf_ptp.h"
 
+/**
+ * idpf_ptp_get_access - Determine the access type of the PTP features
+ * @adapter: Driver specific private structure
+ * @direct: Capability that indicates the direct access
+ * @mailbox: Capability that indicates

[Intel-wired-lan] [PATCH v9 iwl-next 03/10] idpf: move virtchnl structures to the header file

2025-03-13 Thread Milena Olech
Move virtchnl structures to the header file to expose them for the PTP
virtchnl file.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Willem de Bruijn 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
v1 -> v2: fix commit message title

 .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 86 +--
 .../net/ethernet/intel/idpf/idpf_virtchnl.h   | 84 ++
 2 files changed, 86 insertions(+), 84 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c 
b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 7004289b974c..a55ff20895ed 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -7,88 +7,6 @@
 #include "idpf_virtchnl.h"
 #include "idpf_ptp.h"
 
-#define IDPF_VC_XN_MIN_TIMEOUT_MSEC2000
-#define IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC(60 * 1000)
-#define IDPF_VC_XN_IDX_M   GENMASK(7, 0)
-#define IDPF_VC_XN_SALT_M  GENMASK(15, 8)
-#define IDPF_VC_XN_RING_LENU8_MAX
-
-/**
- * enum idpf_vc_xn_state - Virtchnl transaction status
- * @IDPF_VC_XN_IDLE: not expecting a reply, ready to be used
- * @IDPF_VC_XN_WAITING: expecting a reply, not yet received
- * @IDPF_VC_XN_COMPLETED_SUCCESS: a reply was expected and received,
- *   buffer updated
- * @IDPF_VC_XN_COMPLETED_FAILED: a reply was expected and received, but there
- *  was an error, buffer not updated
- * @IDPF_VC_XN_SHUTDOWN: transaction object cannot be used, VC torn down
- * @IDPF_VC_XN_ASYNC: transaction sent asynchronously and doesn't have the
- *   return context; a callback may be provided to handle
- *   return
- */
-enum idpf_vc_xn_state {
-   IDPF_VC_XN_IDLE = 1,
-   IDPF_VC_XN_WAITING,
-   IDPF_VC_XN_COMPLETED_SUCCESS,
-   IDPF_VC_XN_COMPLETED_FAILED,
-   IDPF_VC_XN_SHUTDOWN,
-   IDPF_VC_XN_ASYNC,
-};
-
-struct idpf_vc_xn;
-/* Callback for asynchronous messages */
-typedef int (*async_vc_cb) (struct idpf_adapter *, struct idpf_vc_xn *,
-   const struct idpf_ctlq_msg *);
-
-/**
- * struct idpf_vc_xn - Data structure representing virtchnl transactions
- * @completed: virtchnl event loop uses that to signal when a reply is
- *available, uses kernel completion API
- * @state: virtchnl event loop stores the data below, protected by the
- *completion's lock.
- * @reply_sz: Original size of reply, may be > reply_buf.iov_len; it will be
- *   truncated on its way to the receiver thread according to
- *   reply_buf.iov_len.
- * @reply: Reference to the buffer(s) where the reply data should be written
- *to. May be 0-length (then NULL address permitted) if the reply data
- *should be ignored.
- * @async_handler: if sent asynchronously, a callback can be provided to handle
- *the reply when it's received
- * @vc_op: corresponding opcode sent with this transaction
- * @idx: index used as retrieval on reply receive, used for cookie
- * @salt: changed every message to make unique, used for cookie
- */
-struct idpf_vc_xn {
-   struct completion completed;
-   enum idpf_vc_xn_state state;
-   size_t reply_sz;
-   struct kvec reply;
-   async_vc_cb async_handler;
-   u32 vc_op;
-   u8 idx;
-   u8 salt;
-};
-
-/**
- * struct idpf_vc_xn_params - Parameters for executing transaction
- * @send_buf: kvec for send buffer
- * @recv_buf: kvec for recv buffer, may be NULL, must then have zero length
- * @timeout_ms: timeout to wait for reply
- * @async: send message asynchronously, will not wait on completion
- * @async_handler: If sent asynchronously, optional callback handler. The user
- *must be careful when using async handlers as the memory for
- *the recv_buf _cannot_ be on stack if this is async.
- * @vc_op: virtchnl op to send
- */
-struct idpf_vc_xn_params {
-   struct kvec send_buf;
-   struct kvec recv_buf;
-   int timeout_ms;
-   bool async;
-   async_vc_cb async_handler;
-   u32 vc_op;
-};
-
 /**
  * struct idpf_vc_xn_manager - Manager for tracking transactions
  * @ring: backing and lookup for transactions
@@ -450,8 +368,8 @@ static void idpf_vc_xn_push_free(struct idpf_vc_xn_manager 
*vcxn_mngr,
  * >= @recv_buf.iov_len, but we never overflow @@recv_buf_iov_base). < 0 for
  * error.
  */
-static ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
-  const struct idpf_vc_xn_params *params)
+ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
+   const struct idpf_vc_xn_params *params)
 {
const struct kvec *send_buf = ¶ms->send_buf;
struct idpf_vc_xn *xn;
diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h 
b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
index 83da5d8da56b..3522c1238ea2 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl

[Intel-wired-lan] [PATCH v9 iwl-next 02/10] virtchnl: add PTP virtchnl definitions

2025-03-13 Thread Milena Olech
PTP capabilities are negotiated using virtchnl commands. There are two
available modes of the PTP support: direct and mailbox. When the direct
access to PTP resources is negotiated, virtchnl messages returns a set
of registers that allow read/write directly. When the mailbox access to
PTP resources is negotiated, virtchnl messages are used to access
PTP clock and to read the timestamp values.

Virtchnl API covers both modes and exposes a set of PTP capabilities.

Using virtchnl API, the driver recognizes also HW abilities - maximum
adjustment of the clock and the basic increment value.

Additionally, API allows to configure the secondary mailbox, dedicated
exclusively for PTP purposes.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Willem de Bruijn 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
v1 -> v2: fix struct description

 drivers/net/ethernet/intel/idpf/virtchnl2.h | 302 
 1 file changed, 302 insertions(+)

diff --git a/drivers/net/ethernet/intel/idpf/virtchnl2.h 
b/drivers/net/ethernet/intel/idpf/virtchnl2.h
index 63deb120359c..44a5ee84ed60 100644
--- a/drivers/net/ethernet/intel/idpf/virtchnl2.h
+++ b/drivers/net/ethernet/intel/idpf/virtchnl2.h
@@ -68,6 +68,16 @@ enum virtchnl2_op {
VIRTCHNL2_OP_ADD_MAC_ADDR   = 535,
VIRTCHNL2_OP_DEL_MAC_ADDR   = 536,
VIRTCHNL2_OP_CONFIG_PROMISCUOUS_MODE= 537,
+
+   /* TimeSync opcodes */
+   VIRTCHNL2_OP_PTP_GET_CAPS   = 541,
+   VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP= 542,
+   VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME   = 543,
+   VIRTCHNL2_OP_PTP_GET_CROSS_TIME = 544,
+   VIRTCHNL2_OP_PTP_SET_DEV_CLK_TIME   = 545,
+   VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_FINE   = 546,
+   VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_TIME   = 547,
+   VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP_CAPS   = 548,
 };
 
 /**
@@ -1270,4 +1280,296 @@ struct virtchnl2_promisc_info {
 };
 VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_promisc_info);
 
+/**
+ * enum virtchnl2_ptp_caps - PTP capabilities
+ * @VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME: direct access to get the time of
+ *device clock
+ * @VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME_MB: mailbox access to get the time of
+ *   device clock
+ * @VIRTCHNL2_CAP_PTP_GET_CROSS_TIME: direct access to cross timestamp
+ * @VIRTCHNL2_CAP_PTP_GET_CROSS_TIME_MB: mailbox access to cross timestamp
+ * @VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME: direct access to set the time of
+ *device clock
+ * @VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB: mailbox access to set the time of
+ *   device clock
+ * @VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK: direct access to adjust the time of 
device
+ *   clock
+ * @VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK_MB: mailbox access to adjust the time of
+ *  device clock
+ * @VIRTCHNL2_CAP_PTP_TX_TSTAMPS: direct access to the Tx timestamping
+ * @VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB: mailbox access to the Tx timestamping
+ *
+ * PF/VF negotiates a set of supported PTP capabilities with the Control Plane.
+ * There are two access methods - mailbox (_MB) and direct.
+ * PTP capabilities enables Main Timer operations: get/set/adjust Main Timer,
+ * cross timestamping and the Tx timestamping.
+ */
+enum virtchnl2_ptp_caps {
+   VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME   = BIT(0),
+   VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME_MB= BIT(1),
+   VIRTCHNL2_CAP_PTP_GET_CROSS_TIME= BIT(2),
+   VIRTCHNL2_CAP_PTP_GET_CROSS_TIME_MB = BIT(3),
+   VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME   = BIT(4),
+   VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB= BIT(5),
+   VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK= BIT(6),
+   VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK_MB = BIT(7),
+   VIRTCHNL2_CAP_PTP_TX_TSTAMPS= BIT(8),
+   VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB = BIT(9),
+};
+
+/**
+ * struct virtchnl2_ptp_clk_reg_offsets - Offsets of device and PHY clocks
+ *   registers.
+ * @dev_clk_ns_l: Device clock low register offset
+ * @dev_clk_ns_h: Device clock high register offset
+ * @phy_clk_ns_l: PHY clock low register offset
+ * @phy_clk_ns_h: PHY clock high register offset
+ * @cmd_sync_trigger: The command sync trigger register offset
+ * @pad: Padding for future extensions
+ */
+struct virtchnl2_ptp_clk_reg_offsets {
+   __le32 dev_clk_ns_l;
+   __le32 dev_clk_ns_h;
+   __le32 phy_clk_ns_l;
+   __le32 phy_clk_ns_h;
+   __le32 cmd_sync_trigger;
+   u8 pad[4];
+};
+VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_ptp_clk_reg_offsets);
+
+/**
+ * struct virtchnl2_ptp_cross_time_reg_offsets - Offsets of the device

[Intel-wired-lan] [PATCH v9 iwl-next 00/10] idpf: add initial PTP support

2025-03-13 Thread Milena Olech
This patch series introduces support for Precision Time Protocol (PTP) to
Intel(R) Infrastructure Data Path Function (IDPF) driver. PTP feature is
supported when the PTP capability is negotiated with the Control
Plane (CP). IDPF creates a PTP clock and sets a set of supported
functions.

During the PTP initialization, IDPF requests a set of PTP capabilities
and receives a writeback from the CP with the set of supported options.
These options are:
- get time of the PTP clock
- get cross timestamp
- set the time of the PTP clock
- adjust the PTP clock
- Tx timestamping

Each feature is considered to have direct access, where the operations
on PCIe BAR registers are allowed, or the mailbox access, where the
virtchnl messages are used to perform any PTP action. Mailbox access
means that PTP requests are sent to the CP through dedicated secondary
mailbox and the CP reads/writes/modifies desired resource - PTP Clock
or Tx timestamp registers.

Tx timestamp capabilities are negotiated only for vports that have
UPLINK_VPORT flag set by the CP. Capabilities provide information about
the number of available Tx timestamp latches, their indexes and size of
the Tx timestamp value. IDPF requests Tx timestamp by setting the
TSYN bit and the requested timestamp index in the context descriptor for
the PTP packets. When the completion tag for that packet is received,
IDPF schedules a worker to read the Tx timestamp value.

v8 -> v9: fix Rx filters upscaling, check if the link is up in
idpf_hwtstamp_get/set, fix typo
v7 -> v8: split Tx and Rx timestamping enablement, refactor
idpf_for_each_vport
v6 -> v7: remove section about Tx timestamp limitation from cover letter
since it has been fixed, change preparing flow descriptor method
v5 -> v6: change locking mechanism in get_ts_info, clean timestamp
fields when preparing flow descriptor, add Rx filter
v4 -> v5: fix spin unlock when Tx timestamp index is requested
v3 -> v4: change timestamp filters dependent on Tx timestamp cap,
rewrite function that extends Tx timestamp value, minor fixes
v2 -> v3: fix minor issues, revert idpf_for_each_vport changes,
extend idpf_ptp_set_rx_tstamp, split tstamp statistics
v1 -> v2: add stats for timestamping, use ndo_hwtamp_get/set,
fix minor spelling issues

Milena Olech (10):
  idpf: add initial PTP support
  virtchnl: add PTP virtchnl definitions
  idpf: move virtchnl structures to the header file
  idpf: negotiate PTP capabilities and get PTP clock
  idpf: add mailbox access to read PTP clock time
  idpf: add PTP clock configuration
  idpf: add Tx timestamp capabilities negotiation
  idpf: add Tx timestamp flows
  idpf: add support for Rx timestamping
  idpf: change the method for mailbox workqueue allocation

 drivers/net/ethernet/intel/idpf/Kconfig   |   1 +
 drivers/net/ethernet/intel/idpf/Makefile  |   3 +
 drivers/net/ethernet/intel/idpf/idpf.h|  35 +
 .../ethernet/intel/idpf/idpf_controlq_api.h   |   3 +
 drivers/net/ethernet/intel/idpf/idpf_dev.c|  14 +
 .../net/ethernet/intel/idpf/idpf_ethtool.c|  75 +-
 .../ethernet/intel/idpf/idpf_lan_pf_regs.h|   4 +
 .../net/ethernet/intel/idpf/idpf_lan_txrx.h   |  13 +-
 drivers/net/ethernet/intel/idpf/idpf_lib.c|  57 +
 drivers/net/ethernet/intel/idpf/idpf_main.c   |   9 +-
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 996 ++
 drivers/net/ethernet/intel/idpf/idpf_ptp.h| 370 +++
 drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 171 ++-
 drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  18 +-
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 160 ++-
 .../net/ethernet/intel/idpf/idpf_virtchnl.h   |  84 ++
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   | 677 
 drivers/net/ethernet/intel/idpf/virtchnl2.h   | 314 +-
 18 files changed, 2901 insertions(+), 103 deletions(-)
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_ptp.c
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_ptp.h
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c

-- 
2.31.1



[Intel-wired-lan] [PATCH v9 iwl-next 01/10] idpf: add initial PTP support

2025-03-13 Thread Milena Olech
PTP feature is supported if the VIRTCHNL2_CAP_PTP is negotiated during the
capabilities recognition. Initial PTP support includes PTP initialization
and registration of the clock.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Vadim Fedorenko 
Reviewed-by: Willem de Bruijn 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
 drivers/net/ethernet/intel/idpf/Kconfig   |  1 +
 drivers/net/ethernet/intel/idpf/Makefile  |  1 +
 drivers/net/ethernet/intel/idpf/idpf.h|  3 +
 drivers/net/ethernet/intel/idpf/idpf_main.c   |  4 +
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 89 +++
 drivers/net/ethernet/intel/idpf/idpf_ptp.h| 32 +++
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   |  9 +-
 7 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_ptp.c
 create mode 100644 drivers/net/ethernet/intel/idpf/idpf_ptp.h

diff --git a/drivers/net/ethernet/intel/idpf/Kconfig 
b/drivers/net/ethernet/intel/idpf/Kconfig
index 1addd663acad..2c359a8551c7 100644
--- a/drivers/net/ethernet/intel/idpf/Kconfig
+++ b/drivers/net/ethernet/intel/idpf/Kconfig
@@ -4,6 +4,7 @@
 config IDPF
tristate "Intel(R) Infrastructure Data Path Function Support"
depends on PCI_MSI
+   depends on PTP_1588_CLOCK_OPTIONAL
select DIMLIB
select LIBETH
help
diff --git a/drivers/net/ethernet/intel/idpf/Makefile 
b/drivers/net/ethernet/intel/idpf/Makefile
index 2ce01a0b5898..1f38a9d7125c 100644
--- a/drivers/net/ethernet/intel/idpf/Makefile
+++ b/drivers/net/ethernet/intel/idpf/Makefile
@@ -17,3 +17,4 @@ idpf-y := \
idpf_vf_dev.o
 
 idpf-$(CONFIG_IDPF_SINGLEQ)+= idpf_singleq_txrx.o
+idpf-$(CONFIG_PTP_1588_CLOCK)  += idpf_ptp.o
diff --git a/drivers/net/ethernet/intel/idpf/idpf.h 
b/drivers/net/ethernet/intel/idpf/idpf.h
index 66544faab710..2e8b14dd9d96 100644
--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -530,6 +530,7 @@ struct idpf_vc_xn_manager;
  * @vector_lock: Lock to protect vector distribution
  * @queue_lock: Lock to protect queue distribution
  * @vc_buf_lock: Lock to protect virtchnl buffer
+ * @ptp: Storage for PTP-related data
  */
 struct idpf_adapter {
struct pci_dev *pdev;
@@ -587,6 +588,8 @@ struct idpf_adapter {
struct mutex vector_lock;
struct mutex queue_lock;
struct mutex vc_buf_lock;
+
+   struct idpf_ptp *ptp;
 };
 
 /**
diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c 
b/drivers/net/ethernet/intel/idpf/idpf_main.c
index b6c515d14cbf..60bae3081035 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -163,6 +163,10 @@ static int idpf_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_free;
}
 
+   err = pci_enable_ptm(pdev, NULL);
+   if (err)
+   pci_dbg(pdev, "PCIe PTM is not supported by PCIe 
bus/controller\n");
+
/* set up for high or low dma */
err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (err) {
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
new file mode 100644
index ..1ac6367f5989
--- /dev/null
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2024 Intel Corporation */
+
+#include "idpf.h"
+#include "idpf_ptp.h"
+
+/**
+ * idpf_ptp_create_clock - Create PTP clock device for userspace
+ * @adapter: Driver specific private structure
+ *
+ * This function creates a new PTP clock device.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int idpf_ptp_create_clock(const struct idpf_adapter *adapter)
+{
+   struct ptp_clock *clock;
+
+   /* Attempt to register the clock before enabling the hardware. */
+   clock = ptp_clock_register(&adapter->ptp->info,
+  &adapter->pdev->dev);
+   if (IS_ERR(clock)) {
+   pci_err(adapter->pdev, "PTP clock creation failed: %pe\n", 
clock);
+   return PTR_ERR(clock);
+   }
+
+   adapter->ptp->clock = clock;
+
+   return 0;
+}
+
+/**
+ * idpf_ptp_init - Initialize PTP hardware clock support
+ * @adapter: Driver specific private structure
+ *
+ * Set up the device for interacting with the PTP hardware clock for all
+ * functions. Function will allocate and register a ptp_clock with the
+ * PTP_1588_CLOCK infrastructure.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int idpf_ptp_init(struct idpf_adapter *adapter)
+{
+   int err;
+
+   if (!idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_PTP)) {
+   pci_dbg(adapter->pdev, "PTP capability is not detected\n");
+   return -EOPNOTSUPP;
+   }
+
+   adapter->ptp = kzalloc(sizeof(*adapter->ptp), GFP_KERNEL);
+   if (!adapter->ptp)
+   return -ENOMEM;
+
+   /* add

[Intel-wired-lan] [PATCH v9 iwl-next 05/10] idpf: add mailbox access to read PTP clock time

2025-03-13 Thread Milena Olech
When the access to read PTP clock is specified as mailbox, the driver
needs to send virtchnl message to perform PTP actions. Message is sent
using idpf_mbq_opc_send_msg_to_peer_drv mailbox opcode, with the parameters
received during PTP capabilities negotiation.

Add functions to recognize PTP messages, move them to dedicated secondary
mailbox, read the PTP clock time and cross timestamp using mailbox
messages.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Willem de Bruijn 
Signed-off-by: Milena Olech 
---
 .../ethernet/intel/idpf/idpf_controlq_api.h   |  3 +
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 66 +++
 drivers/net/ethernet/intel/idpf/idpf_ptp.h| 43 ++
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 47 +++
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   | 83 +++
 5 files changed, 242 insertions(+)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_controlq_api.h 
b/drivers/net/ethernet/intel/idpf/idpf_controlq_api.h
index e8e046ef2f0d..9642494a67d8 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_controlq_api.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_controlq_api.h
@@ -123,9 +123,12 @@ struct idpf_ctlq_info {
 /**
  * enum idpf_mbx_opc - PF/VF mailbox commands
  * @idpf_mbq_opc_send_msg_to_cp: used by PF or VF to send a message to its CP
+ * @idpf_mbq_opc_send_msg_to_peer_drv: used by PF or VF to send a message to
+ *any peer driver
  */
 enum idpf_mbx_opc {
idpf_mbq_opc_send_msg_to_cp = 0x0801,
+   idpf_mbq_opc_send_msg_to_peer_drv   = 0x0804,
 };
 
 /* API supported for control queue management */
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index 12caeaf4c1a1..01e28085eb39 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -95,6 +95,37 @@ static u64 idpf_ptp_read_src_clk_reg_direct(struct 
idpf_adapter *adapter,
return ((u64)hi << 32) | lo;
 }
 
+/**
+ * idpf_ptp_read_src_clk_reg_mailbox - Read the main timer value through 
mailbox
+ * @adapter: Driver specific private structure
+ * @sts: Optional parameter for holding a pair of system timestamps from
+ *  the system clock. Will be ignored when NULL is given.
+ * @src_clk: Returned main timer value in nanoseconds unit
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int idpf_ptp_read_src_clk_reg_mailbox(struct idpf_adapter *adapter,
+struct ptp_system_timestamp *sts,
+u64 *src_clk)
+{
+   struct idpf_ptp_dev_timers clk_time;
+   int err;
+
+   /* Read the system timestamp pre PHC read */
+   ptp_read_system_prets(sts);
+
+   err = idpf_ptp_get_dev_clk_time(adapter, &clk_time);
+   if (err)
+   return err;
+
+   /* Read the system timestamp post PHC read */
+   ptp_read_system_postts(sts);
+
+   *src_clk = clk_time.dev_clk_time_ns;
+
+   return 0;
+}
+
 /**
  * idpf_ptp_read_src_clk_reg - Read the main timer value
  * @adapter: Driver specific private structure
@@ -110,6 +141,8 @@ static int idpf_ptp_read_src_clk_reg(struct idpf_adapter 
*adapter, u64 *src_clk,
switch (adapter->ptp->get_dev_clk_time_access) {
case IDPF_PTP_NONE:
return -EOPNOTSUPP;
+   case IDPF_PTP_MAILBOX:
+   return idpf_ptp_read_src_clk_reg_mailbox(adapter, sts, src_clk);
case IDPF_PTP_DIRECT:
*src_clk = idpf_ptp_read_src_clk_reg_direct(adapter, sts);
break;
@@ -146,6 +179,31 @@ static void idpf_ptp_get_sync_device_time_direct(struct 
idpf_adapter *adapter,
*sys_time = ((u64)sys_time_hi << 32) | sys_time_lo;
 }
 
+/**
+ * idpf_ptp_get_sync_device_time_mailbox - Get the cross time stamp values
+ *through mailbox
+ * @adapter: Driver specific private structure
+ * @dev_time: 64bit main timer value expressed in nanoseconds
+ * @sys_time: 64bit system time value expressed in nanoseconds
+ *
+ * Return: a pair of cross timestamp values on success, -errno otherwise.
+ */
+static int idpf_ptp_get_sync_device_time_mailbox(struct idpf_adapter *adapter,
+u64 *dev_time, u64 *sys_time)
+{
+   struct idpf_ptp_dev_timers cross_time;
+   int err;
+
+   err = idpf_ptp_get_cross_time(adapter, &cross_time);
+   if (err)
+   return err;
+
+   *dev_time = cross_time.dev_clk_time_ns;
+   *sys_time = cross_time.sys_time_ns;
+
+   return err;
+}
+
 /**
  * idpf_ptp_get_sync_device_time - Get the cross time stamp info
  * @device: Current device time
@@ -161,10 +219,18 @@ static int idpf_ptp_get_sync_device_time(ktime_t *device,
 {
struct idpf_adapter *adapter = ctx;
u64 ns_time_dev, ns_time_sys;
+   int err;
 
switch (adapter->ptp->get_cross_tstamp_access) {
  

[Intel-wired-lan] [PATCH v9 iwl-next 07/10] idpf: add Tx timestamp capabilities negotiation

2025-03-13 Thread Milena Olech
Tx timestamp capabilities are negotiated for the uplink Vport.
Driver receives information about the number of available Tx timestamp
latches, the size of Tx timestamp value and the set of indexes used
for Tx timestamping.

Add function to get the Tx timestamp capabilities and parse the uplink
vport flag.

Reviewed-by: Alexander Lobakin 
Co-developed-by: Emil Tantilov 
Signed-off-by: Emil Tantilov 
Co-developed-by: Pavan Kumar Linga 
Signed-off-by: Pavan Kumar Linga 
Signed-off-by: Milena Olech 
---
v7 -> v8: refactor idpf_for_each_vport, change a function that
checks if Tx timestamp for a given vport is enabled
v2 -> v3: revert changes in idpf_for_each_vport, fix minor issues
v1 -> v2: change the idpf_for_each_vport macro

 drivers/net/ethernet/intel/idpf/idpf.h|  10 ++
 drivers/net/ethernet/intel/idpf/idpf_ptp.c|  65 +
 drivers/net/ethernet/intel/idpf/idpf_ptp.h|  95 -
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   |  11 ++
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   | 128 +-
 drivers/net/ethernet/intel/idpf/virtchnl2.h   |  12 +-
 6 files changed, 317 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf.h 
b/drivers/net/ethernet/intel/idpf/idpf.h
index d5d5064d313b..fe4d8ad75b04 100644
--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -292,6 +292,7 @@ struct idpf_port_stats {
  * @port_stats: per port csum, header split, and other offload stats
  * @link_up: True if link is up
  * @sw_marker_wq: workqueue for marker packets
+ * @tx_tstamp_caps: Capabilities negotiated for Tx timestamping
  */
 struct idpf_vport {
u16 num_txq;
@@ -336,6 +337,8 @@ struct idpf_vport {
bool link_up;
 
wait_queue_head_t sw_marker_wq;
+
+   struct idpf_ptp_vport_tx_tstamp_caps *tx_tstamp_caps;
 };
 
 /**
@@ -480,6 +483,13 @@ struct idpf_vport_config {
 
 struct idpf_vc_xn_manager;
 
+#define idpf_for_each_vport(adapter, iter) \
+   for (struct idpf_vport **__##iter = &(adapter)->vports[0], \
+*iter = (adapter)->max_vports ? *__##iter : NULL; \
+iter; \
+iter = (++__##iter) < &(adapter)->vports[(adapter)->max_vports] ? \
+*__##iter : NULL)
+
 /**
  * struct idpf_adapter - Device data struct generated on probe
  * @pdev: PCI device struct given on probe
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index 54b7ccb16da0..d096a16bd262 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -62,6 +62,13 @@ void idpf_ptp_get_features_access(const struct idpf_adapter 
*adapter)
ptp->adj_dev_clk_time_access = idpf_ptp_get_access(adapter,
   direct,
   mailbox);
+
+   /* Tx timestamping */
+   direct = VIRTCHNL2_CAP_PTP_TX_TSTAMPS;
+   mailbox = VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB;
+   ptp->tx_tstamp_access = idpf_ptp_get_access(adapter,
+   direct,
+   mailbox);
 }
 
 /**
@@ -517,6 +524,61 @@ static int idpf_ptp_create_clock(const struct idpf_adapter 
*adapter)
return 0;
 }
 
+/**
+ * idpf_ptp_release_vport_tstamp - Release the Tx timestamps trakcers for a
+ *given vport.
+ * @vport: Virtual port structure
+ *
+ * Remove the queues and delete lists that tracks Tx timestamp entries for a
+ * given vport.
+ */
+static void idpf_ptp_release_vport_tstamp(struct idpf_vport *vport)
+{
+   struct idpf_ptp_tx_tstamp *ptp_tx_tstamp, *tmp;
+   struct list_head *head;
+
+   /* Remove list with free latches */
+   spin_lock(&vport->tx_tstamp_caps->lock_free);
+
+   head = &vport->tx_tstamp_caps->latches_free;
+   list_for_each_entry_safe(ptp_tx_tstamp, tmp, head, list_member) {
+   list_del(&ptp_tx_tstamp->list_member);
+   kfree(ptp_tx_tstamp);
+   }
+
+   spin_unlock(&vport->tx_tstamp_caps->lock_free);
+
+   /* Remove list with latches in use */
+   spin_lock(&vport->tx_tstamp_caps->lock_in_use);
+
+   head = &vport->tx_tstamp_caps->latches_in_use;
+   list_for_each_entry_safe(ptp_tx_tstamp, tmp, head, list_member) {
+   list_del(&ptp_tx_tstamp->list_member);
+   kfree(ptp_tx_tstamp);
+   }
+
+   spin_unlock(&vport->tx_tstamp_caps->lock_in_use);
+
+   kfree(vport->tx_tstamp_caps);
+   vport->tx_tstamp_caps = NULL;
+}
+
+/**
+ * idpf_ptp_release_tstamp - Release the Tx timestamps trackers
+ * @adapter: Driver specific private structure
+ *
+ * Remove the queues and delete lists that tracks Tx timestamp entries.
+ */
+static void idpf_ptp_release_tstamp(struct idpf_adapter *adapter)
+{
+   idpf_for_each_vport(adapter, vport) {
+   if (!idpf_ptp_is_vpo

[Intel-wired-lan] [PATCH v9 iwl-next 09/10] idpf: add support for Rx timestamping

2025-03-13 Thread Milena Olech
Add Rx timestamp function when the Rx timestamp value is read directly
from the Rx descriptor. In order to extend the Rx timestamp value to 64
bit in hot path, the PHC time is cached in the receive groups.
Add supported Rx timestamp modes.

Tested-by: YiFei Zhu 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
v8 -> v9: upscale Rx filters to HWTSTAMP_FILTER_ALL if Rx filter is
different than HWTSTAMP_FILTER_NONE
v7 -> v8: add a function to check if the Rx timestamp for a given vport
is enabled
v5 -> v6: add Rx filter
v2 -> v3: add disable Rx timestamp
v1 -> v2: extend commit message

 .../net/ethernet/intel/idpf/idpf_ethtool.c|  1 +
 drivers/net/ethernet/intel/idpf/idpf_lib.c|  6 +-
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 89 ++-
 drivers/net/ethernet/intel/idpf/idpf_ptp.h| 21 +
 drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 30 +++
 drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  7 +-
 6 files changed, 150 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c 
b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
index ec4183a609c4..7a4793749bc5 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
@@ -1333,6 +1333,7 @@ static void idpf_get_timestamp_filters(const struct 
idpf_vport *vport,
SOF_TIMESTAMPING_RAW_HARDWARE;
 
info->tx_types = BIT(HWTSTAMP_TX_OFF);
+   info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
 
if (!vport->tx_tstamp_caps ||
vport->adapter->ptp->tx_tstamp_access == IDPF_PTP_NONE)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c 
b/drivers/net/ethernet/intel/idpf/idpf_lib.c
index 26ea0d4eab0a..7e9a414dffa5 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
@@ -2374,7 +2374,8 @@ static int idpf_hwtstamp_set(struct net_device *netdev,
return -EPERM;
}
 
-   if (!idpf_ptp_is_vport_tx_tstamp_ena(vport)) {
+   if (!idpf_ptp_is_vport_tx_tstamp_ena(vport) &&
+   !idpf_ptp_is_vport_rx_tstamp_ena(vport)) {
idpf_vport_ctrl_unlock(netdev);
return -EOPNOTSUPP;
}
@@ -2399,7 +2400,8 @@ static int idpf_hwtstamp_get(struct net_device *netdev,
return -EPERM;
}
 
-   if (!idpf_ptp_is_vport_tx_tstamp_ena(vport)) {
+   if (!idpf_ptp_is_vport_tx_tstamp_ena(vport) &&
+   !idpf_ptp_is_vport_rx_tstamp_ena(vport)) {
idpf_vport_ctrl_unlock(netdev);
return 0;
}
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index ddccd409b864..4def3400a44c 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -317,12 +317,41 @@ static int idpf_ptp_gettimex64(struct ptp_clock_info 
*info,
return 0;
 }
 
+/**
+ * idpf_ptp_update_phctime_rxq_grp - Update the cached PHC time for a given Rx
+ *  queue group.
+ * @grp: receive queue group in which Rx timestamp is enabled
+ * @split: Indicates whether the queue model is split or single queue
+ * @systime: Cached system time
+ */
+static void
+idpf_ptp_update_phctime_rxq_grp(const struct idpf_rxq_group *grp, bool split,
+   u64 systime)
+{
+   struct idpf_rx_queue *rxq;
+   u16 i;
+
+   if (!split) {
+   for (i = 0; i < grp->singleq.num_rxq; i++) {
+   rxq = grp->singleq.rxqs[i];
+   if (rxq)
+   WRITE_ONCE(rxq->cached_phc_time, systime);
+   }
+   } else {
+   for (i = 0; i < grp->splitq.num_rxq_sets; i++) {
+   rxq = &grp->splitq.rxq_sets[i]->rxq;
+   if (rxq)
+   WRITE_ONCE(rxq->cached_phc_time, systime);
+   }
+   }
+}
+
 /**
  * idpf_ptp_update_cached_phctime - Update the cached PHC time values
  * @adapter: Driver specific private structure
  *
  * This function updates the system time values which are cached in the adapter
- * structure.
+ * structure and the Rx queues.
  *
  * This function must be called periodically to ensure that the cached value
  * is never more than 2 seconds old.
@@ -345,6 +374,21 @@ static int idpf_ptp_update_cached_phctime(struct 
idpf_adapter *adapter)
WRITE_ONCE(adapter->ptp->cached_phc_time, systime);
WRITE_ONCE(adapter->ptp->cached_phc_jiffies, jiffies);
 
+   idpf_for_each_vport(adapter, vport) {
+   bool split;
+
+   if (!vport || !vport->rxq_grps)
+   continue;
+
+   split = idpf_is_queue_model_split(vport->rxq_model);
+
+   for (u16 i = 0; i < vport->num_rxq_grp; i++) {
+   struct idpf_rxq_group *grp = &vport->rxq_grps[i

[Intel-wired-lan] [PATCH iwl-next v8 10/15] ixgbe: extend .info_get with() stored versions

2025-03-13 Thread Jedrzej Jagielski
Add functions reading inactive versions from the inactive flash
bank.

Print stored NVM, OROM and netlist versions by devlink when there
is an ongoing update for E610 device.

Reviewed-by: Mateusz Polchlopek 
Reviewed-by: Przemek Kitszel 
Tested-by: Bharath R 
Co-developed-by: Slawomir Mrozowicz 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Signed-off-by: Jedrzej Jagielski 
---
v3: use devlink_info_version_*_put() function; squash functions dealing with 
running and stored versions into single ones
v5: add else to if/else if statements
---
 .../ethernet/intel/ixgbe/devlink/devlink.c| 214 --
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c |  59 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_e610.h |   3 +
 3 files changed, 252 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index 8f44c3dee0b5..6b45846f0ddd 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -6,6 +6,15 @@
 
 struct ixgbe_info_ctx {
char buf[128];
+   struct ixgbe_orom_info pending_orom;
+   struct ixgbe_nvm_info pending_nvm;
+   struct ixgbe_netlist_info pending_netlist;
+   struct ixgbe_hw_dev_caps dev_caps;
+};
+
+enum ixgbe_devlink_version_type {
+   IXGBE_DL_VERSION_RUNNING,
+   IXGBE_DL_VERSION_STORED
 };
 
 static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
@@ -20,7 +29,8 @@ static void ixgbe_info_get_dsn(struct ixgbe_adapter *adapter,
 }
 
 static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter,
-   struct ixgbe_info_ctx *ctx)
+   struct ixgbe_info_ctx *ctx,
+   enum ixgbe_devlink_version_type type)
 {
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_nvm_version nvm_ver;
@@ -28,7 +38,14 @@ static void ixgbe_info_orom_ver(struct ixgbe_adapter 
*adapter,
ctx->buf[0] = '\0';
 
if (hw->mac.type == ixgbe_mac_e610) {
-   struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
+   struct ixgbe_orom_info *orom;
+
+   if (type == IXGBE_DL_VERSION_RUNNING)
+   orom = &adapter->hw.flash.orom;
+   else if (type == IXGBE_DL_VERSION_STORED)
+   orom = &ctx->pending_orom;
+   else
+   return;
 
snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
 orom->major, orom->build, orom->patch);
@@ -51,14 +68,23 @@ static void ixgbe_info_orom_ver(struct ixgbe_adapter 
*adapter,
 }
 
 static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
-  struct ixgbe_info_ctx *ctx)
+  struct ixgbe_info_ctx *ctx,
+  enum ixgbe_devlink_version_type type)
 {
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_nvm_version nvm_ver;
 
if (hw->mac.type == ixgbe_mac_e610) {
-   snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x",
-hw->flash.nvm.eetrack);
+   u32 eetrack;
+
+   if (type == IXGBE_DL_VERSION_RUNNING)
+   eetrack = hw->flash.nvm.eetrack;
+   else if (type == IXGBE_DL_VERSION_STORED)
+   eetrack = ctx->pending_nvm.eetrack;
+   else
+   return;
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", eetrack);
return;
}
 
@@ -92,33 +118,65 @@ static void ixgbe_info_fw_build(struct ixgbe_adapter 
*adapter,
 }
 
 static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter,
-  struct ixgbe_info_ctx *ctx)
+  struct ixgbe_info_ctx *ctx,
+  enum ixgbe_devlink_version_type type)
 {
-   struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
+   struct ixgbe_nvm_info *nvm;
+
+   if (type == IXGBE_DL_VERSION_RUNNING)
+   nvm = &adapter->hw.flash.nvm;
+   else if (type == IXGBE_DL_VERSION_STORED)
+   nvm = &ctx->pending_nvm;
+   else
+   return;
 
snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
 }
 
 static void ixgbe_info_orom_srev(struct ixgbe_adapter *adapter,
-struct ixgbe_info_ctx *ctx)
+struct ixgbe_info_ctx *ctx,
+enum ixgbe_devlink_version_type type)
 {
-   struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
+   struct ixgbe_orom_info *orom;
+
+   if (type == IXGBE_DL_VERSION_RUNNING)
+   orom = &adapter->hw.flash.orom;
+   else if (type == IXGBE_DL_VERSION_STORED)
+   orom = &ctx->pending_orom;
+   else
+   return;
 
sn

[Intel-wired-lan] [PATCH v9 iwl-next 08/10] idpf: add Tx timestamp flows

2025-03-13 Thread Milena Olech
Add functions to request Tx timestamp for the PTP packets, read the Tx
timestamp when the completion tag for that packet is being received,
extend the Tx timestamp value and set the supported timestamping modes.

Tx timestamp is requested for the PTP packets by setting a TSYN bit and
index value in the Tx context descriptor. The driver assumption is that
the Tx timestamp value is ready to be read when the completion tag is
received. Then the driver schedules delayed work and the Tx timestamp
value read is requested through virtchnl message. At the end, the Tx
timestamp value is extended to 64-bit and provided back to the skb.

Co-developed-by: Josh Hay 
Signed-off-by: Josh Hay 
Signed-off-by: Milena Olech 
---
v8 -> v9: update kernel_hwtstamp_config when timestamp mode is set,
check link status in timestamp callbacks idpf_hwtstamp_get/set
v7 -> v8: change the type of delta calculated when the timestamp is
extended to 64 bit based on the device clock value
v6 -> v7: change the method for preparing flow desciptor to set
tstamp fields to 0 indirectly
v5 -> v6: change locking mechanism in get_ts_info, clean timestamp
fields when preparing flow descriptor to prevent collisions with
PHY timestamping
v4 -> v5: fix the spin_unlock_bh when the Tx timestamp is requested
and the list of free latches is empty
v3 -> v4: change Tx timestamp filters based on the PTP capabilities,
use list_for_each_entry_safe when deleting list items, rewrite
function that extends Tx timestamp value to 64 bits, minor fixes
v2 -> v3: change get_timestamp_filter function name, split stats
into vport-based and tx queue-based
v1 -> v2: add timestamping stats, use ndo_hwtamp_get/ndo_hwstamp_set

 drivers/net/ethernet/intel/idpf/idpf.h|  20 ++
 .../net/ethernet/intel/idpf/idpf_ethtool.c|  74 +-
 .../net/ethernet/intel/idpf/idpf_lan_txrx.h   |  13 +-
 drivers/net/ethernet/intel/idpf/idpf_lib.c|  55 
 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 239 +-
 drivers/net/ethernet/intel/idpf/idpf_ptp.h|  51 
 drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 141 ++-
 drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  11 +-
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   |   6 +-
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   | 235 +
 10 files changed, 830 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf.h 
b/drivers/net/ethernet/intel/idpf/idpf.h
index fe4d8ad75b04..d7dbf7d9c7d3 100644
--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -246,9 +246,23 @@ struct idpf_port_stats {
u64_stats_t tx_busy;
u64_stats_t tx_drops;
u64_stats_t tx_dma_map_errs;
+   u64_stats_t tx_hwtstamp_skipped;
struct virtchnl2_vport_stats vport_stats;
 };
 
+/**
+ * struct idpf_tx_tstamp_stats - Tx timestamp statistics
+ * @tx_hwtstamp_lock: Lock to protect Tx tstamp stats
+ * @tx_hwtstamp_discarded: Number of Tx skbs discarded due to cached PHC time
+ *being too old to correctly extend timestamp
+ * @tx_hwtstamp_flushed: Number of Tx skbs flushed due to interface closed
+ */
+struct idpf_tx_tstamp_stats {
+   struct mutex tx_hwtstamp_lock;
+   u32 tx_hwtstamp_discarded;
+   u32 tx_hwtstamp_flushed;
+};
+
 /**
  * struct idpf_vport - Handle for netdevices and queue resources
  * @num_txq: Number of allocated TX queues
@@ -293,6 +307,9 @@ struct idpf_port_stats {
  * @link_up: True if link is up
  * @sw_marker_wq: workqueue for marker packets
  * @tx_tstamp_caps: Capabilities negotiated for Tx timestamping
+ * @tstamp_config: The Tx tstamp config
+ * @tstamp_task: Tx timestamping task
+ * @tstamp_stats: Tx timestamping statistics
  */
 struct idpf_vport {
u16 num_txq;
@@ -339,6 +356,9 @@ struct idpf_vport {
wait_queue_head_t sw_marker_wq;
 
struct idpf_ptp_vport_tx_tstamp_caps *tx_tstamp_caps;
+   struct kernel_hwtstamp_config tstamp_config;
+   struct work_struct tstamp_task;
+   struct idpf_tx_tstamp_stats tstamp_stats;
 };
 
 /**
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c 
b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
index 59b1a1a09996..ec4183a609c4 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
@@ -2,6 +2,7 @@
 /* Copyright (C) 2023 Intel Corporation */
 
 #include "idpf.h"
+#include "idpf_ptp.h"
 
 /**
  * idpf_get_rxnfc - command to get RX flow classification rules
@@ -479,6 +480,9 @@ static const struct idpf_stats idpf_gstrings_port_stats[] = 
{
IDPF_PORT_STAT("tx-unicast_pkts", port_stats.vport_stats.tx_unicast),
IDPF_PORT_STAT("tx-multicast_pkts", 
port_stats.vport_stats.tx_multicast),
IDPF_PORT_STAT("tx-broadcast_pkts", 
port_stats.vport_stats.tx_broadcast),
+   IDPF_PORT_STAT("tx-hwtstamp_skipped", port_stats.tx_hwtstamp_skipped),
+   IDPF_PORT_STAT("tx-hwtstamp_flushed", tstamp_stats.tx_hwtstamp_flushed

[Intel-wired-lan] [PATCH v9 iwl-next 10/10] idpf: change the method for mailbox workqueue allocation

2025-03-13 Thread Milena Olech
Since workqueues are created per CPU, the works scheduled to this
workqueues are run on the CPU they were assigned. It may result in
overloaded CPU that is not able to handle virtchnl messages in
relatively short time. Allocating workqueue with WQ_UNBOUND and
WQ_HIGHPRI flags allows scheduler to queue virtchl messages on less loaded
CPUs, what eliminates delays.

Reviewed-by: Alexander Lobakin 
Signed-off-by: Milena Olech 
---
 drivers/net/ethernet/intel/idpf/idpf_main.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c 
b/drivers/net/ethernet/intel/idpf/idpf_main.c
index 60bae3081035..022645f4fa9c 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -198,9 +198,8 @@ static int idpf_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto err_serv_wq_alloc;
}
 
-   adapter->mbx_wq = alloc_workqueue("%s-%s-mbx",
- WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
- dev_driver_string(dev),
+   adapter->mbx_wq = alloc_workqueue("%s-%s-mbx", WQ_UNBOUND | WQ_HIGHPRI,
+ 0, dev_driver_string(dev),
  dev_name(dev));
if (!adapter->mbx_wq) {
dev_err(dev, "Failed to allocate mailbox workqueue\n");
-- 
2.31.1



[Intel-wired-lan] [PATCH v9 iwl-next 06/10] idpf: add PTP clock configuration

2025-03-13 Thread Milena Olech
PTP clock configuration operations - set time, adjust time and adjust
frequency are required to control the clock and maintain synchronization
process.

Extend get PTP capabilities function to request for the clock adjustments
and add functions to enable these actions using dedicated virtchnl
messages.

Reviewed-by: Alexander Lobakin 
Reviewed-by: Willem de Bruijn 
Tested-by: Mina Almasry 
Signed-off-by: Milena Olech 
---
v8 -> v9: minor - remove unnecessary dot in the function description

 drivers/net/ethernet/intel/idpf/idpf_ptp.c| 191 ++
 drivers/net/ethernet/intel/idpf/idpf_ptp.h|  43 +++-
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   |   3 +
 .../ethernet/intel/idpf/idpf_virtchnl_ptp.c   | 142 -
 4 files changed, 376 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c 
b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
index 01e28085eb39..54b7ccb16da0 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
@@ -48,6 +48,20 @@ void idpf_ptp_get_features_access(const struct idpf_adapter 
*adapter)
ptp->get_cross_tstamp_access = idpf_ptp_get_access(adapter,
   direct,
   mailbox);
+
+   /* Set the device clock time */
+   direct = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
+   mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
+   ptp->set_dev_clk_time_access = idpf_ptp_get_access(adapter,
+  direct,
+  mailbox);
+
+   /* Adjust the device clock time */
+   direct = VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK;
+   mailbox = VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK_MB;
+   ptp->adj_dev_clk_time_access = idpf_ptp_get_access(adapter,
+  direct,
+  mailbox);
 }
 
 /**
@@ -296,6 +310,154 @@ static int idpf_ptp_gettimex64(struct ptp_clock_info 
*info,
return 0;
 }
 
+/**
+ * idpf_ptp_settime64 - Set the time of the clock
+ * @info: the driver's PTP info structure
+ * @ts: timespec64 structure that holds the new time value
+ *
+ * Set the device clock to the user input value. The conversion from timespec
+ * to ns happens in the write function.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int idpf_ptp_settime64(struct ptp_clock_info *info,
+ const struct timespec64 *ts)
+{
+   struct idpf_adapter *adapter = idpf_ptp_info_to_adapter(info);
+   enum idpf_ptp_access access;
+   int err;
+   u64 ns;
+
+   access = adapter->ptp->set_dev_clk_time_access;
+   if (access != IDPF_PTP_MAILBOX)
+   return -EOPNOTSUPP;
+
+   ns = timespec64_to_ns(ts);
+
+   err = idpf_ptp_set_dev_clk_time(adapter, ns);
+   if (err) {
+   pci_err(adapter->pdev, "Failed to set the time, err: %pe\n", 
ERR_PTR(err));
+   return err;
+   }
+
+   return 0;
+}
+
+/**
+ * idpf_ptp_adjtime_nonatomic - Do a non-atomic clock adjustment
+ * @info: the driver's PTP info structure
+ * @delta: Offset in nanoseconds to adjust the time by
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int idpf_ptp_adjtime_nonatomic(struct ptp_clock_info *info, s64 delta)
+{
+   struct timespec64 now, then;
+   int err;
+
+   err = idpf_ptp_gettimex64(info, &now, NULL);
+   if (err)
+   return err;
+
+   then = ns_to_timespec64(delta);
+   now = timespec64_add(now, then);
+
+   return idpf_ptp_settime64(info, &now);
+}
+
+/**
+ * idpf_ptp_adjtime - Adjust the time of the clock by the indicated delta
+ * @info: the driver's PTP info structure
+ * @delta: Offset in nanoseconds to adjust the time by
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int idpf_ptp_adjtime(struct ptp_clock_info *info, s64 delta)
+{
+   struct idpf_adapter *adapter = idpf_ptp_info_to_adapter(info);
+   enum idpf_ptp_access access;
+   int err;
+
+   access = adapter->ptp->adj_dev_clk_time_access;
+   if (access != IDPF_PTP_MAILBOX)
+   return -EOPNOTSUPP;
+
+   /* Hardware only supports atomic adjustments using signed 32-bit
+* integers. For any adjustment outside this range, perform
+* a non-atomic get->adjust->set flow.
+*/
+   if (delta > S32_MAX || delta < S32_MIN)
+   return idpf_ptp_adjtime_nonatomic(info, delta);
+
+   err = idpf_ptp_adj_dev_clk_time(adapter, delta);
+   if (err) {
+   pci_err(adapter->pdev, "Failed to adjust the clock with delta 
%lld err: %pe\n", delta, ERR_PTR(err));
+   return err;
+   }
+
+   return 0;
+}
+
+/**
+ * idpf_ptp_adjfine - Adjust clock increment rate
+ * @info: the driver's PTP info structure
+

[Intel-wired-lan] [PATCH iwl-next v8 08/15] ixgbe: add .info_get extension specific for E610 devices

2025-03-13 Thread Jedrzej Jagielski
E610 devices give possibility to show more detailed info than the previous
boards.
Extend reporting NVM info with following pieces:
 fw.mgmt.api -> version number of the API
 fw.mgmt.build -> identifier of the source for the FW
 fw.psid.api -> version defining the format of the flash contents
 fw.netlist -> version of the netlist module
 fw.netlist.build -> first 4 bytes of the netlist hash

Reviewed-by: Mateusz Polchlopek 
Tested-by: Bharath R 
Co-developed-by: Slawomir Mrozowicz 
Signed-off-by: Slawomir Mrozowicz 
Co-developed-by: Piotr Kwapulinski 
Signed-off-by: Piotr Kwapulinski 
Signed-off-by: Jedrzej Jagielski 
---
 Documentation/networking/devlink/ixgbe.rst|  26 
 .../ethernet/intel/ixgbe/devlink/devlink.c| 132 +-
 2 files changed, 153 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/devlink/ixgbe.rst 
b/Documentation/networking/devlink/ixgbe.rst
index b63645de37e8..a41073a62776 100644
--- a/Documentation/networking/devlink/ixgbe.rst
+++ b/Documentation/networking/devlink/ixgbe.rst
@@ -38,3 +38,29 @@ The ``ixgbe`` driver reports the following versions
   - 0x8d0d
   - Unique identifier of the firmware image file that was loaded onto
 the device. Also referred to as the EETRACK identifier of the NVM.
+* - ``fw.mgmt.api``
+  - running
+  - 1.5.1
+  - 3-digit version number (major.minor.patch) of the API exported over
+the AdminQ by the management firmware. Used by the driver to
+identify what commands are supported. Historical versions of the
+kernel only displayed a 2-digit version number (major.minor).
+* - ``fw.mgmt.build``
+  - running
+  - 0x305d955f
+  - Unique identifier of the source for the management firmware.
+* - ``fw.psid.api``
+  - running
+  - 0.80
+  - Version defining the format of the flash contents.
+* - ``fw.netlist``
+  - running
+  - 1.1.2000-6.7.0
+  - The version of the netlist module. This module defines the device's
+Ethernet capabilities and default settings, and is used by the
+management firmware as part of managing link and device
+connectivity.
+* - ``fw.netlist.build``
+  - running
+  - 0xee16ced7
+  - The first 4 bytes of the hash of the netlist module contents.
diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c 
b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
index d91252da4a61..365310a6910d 100644
--- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
+++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
@@ -19,14 +19,22 @@ static void ixgbe_info_get_dsn(struct ixgbe_adapter 
*adapter,
snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
 }
 
-static void ixgbe_info_nvm_ver(struct ixgbe_adapter *adapter,
-  struct ixgbe_info_ctx *ctx)
+static void ixgbe_info_orom_ver(struct ixgbe_adapter *adapter,
+   struct ixgbe_info_ctx *ctx)
 {
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_nvm_version nvm_ver;
 
ctx->buf[0] = '\0';
 
+   if (hw->mac.type == ixgbe_mac_e610) {
+   struct ixgbe_orom_info *orom = &adapter->hw.flash.orom;
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
+orom->major, orom->build, orom->patch);
+   return;
+   }
+
ixgbe_get_oem_prod_version(hw, &nvm_ver);
if (nvm_ver.oem_valid) {
snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x",
@@ -48,6 +56,12 @@ static void ixgbe_info_eetrack(struct ixgbe_adapter *adapter,
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_nvm_version nvm_ver;
 
+   if (hw->mac.type == ixgbe_mac_e610) {
+   snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x",
+hw->flash.nvm.eetrack);
+   return;
+   }
+
ixgbe_get_oem_prod_version(hw, &nvm_ver);
 
/* No ETRACK version for OEM */
@@ -60,6 +74,112 @@ static void ixgbe_info_eetrack(struct ixgbe_adapter 
*adapter,
snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm_ver.etk_id);
 }
 
+static void ixgbe_info_fw_api(struct ixgbe_adapter *adapter,
+ struct ixgbe_info_ctx *ctx)
+{
+   struct ixgbe_hw *hw = &adapter->hw;
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
+hw->api_maj_ver, hw->api_min_ver, hw->api_patch);
+}
+
+static void ixgbe_info_fw_build(struct ixgbe_adapter *adapter,
+   struct ixgbe_info_ctx *ctx)
+{
+   struct ixgbe_hw *hw = &adapter->hw;
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);
+}
+
+static void ixgbe_info_fw_srev(struct ixgbe_adapter *adapter,
+  struct ixgbe_info_ctx *ctx)
+{
+   struct ixgbe_nvm_info *nvm = &adapter->hw.flash.nvm;
+
+   snprintf(ctx->buf, sizeof(ctx->buf), "%u", nvm->srev);
+}
+
+static void ixgbe_info_oro

[Intel-wired-lan] [PATCH net v2 3/5] net: lan743x: reject unsupported external timestamp requests

2025-03-13 Thread Jacob Keller
The lan743x_ptp_io_event_cap_en() function checks that the given request
sets only one of PTP_RISING_EDGE or PTP_FALLING_EDGE, but not both.

However, this driver does not check whether other flags (such as
PTP_EXT_OFF) are set, nor whether any future unrecognized flags are set.

Fix this by adding the appropriate check to the lan743x_ptp_io_extts()
function.

Fixes: 60942c397af6 ("net: lan743x: Add support for PTP-IO Event Input External 
Timestamp (extts)")
Signed-off-by: Jacob Keller 
---
 drivers/net/ethernet/microchip/lan743x_ptp.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c 
b/drivers/net/ethernet/microchip/lan743x_ptp.c
index 
4a777b449ecd03ac0d7576f8570f1a7794fb3d06..0be44dcb339387e9756f36f909f65c20870bc49b
 100644
--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
+++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
@@ -942,6 +942,12 @@ static int lan743x_ptp_io_extts(struct lan743x_adapter 
*adapter, int on,
 
extts = &ptp->extts[index];
 
+   if (extts_request->flags & ~(PTP_ENABLE_FEATURE |
+PTP_RISING_EDGE |
+PTP_FALLING_EDGE |
+PTP_STRICT_FLAGS))
+   return -EOPNOTSUPP;
+
if (on) {
extts_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, index);
if (extts_pin < 0)

-- 
2.48.1.397.gec9d649cc640



Re: [Intel-wired-lan] [iwl-next v4 1/1] iidc/ice/irdma: Update IDC to support multiple consumers

2025-03-13 Thread Samudrala, Sridhar




On 3/2/2025 12:26 AM, Leon Romanovsky wrote:

On Wed, Feb 26, 2025 at 11:01:52PM +, Ertman, David M wrote:




-Original Message-
From: Leon Romanovsky 
Sent: Wednesday, February 26, 2025 10:50 AM
To: Ertman, David M 
Cc: Nikolova, Tatyana E ; j...@nvidia.com;
intel-wired-...@lists.osuosl.org; linux-r...@vger.kernel.org;
net...@vger.kernel.org
Subject: Re: [iwl-next v4 1/1] iidc/ice/irdma: Update IDC to support multiple
consumers

On Wed, Feb 26, 2025 at 05:36:44PM +, Ertman, David M wrote:

-Original Message-
From: Leon Romanovsky 
Sent: Monday, February 24, 2025 11:56 PM
To: Nikolova, Tatyana E 
Cc: j...@nvidia.com; intel-wired-...@lists.osuosl.org; linux-
r...@vger.kernel.org; net...@vger.kernel.org; Ertman, David M

Subject: Re: [iwl-next v4 1/1] iidc/ice/irdma: Update IDC to support

multiple

consumers

On Mon, Feb 24, 2025 at 11:04:28PM -0600, Tatyana Nikolova wrote:

From: Dave Ertman 

To support RDMA for E2000 product, the idpf driver will use the IDC
interface with the irdma auxiliary driver, thus becoming a second
consumer of it. This requires the IDC be updated to support multiple
consumers. The use of exported symbols no longer makes sense

because it

will require all core drivers (ice/idpf) that can interface with irdma
auxiliary driver to be loaded even if hardware is not present for those
drivers.


In auxiliary bus world, the code drivers (ice/idpf) need to created
auxiliary devices only if specific device present. That auxiliary device
will trigger the load of specific module (irdma in our case).

EXPORT_SYMBOL won't trigger load of irdma driver, but the opposite is
true, load of irdma will trigger load of ice/idpf drivers (depends on
their exported symbol).



To address this, implement an ops struct that will be universal set of
naked function pointers that will be populated by each core driver for
the irdma auxiliary driver to call.


No, we worked very hard to make proper HW discovery and driver

autoload,

let's not return back. For now, it is no-go.


Hi Leon,

I am a little confused about what the problem here is.  The main issue I pull
from your response is: Removing exported symbols will stop ice/idpf from
autoloading when irdma loads.  Is this correct or did I miss your point?


It is one of the main points.



But, if there is an ice or idpf supported device present in the system, the
appropriate driver will have already been loaded anyway (and gone

through its

probe flow to create auxiliary devices).  If it is not loaded, then the system

owner

has either unloaded it manually or blacklisted it.  This would not cause an

issue

anyway, since irdma and ice/idpf can load in any order.


There are two assumptions above, which both not true.
1. Users never issue "modprobe irdma" command alone and always will call
to whole chain "modprobe ice ..." before.
2. You open-code module subsystem properly with reference counters,
ownership and locks to protect from function pointers to be set/clear
dynamically.


Ah, I see your reasoning now.  Our goal was to make the two modules independent,
with no prescribed load order mandated, and utilize the auxiliary bus and 
device subsystem
to handle load order and unload of one or the other module.  The auxiliary 
device only has
the lifespan of the core PCI driver, so if the core driver unloads, then the 
auxiliary device gets
destroyed, and the associated link based off it will be gone.  We wanted to be 
able to unload
and reload either of the modules (core or irdma) and have the interaction be 
able to restart with a
new probe.  All our inter-driver function calls are protected by device lock on 
the auxiliary
device for the duration of the call.


Yes, you are trying to return to pre-aux era.



The main motivation to go with callbacks to the parent driver instead of 
using exported symbols is to allow loading only the parent driver 
required for a particular deployment. irdma is a common rdma auxilary 
driver that supports multiple parent pci drivers(ice, idpf, i40e, iavf). 
If we use exported symbols, all these modules will get loaded even on a 
system with only idpf device.


The documentation for auxiliary bus
https://docs.kernel.org/driver-api/auxiliary_bus.html
shows an example on how shared data/callbacks can be used to establish 
connection with the parent.


Auxiliary devices are created and registered by a subsystem-level core 
device that needs to break up its functionality into smaller fragments. 
One way to extend the scope of an auxiliary_device is to encapsulate it 
within a domain-specific structure defined by the parent device. This 
structure contains the auxiliary_device and any associated shared 
data/callbacks needed to establish the connection with the parent.


An example is:

 struct foo {
  struct auxiliary_device auxdev;
  void (*connect)(struct auxiliary_device *auxdev);
  void (*disconnect)(struct auxiliary_device *auxdev);
  void *data;
};

This example clear

Re: [Intel-wired-lan] [PATCH iwl-next v7 11/15] ixgbe: add device flash update via devlink

2025-03-13 Thread Jagielski, Jedrzej
From: Simon Horman  
Sent: Wednesday, March 12, 2025 3:56 PM

>On Wed, Mar 12, 2025 at 01:58:39PM +0100, Jedrzej Jagielski wrote:
>
>...
>
>> diff --git a/Documentation/networking/devlink/ixgbe.rst 
>> b/Documentation/networking/devlink/ixgbe.rst
>> index a41073a62776..41aedf4b8017 100644
>> --- a/Documentation/networking/devlink/ixgbe.rst
>> +++ b/Documentation/networking/devlink/ixgbe.rst
>> @@ -64,3 +64,27 @@ The ``ixgbe`` driver reports the following versions
>>- running
>>- 0xee16ced7
>>- The first 4 bytes of the hash of the netlist module contents.
>> +
>> +Flash Update
>> +
>> +The ``ixgbe`` driver implements support for flash update using the
>> +``devlink-flash`` interface. It supports updating the device flash using a
>> +combined flash image that contains the ``fw.mgmt``, ``fw.undi``, and
>> +``fw.netlist`` components.
>> +.. list-table:: List of supported overwrite modes
>> +   :widths: 5 95
>
>Hi Jedrzej,
>
>make htmldocs flags two warnings, which I believe can be resolved by
>adding a blank line here.
>
>  .../ixgbe.rst:75: ERROR: Unexpected indentation.
>  .../ixgbe.rst:76: WARNING: Field list ends without a blank line; unexpected 
> unindent.

Hello Simon

thanks for finding these.

I will fix it and resend it later today probably.

>
>> +   * - Bits
>> + - Behavior
>> +   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
>> + - Do not preserve settings stored in the flash components being
>> +   updated. This includes overwriting the port configuration that
>> +   determines the number of physical functions the device will
>> +   initialize with.
>> +   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS`` and 
>> ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
>> + - Do not preserve either settings or identifiers. Overwrite everything
>> +   in the flash with the contents from the provided image, without
>> +   performing any preservation. This includes overwriting device
>> +   identifying fields such as the MAC address, Vital product Data (VPD) 
>> area,
>> +   and device serial number. It is expected that this combination be 
>> used with an
>> +   image customized for the specific device.
>> +
>
>...