diff mbox series

[v2,net-next,6/6] net: dsa: autoload tag driver module on tagging protocol change

Message ID 20221115011847.2843127-7-vladimir.oltean@nxp.com (mailing list archive)
State Accepted
Commit 0184c07a11a243569cb90104980237c8e101f363
Delegated to: Netdev Maintainers
Headers show
Series Autoload DSA tagging driver when dynamically changing protocol | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 42 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Vladimir Oltean Nov. 15, 2022, 1:18 a.m. UTC
Issue a request_module() call when an attempt to change the tagging
protocol is made, either by sysfs or by device tree. In the case of
ocelot (the only driver for which the default and the alternative
tagging protocol are compiled as different modules), the user is now no
longer required to insert tag_ocelot_8021q.ko manually.

In the particular case of ocelot, this solves a problem where
tag_ocelot_8021q.ko is built as module, and this is present in the
device tree:

&mscc_felix_port4 {
	dsa-tag-protocol = "ocelot-8021q";
};

&mscc_felix_port5 {
	dsa-tag-protocol = "ocelot-8021q";
};

Because no one attempts to load the module into the kernel at boot time,
the switch driver will fail to probe (actually forever defer) until
someone manually inserts tag_ocelot_8021q.ko. This is now no longer
necessary and happens automatically.

Rename dsa_find_tagger_by_name() to denote the change in functionality:
there is now feature parity with dsa_tag_driver_get_by_id(), i.o.w. we
also load the module if it's missing.

Link: https://lore.kernel.org/lkml/20221027113248.420216-1-michael@walle.cc/
Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Michael Walle <michael@walle.cc> # on kontron-sl28 w/ ocelot_8021q
---
v1->v2:
- don't call request_module() with sysfs-formatted names that end in '\n'

 net/dsa/dsa.c      | 4 +++-
 net/dsa/dsa2.c     | 2 +-
 net/dsa/dsa_priv.h | 2 +-
 net/dsa/master.c   | 4 ++--
 4 files changed, 7 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index d51b81cc196c..857d07c6d0cb 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -78,11 +78,13 @@  const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops)
 /* Function takes a reference on the module owning the tagger,
  * so dsa_tag_driver_put must be called afterwards.
  */
-const struct dsa_device_ops *dsa_find_tagger_by_name(const char *name)
+const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name)
 {
 	const struct dsa_device_ops *ops = ERR_PTR(-ENOPROTOOPT);
 	struct dsa_tag_driver *dsa_tag_driver;
 
+	request_module("%s%s", DSA_TAG_DRIVER_ALIAS, name);
+
 	mutex_lock(&dsa_tag_drivers_lock);
 	list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
 		const struct dsa_device_ops *tmp = dsa_tag_driver->ops;
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 9920eed0c654..1bcf8a2d4a95 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -1424,7 +1424,7 @@  static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
 			return -EINVAL;
 		}
 
-		tag_ops = dsa_find_tagger_by_name(user_protocol);
+		tag_ops = dsa_tag_driver_get_by_name(user_protocol);
 		if (IS_ERR(tag_ops)) {
 			dev_warn(ds->dev,
 				 "Failed to find a tagging driver for protocol %s, using default\n",
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index e128095f9e65..d2fefc40bc7a 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -244,8 +244,8 @@  struct dsa_slave_priv {
 
 /* dsa.c */
 const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol);
+const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name);
 void dsa_tag_driver_put(const struct dsa_device_ops *ops);
-const struct dsa_device_ops *dsa_find_tagger_by_name(const char *name);
 
 bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b);
 
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 104eab880076..56ed7af89ac3 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -315,9 +315,9 @@  static ssize_t tagging_store(struct device *d, struct device_attribute *attr,
 		return -ENOMEM;
 
 	old_tag_ops = cpu_dp->tag_ops;
-	new_tag_ops = dsa_find_tagger_by_name(name);
+	new_tag_ops = dsa_tag_driver_get_by_name(name);
 	kfree(name);
-	/* Bad tagger name, or module is not loaded? */
+	/* Bad tagger name? */
 	if (IS_ERR(new_tag_ops))
 		return PTR_ERR(new_tag_ops);