openwrt/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
Mathew McBride 40b02a2301
armsr: rename from armvirt
Now that the armvirt target supports real hardware, not just
VMs, thanks to the addition of EFI, rename it to something
more appropriate.

'armsr' (Arm SystemReady) was chosen after the name of
the Arm standards program.

The 32 and 64 bit targets have also been renamed
armv7 and armv8 respectively, to allow future profiles
where required (such as armv9).

See https://developer.arm.com/documentation/102858/0100/Introduction
for more information.

Signed-off-by: Mathew McBride <matt@traverse.com.au>
2023-06-10 21:30:19 +02:00

204 lines
6.4 KiB
Diff

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);
@@ -3256,6 +3279,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 */