From ed1fe1bebe18884b11e5536b5ac42e3a48960835 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 11 Nov 2022 23:10:20 +0200 Subject: net: dsa: make dsa_master_ioctl() see through port_hwtstamp_get() shims MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are multi-generational drivers like mv88e6xxx which have code like this: int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) { if (!chip->info->ptp_support) return -EOPNOTSUPP; ... } DSA wants to deny PTP timestamping on the master if the switch supports timestamping too. However it currently relies on the presence of the port_hwtstamp_get() callback to determine PTP capability, and this clearly does not work in that case (method is present but returns -EOPNOTSUPP). We should not deny PTP on the DSA master for those switches which truly do not support hardware timestamping. Create a dsa_port_supports_hwtstamp() method which actually probes for support by calling port_hwtstamp_get() and seeing whether that returned -EOPNOTSUPP or not. Fixes: f685e609a301 ("net: dsa: Deny PTP on master if switch supports it") Link: https://patchwork.kernel.org/project/netdevbpf/patch/20221110124345.3901389-1-festevam@gmail.com/ Reported-by: Fabio Estevam Reported-by: Steffen Bätz Signed-off-by: Vladimir Oltean Tested-by: Fabio Estevam Signed-off-by: David S. Miller --- net/dsa/master.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index 40367ab41cf8..421de166515f 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -204,8 +204,7 @@ static int dsa_master_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) * switch in the tree that is PTP capable. */ list_for_each_entry(dp, &dst->ports, list) - if (dp->ds->ops->port_hwtstamp_get || - dp->ds->ops->port_hwtstamp_set) + if (dsa_port_supports_hwtstamp(dp, ifr)) return -EBUSY; break; } -- cgit From e8666130b995a6a1a99c319d33fae2046213c39b Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 15 Nov 2022 03:18:45 +0200 Subject: net: dsa: strip sysfs "tagging" string of trailing newline Currently, dsa_find_tagger_by_name() uses sysfs_streq() which works both with strings that contain \n at the end (echo ocelot > .../dsa/tagging) and with strings that don't (printf ocelot > .../dsa/tagging). There will be a problem once we'll want to construct the modalias string based on which we auto-load the protocol kernel module. If the sysfs buffer ends in a newline, we need to strip it first. This is a preparatory patch specifically for that. Signed-off-by: Vladimir Oltean Tested-by: Michael Walle Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index 421de166515f..f443bf4a3c8c 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -299,12 +299,23 @@ static ssize_t tagging_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { const struct dsa_device_ops *new_tag_ops, *old_tag_ops; + const char *end = strchrnul(buf, '\n'), *name; struct net_device *dev = to_net_dev(d); struct dsa_port *cpu_dp = dev->dsa_ptr; + size_t len = end - buf; int err; + /* Empty string passed */ + if (!len) + return -ENOPROTOOPT; + + name = kstrndup(buf, len, GFP_KERNEL); + if (!name) + return -ENOMEM; + old_tag_ops = cpu_dp->tag_ops; - new_tag_ops = dsa_find_tagger_by_name(buf); + new_tag_ops = dsa_find_tagger_by_name(name); + kfree(name); /* Bad tagger name, or module is not loaded? */ if (IS_ERR(new_tag_ops)) return PTR_ERR(new_tag_ops); -- cgit From 0184c07a11a243569cb90104980237c8e101f363 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 15 Nov 2022 03:18:47 +0200 Subject: net: dsa: autoload tag driver module on tagging protocol change 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 Signed-off-by: Vladimir Oltean Tested-by: Michael Walle # on kontron-sl28 w/ ocelot_8021q Tested-by: Michael Walle Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index f443bf4a3c8c..e24f02743c21 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -314,9 +314,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); -- cgit From 022bba63c3ca02fc074c68b4e7b949bddcf320d6 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Mon, 21 Nov 2022 15:55:44 +0200 Subject: net: dsa: move headers exported by port.c to port.h Minimize the use of the bloated dsa_priv.h by moving the prototypes exported by port.c to their own header file. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index e24f02743c21..0d3ef591b3b4 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -7,6 +7,7 @@ */ #include "dsa_priv.h" +#include "port.h" static int dsa_master_get_regs_len(struct net_device *dev) { -- cgit From 94ef6fad3bf317b43cdc59ba171dff2486e59975 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Mon, 21 Nov 2022 15:55:45 +0200 Subject: net: dsa: move headers exported by master.c to master.h Minimize the use of the bloated dsa_priv.h by moving the prototypes exported by master.c to their own header file. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index 0d3ef591b3b4..6105821834a2 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -6,7 +6,13 @@ * Vivien Didelot */ +#include +#include +#include +#include + #include "dsa_priv.h" +#include "master.h" #include "port.h" static int dsa_master_get_regs_len(struct net_device *dev) -- cgit From bd954b826032e7bd6be8a53e30eb81c1b348aef6 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Mon, 21 Nov 2022 15:55:47 +0200 Subject: net: dsa: move tagging protocol code to tag.{c,h} It would be nice if tagging protocol drivers could include just the header they need, since they are (mostly) data path and isolated from most of the other DSA core code does. Create a tag.c and a tag.h file which are meant to support tagging protocol drivers. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index 6105821834a2..e38b349ca7f8 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -14,6 +14,7 @@ #include "dsa_priv.h" #include "master.h" #include "port.h" +#include "tag.h" static int dsa_master_get_regs_len(struct net_device *dev) { -- cgit From 47d2ce03dcfb6b7f0373aac6c667715d94caba78 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Mon, 21 Nov 2022 15:55:52 +0200 Subject: net: dsa: rename dsa2.c back into dsa.c and create its header The previous change moved the code into the larger file (dsa2.c) to minimize the delta. Rename that now to dsa.c, and create dsa.h, where all related definitions from dsa_priv.h go. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- net/dsa/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/dsa/master.c') diff --git a/net/dsa/master.c b/net/dsa/master.c index e38b349ca7f8..26d90140d271 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -11,7 +11,7 @@ #include #include -#include "dsa_priv.h" +#include "dsa.h" #include "master.h" #include "port.h" #include "tag.h" -- cgit