mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-20 22:01:38 +00:00
40b02a2301
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>
204 lines
6.4 KiB
Diff
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 */
|