-From c368fc75e177fb226dae0ced44095671614f89cb Mon Sep 17 00:00:00 2001
+From fc79acab6ab9cc70a3a2975ec5065406ce72c4d0 Mon Sep 17 00:00:00 2001
From: Sasha Levin <sashal@kernel.org>
Date: Thu, 25 Jul 2024 15:23:51 -0700
Subject: ethtool: fix setting key and resetting indir at once
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
-index d9c8a6a16cb2a..f3ae4c56279c1 100644
+index 223dcd25d88a2..fcc3dbef8b503 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
-@@ -1280,13 +1280,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
+@@ -1277,11 +1277,11 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
const struct ethtool_ops *ops = dev->ethtool_ops;
u32 dev_indir_size = 0, dev_key_size = 0, i;
+ u32 user_indir_len = 0, indir_bytes = 0;
struct ethtool_rxfh_param rxfh_dev = {};
- struct ethtool_rxfh_context *ctx = NULL;
struct netlink_ext_ack *extack = NULL;
struct ethtool_rxnfc rx_rings;
struct ethtool_rxfh rxfh;
- bool locked = false; /* dev->ethtool->rss_lock taken */
- u32 indir_bytes = 0;
- bool create = false;
u8 *rss_config;
int ret;
-@@ -1349,6 +1349,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
+
+@@ -1342,6 +1342,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
*/
if (rxfh.indir_size &&
rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE) {
rxfh_dev.indir = (u32 *)rss_config;
rxfh_dev.indir_size = dev_indir_size;
ret = ethtool_copy_validate_indir(rxfh_dev.indir,
-@@ -1375,7 +1376,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
+@@ -1368,7 +1369,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
rxfh_dev.key_size = dev_key_size;
rxfh_dev.key = rss_config + indir_bytes;
if (copy_from_user(rxfh_dev.key,
+++ /dev/null
-From e27bfbafce976f8887b83a0c835641cc58e8df38 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 27 Jun 2024 17:08:52 +0300
-Subject: ethtool: Veto some operations during firmware flashing process
-
-From: Danielle Ratson <danieller@nvidia.com>
-
-[ Upstream commit 31e0aa99dc02b2b038a270b0670fc8201b69ec8a ]
-
-Some operations cannot be performed during the firmware flashing
-process.
-
-For example:
-
-- Port must be down during the whole flashing process to avoid packet loss
- while committing reset for example.
-
-- Writing to EEPROM interrupts the flashing process, so operations like
- ethtool dump, module reset, get and set power mode should be vetoed.
-
-- Split port firmware flashing should be vetoed.
-
-In order to veto those scenarios, add a flag in 'struct net_device' that
-indicates when a firmware flash is taking place on the module and use it
-to prevent interruptions during the process.
-
-Signed-off-by: Danielle Ratson <danieller@nvidia.com>
-Reviewed-by: Petr Machata <petrm@nvidia.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Stable-dep-of: 7195f0ef7f5b ("ethtool: fix setting key and resetting indir at once")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netdevice.h | 4 +++-
- net/ethtool/eeprom.c | 6 ++++++
- net/ethtool/ioctl.c | 12 ++++++++++++
- net/ethtool/netlink.c | 12 ++++++++++++
- 4 files changed, 33 insertions(+), 1 deletion(-)
-
-diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index d20c6c99eb887..ccba9f145edaa 100644
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1989,6 +1989,8 @@ enum netdev_reg_state {
- *
- * @threaded: napi threaded mode is enabled
- *
-+ * @module_fw_flash_in_progress: Module firmware flashing is in progress.
-+ *
- * @net_notifier_list: List of per-net netdev notifier block
- * that follow this device when it is moved
- * to another network namespace.
-@@ -2373,7 +2375,7 @@ struct net_device {
- bool proto_down;
- bool threaded;
- unsigned wol_enabled:1;
--
-+ unsigned module_fw_flash_in_progress:1;
- struct list_head net_notifier_list;
-
- #if IS_ENABLED(CONFIG_MACSEC)
-diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
-index 6209c3a9c8f72..f36811b3ecf16 100644
---- a/net/ethtool/eeprom.c
-+++ b/net/ethtool/eeprom.c
-@@ -91,6 +91,12 @@ static int get_module_eeprom_by_page(struct net_device *dev,
- {
- const struct ethtool_ops *ops = dev->ethtool_ops;
-
-+ if (dev->module_fw_flash_in_progress) {
-+ NL_SET_ERR_MSG(extack,
-+ "Module firmware flashing is in progress");
-+ return -EBUSY;
-+ }
-+
- if (dev->sfp_bus)
- return sfp_get_module_eeprom_by_page(dev->sfp_bus, page_data, extack);
-
-diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
-index 223dcd25d88a2..3c8821adc4891 100644
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -658,6 +658,9 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
- if (!dev->ethtool_ops->get_link_ksettings)
- return -EOPNOTSUPP;
-
-+ if (dev->module_fw_flash_in_progress)
-+ return -EBUSY;
-+
- memset(&link_ksettings, 0, sizeof(link_ksettings));
- err = dev->ethtool_ops->get_link_ksettings(dev, &link_ksettings);
- if (err < 0)
-@@ -1450,6 +1453,9 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
- if (!dev->ethtool_ops->reset)
- return -EOPNOTSUPP;
-
-+ if (dev->module_fw_flash_in_progress)
-+ return -EBUSY;
-+
- if (copy_from_user(&reset, useraddr, sizeof(reset)))
- return -EFAULT;
-
-@@ -2463,6 +2469,9 @@ int ethtool_get_module_info_call(struct net_device *dev,
- const struct ethtool_ops *ops = dev->ethtool_ops;
- struct phy_device *phydev = dev->phydev;
-
-+ if (dev->module_fw_flash_in_progress)
-+ return -EBUSY;
-+
- if (dev->sfp_bus)
- return sfp_get_module_info(dev->sfp_bus, modinfo);
-
-@@ -2500,6 +2509,9 @@ int ethtool_get_module_eeprom_call(struct net_device *dev,
- const struct ethtool_ops *ops = dev->ethtool_ops;
- struct phy_device *phydev = dev->phydev;
-
-+ if (dev->module_fw_flash_in_progress)
-+ return -EBUSY;
-+
- if (dev->sfp_bus)
- return sfp_get_module_eeprom(dev->sfp_bus, ee, data);
-
-diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
-index bd04f28d5cf4b..5b42c736d7254 100644
---- a/net/ethtool/netlink.c
-+++ b/net/ethtool/netlink.c
-@@ -760,10 +760,22 @@ static void ethnl_notify_features(struct netdev_notifier_info *info)
- static int ethnl_netdev_event(struct notifier_block *this, unsigned long event,
- void *ptr)
- {
-+ struct netdev_notifier_info *info = ptr;
-+ struct netlink_ext_ack *extack;
-+ struct net_device *dev;
-+
-+ dev = netdev_notifier_info_to_dev(info);
-+ extack = netdev_notifier_info_to_extack(info);
-+
- switch (event) {
- case NETDEV_FEAT_CHANGE:
- ethnl_notify_features(ptr);
- break;
-+ case NETDEV_PRE_UP:
-+ if (dev->module_fw_flash_in_progress) {
-+ NL_SET_ERR_MSG(extack, "Can't set port up while flashing module firmware");
-+ return NOTIFY_BAD;
-+ }
- }
-
- return NOTIFY_DONE;
---
-2.43.0
-
+++ /dev/null
-From 01764eaa588997eb987eb407719bfc56bdf3907c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 27 Jun 2024 16:33:51 +0100
-Subject: net: ethtool: add a mutex protecting RSS contexts
-
-From: Edward Cree <ecree.xilinx@gmail.com>
-
-[ Upstream commit 87925151191b64d9623e63ccf11e517eacc99d7d ]
-
-While this is not needed to serialise the ethtool entry points (which
- are all under RTNL), drivers may have cause to asynchronously access
- dev->ethtool->rss_ctx; taking dev->ethtool->rss_lock allows them to
- do this safely without needing to take the RTNL.
-
-Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
-Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
-Link: https://patch.msgid.link/7f9c15eb7525bf87af62c275dde3a8570ee8bf0a.1719502240.git.ecree.xilinx@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: 7195f0ef7f5b ("ethtool: fix setting key and resetting indir at once")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/ethtool.h | 3 +++
- net/core/dev.c | 5 +++++
- net/ethtool/ioctl.c | 7 +++++++
- 3 files changed, 15 insertions(+)
-
-diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
-index 8fa2f8bd474b6..787dd63c3acb3 100644
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -1055,10 +1055,13 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
- /**
- * struct ethtool_netdev_state - per-netdevice state for ethtool features
- * @rss_ctx: XArray of custom RSS contexts
-+ * @rss_lock: Protects entries in @rss_ctx. May be taken from
-+ * within RTNL.
- * @wol_enabled: Wake-on-LAN is enabled
- */
- struct ethtool_netdev_state {
- struct xarray rss_ctx;
-+ struct mutex rss_lock;
- unsigned wol_enabled:1;
- };
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index b390b4cd9098f..8a9ab7b12c618 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -10287,6 +10287,7 @@ int register_netdevice(struct net_device *dev)
-
- /* rss ctx ID 0 is reserved for the default context, start from 1 */
- xa_init_flags(&dev->ethtool->rss_ctx, XA_FLAGS_ALLOC1);
-+ mutex_init(&dev->ethtool->rss_lock);
-
- spin_lock_init(&dev->addr_list_lock);
- netdev_set_addr_lockdep_class(dev);
-@@ -11142,6 +11143,7 @@ static void netdev_rss_contexts_free(struct net_device *dev)
- struct ethtool_rxfh_context *ctx;
- unsigned long context;
-
-+ mutex_lock(&dev->ethtool->rss_lock);
- xa_for_each(&dev->ethtool->rss_ctx, context, ctx) {
- struct ethtool_rxfh_param rxfh;
-
-@@ -11157,6 +11159,7 @@ static void netdev_rss_contexts_free(struct net_device *dev)
- kfree(ctx);
- }
- xa_destroy(&dev->ethtool->rss_ctx);
-+ mutex_unlock(&dev->ethtool->rss_lock);
- }
-
- /**
-@@ -11269,6 +11272,8 @@ void unregister_netdevice_many_notify(struct list_head *head,
- if (dev->netdev_ops->ndo_uninit)
- dev->netdev_ops->ndo_uninit(dev);
-
-+ mutex_destroy(&dev->ethtool->rss_lock);
-+
- if (skb)
- rtmsg_ifinfo_send(skb, dev, GFP_KERNEL, portid, nlh);
-
-diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
-index 1e87131f2caf4..d9c8a6a16cb2a 100644
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -1285,6 +1285,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- struct netlink_ext_ack *extack = NULL;
- struct ethtool_rxnfc rx_rings;
- struct ethtool_rxfh rxfh;
-+ bool locked = false; /* dev->ethtool->rss_lock taken */
- u32 indir_bytes = 0;
- bool create = false;
- u8 *rss_config;
-@@ -1381,6 +1382,10 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- }
- }
-
-+ if (rxfh.rss_context) {
-+ mutex_lock(&dev->ethtool->rss_lock);
-+ locked = true;
-+ }
- if (create) {
- if (rxfh_dev.rss_delete) {
- ret = -EINVAL;
-@@ -1471,6 +1476,8 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- }
-
- out:
-+ if (locked)
-+ mutex_unlock(&dev->ethtool->rss_lock);
- kfree(rss_config);
- return ret;
- }
---
-2.43.0
-
+++ /dev/null
-From 536a780f27abae5daf9d71e564a75679740290da Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 27 Jun 2024 16:33:47 +0100
-Subject: net: ethtool: attach an XArray of custom RSS contexts to a netdevice
-
-From: Edward Cree <ecree.xilinx@gmail.com>
-
-[ Upstream commit 6ad2962f8adfd53fca52dce7f830783e95d99ce7 ]
-
-Each context stores the RXFH settings (indir, key, and hfunc) as well
- as optionally some driver private data.
-Delete any still-existing contexts at netdev unregister time.
-
-Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
-Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
-Link: https://patch.msgid.link/cbd1c402cec38f2e03124f2ab65b4ae4e08bd90d.1719502240.git.ecree.xilinx@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: 7195f0ef7f5b ("ethtool: fix setting key and resetting indir at once")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/ethtool.h | 42 +++++++++++++++++++++++++++++++++++++++++
- net/core/dev.c | 27 ++++++++++++++++++++++++++
- 2 files changed, 69 insertions(+)
-
-diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
-index 8cd6b3c993f17..13c9c819de580 100644
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -159,6 +159,46 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
- return index % n_rx_rings;
- }
-
-+/**
-+ * struct ethtool_rxfh_context - a custom RSS context configuration
-+ * @indir_size: Number of u32 entries in indirection table
-+ * @key_size: Size of hash key, in bytes
-+ * @priv_size: Size of driver private data, in bytes
-+ * @hfunc: RSS hash function identifier. One of the %ETH_RSS_HASH_*
-+ * @input_xfrm: Defines how the input data is transformed. Valid values are one
-+ * of %RXH_XFRM_*.
-+ * @indir_configured: indir has been specified (at create time or subsequently)
-+ * @key_configured: hkey has been specified (at create time or subsequently)
-+ */
-+struct ethtool_rxfh_context {
-+ u32 indir_size;
-+ u32 key_size;
-+ u16 priv_size;
-+ u8 hfunc;
-+ u8 input_xfrm;
-+ u8 indir_configured:1;
-+ u8 key_configured:1;
-+ /* private: driver private data, indirection table, and hash key are
-+ * stored sequentially in @data area. Use below helpers to access.
-+ */
-+ u8 data[] __aligned(sizeof(void *));
-+};
-+
-+static inline void *ethtool_rxfh_context_priv(struct ethtool_rxfh_context *ctx)
-+{
-+ return ctx->data;
-+}
-+
-+static inline u32 *ethtool_rxfh_context_indir(struct ethtool_rxfh_context *ctx)
-+{
-+ return (u32 *)(ctx->data + ALIGN(ctx->priv_size, sizeof(u32)));
-+}
-+
-+static inline u8 *ethtool_rxfh_context_key(struct ethtool_rxfh_context *ctx)
-+{
-+ return (u8 *)(ethtool_rxfh_context_indir(ctx) + ctx->indir_size);
-+}
-+
- /* declare a link mode bitmap */
- #define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
- DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
-@@ -1000,9 +1040,11 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
-
- /**
- * struct ethtool_netdev_state - per-netdevice state for ethtool features
-+ * @rss_ctx: XArray of custom RSS contexts
- * @wol_enabled: Wake-on-LAN is enabled
- */
- struct ethtool_netdev_state {
-+ struct xarray rss_ctx;
- unsigned wol_enabled:1;
- };
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 250752751811c..b390b4cd9098f 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -10285,6 +10285,9 @@ int register_netdevice(struct net_device *dev)
- if (ret)
- return ret;
-
-+ /* rss ctx ID 0 is reserved for the default context, start from 1 */
-+ xa_init_flags(&dev->ethtool->rss_ctx, XA_FLAGS_ALLOC1);
-+
- spin_lock_init(&dev->addr_list_lock);
- netdev_set_addr_lockdep_class(dev);
-
-@@ -11134,6 +11137,28 @@ void synchronize_net(void)
- }
- EXPORT_SYMBOL(synchronize_net);
-
-+static void netdev_rss_contexts_free(struct net_device *dev)
-+{
-+ struct ethtool_rxfh_context *ctx;
-+ unsigned long context;
-+
-+ xa_for_each(&dev->ethtool->rss_ctx, context, ctx) {
-+ struct ethtool_rxfh_param rxfh;
-+
-+ rxfh.indir = ethtool_rxfh_context_indir(ctx);
-+ rxfh.key = ethtool_rxfh_context_key(ctx);
-+ rxfh.hfunc = ctx->hfunc;
-+ rxfh.input_xfrm = ctx->input_xfrm;
-+ rxfh.rss_context = context;
-+ rxfh.rss_delete = true;
-+
-+ xa_erase(&dev->ethtool->rss_ctx, context);
-+ dev->ethtool_ops->set_rxfh(dev, &rxfh, NULL);
-+ kfree(ctx);
-+ }
-+ xa_destroy(&dev->ethtool->rss_ctx);
-+}
-+
- /**
- * unregister_netdevice_queue - remove device from the kernel
- * @dev: device
-@@ -11237,6 +11262,8 @@ void unregister_netdevice_many_notify(struct list_head *head,
- netdev_name_node_alt_flush(dev);
- netdev_name_node_free(dev->name_node);
-
-+ netdev_rss_contexts_free(dev);
-+
- call_netdevice_notifiers(NETDEV_PRE_UNINIT, dev);
-
- if (dev->netdev_ops->ndo_uninit)
---
-2.43.0
-
+++ /dev/null
-From 756a1c7a95d270503dade14dc9786da1168d1f4d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 27 Jun 2024 16:33:48 +0100
-Subject: net: ethtool: record custom RSS contexts in the XArray
-
-From: Edward Cree <ecree.xilinx@gmail.com>
-
-[ Upstream commit eac9122f0c41b832065e01977c34946ec8e76c24 ]
-
-Since drivers are still choosing the context IDs, we have to force the
- XArray to use the ID they've chosen rather than picking one ourselves,
- and handle the case where they give us an ID that's already in use.
-
-Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
-Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
-Link: https://patch.msgid.link/801f5faa4cec87c65b2c6e27fb220c944bce593a.1719502240.git.ecree.xilinx@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: 7195f0ef7f5b ("ethtool: fix setting key and resetting indir at once")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/ethtool.h | 14 ++++++++
- net/ethtool/ioctl.c | 74 ++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 87 insertions(+), 1 deletion(-)
-
-diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
-index 13c9c819de580..8fa2f8bd474b6 100644
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -199,6 +199,17 @@ static inline u8 *ethtool_rxfh_context_key(struct ethtool_rxfh_context *ctx)
- return (u8 *)(ethtool_rxfh_context_indir(ctx) + ctx->indir_size);
- }
-
-+static inline size_t ethtool_rxfh_context_size(u32 indir_size, u32 key_size,
-+ u16 priv_size)
-+{
-+ size_t indir_bytes = array_size(indir_size, sizeof(u32));
-+ size_t flex_len;
-+
-+ flex_len = size_add(size_add(indir_bytes, key_size),
-+ ALIGN(priv_size, sizeof(u32)));
-+ return struct_size_t(struct ethtool_rxfh_context, data, flex_len);
-+}
-+
- /* declare a link mode bitmap */
- #define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
- DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
-@@ -709,6 +720,8 @@ struct ethtool_rxfh_param {
- * contexts.
- * @cap_rss_sym_xor_supported: indicates if the driver supports symmetric-xor
- * RSS.
-+ * @rxfh_priv_size: size of the driver private data area the core should
-+ * allocate for an RSS context (in &struct ethtool_rxfh_context).
- * @supported_coalesce_params: supported types of interrupt coalescing.
- * @supported_ring_params: supported ring params.
- * @get_drvinfo: Report driver/device information. Modern drivers no
-@@ -892,6 +905,7 @@ struct ethtool_ops {
- u32 cap_link_lanes_supported:1;
- u32 cap_rss_ctx_supported:1;
- u32 cap_rss_sym_xor_supported:1;
-+ u16 rxfh_priv_size;
- u32 supported_coalesce_params;
- u32 supported_ring_params;
- void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
-diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
-index 8d85a9900538b..1e87131f2caf4 100644
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -1281,10 +1281,12 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- const struct ethtool_ops *ops = dev->ethtool_ops;
- u32 dev_indir_size = 0, dev_key_size = 0, i;
- struct ethtool_rxfh_param rxfh_dev = {};
-+ struct ethtool_rxfh_context *ctx = NULL;
- struct netlink_ext_ack *extack = NULL;
- struct ethtool_rxnfc rx_rings;
- struct ethtool_rxfh rxfh;
- u32 indir_bytes = 0;
-+ bool create = false;
- u8 *rss_config;
- int ret;
-
-@@ -1313,6 +1315,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- (rxfh.input_xfrm & RXH_XFRM_SYM_XOR) &&
- !ops->cap_rss_sym_xor_supported)
- return -EOPNOTSUPP;
-+ create = rxfh.rss_context == ETH_RXFH_CONTEXT_ALLOC;
-
- /* If either indir, hash key or function is valid, proceed further.
- * Must request at least one change: indir size, hash key, function
-@@ -1378,13 +1381,42 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- }
- }
-
-+ if (create) {
-+ if (rxfh_dev.rss_delete) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+ ctx = kzalloc(ethtool_rxfh_context_size(dev_indir_size,
-+ dev_key_size,
-+ ops->rxfh_priv_size),
-+ GFP_KERNEL_ACCOUNT);
-+ if (!ctx) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+ ctx->indir_size = dev_indir_size;
-+ ctx->key_size = dev_key_size;
-+ ctx->hfunc = rxfh.hfunc;
-+ ctx->input_xfrm = rxfh.input_xfrm;
-+ ctx->priv_size = ops->rxfh_priv_size;
-+ } else if (rxfh.rss_context) {
-+ ctx = xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context);
-+ if (!ctx) {
-+ ret = -ENOENT;
-+ goto out;
-+ }
-+ }
- rxfh_dev.hfunc = rxfh.hfunc;
- rxfh_dev.rss_context = rxfh.rss_context;
- rxfh_dev.input_xfrm = rxfh.input_xfrm;
-
- ret = ops->set_rxfh(dev, &rxfh_dev, extack);
-- if (ret)
-+ if (ret) {
-+ if (create)
-+ /* failed to create, free our new tracking entry */
-+ kfree(ctx);
- goto out;
-+ }
-
- if (copy_to_user(useraddr + offsetof(struct ethtool_rxfh, rss_context),
- &rxfh_dev.rss_context, sizeof(rxfh_dev.rss_context)))
-@@ -1397,6 +1429,46 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
- else if (rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE)
- dev->priv_flags |= IFF_RXFH_CONFIGURED;
- }
-+ /* Update rss_ctx tracking */
-+ if (create) {
-+ /* Ideally this should happen before calling the driver,
-+ * so that we can fail more cleanly; but we don't have the
-+ * context ID until the driver picks it, so we have to
-+ * wait until after.
-+ */
-+ if (WARN_ON(xa_load(&dev->ethtool->rss_ctx, rxfh.rss_context))) {
-+ /* context ID reused, our tracking is screwed */
-+ kfree(ctx);
-+ goto out;
-+ }
-+ /* Allocate the exact ID the driver gave us */
-+ if (xa_is_err(xa_store(&dev->ethtool->rss_ctx, rxfh.rss_context,
-+ ctx, GFP_KERNEL))) {
-+ kfree(ctx);
-+ goto out;
-+ }
-+ ctx->indir_configured = rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE;
-+ ctx->key_configured = !!rxfh.key_size;
-+ }
-+ if (rxfh_dev.rss_delete) {
-+ WARN_ON(xa_erase(&dev->ethtool->rss_ctx, rxfh.rss_context) != ctx);
-+ kfree(ctx);
-+ } else if (ctx) {
-+ if (rxfh_dev.indir) {
-+ for (i = 0; i < dev_indir_size; i++)
-+ ethtool_rxfh_context_indir(ctx)[i] = rxfh_dev.indir[i];
-+ ctx->indir_configured = 1;
-+ }
-+ if (rxfh_dev.key) {
-+ memcpy(ethtool_rxfh_context_key(ctx), rxfh_dev.key,
-+ dev_key_size);
-+ ctx->key_configured = 1;
-+ }
-+ if (rxfh_dev.hfunc != ETH_RSS_HASH_NO_CHANGE)
-+ ctx->hfunc = rxfh_dev.hfunc;
-+ if (rxfh_dev.input_xfrm != RXH_XFRM_NO_CHANGE)
-+ ctx->input_xfrm = rxfh_dev.input_xfrm;
-+ }
-
- out:
- kfree(rss_config);
---
-2.43.0
-
+++ /dev/null
-From e331e73ff4c5c89a7f51a465ae40a7ad9fcd7a28 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 27 Jun 2024 16:33:46 +0100
-Subject: net: move ethtool-related netdev state into its own struct
-
-From: Edward Cree <ecree.xilinx@gmail.com>
-
-[ Upstream commit 3ebbd9f6de7ec6d538639ebb657246f629ace81e ]
-
-net_dev->ethtool is a pointer to new struct ethtool_netdev_state, which
- currently contains only the wol_enabled field.
-
-Suggested-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
-Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
-Link: https://patch.msgid.link/293a562278371de7534ed1eb17531838ca090633.1719502239.git.ecree.xilinx@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Stable-dep-of: 7195f0ef7f5b ("ethtool: fix setting key and resetting indir at once")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 4 ++--
- drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c | 4 ++--
- drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 2 +-
- drivers/net/phy/phy.c | 2 +-
- drivers/net/phy/phy_device.c | 5 +++--
- drivers/net/phy/phylink.c | 2 +-
- include/linux/ethtool.h | 8 ++++++++
- include/linux/netdevice.h | 8 +++++---
- net/core/dev.c | 4 ++++
- net/ethtool/ioctl.c | 2 +-
- net/ethtool/wol.c | 2 +-
- 11 files changed, 29 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
-index 7b9e04884575e..a06ac1a7a1822 100644
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -1608,7 +1608,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
-
- if (!tp->dash_enabled) {
- rtl_set_d3_pll_down(tp, !wolopts);
-- tp->dev->wol_enabled = wolopts ? 1 : 0;
-+ tp->dev->ethtool->wol_enabled = wolopts ? 1 : 0;
- }
- }
-
-@@ -5478,7 +5478,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
- rtl_set_d3_pll_down(tp, true);
- } else {
- rtl_set_d3_pll_down(tp, false);
-- dev->wol_enabled = 1;
-+ dev->ethtool->wol_enabled = 1;
- }
-
- jumbo_max = rtl_jumbo_max(tp);
-diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
-index 46a5a3e952021..e868f7ef49203 100644
---- a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
-+++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
-@@ -37,9 +37,9 @@ static int ngbe_set_wol(struct net_device *netdev,
- wx->wol = 0;
- if (wol->wolopts & WAKE_MAGIC)
- wx->wol = WX_PSR_WKUP_CTL_MAG;
-- netdev->wol_enabled = !!(wx->wol);
-+ netdev->ethtool->wol_enabled = !!(wx->wol);
- wr32(wx, WX_PSR_WKUP_CTL, wx->wol);
-- device_set_wakeup_enable(&pdev->dev, netdev->wol_enabled);
-+ device_set_wakeup_enable(&pdev->dev, netdev->ethtool->wol_enabled);
-
- return 0;
- }
-diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
-index af30ca0312b81..53aeae2f884b0 100644
---- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
-+++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
-@@ -652,7 +652,7 @@ static int ngbe_probe(struct pci_dev *pdev,
- if (wx->wol_hw_supported)
- wx->wol = NGBE_PSR_WKUP_CTL_MAG;
-
-- netdev->wol_enabled = !!(wx->wol);
-+ netdev->ethtool->wol_enabled = !!(wx->wol);
- wr32(wx, NGBE_PSR_WKUP_CTL, wx->wol);
- device_set_wakeup_enable(&pdev->dev, wx->wol);
-
-diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
-index c4236564c1cd0..785182fa5fe01 100644
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -1309,7 +1309,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
- if (netdev) {
- struct device *parent = netdev->dev.parent;
-
-- if (netdev->wol_enabled)
-+ if (netdev->ethtool->wol_enabled)
- pm_system_wakeup();
- else if (device_may_wakeup(&netdev->dev))
- pm_wakeup_dev_event(&netdev->dev, 0, true);
-diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
-index 6c6ec94757092..473cbc1d497b3 100644
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -296,7 +296,7 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
- if (!netdev)
- goto out;
-
-- if (netdev->wol_enabled)
-+ if (netdev->ethtool->wol_enabled)
- return false;
-
- /* As long as not all affected network drivers support the
-@@ -1984,7 +1984,8 @@ int phy_suspend(struct phy_device *phydev)
- return 0;
-
- phy_ethtool_get_wol(phydev, &wol);
-- phydev->wol_enabled = wol.wolopts || (netdev && netdev->wol_enabled);
-+ phydev->wol_enabled = wol.wolopts ||
-+ (netdev && netdev->ethtool->wol_enabled);
- /* If the device has WOL enabled, we cannot suspend the PHY */
- if (phydev->wol_enabled && !(phydrv->flags & PHY_ALWAYS_CALL_SUSPEND))
- return -EBUSY;
-diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
-index 994471fad833f..d73a7bfb355ed 100644
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -2270,7 +2270,7 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
- {
- ASSERT_RTNL();
-
-- if (mac_wol && (!pl->netdev || pl->netdev->wol_enabled)) {
-+ if (mac_wol && (!pl->netdev || pl->netdev->ethtool->wol_enabled)) {
- /* Wake-on-Lan enabled, MAC handling */
- mutex_lock(&pl->state_mutex);
-
-diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
-index 6fd9107d3cc01..8cd6b3c993f17 100644
---- a/include/linux/ethtool.h
-+++ b/include/linux/ethtool.h
-@@ -998,6 +998,14 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
- const struct ethtool_link_ksettings *cmd,
- u32 *dev_speed, u8 *dev_duplex);
-
-+/**
-+ * struct ethtool_netdev_state - per-netdevice state for ethtool features
-+ * @wol_enabled: Wake-on-LAN is enabled
-+ */
-+struct ethtool_netdev_state {
-+ unsigned wol_enabled:1;
-+};
-+
- struct phy_device;
- struct phy_tdr_config;
- struct phy_plca_cfg;
-diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index ccba9f145edaa..e1ef352f592fa 100644
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -79,6 +79,7 @@ struct xdp_buff;
- struct xdp_frame;
- struct xdp_metadata_ops;
- struct xdp_md;
-+struct ethtool_netdev_state;
-
- typedef u32 xdp_features_t;
-
-@@ -1985,8 +1986,6 @@ enum netdev_reg_state {
- * switch driver and used to set the phys state of the
- * switch port.
- *
-- * @wol_enabled: Wake-on-LAN is enabled
-- *
- * @threaded: napi threaded mode is enabled
- *
- * @module_fw_flash_in_progress: Module firmware flashing is in progress.
-@@ -2000,6 +1999,7 @@ enum netdev_reg_state {
- * @udp_tunnel_nic_info: static structure describing the UDP tunnel
- * offload capabilities of the device
- * @udp_tunnel_nic: UDP tunnel offload state
-+ * @ethtool: ethtool related state
- * @xdp_state: stores info on attached XDP BPF programs
- *
- * @nested_level: Used as a parameter of spin_lock_nested() of
-@@ -2374,7 +2374,7 @@ struct net_device {
- struct lock_class_key *qdisc_tx_busylock;
- bool proto_down;
- bool threaded;
-- unsigned wol_enabled:1;
-+
- unsigned module_fw_flash_in_progress:1;
- struct list_head net_notifier_list;
-
-@@ -2385,6 +2385,8 @@ struct net_device {
- const struct udp_tunnel_nic_info *udp_tunnel_nic_info;
- struct udp_tunnel_nic *udp_tunnel_nic;
-
-+ struct ethtool_netdev_state *ethtool;
-+
- /* protected by rtnl_lock */
- struct bpf_xdp_entity xdp_state[__MAX_XDP_MODE];
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 2b4819b610b8a..250752751811c 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -11015,6 +11015,9 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
- dev->real_num_rx_queues = rxqs;
- if (netif_alloc_rx_queues(dev))
- goto free_all;
-+ dev->ethtool = kzalloc(sizeof(*dev->ethtool), GFP_KERNEL_ACCOUNT);
-+ if (!dev->ethtool)
-+ goto free_all;
-
- strcpy(dev->name, name);
- dev->name_assign_type = name_assign_type;
-@@ -11065,6 +11068,7 @@ void free_netdev(struct net_device *dev)
- return;
- }
-
-+ kfree(dev->ethtool);
- netif_free_tx_queues(dev);
- netif_free_rx_queues(dev);
-
-diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
-index 3c8821adc4891..8d85a9900538b 100644
---- a/net/ethtool/ioctl.c
-+++ b/net/ethtool/ioctl.c
-@@ -1510,7 +1510,7 @@ static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
- if (ret)
- return ret;
-
-- dev->wol_enabled = !!wol.wolopts;
-+ dev->ethtool->wol_enabled = !!wol.wolopts;
- ethtool_notify(dev, ETHTOOL_MSG_WOL_NTF, NULL);
-
- return 0;
-diff --git a/net/ethtool/wol.c b/net/ethtool/wol.c
-index 0ed56c9ac1bc4..a39d8000d808a 100644
---- a/net/ethtool/wol.c
-+++ b/net/ethtool/wol.c
-@@ -137,7 +137,7 @@ ethnl_set_wol(struct ethnl_req_info *req_info, struct genl_info *info)
- ret = dev->ethtool_ops->set_wol(dev, &wol);
- if (ret)
- return ret;
-- dev->wol_enabled = !!wol.wolopts;
-+ dev->ethtool->wol_enabled = !!wol.wolopts;
- return 1;
- }
-
---
-2.43.0
-
bluetooth-btintel-fail-setup-on-error.patch
bluetooth-hci_sync-fix-suspending-with-wrong-filter-.patch
drm-client-fix-error-code-in-drm_client_buffer_vmap_.patch
-ethtool-veto-some-operations-during-firmware-flashin.patch
-net-move-ethtool-related-netdev-state-into-its-own-s.patch
-net-ethtool-attach-an-xarray-of-custom-rss-contexts-.patch
-net-ethtool-record-custom-rss-contexts-in-the-xarray.patch
-net-ethtool-add-a-mutex-protecting-rss-contexts.patch
ethtool-fix-setting-key-and-resetting-indir-at-once.patch
tcp-adjust-clamping-window-for-applications-specifyi.patch
net-axienet-start-napi-before-enabling-rx-tx.patch