mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 07:46:48 +00:00
kernel/armsr: Add configuration files and patches for v6.6
Based on the 6.1 files, but without any 6.6 additions. Signed-off-by: Mathew McBride <matt@traverse.com.au>
This commit is contained in:
parent
bd6852185b
commit
f125e38ced
@ -1,44 +0,0 @@
|
|||||||
From f3763a0c1b07273218cbf5886bdf8df9df501111 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:10 +0200
|
|
||||||
Subject: [PATCH 03/14] net: dpaa2-eth: don't use -ENOTSUPP error code
|
|
||||||
|
|
||||||
dpaa2_eth_setup_dpni() is called from the probe path and
|
|
||||||
dpaa2_eth_set_link_ksettings() is propagated to user space.
|
|
||||||
|
|
||||||
include/linux/errno.h says that ENOTSUPP is "Defined for the NFSv3
|
|
||||||
protocol". Conventional wisdom has it to not use it in networking
|
|
||||||
drivers. Replace it with -EOPNOTSUPP.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +-
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -3614,7 +3614,7 @@ static int dpaa2_eth_setup_dpni(struct f
|
|
||||||
dev_err(dev, "DPNI version %u.%u not supported, need >= %u.%u\n",
|
|
||||||
priv->dpni_ver_major, priv->dpni_ver_minor,
|
|
||||||
DPNI_VER_MAJOR, DPNI_VER_MINOR);
|
|
||||||
- err = -ENOTSUPP;
|
|
||||||
+ err = -EOPNOTSUPP;
|
|
||||||
goto close;
|
|
||||||
}
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
@@ -118,7 +118,7 @@ dpaa2_eth_set_link_ksettings(struct net_
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
|
|
||||||
if (!dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return -ENOTSUPP;
|
|
||||||
+ return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
From 022a11062261dc4703da846d3bf4d194ef6bebf5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:11 +0200
|
|
||||||
Subject: [PATCH 04/14] net: dpaa2: replace dpaa2_mac_is_type_fixed() with
|
|
||||||
dpaa2_mac_is_type_phy()
|
|
||||||
|
|
||||||
dpaa2_mac_is_type_fixed() is a header with no implementation and no
|
|
||||||
callers, which is referenced from the documentation though. It can be
|
|
||||||
deleted.
|
|
||||||
|
|
||||||
On the other hand, it would be useful to reuse the code between
|
|
||||||
dpaa2_eth_is_type_phy() and dpaa2_switch_port_is_type_phy(). That common
|
|
||||||
code should be called dpaa2_mac_is_type_phy(), so let's create that.
|
|
||||||
|
|
||||||
The removal and the addition are merged into the same patch because,
|
|
||||||
in fact, is_type_phy() is the logical opposite of is_type_fixed().
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../ethernet/freescale/dpaa2/mac-phy-support.rst | 9 ++++++---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 7 +------
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++++++++--
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h | 7 +------
|
|
||||||
4 files changed, 16 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
--- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
|
|
||||||
+++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst
|
|
||||||
@@ -181,10 +181,13 @@ when necessary using the below listed AP
|
|
||||||
- int dpaa2_mac_connect(struct dpaa2_mac *mac);
|
|
||||||
- void dpaa2_mac_disconnect(struct dpaa2_mac *mac);
|
|
||||||
|
|
||||||
-A phylink integration is necessary only when the partner DPMAC is not of TYPE_FIXED.
|
|
||||||
-One can check for this condition using the below API::
|
|
||||||
+A phylink integration is necessary only when the partner DPMAC is not of
|
|
||||||
+``TYPE_FIXED``. This means it is either of ``TYPE_PHY``, or of
|
|
||||||
+``TYPE_BACKPLANE`` (the difference being the two that in the ``TYPE_BACKPLANE``
|
|
||||||
+mode, the MC firmware does not access the PCS registers). One can check for
|
|
||||||
+this condition using the following helper::
|
|
||||||
|
|
||||||
- - bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,struct fsl_mc_io *mc_io);
|
|
||||||
+ - static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac);
|
|
||||||
|
|
||||||
Before connection to a MAC, the caller must allocate and populate the
|
|
||||||
dpaa2_mac structure with the associated net_device, a pointer to the MC portal
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
|
|
||||||
@@ -733,12 +733,7 @@ static inline unsigned int dpaa2_eth_rx_
|
|
||||||
|
|
||||||
static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
|
|
||||||
{
|
|
||||||
- if (priv->mac &&
|
|
||||||
- (priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
|
|
||||||
- priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
|
|
||||||
- return true;
|
|
||||||
-
|
|
||||||
- return false;
|
|
||||||
+ return dpaa2_mac_is_type_phy(priv->mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
|
|
||||||
@@ -30,8 +30,14 @@ struct dpaa2_mac {
|
|
||||||
struct phy *serdes_phy;
|
|
||||||
};
|
|
||||||
|
|
||||||
-bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
|
|
||||||
- struct fsl_mc_io *mc_io);
|
|
||||||
+static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac)
|
|
||||||
+{
|
|
||||||
+ if (!mac)
|
|
||||||
+ return false;
|
|
||||||
+
|
|
||||||
+ return mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
|
|
||||||
+ mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE;
|
|
||||||
+}
|
|
||||||
|
|
||||||
int dpaa2_mac_open(struct dpaa2_mac *mac);
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
|
|
||||||
@@ -230,12 +230,7 @@ static inline bool dpaa2_switch_supports
|
|
||||||
static inline bool
|
|
||||||
dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv)
|
|
||||||
{
|
|
||||||
- if (port_priv->mac &&
|
|
||||||
- (port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY ||
|
|
||||||
- port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE))
|
|
||||||
- return true;
|
|
||||||
-
|
|
||||||
- return false;
|
|
||||||
+ return dpaa2_mac_is_type_phy(port_priv->mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv)
|
|
@ -1,88 +0,0 @@
|
|||||||
From 97c07369ab8bf9895e05d4b468f18e6567263154 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:12 +0200
|
|
||||||
Subject: [PATCH 05/14] net: dpaa2-mac: absorb phylink_start() call into
|
|
||||||
dpaa2_mac_start()
|
|
||||||
|
|
||||||
The phylink handling is intended to be hidden inside the dpaa2_mac
|
|
||||||
object. Move the phylink_start() call into dpaa2_mac_start(), and
|
|
||||||
phylink_stop() into dpaa2_mac_stop().
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 5 +----
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 8 ++++++++
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 5 +----
|
|
||||||
3 files changed, 10 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -2083,10 +2083,8 @@ static int dpaa2_eth_open(struct net_dev
|
|
||||||
goto enable_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
+ if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
dpaa2_mac_start(priv->mac);
|
|
||||||
- phylink_start(priv->mac->phylink);
|
|
||||||
- }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -2160,7 +2158,6 @@ static int dpaa2_eth_stop(struct net_dev
|
|
||||||
int retries = 10;
|
|
||||||
|
|
||||||
if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
- phylink_stop(priv->mac->phylink);
|
|
||||||
dpaa2_mac_stop(priv->mac);
|
|
||||||
} else {
|
|
||||||
netif_tx_stop_all_queues(net_dev);
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
@@ -336,12 +336,20 @@ static void dpaa2_mac_set_supported_inte
|
|
||||||
|
|
||||||
void dpaa2_mac_start(struct dpaa2_mac *mac)
|
|
||||||
{
|
|
||||||
+ ASSERT_RTNL();
|
|
||||||
+
|
|
||||||
if (mac->serdes_phy)
|
|
||||||
phy_power_on(mac->serdes_phy);
|
|
||||||
+
|
|
||||||
+ phylink_start(mac->phylink);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dpaa2_mac_stop(struct dpaa2_mac *mac)
|
|
||||||
{
|
|
||||||
+ ASSERT_RTNL();
|
|
||||||
+
|
|
||||||
+ phylink_stop(mac->phylink);
|
|
||||||
+
|
|
||||||
if (mac->serdes_phy)
|
|
||||||
phy_power_off(mac->serdes_phy);
|
|
||||||
}
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
@@ -703,10 +703,8 @@ static int dpaa2_switch_port_open(struct
|
|
||||||
|
|
||||||
dpaa2_switch_enable_ctrl_if_napi(ethsw);
|
|
||||||
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
+ if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
dpaa2_mac_start(port_priv->mac);
|
|
||||||
- phylink_start(port_priv->mac->phylink);
|
|
||||||
- }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -718,7 +716,6 @@ static int dpaa2_switch_port_stop(struct
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
- phylink_stop(port_priv->mac->phylink);
|
|
||||||
dpaa2_mac_stop(port_priv->mac);
|
|
||||||
} else {
|
|
||||||
netif_tx_stop_all_queues(netdev);
|
|
@ -1,50 +0,0 @@
|
|||||||
From 095ef388f714d622aa503fcccf20dc4095b72762 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:13 +0200
|
|
||||||
Subject: [PATCH 06/14] net: dpaa2-mac: remove defensive check in
|
|
||||||
dpaa2_mac_disconnect()
|
|
||||||
|
|
||||||
dpaa2_mac_disconnect() will only be called with a NULL mac->phylink if
|
|
||||||
dpaa2_mac_connect() failed, or was never called.
|
|
||||||
|
|
||||||
The callers are these:
|
|
||||||
|
|
||||||
dpaa2_eth_disconnect_mac():
|
|
||||||
|
|
||||||
if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
dpaa2_mac_disconnect(priv->mac);
|
|
||||||
|
|
||||||
dpaa2_switch_port_disconnect_mac():
|
|
||||||
|
|
||||||
if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
dpaa2_mac_disconnect(port_priv->mac);
|
|
||||||
|
|
||||||
priv->mac can be NULL, but in that case, dpaa2_eth_is_type_phy() returns
|
|
||||||
false, and dpaa2_mac_disconnect() is never called. Similar for
|
|
||||||
dpaa2-switch.
|
|
||||||
|
|
||||||
When priv->mac is non-NULL, it means that dpaa2_mac_connect() returned
|
|
||||||
zero (success), and therefore, priv->mac->phylink is also a valid
|
|
||||||
pointer.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ---
|
|
||||||
1 file changed, 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
@@ -446,9 +446,6 @@ err_pcs_destroy:
|
|
||||||
|
|
||||||
void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
|
|
||||||
{
|
|
||||||
- if (!mac->phylink)
|
|
||||||
- return;
|
|
||||||
-
|
|
||||||
phylink_disconnect_phy(mac->phylink);
|
|
||||||
phylink_destroy(mac->phylink);
|
|
||||||
dpaa2_pcs_destroy(mac);
|
|
@ -1,101 +0,0 @@
|
|||||||
From 06efc9b8a1360cad83cae6e71558e5458cc1fbf3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:14 +0200
|
|
||||||
Subject: [PATCH 07/14] net: dpaa2-eth: assign priv->mac after
|
|
||||||
dpaa2_mac_connect() call
|
|
||||||
|
|
||||||
There are 2 requirements for correct code:
|
|
||||||
|
|
||||||
- Any time the driver accesses the priv->mac pointer at runtime, it
|
|
||||||
either holds NULL to indicate a DPNI-DPNI connection (or unconnected
|
|
||||||
DPNI), or a struct dpaa2_mac whose phylink instance was fully
|
|
||||||
initialized (created and connected to the PHY). No changes are made to
|
|
||||||
priv->mac while it is being used. Currently, rtnl_lock() watches over
|
|
||||||
the call to dpaa2_eth_connect_mac(), so it serves the purpose of
|
|
||||||
serializing this with all readers of priv->mac.
|
|
||||||
|
|
||||||
- dpaa2_mac_connect() should run unlocked, because inside it are 2
|
|
||||||
phylink calls with incompatible locking requirements: phylink_create()
|
|
||||||
requires that the rtnl_mutex isn't held, and phylink_fwnode_phy_connect()
|
|
||||||
requires that the rtnl_mutex is held. The only way to solve those
|
|
||||||
contradictory requirements is to let dpaa2_mac_connect() take
|
|
||||||
rtnl_lock() when it needs to.
|
|
||||||
|
|
||||||
To solve both requirements, we need to identify the writer side of the
|
|
||||||
priv->mac pointer, which can be wrapped in a mutex private to the driver
|
|
||||||
in a future patch. The dpaa2_mac_connect() cannot be part of the writer
|
|
||||||
side critical section, because of an AB/BA deadlock with rtnl_lock().
|
|
||||||
|
|
||||||
So the strategy needs to be that where we prepare the DPMAC by calling
|
|
||||||
dpaa2_mac_connect(), and only make priv->mac point to it once it's fully
|
|
||||||
prepared. This ensures that the writer side critical section has the
|
|
||||||
absolute minimum surface it can.
|
|
||||||
|
|
||||||
The reverse strategy is adopted in the dpaa2_eth_disconnect_mac() code
|
|
||||||
path. This makes sure that priv->mac is NULL when we start tearing down
|
|
||||||
the DPMAC that we disconnected from, and concurrent code will simply not
|
|
||||||
see it.
|
|
||||||
|
|
||||||
No locking changes in this patch (concurrent code is still blocked by
|
|
||||||
the rtnl_mutex).
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 21 +++++++++++--------
|
|
||||||
1 file changed, 12 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -4444,9 +4444,8 @@ static int dpaa2_eth_connect_mac(struct
|
|
||||||
err = dpaa2_mac_open(mac);
|
|
||||||
if (err)
|
|
||||||
goto err_free_mac;
|
|
||||||
- priv->mac = mac;
|
|
||||||
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
+ if (dpaa2_mac_is_type_phy(mac)) {
|
|
||||||
err = dpaa2_mac_connect(mac);
|
|
||||||
if (err && err != -EPROBE_DEFER)
|
|
||||||
netdev_err(priv->net_dev, "Error connecting to the MAC endpoint: %pe",
|
|
||||||
@@ -4455,11 +4454,12 @@ static int dpaa2_eth_connect_mac(struct
|
|
||||||
goto err_close_mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ priv->mac = mac;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_close_mac:
|
|
||||||
dpaa2_mac_close(mac);
|
|
||||||
- priv->mac = NULL;
|
|
||||||
err_free_mac:
|
|
||||||
kfree(mac);
|
|
||||||
return err;
|
|
||||||
@@ -4467,15 +4467,18 @@ err_free_mac:
|
|
||||||
|
|
||||||
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
|
|
||||||
{
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
- dpaa2_mac_disconnect(priv->mac);
|
|
||||||
+ struct dpaa2_mac *mac = priv->mac;
|
|
||||||
+
|
|
||||||
+ priv->mac = NULL;
|
|
||||||
|
|
||||||
- if (!dpaa2_eth_has_mac(priv))
|
|
||||||
+ if (!mac)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- dpaa2_mac_close(priv->mac);
|
|
||||||
- kfree(priv->mac);
|
|
||||||
- priv->mac = NULL;
|
|
||||||
+ if (dpaa2_mac_is_type_phy(mac))
|
|
||||||
+ dpaa2_mac_disconnect(mac);
|
|
||||||
+
|
|
||||||
+ dpaa2_mac_close(mac);
|
|
||||||
+ kfree(mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
|
|
@ -1,73 +0,0 @@
|
|||||||
From a5e7f7e277bd4403c45c1c7922d56d0eb08dbc7c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:15 +0200
|
|
||||||
Subject: [PATCH 08/14] net: dpaa2-switch: assign port_priv->mac after
|
|
||||||
dpaa2_mac_connect() call
|
|
||||||
|
|
||||||
The dpaa2-switch has the exact same locking requirements when connected
|
|
||||||
to a DPMAC, so it needs port_priv->mac to always point either to NULL,
|
|
||||||
or to a DPMAC with a fully initialized phylink instance.
|
|
||||||
|
|
||||||
Make the same preparatory change in the dpaa2-switch driver as in the
|
|
||||||
dpaa2-eth one.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 21 +++++++++++--------
|
|
||||||
1 file changed, 12 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
@@ -1450,9 +1450,8 @@ static int dpaa2_switch_port_connect_mac
|
|
||||||
err = dpaa2_mac_open(mac);
|
|
||||||
if (err)
|
|
||||||
goto err_free_mac;
|
|
||||||
- port_priv->mac = mac;
|
|
||||||
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
+ if (dpaa2_mac_is_type_phy(mac)) {
|
|
||||||
err = dpaa2_mac_connect(mac);
|
|
||||||
if (err) {
|
|
||||||
netdev_err(port_priv->netdev,
|
|
||||||
@@ -1462,11 +1461,12 @@ static int dpaa2_switch_port_connect_mac
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ port_priv->mac = mac;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_close_mac:
|
|
||||||
dpaa2_mac_close(mac);
|
|
||||||
- port_priv->mac = NULL;
|
|
||||||
err_free_mac:
|
|
||||||
kfree(mac);
|
|
||||||
return err;
|
|
||||||
@@ -1474,15 +1474,18 @@ err_free_mac:
|
|
||||||
|
|
||||||
static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
|
|
||||||
{
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
- dpaa2_mac_disconnect(port_priv->mac);
|
|
||||||
+ struct dpaa2_mac *mac = port_priv->mac;
|
|
||||||
+
|
|
||||||
+ port_priv->mac = NULL;
|
|
||||||
|
|
||||||
- if (!dpaa2_switch_port_has_mac(port_priv))
|
|
||||||
+ if (!mac)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- dpaa2_mac_close(port_priv->mac);
|
|
||||||
- kfree(port_priv->mac);
|
|
||||||
- port_priv->mac = NULL;
|
|
||||||
+ if (dpaa2_mac_is_type_phy(mac))
|
|
||||||
+ dpaa2_mac_disconnect(mac);
|
|
||||||
+
|
|
||||||
+ dpaa2_mac_close(mac);
|
|
||||||
+ kfree(mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
|
|
@ -1,111 +0,0 @@
|
|||||||
From ce44b6ed9ee65efa9b3025552c513842eabcab88 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:16 +0200
|
|
||||||
Subject: [PATCH 09/14] net: dpaa2: publish MAC stringset to ethtool -S even if
|
|
||||||
MAC is missing
|
|
||||||
|
|
||||||
DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC
|
|
||||||
objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S"
|
|
||||||
unstructured counters. Those counters are only shown for the entity
|
|
||||||
owning the netdev (DPNI, DPSW) if it's connected to a DPMAC.
|
|
||||||
|
|
||||||
The ethtool stringset code path is split into multiple callbacks, but
|
|
||||||
currently, connecting and disconnecting the DPMAC takes the rtnl_lock().
|
|
||||||
This blocks the entire ethtool code path from running, see
|
|
||||||
ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() ->
|
|
||||||
strset_prepare_data().
|
|
||||||
|
|
||||||
This is going to be a problem if we are going to no longer require
|
|
||||||
rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC
|
|
||||||
could appear between ops->get_sset_count() and ops->get_strings().
|
|
||||||
If it appears out of the blue, we will provide a stringset into an array
|
|
||||||
that was dimensioned thinking the DPMAC wouldn't be there => array
|
|
||||||
accessed out of bounds.
|
|
||||||
|
|
||||||
There isn't really a good way to work around that, and I don't want to
|
|
||||||
put too much pressure on the ethtool framework by playing locking games.
|
|
||||||
Just make the DPMAC counters be always available. They'll be zeroes if
|
|
||||||
the DPNI or DPSW isn't connected to a DPMAC.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 12 +++---------
|
|
||||||
.../ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 11 ++---------
|
|
||||||
2 files changed, 5 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
@@ -186,7 +186,6 @@ static int dpaa2_eth_set_pauseparam(stru
|
|
||||||
static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
|
|
||||||
u8 *data)
|
|
||||||
{
|
|
||||||
- struct dpaa2_eth_priv *priv = netdev_priv(netdev);
|
|
||||||
u8 *p = data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
@@ -200,22 +199,17 @@ static void dpaa2_eth_get_strings(struct
|
|
||||||
strscpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
|
|
||||||
p += ETH_GSTRING_LEN;
|
|
||||||
}
|
|
||||||
- if (dpaa2_eth_has_mac(priv))
|
|
||||||
- dpaa2_mac_get_strings(p);
|
|
||||||
+ dpaa2_mac_get_strings(p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
|
|
||||||
{
|
|
||||||
- int num_ss_stats = DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS;
|
|
||||||
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
-
|
|
||||||
switch (sset) {
|
|
||||||
case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
|
|
||||||
- if (dpaa2_eth_has_mac(priv))
|
|
||||||
- num_ss_stats += dpaa2_mac_get_sset_count();
|
|
||||||
- return num_ss_stats;
|
|
||||||
+ return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS +
|
|
||||||
+ dpaa2_mac_get_sset_count();
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
@@ -145,14 +145,9 @@ dpaa2_switch_set_link_ksettings(struct n
|
|
||||||
static int
|
|
||||||
dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
|
|
||||||
{
|
|
||||||
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
|
|
||||||
- int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;
|
|
||||||
-
|
|
||||||
switch (sset) {
|
|
||||||
case ETH_SS_STATS:
|
|
||||||
- if (port_priv->mac)
|
|
||||||
- num_ss_stats += dpaa2_mac_get_sset_count();
|
|
||||||
- return num_ss_stats;
|
|
||||||
+ return DPAA2_SWITCH_NUM_COUNTERS + dpaa2_mac_get_sset_count();
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
@@ -161,7 +156,6 @@ dpaa2_switch_ethtool_get_sset_count(stru
|
|
||||||
static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
|
|
||||||
u32 stringset, u8 *data)
|
|
||||||
{
|
|
||||||
- struct ethsw_port_priv *port_priv = netdev_priv(netdev);
|
|
||||||
u8 *p = data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
@@ -172,8 +166,7 @@ static void dpaa2_switch_ethtool_get_str
|
|
||||||
ETH_GSTRING_LEN);
|
|
||||||
p += ETH_GSTRING_LEN;
|
|
||||||
}
|
|
||||||
- if (port_priv->mac)
|
|
||||||
- dpaa2_mac_get_strings(p);
|
|
||||||
+ dpaa2_mac_get_strings(p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
From c838d9fd7e6ba9ddd6006bf0a296396266e9f121 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:17 +0200
|
|
||||||
Subject: [PATCH 10/14] net: dpaa2-switch replace direct MAC access with
|
|
||||||
dpaa2_switch_port_has_mac()
|
|
||||||
|
|
||||||
The helper function will gain a lockdep annotation in a future patch.
|
|
||||||
Make sure to benefit from it.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
@@ -189,7 +189,7 @@ static void dpaa2_switch_ethtool_get_sta
|
|
||||||
dpaa2_switch_ethtool_counters[i].name, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (port_priv->mac)
|
|
||||||
+ if (dpaa2_switch_port_has_mac(port_priv))
|
|
||||||
dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
|||||||
From e0ea63162cb5f1ca7f844d6ef5fc4079448ee2d5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:18 +0200
|
|
||||||
Subject: [PATCH 11/14] net: dpaa2-eth: connect to MAC before requesting the
|
|
||||||
"endpoint changed" IRQ
|
|
||||||
|
|
||||||
dpaa2_eth_connect_mac() is called both from dpaa2_eth_probe() and from
|
|
||||||
dpni_irq0_handler_thread().
|
|
||||||
|
|
||||||
It could happen that the DPNI gets connected to a DPMAC on the fsl-mc
|
|
||||||
bus exactly during probe, as soon as the "endpoint change" interrupt is
|
|
||||||
requested in dpaa2_eth_setup_irqs(). This will cause the
|
|
||||||
dpni_irq0_handler_thread() to register a phylink instance for that DPMAC.
|
|
||||||
|
|
||||||
Then, the probing function will also try to register a phylink instance
|
|
||||||
for the same DPMAC, operation which should fail (and this will fail the
|
|
||||||
probing of the driver).
|
|
||||||
|
|
||||||
Reorder dpaa2_eth_setup_irqs() and dpaa2_eth_connect_mac(), such that
|
|
||||||
dpni_irq0_handler_thread() never races with the DPMAC-related portion of
|
|
||||||
the probing path.
|
|
||||||
|
|
||||||
Also reorder dpaa2_eth_disconnect_mac() to be in the mirror position of
|
|
||||||
dpaa2_eth_connect_mac() in the teardown path.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 18 +++++++++---------
|
|
||||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -4711,6 +4711,10 @@ static int dpaa2_eth_probe(struct fsl_mc
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ err = dpaa2_eth_connect_mac(priv);
|
|
||||||
+ if (err)
|
|
||||||
+ goto err_connect_mac;
|
|
||||||
+
|
|
||||||
err = dpaa2_eth_setup_irqs(dpni_dev);
|
|
||||||
if (err) {
|
|
||||||
netdev_warn(net_dev, "Failed to set link interrupt, fall back to polling\n");
|
|
||||||
@@ -4723,10 +4727,6 @@ static int dpaa2_eth_probe(struct fsl_mc
|
|
||||||
priv->do_link_poll = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
- err = dpaa2_eth_connect_mac(priv);
|
|
||||||
- if (err)
|
|
||||||
- goto err_connect_mac;
|
|
||||||
-
|
|
||||||
err = dpaa2_eth_dl_alloc(priv);
|
|
||||||
if (err)
|
|
||||||
goto err_dl_register;
|
|
||||||
@@ -4762,13 +4762,13 @@ err_dl_port_add:
|
|
||||||
err_dl_trap_register:
|
|
||||||
dpaa2_eth_dl_free(priv);
|
|
||||||
err_dl_register:
|
|
||||||
- dpaa2_eth_disconnect_mac(priv);
|
|
||||||
-err_connect_mac:
|
|
||||||
if (priv->do_link_poll)
|
|
||||||
kthread_stop(priv->poll_thread);
|
|
||||||
else
|
|
||||||
fsl_mc_free_irqs(dpni_dev);
|
|
||||||
err_poll_thread:
|
|
||||||
+ dpaa2_eth_disconnect_mac(priv);
|
|
||||||
+err_connect_mac:
|
|
||||||
dpaa2_eth_free_rings(priv);
|
|
||||||
err_alloc_rings:
|
|
||||||
err_csum:
|
|
||||||
@@ -4816,9 +4816,6 @@ static int dpaa2_eth_remove(struct fsl_m
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unregister_netdev(net_dev);
|
|
||||||
- rtnl_lock();
|
|
||||||
- dpaa2_eth_disconnect_mac(priv);
|
|
||||||
- rtnl_unlock();
|
|
||||||
|
|
||||||
dpaa2_eth_dl_port_del(priv);
|
|
||||||
dpaa2_eth_dl_traps_unregister(priv);
|
|
||||||
@@ -4829,6 +4826,9 @@ static int dpaa2_eth_remove(struct fsl_m
|
|
||||||
else
|
|
||||||
fsl_mc_free_irqs(ls_dev);
|
|
||||||
|
|
||||||
+ rtnl_lock();
|
|
||||||
+ dpaa2_eth_disconnect_mac(priv);
|
|
||||||
+ rtnl_unlock();
|
|
||||||
dpaa2_eth_free_rings(priv);
|
|
||||||
free_percpu(priv->fd);
|
|
||||||
free_percpu(priv->sgt_cache);
|
|
@ -1,320 +0,0 @@
|
|||||||
From 5e448a17dfa2e95166534df7f677a3694ef6187d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:19 +0200
|
|
||||||
Subject: [PATCH 12/14] net: dpaa2-eth: serialize changes to priv->mac with a
|
|
||||||
mutex
|
|
||||||
|
|
||||||
The dpaa2 architecture permits dynamic connections between objects on
|
|
||||||
the fsl-mc bus, specifically between a DPNI object (represented by a
|
|
||||||
struct net_device) and a DPMAC object (represented by a struct phylink).
|
|
||||||
|
|
||||||
The DPNI driver is notified when those connections are created/broken
|
|
||||||
through the dpni_irq0_handler_thread() method. To ensure that ethtool
|
|
||||||
operations, as well as netdev up/down operations serialize with the
|
|
||||||
connection/disconnection of the DPNI with a DPMAC,
|
|
||||||
dpni_irq0_handler_thread() takes the rtnl_lock() to block those other
|
|
||||||
operations from taking place.
|
|
||||||
|
|
||||||
There is code called by dpaa2_mac_connect() which wants to acquire the
|
|
||||||
rtnl_mutex once again, see phylink_create() -> phylink_register_sfp() ->
|
|
||||||
sfp_bus_add_upstream() -> rtnl_lock(). So the strategy doesn't quite
|
|
||||||
work out, even though it's fairly simple.
|
|
||||||
|
|
||||||
Create a different strategy, where all code paths in the dpaa2-eth
|
|
||||||
driver access priv->mac only while they are holding priv->mac_lock.
|
|
||||||
The phylink instance is not created or connected to the PHY under the
|
|
||||||
priv->mac_lock, but only assigned to priv->mac then. This will eliminate
|
|
||||||
the reliance on the rtnl_mutex.
|
|
||||||
|
|
||||||
Add lockdep annotations and put comments where holding the lock is not
|
|
||||||
necessary, and priv->mac can be dereferenced freely.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++++++--
|
|
||||||
.../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 ++
|
|
||||||
.../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 58 +++++++++++++++----
|
|
||||||
3 files changed, 91 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -2021,8 +2021,11 @@ static int dpaa2_eth_link_state_update(s
|
|
||||||
|
|
||||||
/* When we manage the MAC/PHY using phylink there is no need
|
|
||||||
* to manually update the netif_carrier.
|
|
||||||
+ * We can avoid locking because we are called from the "link changed"
|
|
||||||
+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
|
|
||||||
+ * (the writer to priv->mac), so we cannot race with it.
|
|
||||||
*/
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
+ if (dpaa2_mac_is_type_phy(priv->mac))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Chech link state; speed / duplex changes are not treated yet */
|
|
||||||
@@ -2061,6 +2064,8 @@ static int dpaa2_eth_open(struct net_dev
|
|
||||||
priv->dpbp_dev->obj_desc.id, priv->bpid);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (!dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
/* We'll only start the txqs when the link is actually ready;
|
|
||||||
* make sure we don't race against the link up notification,
|
|
||||||
@@ -2079,6 +2084,7 @@ static int dpaa2_eth_open(struct net_dev
|
|
||||||
|
|
||||||
err = dpni_enable(priv->mc_io, 0, priv->mc_token);
|
|
||||||
if (err < 0) {
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
netdev_err(net_dev, "dpni_enable() failed\n");
|
|
||||||
goto enable_err;
|
|
||||||
}
|
|
||||||
@@ -2086,6 +2092,8 @@ static int dpaa2_eth_open(struct net_dev
|
|
||||||
if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
dpaa2_mac_start(priv->mac);
|
|
||||||
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
enable_err:
|
|
||||||
@@ -2157,6 +2165,8 @@ static int dpaa2_eth_stop(struct net_dev
|
|
||||||
int dpni_enabled = 0;
|
|
||||||
int retries = 10;
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
dpaa2_mac_stop(priv->mac);
|
|
||||||
} else {
|
|
||||||
@@ -2164,6 +2174,8 @@ static int dpaa2_eth_stop(struct net_dev
|
|
||||||
netif_carrier_off(net_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
/* On dpni_disable(), the MC firmware will:
|
|
||||||
* - stop MAC Rx and wait for all Rx frames to be enqueued to software
|
|
||||||
* - cut off WRIOP dequeues from egress FQs and wait until transmission
|
|
||||||
@@ -2489,12 +2501,20 @@ static int dpaa2_eth_ts_ioctl(struct net
|
|
||||||
static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|
||||||
{
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(dev);
|
|
||||||
+ int err;
|
|
||||||
|
|
||||||
if (cmd == SIOCSHWTSTAMP)
|
|
||||||
return dpaa2_eth_ts_ioctl(dev, rq, cmd);
|
|
||||||
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
+ err = phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
@@ -4454,7 +4474,9 @@ static int dpaa2_eth_connect_mac(struct
|
|
||||||
goto err_close_mac;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
priv->mac = mac;
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -4467,9 +4489,12 @@ err_free_mac:
|
|
||||||
|
|
||||||
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
|
|
||||||
{
|
|
||||||
- struct dpaa2_mac *mac = priv->mac;
|
|
||||||
+ struct dpaa2_mac *mac;
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+ mac = priv->mac;
|
|
||||||
priv->mac = NULL;
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
|
|
||||||
if (!mac)
|
|
||||||
return;
|
|
||||||
@@ -4488,6 +4513,7 @@ static irqreturn_t dpni_irq0_handler_thr
|
|
||||||
struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev);
|
|
||||||
struct net_device *net_dev = dev_get_drvdata(dev);
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
+ bool had_mac;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = dpni_get_irq_status(dpni_dev->mc_io, 0, dpni_dev->mc_handle,
|
|
||||||
@@ -4505,7 +4531,12 @@ static irqreturn_t dpni_irq0_handler_thr
|
|
||||||
dpaa2_eth_update_tx_fqids(priv);
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
- if (dpaa2_eth_has_mac(priv))
|
|
||||||
+ /* We can avoid locking because the "endpoint changed" IRQ
|
|
||||||
+ * handler is the only one who changes priv->mac at runtime,
|
|
||||||
+ * so we are not racing with anyone.
|
|
||||||
+ */
|
|
||||||
+ had_mac = !!priv->mac;
|
|
||||||
+ if (had_mac)
|
|
||||||
dpaa2_eth_disconnect_mac(priv);
|
|
||||||
else
|
|
||||||
dpaa2_eth_connect_mac(priv);
|
|
||||||
@@ -4606,6 +4637,8 @@ static int dpaa2_eth_probe(struct fsl_mc
|
|
||||||
priv = netdev_priv(net_dev);
|
|
||||||
priv->net_dev = net_dev;
|
|
||||||
|
|
||||||
+ mutex_init(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
priv->iommu_domain = iommu_get_domain_for_dev(dev);
|
|
||||||
|
|
||||||
priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
|
|
||||||
@@ -580,6 +580,8 @@ struct dpaa2_eth_priv {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct dpaa2_mac *mac;
|
|
||||||
+ /* Serializes changes to priv->mac */
|
|
||||||
+ struct mutex mac_lock;
|
|
||||||
struct workqueue_struct *dpaa2_ptp_wq;
|
|
||||||
struct work_struct tx_onestep_tstamp;
|
|
||||||
struct sk_buff_head tx_skbs;
|
|
||||||
@@ -733,11 +735,15 @@ static inline unsigned int dpaa2_eth_rx_
|
|
||||||
|
|
||||||
static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
|
|
||||||
{
|
|
||||||
+ lockdep_assert_held(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
return dpaa2_mac_is_type_phy(priv->mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
|
|
||||||
{
|
|
||||||
+ lockdep_assert_held(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
return priv->mac ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
|
|
||||||
@@ -86,11 +86,16 @@ static void dpaa2_eth_get_drvinfo(struct
|
|
||||||
static int dpaa2_eth_nway_reset(struct net_device *net_dev)
|
|
||||||
{
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
+ int err = -EOPNOTSUPP;
|
|
||||||
+
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
|
|
||||||
if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return phylink_ethtool_nway_reset(priv->mac->phylink);
|
|
||||||
+ err = phylink_ethtool_nway_reset(priv->mac->phylink);
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
|
|
||||||
- return -EOPNOTSUPP;
|
|
||||||
+ return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
@@ -98,10 +103,18 @@ dpaa2_eth_get_link_ksettings(struct net_
|
|
||||||
struct ethtool_link_ksettings *link_settings)
|
|
||||||
{
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
+ int err;
|
|
||||||
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return phylink_ethtool_ksettings_get(priv->mac->phylink,
|
|
||||||
- link_settings);
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
+ err = phylink_ethtool_ksettings_get(priv->mac->phylink,
|
|
||||||
+ link_settings);
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
|
|
||||||
link_settings->base.autoneg = AUTONEG_DISABLE;
|
|
||||||
if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX))
|
|
||||||
@@ -116,11 +129,17 @@ dpaa2_eth_set_link_ksettings(struct net_
|
|
||||||
const struct ethtool_link_ksettings *link_settings)
|
|
||||||
{
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
+ int err = -EOPNOTSUPP;
|
|
||||||
|
|
||||||
- if (!dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return -EOPNOTSUPP;
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
+ err = phylink_ethtool_ksettings_set(priv->mac->phylink,
|
|
||||||
+ link_settings);
|
|
||||||
|
|
||||||
- return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
|
|
||||||
@@ -129,11 +148,16 @@ static void dpaa2_eth_get_pauseparam(str
|
|
||||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
|
||||||
u64 link_options = priv->link_state.options;
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
phylink_ethtool_get_pauseparam(priv->mac->phylink, pause);
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
pause->rx_pause = dpaa2_eth_rx_pause_enabled(link_options);
|
|
||||||
pause->tx_pause = dpaa2_eth_tx_pause_enabled(link_options);
|
|
||||||
pause->autoneg = AUTONEG_DISABLE;
|
|
||||||
@@ -152,9 +176,17 @@ static int dpaa2_eth_set_pauseparam(stru
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (dpaa2_eth_is_type_phy(priv))
|
|
||||||
- return phylink_ethtool_set_pauseparam(priv->mac->phylink,
|
|
||||||
- pause);
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_eth_is_type_phy(priv)) {
|
|
||||||
+ err = phylink_ethtool_set_pauseparam(priv->mac->phylink,
|
|
||||||
+ pause);
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (pause->autoneg)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
@@ -307,8 +339,12 @@ static void dpaa2_eth_get_ethtool_stats(
|
|
||||||
}
|
|
||||||
*(data + i++) = buf_cnt;
|
|
||||||
|
|
||||||
+ mutex_lock(&priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (dpaa2_eth_has_mac(priv))
|
|
||||||
dpaa2_mac_get_ethtool_stats(priv->mac, data + i);
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&priv->mac_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dpaa2_eth_prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask,
|
|
@ -1,203 +0,0 @@
|
|||||||
From 80d12452a5f160c39d63efc1be07df36f9d07133 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:20 +0200
|
|
||||||
Subject: [PATCH 13/14] net: dpaa2-switch: serialize changes to priv->mac with
|
|
||||||
a mutex
|
|
||||||
|
|
||||||
The dpaa2-switch driver uses a DPMAC in the same way as the dpaa2-eth
|
|
||||||
driver, so we need to duplicate the locking solution established by the
|
|
||||||
previous change to the switch driver as well.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
.../freescale/dpaa2/dpaa2-switch-ethtool.c | 32 +++++++++++++++----
|
|
||||||
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 31 ++++++++++++++++--
|
|
||||||
.../ethernet/freescale/dpaa2/dpaa2-switch.h | 2 ++
|
|
||||||
3 files changed, 55 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
|
|
||||||
@@ -60,11 +60,18 @@ dpaa2_switch_get_link_ksettings(struct n
|
|
||||||
{
|
|
||||||
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
|
|
||||||
struct dpsw_link_state state = {0};
|
|
||||||
- int err = 0;
|
|
||||||
+ int err;
|
|
||||||
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
- return phylink_ethtool_ksettings_get(port_priv->mac->phylink,
|
|
||||||
- link_ksettings);
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
+ err = phylink_ethtool_ksettings_get(port_priv->mac->phylink,
|
|
||||||
+ link_ksettings);
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
|
|
||||||
err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
|
|
||||||
port_priv->ethsw_data->dpsw_handle,
|
|
||||||
@@ -99,9 +106,16 @@ dpaa2_switch_set_link_ksettings(struct n
|
|
||||||
bool if_running;
|
|
||||||
int err = 0, ret;
|
|
||||||
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
- return phylink_ethtool_ksettings_set(port_priv->mac->phylink,
|
|
||||||
- link_ksettings);
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
+ if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
+ err = phylink_ethtool_ksettings_set(port_priv->mac->phylink,
|
|
||||||
+ link_ksettings);
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
+ return err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
|
|
||||||
/* Interface needs to be down to change link settings */
|
|
||||||
if_running = netif_running(netdev);
|
|
||||||
@@ -189,8 +203,12 @@ static void dpaa2_switch_ethtool_get_sta
|
|
||||||
dpaa2_switch_ethtool_counters[i].name, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (dpaa2_switch_port_has_mac(port_priv))
|
|
||||||
dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct ethtool_ops dpaa2_switch_port_ethtool_ops = {
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
@@ -603,8 +603,11 @@ static int dpaa2_switch_port_link_state_
|
|
||||||
|
|
||||||
/* When we manage the MAC/PHY using phylink there is no need
|
|
||||||
* to manually update the netif_carrier.
|
|
||||||
+ * We can avoid locking because we are called from the "link changed"
|
|
||||||
+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler
|
|
||||||
+ * (the writer to port_priv->mac), so we cannot race with it.
|
|
||||||
*/
|
|
||||||
- if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
+ if (dpaa2_mac_is_type_phy(port_priv->mac))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Interrupts are received even though no one issued an 'ifconfig up'
|
|
||||||
@@ -684,6 +687,8 @@ static int dpaa2_switch_port_open(struct
|
|
||||||
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (!dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
/* Explicitly set carrier off, otherwise
|
|
||||||
* netif_carrier_ok() will return true and cause 'ip link show'
|
|
||||||
@@ -697,6 +702,7 @@ static int dpaa2_switch_port_open(struct
|
|
||||||
port_priv->ethsw_data->dpsw_handle,
|
|
||||||
port_priv->idx);
|
|
||||||
if (err) {
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
netdev_err(netdev, "dpsw_if_enable err %d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
@@ -706,6 +712,8 @@ static int dpaa2_switch_port_open(struct
|
|
||||||
if (dpaa2_switch_port_is_type_phy(port_priv))
|
|
||||||
dpaa2_mac_start(port_priv->mac);
|
|
||||||
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -715,6 +723,8 @@ static int dpaa2_switch_port_stop(struct
|
|
||||||
struct ethsw_core *ethsw = port_priv->ethsw_data;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
if (dpaa2_switch_port_is_type_phy(port_priv)) {
|
|
||||||
dpaa2_mac_stop(port_priv->mac);
|
|
||||||
} else {
|
|
||||||
@@ -722,6 +732,8 @@ static int dpaa2_switch_port_stop(struct
|
|
||||||
netif_carrier_off(netdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
|
|
||||||
port_priv->ethsw_data->dpsw_handle,
|
|
||||||
port_priv->idx);
|
|
||||||
@@ -1461,7 +1473,9 @@ static int dpaa2_switch_port_connect_mac
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
port_priv->mac = mac;
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -1474,9 +1488,12 @@ err_free_mac:
|
|
||||||
|
|
||||||
static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
|
|
||||||
{
|
|
||||||
- struct dpaa2_mac *mac = port_priv->mac;
|
|
||||||
+ struct dpaa2_mac *mac;
|
|
||||||
|
|
||||||
+ mutex_lock(&port_priv->mac_lock);
|
|
||||||
+ mac = port_priv->mac;
|
|
||||||
port_priv->mac = NULL;
|
|
||||||
+ mutex_unlock(&port_priv->mac_lock);
|
|
||||||
|
|
||||||
if (!mac)
|
|
||||||
return;
|
|
||||||
@@ -1495,6 +1512,7 @@ static irqreturn_t dpaa2_switch_irq0_han
|
|
||||||
struct ethsw_port_priv *port_priv;
|
|
||||||
u32 status = ~0;
|
|
||||||
int err, if_id;
|
|
||||||
+ bool had_mac;
|
|
||||||
|
|
||||||
err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
|
|
||||||
DPSW_IRQ_INDEX_IF, &status);
|
|
||||||
@@ -1513,7 +1531,12 @@ static irqreturn_t dpaa2_switch_irq0_han
|
|
||||||
|
|
||||||
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
|
|
||||||
rtnl_lock();
|
|
||||||
- if (dpaa2_switch_port_has_mac(port_priv))
|
|
||||||
+ /* We can avoid locking because the "endpoint changed" IRQ
|
|
||||||
+ * handler is the only one who changes priv->mac at runtime,
|
|
||||||
+ * so we are not racing with anyone.
|
|
||||||
+ */
|
|
||||||
+ had_mac = !!port_priv->mac;
|
|
||||||
+ if (had_mac)
|
|
||||||
dpaa2_switch_port_disconnect_mac(port_priv);
|
|
||||||
else
|
|
||||||
dpaa2_switch_port_connect_mac(port_priv);
|
|
||||||
@@ -3249,6 +3272,8 @@ static int dpaa2_switch_probe_port(struc
|
|
||||||
port_priv->netdev = port_netdev;
|
|
||||||
port_priv->ethsw_data = ethsw;
|
|
||||||
|
|
||||||
+ mutex_init(&port_priv->mac_lock);
|
|
||||||
+
|
|
||||||
port_priv->idx = port_idx;
|
|
||||||
port_priv->stp_state = BR_STATE_FORWARDING;
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
|
|
||||||
@@ -161,6 +161,8 @@ struct ethsw_port_priv {
|
|
||||||
|
|
||||||
struct dpaa2_switch_filter_block *filter_block;
|
|
||||||
struct dpaa2_mac *mac;
|
|
||||||
+ /* Protects against changes to port_priv->mac */
|
|
||||||
+ struct mutex mac_lock;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Switch data */
|
|
@ -1,113 +0,0 @@
|
|||||||
From 4ea2faf5bb13d9ba9f07e996d495c4cbe34a4236 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Date: Tue, 29 Nov 2022 16:12:21 +0200
|
|
||||||
Subject: [PATCH 14/14] net: dpaa2-mac: move rtnl_lock() only around
|
|
||||||
phylink_{,dis}connect_phy()
|
|
||||||
|
|
||||||
After the introduction of a private mac_lock that serializes access to
|
|
||||||
priv->mac (and port_priv->mac in the switch), the only remaining purpose
|
|
||||||
of rtnl_lock() is to satisfy the locking requirements of
|
|
||||||
phylink_fwnode_phy_connect() and phylink_disconnect_phy().
|
|
||||||
|
|
||||||
But the functions these live in, dpaa2_mac_connect() and
|
|
||||||
dpaa2_mac_disconnect(), have contradictory locking requirements.
|
|
||||||
While phylink_fwnode_phy_connect() wants rtnl_lock() to be held,
|
|
||||||
phylink_create() wants it to not be held.
|
|
||||||
|
|
||||||
Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch
|
|
||||||
drivers) to only surround the phylink calls that require it, in the
|
|
||||||
dpaa2-mac library code.
|
|
||||||
|
|
||||||
This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect()
|
|
||||||
run unlocked, and there isn't any danger of an AB/BA deadlock between
|
|
||||||
the rtnl_mutex and other private locks.
|
|
||||||
|
|
||||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
||||||
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|
||||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
||||||
---
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ----
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 5 +++++
|
|
||||||
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ----
|
|
||||||
3 files changed, 5 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
|
|
||||||
@@ -4530,7 +4530,6 @@ static irqreturn_t dpni_irq0_handler_thr
|
|
||||||
dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
|
|
||||||
dpaa2_eth_update_tx_fqids(priv);
|
|
||||||
|
|
||||||
- rtnl_lock();
|
|
||||||
/* We can avoid locking because the "endpoint changed" IRQ
|
|
||||||
* handler is the only one who changes priv->mac at runtime,
|
|
||||||
* so we are not racing with anyone.
|
|
||||||
@@ -4540,7 +4539,6 @@ static irqreturn_t dpni_irq0_handler_thr
|
|
||||||
dpaa2_eth_disconnect_mac(priv);
|
|
||||||
else
|
|
||||||
dpaa2_eth_connect_mac(priv);
|
|
||||||
- rtnl_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
@@ -4859,9 +4857,7 @@ static int dpaa2_eth_remove(struct fsl_m
|
|
||||||
else
|
|
||||||
fsl_mc_free_irqs(ls_dev);
|
|
||||||
|
|
||||||
- rtnl_lock();
|
|
||||||
dpaa2_eth_disconnect_mac(priv);
|
|
||||||
- rtnl_unlock();
|
|
||||||
dpaa2_eth_free_rings(priv);
|
|
||||||
free_percpu(priv->fd);
|
|
||||||
free_percpu(priv->sgt_cache);
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
|
|
||||||
@@ -428,7 +428,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *
|
|
||||||
}
|
|
||||||
mac->phylink = phylink;
|
|
||||||
|
|
||||||
+ rtnl_lock();
|
|
||||||
err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
|
|
||||||
+ rtnl_unlock();
|
|
||||||
if (err) {
|
|
||||||
netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
|
|
||||||
goto err_phylink_destroy;
|
|
||||||
@@ -446,7 +448,10 @@ err_pcs_destroy:
|
|
||||||
|
|
||||||
void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
|
|
||||||
{
|
|
||||||
+ rtnl_lock();
|
|
||||||
phylink_disconnect_phy(mac->phylink);
|
|
||||||
+ rtnl_unlock();
|
|
||||||
+
|
|
||||||
phylink_destroy(mac->phylink);
|
|
||||||
dpaa2_pcs_destroy(mac);
|
|
||||||
of_phy_put(mac->serdes_phy);
|
|
||||||
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
|
|
||||||
@@ -1530,7 +1530,6 @@ static irqreturn_t dpaa2_switch_irq0_han
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
|
|
||||||
- rtnl_lock();
|
|
||||||
/* We can avoid locking because the "endpoint changed" IRQ
|
|
||||||
* handler is the only one who changes priv->mac at runtime,
|
|
||||||
* so we are not racing with anyone.
|
|
||||||
@@ -1540,7 +1539,6 @@ static irqreturn_t dpaa2_switch_irq0_han
|
|
||||||
dpaa2_switch_port_disconnect_mac(port_priv);
|
|
||||||
else
|
|
||||||
dpaa2_switch_port_connect_mac(port_priv);
|
|
||||||
- rtnl_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
@@ -2951,9 +2949,7 @@ static void dpaa2_switch_remove_port(str
|
|
||||||
{
|
|
||||||
struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
|
|
||||||
|
|
||||||
- rtnl_lock();
|
|
||||||
dpaa2_switch_port_disconnect_mac(port_priv);
|
|
||||||
- rtnl_unlock();
|
|
||||||
free_netdev(port_priv->netdev);
|
|
||||||
ethsw->ports[port_idx] = NULL;
|
|
||||||
}
|
|
@ -13,8 +13,8 @@ Signed-off-by: Mathew McBride <matt@traverse.com.au>
|
|||||||
|
|
||||||
--- a/arch/arm/Kconfig
|
--- a/arch/arm/Kconfig
|
||||||
+++ b/arch/arm/Kconfig
|
+++ b/arch/arm/Kconfig
|
||||||
@@ -124,7 +124,6 @@ config ARM
|
@@ -128,7 +128,6 @@ config ARM
|
||||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN
|
select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
|
||||||
select IRQ_FORCED_THREADING
|
select IRQ_FORCED_THREADING
|
||||||
select LOCK_MM_AND_FIND_VMA
|
select LOCK_MM_AND_FIND_VMA
|
||||||
- select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
- select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
Loading…
Reference in New Issue
Block a user