mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-29 10:02:23 +00:00
generic: 6.1, 6.6: mt7530: import accepted patches
Import patches for the MT7530 DSA driver from net-next tree: cae425cb43fe net: dsa: allow DSA switch drivers to provide their own phylink mac ops dd0c9855b413 net: dsa: introduce dsa_phylink_to_port() 7c5e37d7ee78 net: dsa: mt7530: simplify core operations 868ff5f4944a net: dsa: mt7530-mdio: read PHY address of switch from device tree 2c606d138518 net: dsa: mt7530: fix port mirroring for MT7988 SoC switch d59cf049c837 net: dsa: mt7530: fix mirroring frames received on local port 62d6d91db98a net: dsa: mt7530: provide own phylink MAC operations Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
70853560f8
commit
ac8bfe316b
@ -0,0 +1,99 @@
|
||||
From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:38 +0100
|
||||
Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
|
||||
|
||||
We convert from a phylink_config struct to a dsa_port struct in many
|
||||
places, let's provide a helper for this.
|
||||
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 6 ++++++
|
||||
net/dsa/port.c | 12 ++++++------
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -337,6 +337,12 @@ struct dsa_port {
|
||||
struct list_head vlans;
|
||||
};
|
||||
|
||||
+static inline struct dsa_port *
|
||||
+dsa_phylink_to_port(struct phylink_config *config)
|
||||
+{
|
||||
+ return container_of(config, struct dsa_port, pl_config);
|
||||
+}
|
||||
+
|
||||
/* TODO: ideally DSA ports would have a single dp->link_dp member,
|
||||
* and no dst->rtable nor this struct dsa_link would be needed,
|
||||
* but this would require some more complex tree walking,
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1552,7 +1552,7 @@ static void dsa_port_phylink_validate(st
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_validate) {
|
||||
@@ -1567,7 +1567,7 @@ static void dsa_port_phylink_validate(st
|
||||
static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int err;
|
||||
|
||||
@@ -1589,7 +1589,7 @@ static struct phylink_pcs *
|
||||
dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1603,7 +1603,7 @@ static void dsa_port_phylink_mac_config(
|
||||
unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_config)
|
||||
@@ -1614,7 +1614,7 @@ static void dsa_port_phylink_mac_config(
|
||||
|
||||
static void dsa_port_phylink_mac_an_restart(struct phylink_config *config)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_an_restart)
|
||||
@@ -1627,7 +1627,7 @@ static void dsa_port_phylink_mac_link_do
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phy_device *phydev = NULL;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1650,7 +1650,7 @@ static void dsa_port_phylink_mac_link_up
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_link_up) {
|
@ -0,0 +1,117 @@
|
||||
From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:43 +0100
|
||||
Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
|
||||
phylink mac ops
|
||||
|
||||
Rather than having a shim for each and every phylink MAC operation,
|
||||
allow DSA switch drivers to provide their own ops structure. When a
|
||||
DSA driver provides the phylink MAC operations, the shimmed ops must
|
||||
not be provided, so fail an attempt to register a switch with both
|
||||
the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
|
||||
operations populated in dsa_switch_ops populated.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 5 +++++
|
||||
net/dsa/dsa.c | 11 +++++++++++
|
||||
net/dsa/port.c | 26 ++++++++++++++++++++------
|
||||
3 files changed, 36 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -468,6 +468,11 @@ struct dsa_switch {
|
||||
const struct dsa_switch_ops *ops;
|
||||
|
||||
/*
|
||||
+ * Allow a DSA switch driver to override the phylink MAC ops
|
||||
+ */
|
||||
+ const struct phylink_mac_ops *phylink_mac_ops;
|
||||
+
|
||||
+ /*
|
||||
* Slave mii_bus and devices for the individual ports.
|
||||
*/
|
||||
u32 phys_mii_mask;
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1675,6 +1675,7 @@ static const struct phylink_mac_ops dsa_
|
||||
|
||||
int dsa_port_phylink_create(struct dsa_port *dp)
|
||||
{
|
||||
+ const struct phylink_mac_ops *mac_ops;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
phy_interface_t mode;
|
||||
struct phylink *pl;
|
||||
@@ -1694,8 +1695,12 @@ int dsa_port_phylink_create(struct dsa_p
|
||||
if (ds->ops->phylink_get_caps)
|
||||
ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
|
||||
|
||||
- pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
- mode, &dsa_port_phylink_mac_ops);
|
||||
+ mac_ops = &dsa_port_phylink_mac_ops;
|
||||
+ if (ds->phylink_mac_ops)
|
||||
+ mac_ops = ds->phylink_mac_ops;
|
||||
+
|
||||
+ pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
|
||||
+ mac_ops);
|
||||
if (IS_ERR(pl)) {
|
||||
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
|
||||
return PTR_ERR(pl);
|
||||
@@ -1961,12 +1966,23 @@ static void dsa_shared_port_validate_of(
|
||||
dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
}
|
||||
|
||||
+static void dsa_shared_port_link_down(struct dsa_port *dp)
|
||||
+{
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+
|
||||
+ if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
|
||||
+ ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+ else if (ds->ops->phylink_mac_link_down)
|
||||
+ ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+}
|
||||
+
|
||||
int dsa_shared_port_link_register_of(struct dsa_port *dp)
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
bool missing_link_description;
|
||||
bool missing_phy_mode;
|
||||
- int port = dp->index;
|
||||
|
||||
dsa_shared_port_validate_of(dp, &missing_phy_mode,
|
||||
&missing_link_description);
|
||||
@@ -1982,9 +1998,7 @@ int dsa_shared_port_link_register_of(str
|
||||
"Skipping phylink registration for %s port %d\n",
|
||||
dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
} else {
|
||||
- if (ds->ops->phylink_mac_link_down)
|
||||
- ds->ops->phylink_mac_link_down(ds, port,
|
||||
- MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
|
||||
+ dsa_shared_port_link_down(dp);
|
||||
|
||||
return dsa_shared_port_phylink_register(dp);
|
||||
}
|
||||
--- a/net/dsa/dsa2.c
|
||||
+++ b/net/dsa/dsa2.c
|
||||
@@ -1736,6 +1736,15 @@ static int dsa_switch_probe(struct dsa_s
|
||||
if (!ds->num_ports)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (ds->phylink_mac_ops) {
|
||||
+ if (ds->ops->phylink_mac_select_pcs ||
|
||||
+ ds->ops->phylink_mac_config ||
|
||||
+ ds->ops->phylink_mac_link_down ||
|
||||
+ ds->ops->phylink_mac_link_up ||
|
||||
+ ds->ops->adjust_link)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
if (np) {
|
||||
err = dsa_switch_parse_of(ds, np);
|
||||
if (err)
|
@ -0,0 +1,135 @@
|
||||
From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Fri, 12 Apr 2024 16:15:34 +0100
|
||||
Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Convert mt753x to provide its own phylink MAC operations, thus avoiding
|
||||
the shim layer in DSA's port.c
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
|
||||
1 file changed, 29 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2841,28 +2841,34 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
}
|
||||
|
||||
static struct phylink_pcs *
|
||||
-mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
|
||||
+mt753x_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
- return &priv->pcs[port].pcs;
|
||||
+ return &priv->pcs[dp->index].pcs;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- return priv->ports[port].sgmii_pcs;
|
||||
+ return priv->ports[dp->index].sgmii_pcs;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
-mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
+mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ int port = dp->index;
|
||||
+
|
||||
+ priv = ds->priv;
|
||||
|
||||
if ((port == 5 || port == 6) && priv->info->mac_port_config)
|
||||
priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
@@ -2872,23 +2878,25 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_down(struct phylink_config *config,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
+ mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_up(struct phylink_config *config,
|
||||
+ struct phy_device *phydev,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
- struct phy_device *phydev,
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
u32 mcr;
|
||||
|
||||
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
@@ -2923,7 +2931,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
}
|
||||
}
|
||||
|
||||
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
|
||||
+ mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
@@ -3148,16 +3156,19 @@ const struct dsa_switch_ops mt7530_switc
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
- .phylink_mac_config = mt753x_phylink_mac_config,
|
||||
- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
|
||||
- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
.master_state_change = mt753x_conduit_state_change,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
+static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
|
||||
+ .mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
+ .mac_config = mt753x_phylink_mac_config,
|
||||
+ .mac_link_down = mt753x_phylink_mac_link_down,
|
||||
+ .mac_link_up = mt753x_phylink_mac_link_up,
|
||||
+};
|
||||
+
|
||||
const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
@@ -3227,6 +3238,7 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
priv->dev = dev;
|
||||
priv->ds->priv = priv;
|
||||
priv->ds->ops = &mt7530_switch_ops;
|
||||
+ priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
|
||||
mutex_init(&priv->reg_mutex);
|
||||
dev_set_drvdata(dev, priv);
|
||||
|
@ -0,0 +1,70 @@
|
||||
From d4097ddef078a113643a6dcde01e99741f852adb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Sat, 13 Apr 2024 16:01:39 +0300
|
||||
Subject: [PATCH 2/5] net: dsa: mt7530: fix mirroring frames received on local
|
||||
port
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This switch intellectual property provides a bit on the ARL global control
|
||||
register which controls allowing mirroring frames which are received on the
|
||||
local port (monitor port). This bit is unset after reset.
|
||||
|
||||
This ability must be enabled to fully support the port mirroring feature on
|
||||
this switch intellectual property.
|
||||
|
||||
Therefore, this patch fixes the traffic not being reflected on a port,
|
||||
which would be configured like below:
|
||||
|
||||
tc qdisc add dev swp0 clsact
|
||||
|
||||
tc filter add dev swp0 ingress matchall skip_sw \
|
||||
action mirred egress mirror dev swp0
|
||||
|
||||
As a side note, this configuration provides the hairpinning feature for a
|
||||
single port.
|
||||
|
||||
Fixes: 37feab6076aa ("net: dsa: mt7530: add support for port mirroring")
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
drivers/net/dsa/mt7530.h | 4 ++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2471,6 +2471,9 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
|
||||
+ /* Allow mirroring frames received on the local port (monitor port). */
|
||||
+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
|
||||
+
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
ret = mt7530_setup_vlan0(priv);
|
||||
if (ret)
|
||||
@@ -2582,6 +2585,9 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
|
||||
+ /* Allow mirroring frames received on the local port (monitor port). */
|
||||
+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
|
||||
+
|
||||
/* Flush the FDB table */
|
||||
ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
|
||||
if (ret < 0)
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -32,6 +32,10 @@ enum mt753x_id {
|
||||
#define SYSC_REG_RSTCTRL 0x34
|
||||
#define RESET_MCM BIT(2)
|
||||
|
||||
+/* Register for ARL global control */
|
||||
+#define MT753X_AGC 0xc
|
||||
+#define LOCAL_EN BIT(7)
|
||||
+
|
||||
/* Registers to mac forward control for unknown frames */
|
||||
#define MT7530_MFC 0x10
|
||||
#define BC_FFP(x) (((x) & 0xff) << 24)
|
@ -0,0 +1,49 @@
|
||||
From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Sat, 13 Apr 2024 16:01:40 +0300
|
||||
Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC
|
||||
switch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
|
||||
v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU
|
||||
forward control register. Currently, the MT7530 DSA subdriver configures
|
||||
bits 0 to 2 of the CPU forward control register which breaks the port
|
||||
mirroring feature for the MT7988 SoC switch.
|
||||
|
||||
Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET()
|
||||
macros which utilise the correct bits.
|
||||
|
||||
Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1876,14 +1876,16 @@ mt7530_port_vlan_del(struct dsa_switch *
|
||||
|
||||
static int mt753x_mirror_port_get(unsigned int id, u32 val)
|
||||
{
|
||||
- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
+ return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
+ MT7531_MIRROR_PORT_GET(val) :
|
||||
+ MIRROR_PORT(val);
|
||||
}
|
||||
|
||||
static int mt753x_mirror_port_set(unsigned int id, u32 val)
|
||||
{
|
||||
- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
+ return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
+ MT7531_MIRROR_PORT_SET(val) :
|
||||
+ MIRROR_PORT(val);
|
||||
}
|
||||
|
||||
static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
|
@ -0,0 +1,238 @@
|
||||
From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:30 +0300
|
||||
Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
|
||||
device tree
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Read the PHY address the switch listens on from the reg property of the
|
||||
switch node on the device tree. This change brings support for MT7530
|
||||
switches on boards with such bootstrapping configuration where the switch
|
||||
listens on a different PHY address than the hardcoded PHY address on the
|
||||
driver, 31.
|
||||
|
||||
As described on the "MT7621 Programming Guide v0.4" document, the MT7530
|
||||
switch and its PHYs can be configured to listen on the range of 7-12,
|
||||
15-20, 23-28, and 31 and 0-4 PHY addresses.
|
||||
|
||||
There are operations where the switch PHY registers are used. For the PHY
|
||||
address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
|
||||
into a macro and use it. The PHY address for the control PHY is 0 when the
|
||||
switch listens on 31. In any other case, it is one greater than the PHY
|
||||
address the switch listens on.
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
|
||||
drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++------------
|
||||
drivers/net/dsa/mt7530.h | 4 +++-
|
||||
3 files changed, 41 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -18,7 +18,8 @@
|
||||
static int
|
||||
mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
|
||||
lo = val & 0xffff;
|
||||
hi = val >> 16;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, r, lo);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, r, lo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
page = (reg >> 6) & 0x3ff;
|
||||
r = (reg >> 2) & 0xf;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
+ lo = bus->read(bus, priv->mdiodev->addr, r);
|
||||
+ hi = bus->read(bus, priv->mdiodev->addr, 0x10);
|
||||
|
||||
*val = (hi << 16) | (lo & 0xffff);
|
||||
|
||||
@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
- regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7530_regmap_bus, priv->bus,
|
||||
+ regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
mt7531_pcs_config[i]);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
|
||||
priv->bus = mdiodev->bus;
|
||||
priv->dev = &mdiodev->dev;
|
||||
+ priv->mdiodev = mdiodev;
|
||||
|
||||
ret = mt7530_probe_common(priv);
|
||||
if (ret)
|
||||
@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
regmap_config->reg_stride = 4;
|
||||
regmap_config->max_register = MT7530_CREV;
|
||||
regmap_config->disable_locking = true;
|
||||
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
- priv->bus, regmap_config);
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
+ regmap_config);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
|
||||
int value, ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, 0, MII_MMD_DATA);
|
||||
+ value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
|
||||
return value;
|
||||
err:
|
||||
@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
|
||||
int ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the data into MMD's selected register */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, data);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, data);
|
||||
err:
|
||||
if (ret < 0)
|
||||
dev_err(&bus->dev,
|
||||
@@ -2670,16 +2678,19 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
* phy_[read,write]_mmd_indirect is called, we provide our own
|
||||
* mt7531_ind_mmd_phy_[read,write] to complete this function.
|
||||
*/
|
||||
- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
|
||||
+ val = mt7531_ind_c45_phy_read(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4);
|
||||
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
|
||||
val &= ~MT7531_PHY_PLL_OFF;
|
||||
- mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
|
||||
- CORE_PLL_GROUP4, val);
|
||||
+ mt7531_ind_c45_phy_write(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
|
||||
|
||||
/* Disable EEE advertisement on the switch PHYs. */
|
||||
- for (i = MT753X_CTRL_PHY_ADDR;
|
||||
- i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
|
||||
+ for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
|
||||
+ i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
|
||||
+ i++) {
|
||||
mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
|
||||
0);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
|
||||
#define MT7531_PHY_PLL_OFF BIT(5)
|
||||
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
|
||||
|
||||
-#define MT753X_CTRL_PHY_ADDR 0
|
||||
+#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
|
||||
|
||||
#define CORE_PLL_GROUP5 0x404
|
||||
#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
|
||||
@@ -771,6 +771,7 @@ struct mt753x_info {
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
* @active_cpu_ports: Holding the active CPU ports
|
||||
+ * @mdiodev: The pointer to the MDIO device structure
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -797,6 +798,7 @@ struct mt7530_priv {
|
||||
u32 irq_enable;
|
||||
int (*create_sgmii)(struct mt7530_priv *priv);
|
||||
u8 active_cpu_ports;
|
||||
+ struct mdio_device *mdiodev;
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
@ -0,0 +1,186 @@
|
||||
From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:31 +0300
|
||||
Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The core_rmw() function calls core_read_mmd_indirect() to read the
|
||||
requested register, and then calls core_write_mmd_indirect() to write the
|
||||
requested value to the register. Because Clause 22 is used to access Clause
|
||||
45 registers, some operations on core_write_mmd_indirect() are
|
||||
unnecessarily run. Get rid of core_read_mmd_indirect() and
|
||||
core_write_mmd_indirect(), and run only the necessary operations on
|
||||
core_write() and core_rmw().
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
|
||||
1 file changed, 43 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
|
||||
MIB_DESC(1, 0xb8, "RxArlDrop"),
|
||||
};
|
||||
|
||||
-/* Since phy_device has not yet been created and
|
||||
- * phy_{read,write}_mmd_indirect is not available, we provide our own
|
||||
- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
|
||||
- * to complete this function.
|
||||
- */
|
||||
-static int
|
||||
-core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
|
||||
+static void
|
||||
+mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
- int value, ret;
|
||||
+ int ret;
|
||||
+
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
- /* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA);
|
||||
-
|
||||
- return value;
|
||||
+ /* Write the data into MMD's selected register */
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
- dev_err(&bus->dev, "failed to read mmd register\n");
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
- return ret;
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
-static int
|
||||
-core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
|
||||
- int devad, u32 data)
|
||||
+static void
|
||||
+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
+ u32 val;
|
||||
int ret;
|
||||
|
||||
+ mt7530_mutex_lock(priv);
|
||||
+
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
+ /* Read the content of the MMD's selected register */
|
||||
+ val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
/* Write the data into MMD's selected register */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, data);
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
if (ret < 0)
|
||||
- dev_err(&bus->dev,
|
||||
- "failed to write mmd register\n");
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
-{
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
-
|
||||
- mt7530_mutex_unlock(priv);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
mt7530_mutex_unlock(priv);
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:38 +0100
|
||||
Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
|
||||
|
||||
We convert from a phylink_config struct to a dsa_port struct in many
|
||||
places, let's provide a helper for this.
|
||||
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 6 ++++++
|
||||
net/dsa/port.c | 12 ++++++------
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -327,6 +327,12 @@ struct dsa_port {
|
||||
};
|
||||
};
|
||||
|
||||
+static inline struct dsa_port *
|
||||
+dsa_phylink_to_port(struct phylink_config *config)
|
||||
+{
|
||||
+ return container_of(config, struct dsa_port, pl_config);
|
||||
+}
|
||||
+
|
||||
/* TODO: ideally DSA ports would have a single dp->link_dp member,
|
||||
* and no dst->rtable nor this struct dsa_link would be needed,
|
||||
* but this would require some more complex tree walking,
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1572,7 +1572,7 @@ static struct phylink_pcs *
|
||||
dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1586,7 +1586,7 @@ static int dsa_port_phylink_mac_prepare(
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int err = 0;
|
||||
|
||||
@@ -1601,7 +1601,7 @@ static void dsa_port_phylink_mac_config(
|
||||
unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_config)
|
||||
@@ -1614,7 +1614,7 @@ static int dsa_port_phylink_mac_finish(s
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
int err = 0;
|
||||
|
||||
@@ -1629,7 +1629,7 @@ static void dsa_port_phylink_mac_link_do
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct phy_device *phydev = NULL;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
@@ -1652,7 +1652,7 @@ static void dsa_port_phylink_mac_link_up
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->phylink_mac_link_up) {
|
@ -0,0 +1,119 @@
|
||||
From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 10 Apr 2024 20:42:43 +0100
|
||||
Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
|
||||
phylink mac ops
|
||||
|
||||
Rather than having a shim for each and every phylink MAC operation,
|
||||
allow DSA switch drivers to provide their own ops structure. When a
|
||||
DSA driver provides the phylink MAC operations, the shimmed ops must
|
||||
not be provided, so fail an attempt to register a switch with both
|
||||
the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
|
||||
operations populated in dsa_switch_ops populated.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 5 +++++
|
||||
net/dsa/dsa.c | 11 +++++++++++
|
||||
net/dsa/port.c | 26 ++++++++++++++++++++------
|
||||
3 files changed, 36 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -458,6 +458,11 @@ struct dsa_switch {
|
||||
const struct dsa_switch_ops *ops;
|
||||
|
||||
/*
|
||||
+ * Allow a DSA switch driver to override the phylink MAC ops
|
||||
+ */
|
||||
+ const struct phylink_mac_ops *phylink_mac_ops;
|
||||
+
|
||||
+ /*
|
||||
* Slave mii_bus and devices for the individual ports.
|
||||
*/
|
||||
u32 phys_mii_mask;
|
||||
--- a/net/dsa/dsa.c
|
||||
+++ b/net/dsa/dsa.c
|
||||
@@ -1510,6 +1510,17 @@ static int dsa_switch_probe(struct dsa_s
|
||||
if (!ds->num_ports)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (ds->phylink_mac_ops) {
|
||||
+ if (ds->ops->phylink_mac_select_pcs ||
|
||||
+ ds->ops->phylink_mac_prepare ||
|
||||
+ ds->ops->phylink_mac_config ||
|
||||
+ ds->ops->phylink_mac_finish ||
|
||||
+ ds->ops->phylink_mac_link_down ||
|
||||
+ ds->ops->phylink_mac_link_up ||
|
||||
+ ds->ops->adjust_link)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
if (np) {
|
||||
err = dsa_switch_parse_of(ds, np);
|
||||
if (err)
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1677,6 +1677,7 @@ static const struct phylink_mac_ops dsa_
|
||||
|
||||
int dsa_port_phylink_create(struct dsa_port *dp)
|
||||
{
|
||||
+ const struct phylink_mac_ops *mac_ops;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
phy_interface_t mode;
|
||||
struct phylink *pl;
|
||||
@@ -1700,8 +1701,12 @@ int dsa_port_phylink_create(struct dsa_p
|
||||
}
|
||||
}
|
||||
|
||||
- pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
- mode, &dsa_port_phylink_mac_ops);
|
||||
+ mac_ops = &dsa_port_phylink_mac_ops;
|
||||
+ if (ds->phylink_mac_ops)
|
||||
+ mac_ops = ds->phylink_mac_ops;
|
||||
+
|
||||
+ pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
|
||||
+ mac_ops);
|
||||
if (IS_ERR(pl)) {
|
||||
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
|
||||
return PTR_ERR(pl);
|
||||
@@ -1967,12 +1972,23 @@ static void dsa_shared_port_validate_of(
|
||||
dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
}
|
||||
|
||||
+static void dsa_shared_port_link_down(struct dsa_port *dp)
|
||||
+{
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+
|
||||
+ if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
|
||||
+ ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+ else if (ds->ops->phylink_mac_link_down)
|
||||
+ ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_NA);
|
||||
+}
|
||||
+
|
||||
int dsa_shared_port_link_register_of(struct dsa_port *dp)
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
bool missing_link_description;
|
||||
bool missing_phy_mode;
|
||||
- int port = dp->index;
|
||||
|
||||
dsa_shared_port_validate_of(dp, &missing_phy_mode,
|
||||
&missing_link_description);
|
||||
@@ -1988,9 +2004,7 @@ int dsa_shared_port_link_register_of(str
|
||||
"Skipping phylink registration for %s port %d\n",
|
||||
dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
|
||||
} else {
|
||||
- if (ds->ops->phylink_mac_link_down)
|
||||
- ds->ops->phylink_mac_link_down(ds, port,
|
||||
- MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
|
||||
+ dsa_shared_port_link_down(dp);
|
||||
|
||||
return dsa_shared_port_phylink_register(dp);
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Fri, 12 Apr 2024 16:15:34 +0100
|
||||
Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Convert mt753x to provide its own phylink MAC operations, thus avoiding
|
||||
the shim layer in DSA's port.c
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
|
||||
1 file changed, 29 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2850,28 +2850,34 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
}
|
||||
|
||||
static struct phylink_pcs *
|
||||
-mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
|
||||
+mt753x_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
- return &priv->pcs[port].pcs;
|
||||
+ return &priv->pcs[dp->index].pcs;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- return priv->ports[port].sgmii_pcs;
|
||||
+ return priv->ports[dp->index].sgmii_pcs;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
-mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
+mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ int port = dp->index;
|
||||
+
|
||||
+ priv = ds->priv;
|
||||
|
||||
if ((port == 5 || port == 6) && priv->info->mac_port_config)
|
||||
priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
@@ -2881,23 +2887,25 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_down(struct phylink_config *config,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
|
||||
- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
+ mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
-static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
+static void mt753x_phylink_mac_link_up(struct phylink_config *config,
|
||||
+ struct phy_device *phydev,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
- struct phy_device *phydev,
|
||||
int speed, int duplex,
|
||||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_phylink_to_port(config);
|
||||
+ struct mt7530_priv *priv = dp->ds->priv;
|
||||
u32 mcr;
|
||||
|
||||
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
@@ -2932,7 +2940,7 @@ static void mt753x_phylink_mac_link_up(s
|
||||
}
|
||||
}
|
||||
|
||||
- mt7530_set(priv, MT7530_PMCR_P(port), mcr);
|
||||
+ mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
@@ -3152,16 +3160,19 @@ const struct dsa_switch_ops mt7530_switc
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
- .phylink_mac_config = mt753x_phylink_mac_config,
|
||||
- .phylink_mac_link_down = mt753x_phylink_mac_link_down,
|
||||
- .phylink_mac_link_up = mt753x_phylink_mac_link_up,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
.master_state_change = mt753x_conduit_state_change,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
+static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
|
||||
+ .mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
+ .mac_config = mt753x_phylink_mac_config,
|
||||
+ .mac_link_down = mt753x_phylink_mac_link_down,
|
||||
+ .mac_link_up = mt753x_phylink_mac_link_up,
|
||||
+};
|
||||
+
|
||||
const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
@@ -3239,6 +3250,7 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
priv->dev = dev;
|
||||
priv->ds->priv = priv;
|
||||
priv->ds->ops = &mt7530_switch_ops;
|
||||
+ priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
|
||||
mutex_init(&priv->reg_mutex);
|
||||
dev_set_drvdata(dev, priv);
|
||||
|
@ -0,0 +1,70 @@
|
||||
From d4097ddef078a113643a6dcde01e99741f852adb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Sat, 13 Apr 2024 16:01:39 +0300
|
||||
Subject: [PATCH 2/5] net: dsa: mt7530: fix mirroring frames received on local
|
||||
port
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This switch intellectual property provides a bit on the ARL global control
|
||||
register which controls allowing mirroring frames which are received on the
|
||||
local port (monitor port). This bit is unset after reset.
|
||||
|
||||
This ability must be enabled to fully support the port mirroring feature on
|
||||
this switch intellectual property.
|
||||
|
||||
Therefore, this patch fixes the traffic not being reflected on a port,
|
||||
which would be configured like below:
|
||||
|
||||
tc qdisc add dev swp0 clsact
|
||||
|
||||
tc filter add dev swp0 ingress matchall skip_sw \
|
||||
action mirred egress mirror dev swp0
|
||||
|
||||
As a side note, this configuration provides the hairpinning feature for a
|
||||
single port.
|
||||
|
||||
Fixes: 37feab6076aa ("net: dsa: mt7530: add support for port mirroring")
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
drivers/net/dsa/mt7530.h | 4 ++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2480,6 +2480,9 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
|
||||
+ /* Allow mirroring frames received on the local port (monitor port). */
|
||||
+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
|
||||
+
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
ret = mt7530_setup_vlan0(priv);
|
||||
if (ret)
|
||||
@@ -2591,6 +2594,9 @@ mt7531_setup_common(struct dsa_switch *d
|
||||
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
|
||||
+ /* Allow mirroring frames received on the local port (monitor port). */
|
||||
+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
|
||||
+
|
||||
/* Flush the FDB table */
|
||||
ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
|
||||
if (ret < 0)
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -32,6 +32,10 @@ enum mt753x_id {
|
||||
#define SYSC_REG_RSTCTRL 0x34
|
||||
#define RESET_MCM BIT(2)
|
||||
|
||||
+/* Register for ARL global control */
|
||||
+#define MT753X_AGC 0xc
|
||||
+#define LOCAL_EN BIT(7)
|
||||
+
|
||||
/* Registers to mac forward control for unknown frames */
|
||||
#define MT7530_MFC 0x10
|
||||
#define BC_FFP(x) (((x) & 0xff) << 24)
|
@ -0,0 +1,49 @@
|
||||
From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Sat, 13 Apr 2024 16:01:40 +0300
|
||||
Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC
|
||||
switch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
|
||||
v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU
|
||||
forward control register. Currently, the MT7530 DSA subdriver configures
|
||||
bits 0 to 2 of the CPU forward control register which breaks the port
|
||||
mirroring feature for the MT7988 SoC switch.
|
||||
|
||||
Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET()
|
||||
macros which utilise the correct bits.
|
||||
|
||||
Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1883,14 +1883,16 @@ mt7530_port_vlan_del(struct dsa_switch *
|
||||
|
||||
static int mt753x_mirror_port_get(unsigned int id, u32 val)
|
||||
{
|
||||
- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
+ return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
+ MT7531_MIRROR_PORT_GET(val) :
|
||||
+ MIRROR_PORT(val);
|
||||
}
|
||||
|
||||
static int mt753x_mirror_port_set(unsigned int id, u32 val)
|
||||
{
|
||||
- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
|
||||
- MIRROR_PORT(val);
|
||||
+ return (id == ID_MT7531 || id == ID_MT7988) ?
|
||||
+ MT7531_MIRROR_PORT_SET(val) :
|
||||
+ MIRROR_PORT(val);
|
||||
}
|
||||
|
||||
static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
|
@ -0,0 +1,238 @@
|
||||
From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:30 +0300
|
||||
Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
|
||||
device tree
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Read the PHY address the switch listens on from the reg property of the
|
||||
switch node on the device tree. This change brings support for MT7530
|
||||
switches on boards with such bootstrapping configuration where the switch
|
||||
listens on a different PHY address than the hardcoded PHY address on the
|
||||
driver, 31.
|
||||
|
||||
As described on the "MT7621 Programming Guide v0.4" document, the MT7530
|
||||
switch and its PHYs can be configured to listen on the range of 7-12,
|
||||
15-20, 23-28, and 31 and 0-4 PHY addresses.
|
||||
|
||||
There are operations where the switch PHY registers are used. For the PHY
|
||||
address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
|
||||
into a macro and use it. The PHY address for the control PHY is 0 when the
|
||||
switch listens on 31. In any other case, it is one greater than the PHY
|
||||
address the switch listens on.
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
|
||||
drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++------------
|
||||
drivers/net/dsa/mt7530.h | 4 +++-
|
||||
3 files changed, 41 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -18,7 +18,8 @@
|
||||
static int
|
||||
mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
|
||||
lo = val & 0xffff;
|
||||
hi = val >> 16;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, r, lo);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, r, lo);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
- struct mii_bus *bus = context;
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+ struct mii_bus *bus = priv->bus;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
page = (reg >> 6) & 0x3ff;
|
||||
r = (reg >> 2) & 0xf;
|
||||
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
+ lo = bus->read(bus, priv->mdiodev->addr, r);
|
||||
+ hi = bus->read(bus, priv->mdiodev->addr, 0x10);
|
||||
|
||||
*val = (hi << 16) | (lo & 0xffff);
|
||||
|
||||
@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
- regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7530_regmap_bus, priv->bus,
|
||||
+ regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
mt7531_pcs_config[i]);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
|
||||
priv->bus = mdiodev->bus;
|
||||
priv->dev = &mdiodev->dev;
|
||||
+ priv->mdiodev = mdiodev;
|
||||
|
||||
ret = mt7530_probe_common(priv);
|
||||
if (ret)
|
||||
@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
regmap_config->reg_stride = 4;
|
||||
regmap_config->max_register = MT7530_CREV;
|
||||
regmap_config->disable_locking = true;
|
||||
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
- priv->bus, regmap_config);
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
|
||||
+ regmap_config);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
|
||||
int value, ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, 0, MII_MMD_DATA);
|
||||
+ value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
|
||||
return value;
|
||||
err:
|
||||
@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
|
||||
int ret;
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, prtad);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the data into MMD's selected register */
|
||||
- ret = bus->write(bus, 0, MII_MMD_DATA, data);
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, data);
|
||||
err:
|
||||
if (ret < 0)
|
||||
dev_err(&bus->dev,
|
||||
@@ -2679,16 +2687,19 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
* phy_[read,write]_mmd_indirect is called, we provide our own
|
||||
* mt7531_ind_mmd_phy_[read,write] to complete this function.
|
||||
*/
|
||||
- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
|
||||
+ val = mt7531_ind_c45_phy_read(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
MDIO_MMD_VEND2, CORE_PLL_GROUP4);
|
||||
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
|
||||
val &= ~MT7531_PHY_PLL_OFF;
|
||||
- mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
|
||||
- CORE_PLL_GROUP4, val);
|
||||
+ mt7531_ind_c45_phy_write(priv,
|
||||
+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
|
||||
|
||||
/* Disable EEE advertisement on the switch PHYs. */
|
||||
- for (i = MT753X_CTRL_PHY_ADDR;
|
||||
- i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
|
||||
+ for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
|
||||
+ i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
|
||||
+ i++) {
|
||||
mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
|
||||
0);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
|
||||
#define MT7531_PHY_PLL_OFF BIT(5)
|
||||
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
|
||||
|
||||
-#define MT753X_CTRL_PHY_ADDR 0
|
||||
+#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
|
||||
|
||||
#define CORE_PLL_GROUP5 0x404
|
||||
#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
|
||||
@@ -778,6 +778,7 @@ struct mt753x_info {
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
* @active_cpu_ports: Holding the active CPU ports
|
||||
+ * @mdiodev: The pointer to the MDIO device structure
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -804,6 +805,7 @@ struct mt7530_priv {
|
||||
u32 irq_enable;
|
||||
int (*create_sgmii)(struct mt7530_priv *priv);
|
||||
u8 active_cpu_ports;
|
||||
+ struct mdio_device *mdiodev;
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
@ -0,0 +1,186 @@
|
||||
From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
|
||||
Date: Thu, 18 Apr 2024 08:35:31 +0300
|
||||
Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The core_rmw() function calls core_read_mmd_indirect() to read the
|
||||
requested register, and then calls core_write_mmd_indirect() to write the
|
||||
requested value to the register. Because Clause 22 is used to access Clause
|
||||
45 registers, some operations on core_write_mmd_indirect() are
|
||||
unnecessarily run. Get rid of core_read_mmd_indirect() and
|
||||
core_write_mmd_indirect(), and run only the necessary operations on
|
||||
core_write() and core_rmw().
|
||||
|
||||
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
|
||||
1 file changed, 43 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
|
||||
MIB_DESC(1, 0xb8, "RxArlDrop"),
|
||||
};
|
||||
|
||||
-/* Since phy_device has not yet been created and
|
||||
- * phy_{read,write}_mmd_indirect is not available, we provide our own
|
||||
- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
|
||||
- * to complete this function.
|
||||
- */
|
||||
-static int
|
||||
-core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
|
||||
+static void
|
||||
+mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->bus)
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
- int value, ret;
|
||||
+ int ret;
|
||||
+
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
- /* Read the content of the MMD's selected register */
|
||||
- value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA);
|
||||
-
|
||||
- return value;
|
||||
+ /* Write the data into MMD's selected register */
|
||||
+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
- dev_err(&bus->dev, "failed to read mmd register\n");
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
- return ret;
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
-static int
|
||||
-core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
|
||||
- int devad, u32 data)
|
||||
+static void
|
||||
+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
+ u32 val;
|
||||
int ret;
|
||||
|
||||
+ mt7530_mutex_lock(priv);
|
||||
+
|
||||
/* Write the desired MMD Devad */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Write the desired MMD register address */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, prtad);
|
||||
+ MII_MMD_DATA, reg);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* Select the Function : DATA with no post increment */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
|
||||
+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
+ /* Read the content of the MMD's selected register */
|
||||
+ val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
+ MII_MMD_DATA);
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
/* Write the data into MMD's selected register */
|
||||
ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
|
||||
- MII_MMD_DATA, data);
|
||||
+ MII_MMD_DATA, val);
|
||||
err:
|
||||
if (ret < 0)
|
||||
- dev_err(&bus->dev,
|
||||
- "failed to write mmd register\n");
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
-{
|
||||
- if (priv->bus)
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
-{
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
-
|
||||
- mt7530_mutex_unlock(priv);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- mt7530_mutex_lock(priv);
|
||||
-
|
||||
- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
+ dev_err(&bus->dev, "failed to write mmd register\n");
|
||||
|
||||
mt7530_mutex_unlock(priv);
|
||||
}
|
Loading…
Reference in New Issue
Block a user