Patch "net: dsa: make dsa_master_ioctl() see through port_hwtstamp_get() shims" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: dsa: make dsa_master_ioctl() see through port_hwtstamp_get() shims

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-dsa-make-dsa_master_ioctl-see-through-port_hwtst.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 83730ebd680280471ccbf9f92bc797a6b130350f
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Fri Nov 11 23:10:20 2022 +0200

    net: dsa: make dsa_master_ioctl() see through port_hwtstamp_get() shims
    
    [ Upstream commit ed1fe1bebe18884b11e5536b5ac42e3a48960835 ]
    
    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@xxxxxxxxx/
    Reported-by: Fabio Estevam <festevam@xxxxxxxxx>
    Reported-by: Steffen Bätz <steffen@xxxxxxxxxxxx>
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Tested-by: Fabio Estevam <festevam@xxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index a5c9bc7b66c6..e91265434354 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -198,6 +198,7 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
 }
 
 /* port.c */
+bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr);
 void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp,
 			       const struct dsa_device_ops *tag_ops);
 int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age);
diff --git a/net/dsa/master.c b/net/dsa/master.c
index e8e19857621b..69ec510abe83 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;
 	}
diff --git a/net/dsa/port.c b/net/dsa/port.c
index a21015d6bd36..31e8a7a8c3e6 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -75,6 +75,22 @@ static bool dsa_port_can_configure_learning(struct dsa_port *dp)
 	return !err;
 }
 
+bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr)
+{
+	struct dsa_switch *ds = dp->ds;
+	int err;
+
+	if (!ds->ops->port_hwtstamp_get || !ds->ops->port_hwtstamp_set)
+		return false;
+
+	/* "See through" shim implementations of the "get" method.
+	 * This will clobber the ifreq structure, but we will either return an
+	 * error, or the master will overwrite it with proper values.
+	 */
+	err = ds->ops->port_hwtstamp_get(ds, dp->index, ifr);
+	return err != -EOPNOTSUPP;
+}
+
 int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age)
 {
 	struct dsa_switch *ds = dp->ds;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux