diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-11-17 21:16:46 -0800 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-11-17 21:16:47 -0800 |
commit | 4ab45e973c3fd9e460b1e23cd018ea7f3d8a8b67 (patch) | |
tree | 859642e01942d214acf930cedfaabbbc36a6f176 /net/dsa/dsa.c | |
parent | 4a8c14384fa96c0bd6c1a534667f2a72165faacf (diff) | |
parent | 0184c07a11a243569cb90104980237c8e101f363 (diff) |
Merge branch 'autoload-dsa-tagging-driver-when-dynamically-changing-protocol'
Vladimir Oltean says:
====================
Autoload DSA tagging driver when dynamically changing protocol
This patch set solves the issue reported by Michael and Heiko here:
https://lore.kernel.org/lkml/20221027113248.420216-1-michael@walle.cc/
making full use of Michael's suggestion of having two modaliases: one
gets used for loading the tagging protocol when it's the default one
reported by the switch driver, the other gets loaded at user's request,
by name.
# modinfo tag_ocelot
filename: /lib/modules/6.1.0-rc4+/kernel/net/dsa/tag_ocelot.ko
license: GPL v2
alias: dsa_tag:seville
alias: dsa_tag:id-21
alias: dsa_tag:ocelot
alias: dsa_tag:id-15
depends: dsa_core
intree: Y
name: tag_ocelot
vermagic: 6.1.0-rc4+ SMP preempt mod_unload modversions aarch64
Tested on NXP LS1028A-RDB with the following device tree addition:
&mscc_felix_port4 {
dsa-tag-protocol = "ocelot-8021q";
};
&mscc_felix_port5 {
dsa-tag-protocol = "ocelot-8021q";
};
CONFIG_NET_DSA and everything that depends on it is built as module.
Everything auto-loads, and "cat /sys/class/net/eno2/dsa/tagging" shows
"ocelot-8021q". Traffic works as well. Furthermore, "echo ocelot-8021q"
into the aforementioned sysfs file now auto-loads the driver for it.
====================
Link: https://lore.kernel.org/r/20221115011847.2843127-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/dsa/dsa.c')
-rw-r--r-- | net/dsa/dsa.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6caf2ec648fd..4afd3edbd64d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -79,16 +79,18 @@ 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 *buf) +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; - if (!sysfs_streq(buf, tmp->name)) + if (strcmp(name, tmp->name)) continue; if (!try_module_get(dsa_tag_driver->owner)) @@ -102,13 +104,13 @@ const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf) return ops; } -const struct dsa_device_ops *dsa_tag_driver_get(int tag_protocol) +const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol) { struct dsa_tag_driver *dsa_tag_driver; const struct dsa_device_ops *ops; bool found = false; - request_module("%s%d", DSA_TAG_DRIVER_ALIAS, tag_protocol); + request_module("%sid-%d", DSA_TAG_DRIVER_ALIAS, tag_protocol); mutex_lock(&dsa_tag_drivers_lock); list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) { |