The MediaTek MT7988 SoC comes with a built-in switch very similar to
previous MT7530 and MT7531. However, the switch address space is mapped
into the SoCs memory space rather than being connected via MDIO.
Using MMIO simplifies register access and also removes the need for a bus
lock, and for that reason also makes interrupt handling more light-weight.
Note that this is different from previous SoCs like MT7621 and MT7623N
which also came with an integrated MT7530-like switch which yet had to be
accessed via MDIO.
Split-off the part of the driver registering an MDIO driver, then add
another module acting as MMIO/platform driver.
The whole series has been tested on various MediaTek boards:
* MT7623A + MT7530 (BPi-R2)
* MT7986A + MT7531 (BPi-R3)
* MT7988A reference board
Changes since v1:
* use 'internal' PHY mode where appropriate
* use regmap_update_bits in mt7530_rmw
* improve dt-bindings
Changes since RFC v3:
* WARN_ON_ONCE if register read fails
* move probing of the reset GPIO and reset controller link out of
common probe function, as they are not actually common
Changes since RFC v2:
* split into many small commits to ease review
* introduce helper functions to reduce code duplication
* use helpers for locking to make lock-skipping easier and less ugly
to implement.
* add dt-bindings for mediatek,mt7988-switch
Changes since initial RFC:
* use regmap for register access and move register access to bus-
specific driver
* move initialization of MT7531 SGMII PCS to MDIO driver
Daniel Golle (14):
net: dsa: mt7530: make some noise if register read fails
net: dsa: mt7530: refactor SGMII PCS creation
net: dsa: mt7530: use unlocked regmap accessors
net: dsa: mt7530: use regmap to access switch register space
net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function
net: dsa: mt7530: introduce mutex helpers
net: dsa: mt7530: move p5_intf_modes() function to mt7530.c
net: dsa: mt7530: introduce mt7530_probe_common helper function
net: dsa: mt7530: introduce mt7530_remove_common helper function
net: dsa: mt7530: split-off common parts from mt7531_setup
net: dsa: mt7530: introduce separate MDIO driver
net: dsa: mt7530: skip locking if MDIO bus isn't present
net: dsa: mt7530: introduce driver for MT7988 built-in switch
dt-bindings: net: dsa: mediatek,mt7530: add mediatek,mt7988-switch
.../bindings/net/dsa/mediatek,mt7530.yaml | 26 +-
MAINTAINERS | 3 +
drivers/net/dsa/Kconfig | 27 +-
drivers/net/dsa/Makefile | 2 +
drivers/net/dsa/mt7530-mdio.c | 271 +++++++++
drivers/net/dsa/mt7530-mmio.c | 101 ++++
drivers/net/dsa/mt7530.c | 565 +++++++++---------
drivers/net/dsa/mt7530.h | 38 +-
8 files changed, 713 insertions(+), 320 deletions(-)
create mode 100644 drivers/net/dsa/mt7530-mdio.c
create mode 100644 drivers/net/dsa/mt7530-mmio.c
base-commit: 51aaa68222d6c34f0373cf95223ce2f230329e8f
--
2.40.0
Simply returning the negative error value instead of the read value
doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
so this kind of error will not go unnoticed.
Suggested-by: Andrew Lunn <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a0d99af897ace..18d4aa6bb9968 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0) {
+ WARN_ON_ONCE(1);
dev_err(&bus->dev,
"failed to read mt7530 register\n");
- return ret;
+ return 0;
}
lo = bus->read(bus, 0x1f, r);
--
2.40.0
Instead of macro templates use a dedidated function and allocated
regmap_config when creating the regmaps for the pcs-mtk-lynxi
instances.
This is in preparation to switching to use unlocked regmap accessors
and have regmap's locking API handle locking for us.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 24 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 18d4aa6bb9968..5685c71bc9173 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2927,26 +2927,56 @@ static const struct regmap_bus mt7531_regmap_bus = {
.reg_update_bits = mt7530_regmap_update_bits,
};
-#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
- { \
- .name = _name, \
- .reg_bits = 16, \
- .val_bits = 32, \
- .reg_stride = 4, \
- .reg_base = _reg_base, \
- .max_register = 0x17c, \
- }
-
-static const struct regmap_config mt7531_pcs_config[] = {
- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
-};
+static int
+mt7531_create_sgmii(struct mt7530_priv *priv)
+{
+ struct regmap_config *mt7531_pcs_config[2];
+ struct phylink_pcs *pcs;
+ struct regmap *regmap;
+ int i, ret = 0;
+
+ for (i = 0; i < 2; i++) {
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
+ sizeof(struct regmap_config),
+ GFP_KERNEL);
+ if (!mt7531_pcs_config[i]) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
+ mt7531_pcs_config[i]->reg_bits = 16;
+ mt7531_pcs_config[i]->val_bits = 32;
+ mt7531_pcs_config[i]->reg_stride = 4;
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
+ mt7531_pcs_config[i]->max_register = 0x17c;
+
+ regmap = devm_regmap_init(priv->dev,
+ &mt7531_regmap_bus, priv,
+ mt7531_pcs_config[i]);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ break;
+ }
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
+ if (!pcs) {
+ ret = -ENXIO;
+ break;
+ }
+ priv->ports[5 + i].sgmii_pcs = pcs;
+ }
+
+ if (ret && i)
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
+
+ return ret;
+}
static int
mt753x_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
- struct regmap *regmap;
int i, ret;
/* Initialise the PCS devices */
@@ -2968,15 +2998,11 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
- if (priv->id == ID_MT7531)
- for (i = 0; i < 2; i++) {
- regmap = devm_regmap_init(ds->dev,
- &mt7531_regmap_bus, priv,
- &mt7531_pcs_config[i]);
- priv->ports[5 + i].sgmii_pcs =
- mtk_pcs_lynxi_create(ds->dev, regmap,
- MT7531_PHYA_CTRL_SIGNAL3, 0);
- }
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret && priv->irq)
+ mt7530_free_irq_common(priv);
+ }
return ret;
}
--
2.40.0
Instead of wrapping the locked register accessor functions, use the
unlocked variants and add locking wrapper functions to let regmap
handle the locking.
This is a preparation towards being able to always use regmap to
access switch registers instead of open-coded accessor functions.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 5685c71bc9173..d8b041d79f2b7 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2900,7 +2900,7 @@ static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val
{
struct mt7530_priv *priv = context;
- *val = mt7530_read(priv, reg);
+ *val = mt7530_mii_read(priv, reg);
return 0;
};
@@ -2908,23 +2908,25 @@ static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val
{
struct mt7530_priv *priv = context;
- mt7530_write(priv, reg, val);
+ mt7530_mii_write(priv, reg, val);
return 0;
};
-static int mt7530_regmap_update_bits(void *context, unsigned int reg,
- unsigned int mask, unsigned int val)
+static void
+mt7530_mdio_regmap_lock(void *mdio_lock)
{
- struct mt7530_priv *priv = context;
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
+}
- mt7530_rmw(priv, reg, mask, val);
- return 0;
-};
+static void
+mt7530_mdio_regmap_unlock(void *mdio_lock)
+{
+ mutex_unlock(mdio_lock);
+}
static const struct regmap_bus mt7531_regmap_bus = {
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
- .reg_update_bits = mt7530_regmap_update_bits,
};
static int
@@ -2950,6 +2952,9 @@ mt7531_create_sgmii(struct mt7530_priv *priv)
mt7531_pcs_config[i]->reg_stride = 4;
mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
mt7531_pcs_config[i]->max_register = 0x17c;
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
+ 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,
&mt7531_regmap_bus, priv,
--
2.40.0
Use regmap API to access the switch register space.
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
drivers/net/dsa/mt7530.h | 2 +
2 files changed, 62 insertions(+), 39 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d8b041d79f2b7..a0e1e2e015f0b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
}
static int
-mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
{
- struct mii_bus *bus = priv->bus;
+ struct mii_bus *bus = context;
u16 page, r, lo, hi;
int ret;
@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0)
- goto err;
+ return ret;
ret = bus->write(bus, 0x1f, r, lo);
if (ret < 0)
- goto err;
+ return ret;
ret = bus->write(bus, 0x1f, 0x10, hi);
-err:
+ return ret;
+}
+
+static int
+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
+{
+ int ret;
+
+ ret = regmap_write(priv->regmap, reg, val);
+
if (ret < 0)
- dev_err(&bus->dev,
+ dev_err(priv->dev,
"failed to write mt7530 register\n");
+
return ret;
}
-static u32
-mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
+static int
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
{
- struct mii_bus *bus = priv->bus;
+ struct mii_bus *bus = context;
u16 page, r, lo, hi;
int ret;
@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0) {
+ if (ret < 0)
+ return ret;
+
+ lo = bus->read(bus, 0x1f, r);
+ hi = bus->read(bus, 0x1f, 0x10);
+
+ *val = (hi << 16) | (lo & 0xffff);
+
+ return 0;
+}
+
+static u32
+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
+{
+ int ret;
+ u32 val;
+
+ ret = regmap_read(priv->regmap, reg, &val);
+ if (ret) {
WARN_ON_ONCE(1);
- dev_err(&bus->dev,
+ dev_err(priv->dev,
"failed to read mt7530 register\n");
return 0;
}
- lo = bus->read(bus, 0x1f, r);
- hi = bus->read(bus, 0x1f, 0x10);
-
- return (hi << 16) | (lo & 0xffff);
+ return val;
}
static void
@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32 reg,
u32 mask, u32 set)
{
struct mii_bus *bus = priv->bus;
- u32 val;
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
- val = mt7530_mii_read(priv, reg);
- val &= ~mask;
- val |= set;
- mt7530_mii_write(priv, reg, val);
+ regmap_update_bits(priv->regmap, reg, mask, set);
mutex_unlock(&bus->mdio_lock);
}
@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32 reg,
static void
mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
{
- mt7530_rmw(priv, reg, 0, val);
+ mt7530_rmw(priv, reg, val, val);
}
static void
@@ -2896,22 +2917,6 @@ static const struct phylink_pcs_ops mt7530_pcs_ops = {
.pcs_an_restart = mt7530_pcs_an_restart,
};
-static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-{
- struct mt7530_priv *priv = context;
-
- *val = mt7530_mii_read(priv, reg);
- return 0;
-};
-
-static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-{
- struct mt7530_priv *priv = context;
-
- mt7530_mii_write(priv, reg, val);
- return 0;
-};
-
static void
mt7530_mdio_regmap_lock(void *mdio_lock)
{
@@ -2924,7 +2929,7 @@ mt7530_mdio_regmap_unlock(void *mdio_lock)
mutex_unlock(mdio_lock);
}
-static const struct regmap_bus mt7531_regmap_bus = {
+static const struct regmap_bus mt7530_regmap_bus = {
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
};
@@ -2957,7 +2962,7 @@ mt7531_create_sgmii(struct mt7530_priv *priv)
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
regmap = devm_regmap_init(priv->dev,
- &mt7531_regmap_bus, priv,
+ &mt7530_regmap_bus, priv->bus,
mt7531_pcs_config[i]);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
@@ -3128,6 +3133,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
mt7530_probe(struct mdio_device *mdiodev)
{
+ static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
@@ -3207,6 +3213,21 @@ mt7530_probe(struct mdio_device *mdiodev)
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
+ GFP_KERNEL);
+ if (!regmap_config)
+ return -ENOMEM;
+
+ regmap_config->reg_bits = 16;
+ regmap_config->val_bits = 32;
+ 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);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
return dsa_register_switch(priv->ds);
}
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index c5d29f3fc1d80..39aaca50961bd 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -754,6 +754,7 @@ struct mt753x_info {
* @dev: The device pointer
* @ds: The pointer to the dsa core structure
* @bus: The bus used for the device and built-in PHY
+ * @regmap: The regmap instance representing all switch registers
* @rstc: The pointer to reset control used by MCM
* @core_pwr: The power supplied into the core
* @io_pwr: The power supplied into the I/O
@@ -774,6 +775,7 @@ struct mt7530_priv {
struct device *dev;
struct dsa_switch *ds;
struct mii_bus *bus;
+ struct regmap *regmap;
struct reset_control *rstc;
struct regulator *core_pwr;
struct regulator *io_pwr;
--
2.40.0
Move creating the SGMII PCS from mt753x_setup() to the more appropriate
mt7530_probe() function.
This is done also in preparation of moving all functions related to
MDIO-connected MT753x switches to a separate module.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a0e1e2e015f0b..d285a60aaf684 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3008,12 +3008,6 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
- if (priv->id == ID_MT7531) {
- ret = mt7531_create_sgmii(priv);
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
- }
-
return ret;
}
@@ -3136,6 +3130,7 @@ mt7530_probe(struct mdio_device *mdiodev)
static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
+ int ret;
dn = mdiodev->dev.of_node;
@@ -3228,6 +3223,12 @@ mt7530_probe(struct mdio_device *mdiodev)
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret)
+ return ret;
+ }
+
return dsa_register_switch(priv->ds);
}
--
2.40.0
As the MDIO bus lock only needs to be involved if actually operating
on an MDIO-connected switch we will need to skip locking for built-in
switches which are accessed via MMIO.
Create helper functions which simplify that upcoming change.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 37 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d285a60aaf684..9d49cbc8ddcb2 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -143,31 +143,40 @@ core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
}
static void
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+mt7530_mutex_lock(struct mt7530_priv *priv)
{
- struct mii_bus *bus = priv->bus;
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+}
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+static void
+mt7530_mutex_unlock(struct mt7530_priv *priv)
+{
+ 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);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
{
- struct mii_bus *bus = priv->bus;
u32 val;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ 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);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
static void
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
- struct mii_bus *bus = priv->bus;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
mt7530_mii_write(priv, reg, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static u32
@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dummy_poll *p)
static u32
_mt7530_read(struct mt7530_dummy_poll *p)
{
- struct mii_bus *bus = p->priv->bus;
u32 val;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(p->priv);
val = mt7530_mii_read(p->priv, p->reg);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(p->priv);
return val;
}
@@ -307,13 +313,11 @@ static void
mt7530_rmw(struct mt7530_priv *priv, u32 reg,
u32 mask, u32 set)
{
- struct mii_bus *bus = priv->bus;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
regmap_update_bits(priv->regmap, reg, mask, set);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
@@ -657,14 +661,13 @@ static int
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
int regnum)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
u32 reg, val;
int ret;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -697,7 +700,7 @@ mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -706,14 +709,13 @@ static int
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
int regnum, u16 data)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
u32 val, reg;
int ret;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -745,7 +747,7 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
}
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -753,14 +755,13 @@ mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
static int
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
int ret;
u32 val;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -783,7 +784,7 @@ mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -792,14 +793,13 @@ static int
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
u16 data)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
int ret;
u32 reg;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
@@ -821,7 +821,7 @@ mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
}
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -1102,7 +1102,6 @@ static int
mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
struct mt7530_priv *priv = ds->priv;
- struct mii_bus *bus = priv->bus;
int length;
u32 val;
@@ -1113,7 +1112,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
if (!dsa_is_cpu_port(ds, port))
return 0;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
val = mt7530_mii_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
@@ -1134,7 +1133,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
mt7530_mii_write(priv, MT7530_GMACCR, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return 0;
}
@@ -1935,10 +1934,10 @@ mt7530_irq_thread_fn(int irq, void *dev_id)
u32 val;
int p;
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
- mutex_unlock(&priv->bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
for (p = 0; p < MT7530_NUM_PHYS; p++) {
if (BIT(p) & val) {
@@ -1974,7 +1973,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
{
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
}
static void
@@ -1983,7 +1982,7 @@ mt7530_irq_bus_sync_unlock(struct irq_data *d)
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
- mutex_unlock(&priv->bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static struct irq_chip mt7530_irq_chip = {
--
2.40.0
In preparation of splitting mt7530.c into a driver for MDIO-connected
as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
built-in switches move the p5_inft_modes() function from mt7530.h to
mt7530.c. The function is only needed there and will trigger a compiler
warning about a defined but unused function otherwise when including
mt7530.h in the to-be-introduced bus-specific drivers.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
drivers/net/dsa/mt7530.h | 18 ------------------
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 9d49cbc8ddcb2..1215d5e4dd38a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -943,6 +943,24 @@ mt7530_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
return 0;
}
+static const char *p5_intf_modes(unsigned int p5_interface)
+{
+ switch (p5_interface) {
+ case P5_DISABLED:
+ return "DISABLED";
+ case P5_INTF_SEL_PHY_P0:
+ return "PHY P0";
+ case P5_INTF_SEL_PHY_P4:
+ return "PHY P4";
+ case P5_INTF_SEL_GMAC5:
+ return "GMAC5";
+ case P5_INTF_SEL_GMAC5_SGMII:
+ return "GMAC5_SGMII";
+ default:
+ return "unknown";
+ }
+}
+
static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
{
struct mt7530_priv *priv = ds->priv;
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 39aaca50961bd..2a611173a7d08 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -682,24 +682,6 @@ enum p5_interface_select {
P5_INTF_SEL_GMAC5_SGMII,
};
-static const char *p5_intf_modes(unsigned int p5_interface)
-{
- switch (p5_interface) {
- case P5_DISABLED:
- return "DISABLED";
- case P5_INTF_SEL_PHY_P0:
- return "PHY P0";
- case P5_INTF_SEL_PHY_P4:
- return "PHY P4";
- case P5_INTF_SEL_GMAC5:
- return "GMAC5";
- case P5_INTF_SEL_GMAC5_SGMII:
- return "GMAC5_SGMII";
- default:
- return "unknown";
- }
-}
-
struct mt7530_priv;
struct mt753x_pcs {
--
2.40.0
Move commonly used parts from mt7530_probe into new mt7530_probe_common
helper function which will be used by both, mt7530_probe and the
to-be-introduced mt7988_probe.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 44 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 1215d5e4dd38a..a60ed8706ce35 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3142,44 +3142,21 @@ static const struct of_device_id mt7530_of_match[] = {
MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
-mt7530_probe(struct mdio_device *mdiodev)
+mt7530_probe_common(struct mt7530_priv *priv)
{
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
- int ret;
-
- dn = mdiodev->dev.of_node;
-
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
+ struct device *dev = priv->dev;
- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
if (!priv->ds)
return -ENOMEM;
- priv->ds->dev = &mdiodev->dev;
+ priv->ds->dev = dev;
priv->ds->num_ports = MT7530_NUM_PORTS;
- /* Use medatek,mcm property to distinguish hardware type that would
- * casues a little bit differences on power-on sequence.
- */
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
- if (priv->mcm) {
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
- if (IS_ERR(priv->rstc)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->rstc);
- }
- }
-
/* Get the hardware identifier from the devicetree node.
* We will need it for some of the clock and regulator setup.
*/
- priv->info = of_device_get_match_data(&mdiodev->dev);
+ priv->info = of_device_get_match_data(dev);
if (!priv->info)
return -EINVAL;
@@ -3193,23 +3170,53 @@ mt7530_probe(struct mdio_device *mdiodev)
return -EINVAL;
priv->id = priv->info->id;
+ priv->dev = dev;
+ priv->ds->priv = priv;
+ priv->ds->ops = &mt7530_switch_ops;
+ mutex_init(&priv->reg_mutex);
+ dev_set_drvdata(dev, priv);
- if (priv->id == ID_MT7530) {
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
- if (IS_ERR(priv->core_pwr))
- return PTR_ERR(priv->core_pwr);
+ return 0;
+}
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
- if (IS_ERR(priv->io_pwr))
- return PTR_ERR(priv->io_pwr);
- }
+static int
+mt7530_probe(struct mdio_device *mdiodev)
+{
+ static struct regmap_config *regmap_config;
+ struct mt7530_priv *priv;
+ struct device_node *dn;
+ int ret;
+
+ dn = mdiodev->dev.of_node;
- /* Not MCM that indicates switch works as the remote standalone
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = mdiodev->bus;
+ priv->dev = &mdiodev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ /* Use medatek,mcm property to distinguish hardware type that would
+ * cause a little bit differences on power-on sequence.
+ * Not MCM that indicates switch works as the remote standalone
* integrated circuit so the GPIO pin would be used to complete
* the reset, otherwise memory-mapped register accessing used
* through syscon provides in the case of MCM.
*/
- if (!priv->mcm) {
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
+ if (priv->mcm) {
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
+
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+ } else {
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
@@ -3218,12 +3225,15 @@ mt7530_probe(struct mdio_device *mdiodev)
}
}
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
- priv->ds->priv = priv;
- priv->ds->ops = &mt7530_switch_ops;
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(&mdiodev->dev, priv);
+ if (priv->id == ID_MT7530) {
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+ if (IS_ERR(priv->core_pwr))
+ return PTR_ERR(priv->core_pwr);
+
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
+ if (IS_ERR(priv->io_pwr))
+ return PTR_ERR(priv->io_pwr);
+ }
regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
GFP_KERNEL);
--
2.40.0
Split MT7530 switch driver into a common part and a part specific
for MDIO connected switches and multi-chip modules.
Move MDIO-specific functions to newly introduced mt7530-mdio.c while
keeping the common parts in mt7530.c.
Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
implied by CONFIG_NET_DSA_MT7530.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
MAINTAINERS | 1 +
drivers/net/dsa/Kconfig | 15 +-
drivers/net/dsa/Makefile | 1 +
drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
drivers/net/dsa/mt7530.c | 264 +--------------------------------
drivers/net/dsa/mt7530.h | 6 +
6 files changed, 300 insertions(+), 258 deletions(-)
create mode 100644 drivers/net/dsa/mt7530-mdio.c
diff --git a/MAINTAINERS b/MAINTAINERS
index dffcc253563bd..4970a6c6a0a86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13177,6 +13177,7 @@ M: Landen Chao <[email protected]>
M: DENG Qingfang <[email protected]>
L: [email protected]
S: Maintained
+F: drivers/net/dsa/mt7530-mdio.c
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 6b45fa8b69078..941d020fe4b61 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -38,11 +38,22 @@ config NET_DSA_MT7530
tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
select NET_DSA_TAG_MTK
select MEDIATEK_GE_PHY
- select PCS_MTK_LYNXI
+ imply NET_DSA_MT7530_MDIO
help
This enables support for the MediaTek MT7530 and MT7531 Ethernet
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
- MT7621ST and MT7623AI SoCs is supported.
+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
+ supported as well.
+
+config NET_DSA_MT7530_MDIO
+ tristate "MediaTek MT7530 MDIO interface driver"
+ depends on NET_DSA_MT7530
+ select PCS_MTK_LYNXI
+ help
+ This enables support for the MediaTek MT7530 and MT7531 switch
+ chips which are connected via MDIO, as well as multi-chip
+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
+ MT7621ST and MT7623AI SoCs.
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index 16eb879e0cb4d..c5da75cb0a6b5 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
diff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c
new file mode 100644
index 0000000000000..34a547b88e497
--- /dev/null
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/gpio/consumer.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/regulator/consumer.h>
+#include <net/dsa.h>
+
+#include "mt7530.h"
+
+static int
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct mii_bus *bus = context;
+ u16 page, r, lo, hi;
+ int ret;
+
+ page = (reg >> 6) & 0x3ff;
+ r = (reg >> 2) & 0xf;
+ lo = val & 0xffff;
+ hi = val >> 16;
+
+ /* MT7530 uses 31 as the pseudo port */
+ ret = bus->write(bus, 0x1f, 0x1f, page);
+ if (ret < 0)
+ return ret;
+
+ ret = bus->write(bus, 0x1f, r, lo);
+ if (ret < 0)
+ return ret;
+
+ ret = bus->write(bus, 0x1f, 0x10, hi);
+ return ret;
+}
+
+static int
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct mii_bus *bus = context;
+ 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);
+ if (ret < 0)
+ return ret;
+
+ lo = bus->read(bus, 0x1f, r);
+ hi = bus->read(bus, 0x1f, 0x10);
+
+ *val = (hi << 16) | (lo & 0xffff);
+
+ return 0;
+}
+
+static void
+mt7530_mdio_regmap_lock(void *mdio_lock)
+{
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
+}
+
+static void
+mt7530_mdio_regmap_unlock(void *mdio_lock)
+{
+ mutex_unlock(mdio_lock);
+}
+
+static const struct regmap_bus mt7530_regmap_bus = {
+ .reg_write = mt7530_regmap_write,
+ .reg_read = mt7530_regmap_read,
+};
+
+static int
+mt7531_create_sgmii(struct mt7530_priv *priv)
+{
+ struct regmap_config *mt7531_pcs_config[2];
+ struct phylink_pcs *pcs;
+ struct regmap *regmap;
+ int i, ret = 0;
+
+ for (i = 0; i < 2; i++) {
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
+ sizeof(struct regmap_config),
+ GFP_KERNEL);
+ if (!mt7531_pcs_config[i]) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
+ mt7531_pcs_config[i]->reg_bits = 16;
+ mt7531_pcs_config[i]->val_bits = 32;
+ mt7531_pcs_config[i]->reg_stride = 4;
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
+ mt7531_pcs_config[i]->max_register = 0x17c;
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
+ 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,
+ mt7531_pcs_config[i]);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ break;
+ }
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
+ if (!pcs) {
+ ret = -ENXIO;
+ break;
+ }
+ priv->ports[5 + i].sgmii_pcs = pcs;
+ }
+
+ if (ret && i)
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
+
+ return ret;
+}
+
+static const struct of_device_id mt7530_of_match[] = {
+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
+
+static int
+mt7530_probe(struct mdio_device *mdiodev)
+{
+ static struct regmap_config *regmap_config;
+ struct mt7530_priv *priv;
+ struct device_node *dn;
+ int ret;
+
+ dn = mdiodev->dev.of_node;
+
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = mdiodev->bus;
+ priv->dev = &mdiodev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ /* Use medatek,mcm property to distinguish hardware type that would
+ * cause a little bit differences on power-on sequence.
+ * Not MCM that indicates switch works as the remote standalone
+ * integrated circuit so the GPIO pin would be used to complete
+ * the reset, otherwise memory-mapped register accessing used
+ * through syscon provides in the case of MCM.
+ */
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
+ if (priv->mcm) {
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
+
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+ } else {
+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(priv->reset)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->reset);
+ }
+ }
+
+ if (priv->id == ID_MT7530) {
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+ if (IS_ERR(priv->core_pwr))
+ return PTR_ERR(priv->core_pwr);
+
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
+ if (IS_ERR(priv->io_pwr))
+ return PTR_ERR(priv->io_pwr);
+ }
+
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
+ GFP_KERNEL);
+ if (!regmap_config)
+ return -ENOMEM;
+
+ regmap_config->reg_bits = 16;
+ regmap_config->val_bits = 32;
+ 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);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret)
+ return ret;
+ }
+
+ return dsa_register_switch(priv->ds);
+}
+
+static void
+mt7530_remove(struct mdio_device *mdiodev)
+{
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
+ int ret = 0, i;
+
+ if (!priv)
+ return;
+
+ ret = regulator_disable(priv->core_pwr);
+ if (ret < 0)
+ dev_err(priv->dev,
+ "Failed to disable core power: %d\n", ret);
+
+ ret = regulator_disable(priv->io_pwr);
+ if (ret < 0)
+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
+ ret);
+
+ mt7530_remove_common(priv);
+
+ for (i = 0; i < 2; ++i)
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
+}
+
+static void mt7530_shutdown(struct mdio_device *mdiodev)
+{
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
+
+ if (!priv)
+ return;
+
+ dsa_switch_shutdown(priv->ds);
+
+ dev_set_drvdata(&mdiodev->dev, NULL);
+}
+
+static struct mdio_driver mt7530_mdio_driver = {
+ .probe = mt7530_probe,
+ .remove = mt7530_remove,
+ .shutdown = mt7530_shutdown,
+ .mdiodrv.driver = {
+ .name = "mt7530-mdio",
+ .of_match_table = mt7530_of_match,
+ },
+};
+
+mdio_module_driver(mt7530_mdio_driver);
+
+MODULE_AUTHOR("Sean Wang <[email protected]>");
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 47e3c413ccf12..ac485ee83ed07 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -14,7 +14,6 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
-#include <linux/pcs/pcs-mtk-lynxi.h>
#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -191,31 +190,6 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
core_rmw(priv, reg, val, 0);
}
-static int
-mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-{
- struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
- lo = val & 0xffff;
- hi = val >> 16;
-
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0)
- return ret;
-
- ret = bus->write(bus, 0x1f, r, lo);
- if (ret < 0)
- return ret;
-
- ret = bus->write(bus, 0x1f, 0x10, hi);
- return ret;
-}
-
static int
mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
return ret;
}
-static int
-mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-{
- struct mii_bus *bus = context;
- 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);
- if (ret < 0)
- return ret;
-
- lo = bus->read(bus, 0x1f, r);
- hi = bus->read(bus, 0x1f, 0x10);
-
- *val = (hi << 16) | (lo & 0xffff);
-
- return 0;
-}
-
static u32
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
{
@@ -2945,72 +2896,6 @@ static const struct phylink_pcs_ops mt7530_pcs_ops = {
.pcs_an_restart = mt7530_pcs_an_restart,
};
-static void
-mt7530_mdio_regmap_lock(void *mdio_lock)
-{
- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-}
-
-static void
-mt7530_mdio_regmap_unlock(void *mdio_lock)
-{
- mutex_unlock(mdio_lock);
-}
-
-static const struct regmap_bus mt7530_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
-};
-
-static int
-mt7531_create_sgmii(struct mt7530_priv *priv)
-{
- struct regmap_config *mt7531_pcs_config[2];
- struct phylink_pcs *pcs;
- struct regmap *regmap;
- int i, ret = 0;
-
- for (i = 0; i < 2; i++) {
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
- sizeof(struct regmap_config),
- GFP_KERNEL);
- if (!mt7531_pcs_config[i]) {
- ret = -ENOMEM;
- break;
- }
-
- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
- mt7531_pcs_config[i]->reg_bits = 16;
- mt7531_pcs_config[i]->val_bits = 32;
- mt7531_pcs_config[i]->reg_stride = 4;
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
- mt7531_pcs_config[i]->max_register = 0x17c;
- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
- 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,
- mt7531_pcs_config[i]);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- break;
- }
- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
- MT7531_PHYA_CTRL_SIGNAL3, 0);
- if (!pcs) {
- ret = -ENXIO;
- break;
- }
- priv->ports[5 + i].sgmii_pcs = pcs;
- }
-
- if (ret && i)
- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-
- return ret;
-}
-
static int
mt753x_setup(struct dsa_switch *ds)
{
@@ -3069,7 +2954,7 @@ static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
-static const struct dsa_switch_ops mt7530_switch_ops = {
+const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
.get_strings = mt7530_get_strings,
@@ -3103,8 +2988,9 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.get_mac_eee = mt753x_get_mac_eee,
.set_mac_eee = mt753x_set_mac_eee,
};
+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-static const struct mt753x_info mt753x_table[] = {
+const struct mt753x_info mt753x_table[] = {
[ID_MT7621] = {
.id = ID_MT7621,
.pcs_ops = &mt7530_pcs_ops,
@@ -3143,16 +3029,9 @@ static const struct mt753x_info mt753x_table[] = {
.mac_port_config = mt7531_mac_config,
},
};
+EXPORT_SYMBOL_GPL(mt753x_table);
-static const struct of_device_id mt7530_of_match[] = {
- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, mt7530_of_match);
-
-static int
+int
mt7530_probe_common(struct mt7530_priv *priv)
{
struct device *dev = priv->dev;
@@ -3189,88 +3068,9 @@ mt7530_probe_common(struct mt7530_priv *priv)
return 0;
}
+EXPORT_SYMBOL_GPL(mt7530_probe_common);
-static int
-mt7530_probe(struct mdio_device *mdiodev)
-{
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
- int ret;
-
- dn = mdiodev->dev.of_node;
-
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
-
- ret = mt7530_probe_common(priv);
- if (ret)
- return ret;
-
- /* Use medatek,mcm property to distinguish hardware type that would
- * cause a little bit differences on power-on sequence.
- * Not MCM that indicates switch works as the remote standalone
- * integrated circuit so the GPIO pin would be used to complete
- * the reset, otherwise memory-mapped register accessing used
- * through syscon provides in the case of MCM.
- */
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
- if (priv->mcm) {
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
- if (IS_ERR(priv->rstc)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->rstc);
- }
- } else {
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
- GPIOD_OUT_LOW);
- if (IS_ERR(priv->reset)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->reset);
- }
- }
-
- if (priv->id == ID_MT7530) {
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
- if (IS_ERR(priv->core_pwr))
- return PTR_ERR(priv->core_pwr);
-
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
- if (IS_ERR(priv->io_pwr))
- return PTR_ERR(priv->io_pwr);
- }
-
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
- GFP_KERNEL);
- if (!regmap_config)
- return -ENOMEM;
-
- regmap_config->reg_bits = 16;
- regmap_config->val_bits = 32;
- 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);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
- if (priv->id == ID_MT7531) {
- ret = mt7531_create_sgmii(priv);
- if (ret)
- return ret;
- }
-
- return dsa_register_switch(priv->ds);
-}
-
-static void
+void
mt7530_remove_common(struct mt7530_priv *priv)
{
if (priv->irq)
@@ -3280,55 +3080,7 @@ mt7530_remove_common(struct mt7530_priv *priv)
mutex_destroy(&priv->reg_mutex);
}
-
-static void
-mt7530_remove(struct mdio_device *mdiodev)
-{
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
- int ret = 0, i;
-
- if (!priv)
- return;
-
- ret = regulator_disable(priv->core_pwr);
- if (ret < 0)
- dev_err(priv->dev,
- "Failed to disable core power: %d\n", ret);
-
- ret = regulator_disable(priv->io_pwr);
- if (ret < 0)
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
- ret);
-
- mt7530_remove_common(priv);
-
- for (i = 0; i < 2; ++i)
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-}
-
-static void mt7530_shutdown(struct mdio_device *mdiodev)
-{
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-
- if (!priv)
- return;
-
- dsa_switch_shutdown(priv->ds);
-
- dev_set_drvdata(&mdiodev->dev, NULL);
-}
-
-static struct mdio_driver mt7530_mdio_driver = {
- .probe = mt7530_probe,
- .remove = mt7530_remove,
- .shutdown = mt7530_shutdown,
- .mdiodrv.driver = {
- .name = "mt7530",
- .of_match_table = mt7530_of_match,
- },
-};
-
-mdio_module_driver(mt7530_mdio_driver);
+EXPORT_SYMBOL_GPL(mt7530_remove_common);
MODULE_AUTHOR("Sean Wang <[email protected]>");
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 2a611173a7d08..ce02aa592a7a8 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -814,4 +814,10 @@ static inline void INIT_MT7530_DUMMY_POLL(struct mt7530_dummy_poll *p,
p->reg = reg;
}
+int mt7530_probe_common(struct mt7530_priv *priv);
+void mt7530_remove_common(struct mt7530_priv *priv);
+
+extern const struct dsa_switch_ops mt7530_switch_ops;
+extern const struct mt753x_info mt753x_table[];
+
#endif /* __MT7530_H */
--
2.40.0
Add driver for the built-in Gigabit Ethernet switch which can be found
in the MediaTek MT7988 SoC.
The switch shares most of its design with MT7530 and MT7531, but has
it's registers mapped into the SoCs register space rather than being
connected externally or internally via MDIO.
Introduce a new platform driver to support that.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
MAINTAINERS | 2 +
drivers/net/dsa/Kconfig | 12 +++
drivers/net/dsa/Makefile | 1 +
drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++-
drivers/net/dsa/mt7530.h | 12 +--
6 files changed, 255 insertions(+), 10 deletions(-)
create mode 100644 drivers/net/dsa/mt7530-mmio.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 4970a6c6a0a86..7812f0e251ad7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13175,9 +13175,11 @@ MEDIATEK SWITCH DRIVER
M: Sean Wang <[email protected]>
M: Landen Chao <[email protected]>
M: DENG Qingfang <[email protected]>
+M: Daniel Golle <[email protected]>
L: [email protected]
S: Maintained
F: drivers/net/dsa/mt7530-mdio.c
+F: drivers/net/dsa/mt7530-mmio.c
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 941d020fe4b61..3ed5391bb18d6 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -39,6 +39,7 @@ config NET_DSA_MT7530
select NET_DSA_TAG_MTK
select MEDIATEK_GE_PHY
imply NET_DSA_MT7530_MDIO
+ imply NET_DSA_MT7530_MMIO
help
This enables support for the MediaTek MT7530 and MT7531 Ethernet
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
@@ -55,6 +56,17 @@ config NET_DSA_MT7530_MDIO
module MT7530 which can be found in the MT7621AT, MT7621DAT,
MT7621ST and MT7623AI SoCs.
+config NET_DSA_MT7530_MMIO
+ tristate "MediaTek MT7530 MMIO interface driver"
+ depends on NET_DSA_MT7530
+ depends on HAS_IOMEM
+ help
+ This enables support for the built-in Ethernet switch found
+ in the MediaTek MT7988 SoC.
+ The switch is a similar design as MT7531, but the switch registers
+ are directly mapped into the SoCs register space rather than being
+ accessible via MDIO.
+
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
select NET_DSA_TAG_TRAILER
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index c5da75cb0a6b5..cb9a97340e580 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -8,6 +8,7 @@ endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
new file mode 100644
index 0000000000000..1a3d4b692f349
--- /dev/null
+++ b/drivers/net/dsa/mt7530-mmio.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <net/dsa.h>
+
+#include "mt7530.h"
+
+static const struct of_device_id mt7988_of_match[] = {
+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt7988_of_match);
+
+static int
+mt7988_probe(struct platform_device *pdev)
+{
+ static struct regmap_config *sw_regmap_config;
+ struct mt7530_priv *priv;
+ void __iomem *base_addr;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = NULL;
+ priv->dev = &pdev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+
+ base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base_addr)) {
+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
+ return -ENXIO;
+ }
+
+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
+ if (!sw_regmap_config)
+ return -ENOMEM;
+
+ sw_regmap_config->name = "switch";
+ sw_regmap_config->reg_bits = 16;
+ sw_regmap_config->val_bits = 32;
+ sw_regmap_config->reg_stride = 4;
+ sw_regmap_config->max_register = MT7530_CREV;
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ return dsa_register_switch(priv->ds);
+}
+
+static int
+mt7988_remove(struct platform_device *pdev)
+{
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
+
+ if (priv)
+ mt7530_remove_common(priv);
+
+ return 0;
+}
+
+static void mt7988_shutdown(struct platform_device *pdev)
+{
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
+
+ if (!priv)
+ return;
+
+ dsa_switch_shutdown(priv->ds);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+}
+
+static struct platform_driver mt7988_platform_driver = {
+ .probe = mt7988_probe,
+ .remove = mt7988_remove,
+ .shutdown = mt7988_shutdown,
+ .driver = {
+ .name = "mt7530-mmio",
+ .of_match_table = mt7988_of_match,
+ },
+};
+module_platform_driver(mt7988_platform_driver);
+
+MODULE_AUTHOR("Daniel Golle <[email protected]>");
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 394fada7ddf13..e4bb5037d3525 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1981,6 +1981,47 @@ static const struct irq_domain_ops mt7530_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
};
+static void
+mt7988_irq_mask(struct irq_data *d)
+{
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
+
+ priv->irq_enable &= ~BIT(d->hwirq);
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
+}
+
+static void
+mt7988_irq_unmask(struct irq_data *d)
+{
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
+
+ priv->irq_enable |= BIT(d->hwirq);
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
+}
+
+static struct irq_chip mt7988_irq_chip = {
+ .name = KBUILD_MODNAME,
+ .irq_mask = mt7988_irq_mask,
+ .irq_unmask = mt7988_irq_unmask,
+};
+
+static int
+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_data(irq, domain->host_data);
+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
+ irq_set_nested_thread(irq, true);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops mt7988_irq_domain_ops = {
+ .map = mt7988_irq_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
static void
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
{
@@ -2015,8 +2056,15 @@ mt7530_setup_irq(struct mt7530_priv *priv)
return priv->irq ? : -EINVAL;
}
- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
- &mt7530_irq_domain_ops, priv);
+ if (priv->id == ID_MT7988)
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
+ &mt7988_irq_domain_ops,
+ priv);
+ else
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
+ &mt7530_irq_domain_ops,
+ priv);
+
if (!priv->irq_domain) {
dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM;
@@ -2511,6 +2559,25 @@ static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
}
}
+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ phy_interface_zero(config->supported_interfaces);
+
+ switch (port) {
+ case 0 ... 4: /* Internal phy */
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ break;
+
+ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+ MAC_10000FD;
+ }
+}
+
static int
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
{
@@ -2586,6 +2653,17 @@ static bool mt753x_is_mac_port(u32 port)
return (port == 5 || port == 6);
}
+static int
+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface)
+{
+ if (dsa_is_cpu_port(ds, port) &&
+ interface == PHY_INTERFACE_MODE_INTERNAL)
+ return 0;
+
+ return -EINVAL;
+}
+
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
@@ -2656,7 +2734,8 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
switch (port) {
case 0 ... 4: /* Internal phy */
- if (state->interface != PHY_INTERFACE_MODE_GMII)
+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
goto unsupported;
break;
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
@@ -2734,7 +2813,8 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
/* MT753x MAC works in 1G full duplex mode for all up-clocked
* variants.
*/
- if (interface == PHY_INTERFACE_MODE_TRGMII ||
+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
+ interface == PHY_INTERFACE_MODE_TRGMII ||
(phy_interface_mode_is_8023z(interface))) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;
@@ -2814,6 +2894,21 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
return 0;
}
+static int
+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ mt7530_write(priv, MT7530_PMCR_P(port),
+ PMCR_CPU_PORT_SETTING(priv->id));
+
+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
+ PHY_INTERFACE_MODE_INTERNAL, NULL,
+ SPEED_10000, DUPLEX_FULL, true, true);
+
+ return 0;
+}
+
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
@@ -2956,6 +3051,27 @@ static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
+ return 0;
+}
+
+static int mt7988_setup(struct dsa_switch *ds)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ /* Reset the switch */
+ reset_control_assert(priv->rstc);
+ usleep_range(20, 50);
+ reset_control_deassert(priv->rstc);
+ usleep_range(20, 50);
+
+ /* Reset the switch PHYs */
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
+
+ return mt7531_setup_common(ds);
+}
+
const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
@@ -3030,6 +3146,19 @@ const struct mt753x_info mt753x_table[] = {
.mac_port_get_caps = mt7531_mac_port_get_caps,
.mac_port_config = mt7531_mac_config,
},
+ [ID_MT7988] = {
+ .id = ID_MT7988,
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7988_setup,
+ .phy_read_c22 = mt7531_ind_c22_phy_read,
+ .phy_write_c22 = mt7531_ind_c22_phy_write,
+ .phy_read_c45 = mt7531_ind_c45_phy_read,
+ .phy_write_c45 = mt7531_ind_c45_phy_write,
+ .pad_setup = mt7988_pad_setup,
+ .cpu_port_config = mt7988_cpu_port_config,
+ .mac_port_get_caps = mt7988_mac_port_get_caps,
+ .mac_port_config = mt7988_mac_config,
+ },
};
EXPORT_SYMBOL_GPL(mt753x_table);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index ce02aa592a7a8..01db5c9724fa8 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -18,6 +18,7 @@ enum mt753x_id {
ID_MT7530 = 0,
ID_MT7621 = 1,
ID_MT7531 = 2,
+ ID_MT7988 = 3,
};
#define NUM_TRGMII_CTRL 5
@@ -54,11 +55,11 @@ enum mt753x_id {
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
-#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_CFC : MT7530_MFC)
-#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_MIRROR_EN : MIRROR_EN)
-#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_MIRROR_MASK : MIRROR_MASK)
/* Registers for BPDU and PAE frame control*/
@@ -295,9 +296,8 @@ enum mt7530_vlan_port_acc_frm {
MT7531_FORCE_DPX | \
MT7531_FORCE_RX_FC | \
MT7531_FORCE_TX_FC)
-#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
- MT7531_FORCE_MODE : \
- PMCR_FORCE_MODE)
+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
--
2.40.0
As MT7530 and MT7531 internally use 32-bit wide registers, each access
to any register of the switch requires several operations on the MDIO
bus. Hence if there is congruent access, e.g. due to PCS or PHY
polling, this can mess up and interfere with another ongoing register
access sequence.
However, the MDIO bus mutex is only relevant for MDIO-connected
switches. Prepare switches which have there registers directly mapped
into the SoCs register space via MMIO which do not require such
locking. There we can simply use regmap's default locking mechanism.
Hence guard mutex operations to only be performed in case of MDIO
connected switches.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index ac485ee83ed07..394fada7ddf13 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -144,13 +144,15 @@ core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
static void
mt7530_mutex_lock(struct mt7530_priv *priv)
{
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ if (priv->bus)
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
}
static void
mt7530_mutex_unlock(struct mt7530_priv *priv)
{
- mutex_unlock(&priv->bus->mdio_lock);
+ if (priv->bus)
+ mutex_unlock(&priv->bus->mdio_lock);
}
static void
--
2.40.0
MT7988 shares a significant part of the setup function with MT7531.
Split-off those parts into a shared function which is going to be used
also by mt7988_setup.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++------------------
1 file changed, 55 insertions(+), 44 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 9404675c47222..47e3c413ccf12 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2347,12 +2347,65 @@ mt7530_setup(struct dsa_switch *ds)
return 0;
}
+static int
+mt7531_setup_common(struct dsa_switch *ds)
+{
+ struct mt7530_priv *priv = ds->priv;
+ struct dsa_port *cpu_dp;
+ int ret, i;
+
+ /* BPDU to CPU port */
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
+ BIT(cpu_dp->index));
+ break;
+ }
+ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
+ MT753X_BPDU_CPU_ONLY);
+
+ /* Enable and reset MIB counters */
+ mt7530_mib_reset(ds);
+
+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
+ /* Disable forwarding by default on all ports */
+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
+ PCR_MATRIX_CLR);
+
+ /* Disable learning by default on all ports */
+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+
+ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
+
+ if (dsa_is_cpu_port(ds, i)) {
+ ret = mt753x_cpu_port_enable(ds, i);
+ if (ret)
+ return ret;
+ } else {
+ mt7530_port_disable(ds, i);
+
+ /* Set default PVID to 0 on all user ports */
+ mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
+ G0_PORT_VID_DEF);
+ }
+
+ /* Enable consistent egress tag */
+ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+ }
+
+ /* Flush the FDB table */
+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int
mt7531_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
struct mt7530_dummy_poll p;
- struct dsa_port *cpu_dp;
u32 val, id;
int ret, i;
@@ -2430,44 +2483,7 @@ mt7531_setup(struct dsa_switch *ds)
mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
CORE_PLL_GROUP4, val);
- /* BPDU to CPU port */
- dsa_switch_for_each_cpu_port(cpu_dp, ds) {
- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
- BIT(cpu_dp->index));
- break;
- }
- mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
- MT753X_BPDU_CPU_ONLY);
-
- /* Enable and reset MIB counters */
- mt7530_mib_reset(ds);
-
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
- /* Disable forwarding by default on all ports */
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
- PCR_MATRIX_CLR);
-
- /* Disable learning by default on all ports */
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
-
- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
-
- if (dsa_is_cpu_port(ds, i)) {
- ret = mt753x_cpu_port_enable(ds, i);
- if (ret)
- return ret;
- } else {
- mt7530_port_disable(ds, i);
-
- /* Set default PVID to 0 on all user ports */
- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
- G0_PORT_VID_DEF);
- }
-
- /* Enable consistent egress tag */
- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
- }
+ mt7531_setup_common(ds);
/* Setup VLAN ID 0 for VLAN-unaware bridges */
ret = mt7530_setup_vlan0(priv);
@@ -2477,11 +2493,6 @@ mt7531_setup(struct dsa_switch *ds)
ds->assisted_learning_on_cpu_port = true;
ds->mtu_enforcement_ingress = true;
- /* Flush the FDB table */
- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
- if (ret < 0)
- return ret;
-
return 0;
}
--
2.40.0
Add documentation for the built-in switch which can be found in the
MediaTek MT7988 SoC.
Signed-off-by: Daniel Golle <[email protected]>
---
.../bindings/net/dsa/mediatek,mt7530.yaml | 26 +++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
index 5ae9cd8f99a24..8d6dfed11d8d6 100644
--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
@@ -11,16 +11,23 @@ maintainers:
- Landen Chao <[email protected]>
- DENG Qingfang <[email protected]>
- Sean Wang <[email protected]>
+ - Daniel Golle <[email protected]>
description: |
- There are two versions of MT7530, standalone and in a multi-chip module.
+ There are three versions of MT7530, standalone, in a multi-chip module and
+ built-into a SoC.
MT7530 is a part of the multi-chip module in MT7620AN, MT7620DA, MT7620DAN,
MT7620NN, MT7621AT, MT7621DAT, MT7621ST and MT7623AI SoCs.
+ The MT7988 SoC comes with a built-in switch similar to MT7531 as well as four
+ Gigabit Ethernet PHYs. The switch registers are directly mapped into the SoC's
+ memory map rather than using MDIO. The switch got an internally connected 10G
+ CPU port and 4 user ports connected to the built-in Gigabit Ethernet PHYs.
+
MT7530 in MT7620AN, MT7620DA, MT7620DAN and MT7620NN SoCs has got 10/100 PHYs
and the switch registers are directly mapped into SoC's memory map rather than
- using MDIO. The DSA driver currently doesn't support this.
+ using MDIO. The DSA driver currently doesn't support MT7620 variants.
There is only the standalone version of MT7531.
@@ -81,6 +88,10 @@ properties:
Multi-chip module MT7530 in MT7621AT, MT7621DAT and MT7621ST SoCs
const: mediatek,mt7621
+ - description:
+ Built-in switch of the MT7988 SoC
+ const: mediatek,mt7988-switch
+
reg:
maxItems: 1
@@ -268,6 +279,17 @@ allOf:
required:
- mediatek,mcm
+ - if:
+ properties:
+ compatible:
+ const: mediatek,mt7988-switch
+ then:
+ $ref: "#/$defs/mt7530-dsa-port"
+ properties:
+ gpio-controller: false
+ mediatek,mcm: false
+ reset-names: false
+
unevaluatedProperties: false
examples:
--
2.40.0
Move commonly used parts from mt7530_remove into new
mt7530_remove_common helper function which will be used by both,
mt7530_remove and the to-be-introduced mt7988_remove.
Signed-off-by: Daniel Golle <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
---
drivers/net/dsa/mt7530.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index a60ed8706ce35..9404675c47222 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3259,6 +3259,17 @@ mt7530_probe(struct mdio_device *mdiodev)
return dsa_register_switch(priv->ds);
}
+static void
+mt7530_remove_common(struct mt7530_priv *priv)
+{
+ if (priv->irq)
+ mt7530_free_irq(priv);
+
+ dsa_unregister_switch(priv->ds);
+
+ mutex_destroy(&priv->reg_mutex);
+}
+
static void
mt7530_remove(struct mdio_device *mdiodev)
{
@@ -3278,15 +3289,10 @@ mt7530_remove(struct mdio_device *mdiodev)
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
ret);
- if (priv->irq)
- mt7530_free_irq(priv);
-
- dsa_unregister_switch(priv->ds);
+ mt7530_remove_common(priv);
for (i = 0; i < 2; ++i)
mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-
- mutex_destroy(&priv->reg_mutex);
}
static void mt7530_shutdown(struct mdio_device *mdiodev)
--
2.40.0
Hello:
This series was applied to netdev/net-next.git (main)
by David S. Miller <[email protected]>:
On Mon, 3 Apr 2023 02:16:40 +0100 you wrote:
> The MediaTek MT7988 SoC comes with a built-in switch very similar to
> previous MT7530 and MT7531. However, the switch address space is mapped
> into the SoCs memory space rather than being connected via MDIO.
> Using MMIO simplifies register access and also removes the need for a bus
> lock, and for that reason also makes interrupt handling more light-weight.
>
> Note that this is different from previous SoCs like MT7621 and MT7623N
> which also came with an integrated MT7530-like switch which yet had to be
> accessed via MDIO.
>
> [...]
Here is the summary with links:
- [net-next,v2,01/14] net: dsa: mt7530: make some noise if register read fails
https://git.kernel.org/netdev/net-next/c/b6f56cddb5f5
- [net-next,v2,02/14] net: dsa: mt7530: refactor SGMII PCS creation
https://git.kernel.org/netdev/net-next/c/9ecc00164dc2
- [net-next,v2,03/14] net: dsa: mt7530: use unlocked regmap accessors
https://git.kernel.org/netdev/net-next/c/1bd099c49f65
- [net-next,v2,04/14] net: dsa: mt7530: use regmap to access switch register space
https://git.kernel.org/netdev/net-next/c/a08c045580e0
- [net-next,v2,05/14] net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function
https://git.kernel.org/netdev/net-next/c/6de285229773
- [net-next,v2,06/14] net: dsa: mt7530: introduce mutex helpers
https://git.kernel.org/netdev/net-next/c/1557c679f71c
- [net-next,v2,07/14] net: dsa: mt7530: move p5_intf_modes() function to mt7530.c
https://git.kernel.org/netdev/net-next/c/25d15dee34a1
- [net-next,v2,08/14] net: dsa: mt7530: introduce mt7530_probe_common helper function
https://git.kernel.org/netdev/net-next/c/37c9c0d8d0b2
- [net-next,v2,09/14] net: dsa: mt7530: introduce mt7530_remove_common helper function
https://git.kernel.org/netdev/net-next/c/720d73635176
- [net-next,v2,10/14] net: dsa: mt7530: split-off common parts from mt7531_setup
https://git.kernel.org/netdev/net-next/c/7f54cc9772ce
- [net-next,v2,11/14] net: dsa: mt7530: introduce separate MDIO driver
https://git.kernel.org/netdev/net-next/c/cb675afcddbb
- [net-next,v2,12/14] net: dsa: mt7530: skip locking if MDIO bus isn't present
https://git.kernel.org/netdev/net-next/c/54d4147a121c
- [net-next,v2,13/14] net: dsa: mt7530: introduce driver for MT7988 built-in switch
https://git.kernel.org/netdev/net-next/c/110c18bfed41
- [net-next,v2,14/14] dt-bindings: net: dsa: mediatek,mt7530: add mediatek,mt7988-switch
https://git.kernel.org/netdev/net-next/c/386f5fc9061b
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
On 3.04.2023 04:16, Daniel Golle wrote:
> The MediaTek MT7988 SoC comes with a built-in switch very similar to
> previous MT7530 and MT7531. However, the switch address space is mapped
> into the SoCs memory space rather than being connected via MDIO.
> Using MMIO simplifies register access and also removes the need for a bus
> lock, and for that reason also makes interrupt handling more light-weight.
>
> Note that this is different from previous SoCs like MT7621 and MT7623N
> which also came with an integrated MT7530-like switch which yet had to be
> accessed via MDIO.
>
> Split-off the part of the driver registering an MDIO driver, then add
> another module acting as MMIO/platform driver.
>
> The whole series has been tested on various MediaTek boards:
> * MT7623A + MT7530 (BPi-R2)
> * MT7986A + MT7531 (BPi-R3)
> * MT7988A reference board
You did not address the incorrect information I pointed out here. Now
that the patch series is applied, people reading this on the merge
branch commit will be misled by the misinformation.
>
> Changes since v1:
> * use 'internal' PHY mode where appropriate
> * use regmap_update_bits in mt7530_rmw
> * improve dt-bindings
As a maintainer of the said dt-bindings, I pointed out almost 7 things
for you to change. Of those 7 points, you only did one, a trivial
grammar change. The patch series is applied now so one of us maintainers
(you are one too now) need to fix it with additional patches.
Arınç
Hi Arınç,
On Mon, Apr 03, 2023 at 08:08:19PM +0300, Arınç ÜNAL wrote:
> On 3.04.2023 04:16, Daniel Golle wrote:
> > The MediaTek MT7988 SoC comes with a built-in switch very similar to
> > previous MT7530 and MT7531. However, the switch address space is mapped
> > into the SoCs memory space rather than being connected via MDIO.
> > Using MMIO simplifies register access and also removes the need for a bus
> > lock, and for that reason also makes interrupt handling more light-weight.
> >
> > Note that this is different from previous SoCs like MT7621 and MT7623N
> > which also came with an integrated MT7530-like switch which yet had to be
> > accessed via MDIO.
> >
> > Split-off the part of the driver registering an MDIO driver, then add
> > another module acting as MMIO/platform driver.
> >
> > The whole series has been tested on various MediaTek boards:
> > * MT7623A + MT7530 (BPi-R2)
> > * MT7986A + MT7531 (BPi-R3)
> > * MT7988A reference board
>
> You did not address the incorrect information I pointed out here. Now that
I'm sorry, that was certainly not intentional and I may have missed
your comments. Actually it doesn't look like they have made it to the
netdev list archive or patchwork either.
> the patch series is applied, people reading this on the merge branch commit
> will be misled by the misinformation.
I've changed Kconfig stuff according to your recommendation and also
addressed possible misleading USXGMII and 10GBase-KR support by
introducing MT7988-specific functions and using 'internal' PHY mode.
So which of your comments have not been addressed?
>
> >
> > Changes since v1:
> > * use 'internal' PHY mode where appropriate
> > * use regmap_update_bits in mt7530_rmw
> > * improve dt-bindings
>
> As a maintainer of the said dt-bindings, I pointed out almost 7 things for
> you to change. Of those 7 points, you only did one, a trivial grammar
> change. The patch series is applied now so one of us maintainers (you are
> one too now) need to fix it with additional patches.
I was also surprised the series made it to net-next so quickly, but it
wasn't me applying it, I merly posted v2 with all comments I received
addressed.
Me and supposedly also netdevbpf maintainers use patchwork to track
patches and whether comments have been addressed. Can you point me to
emails with the comments which haven't been addressed there? Looking in
patchwork for the dt-bindings patch [1] I don't see any comments there.
Thank you for reviewing!
Daniel
[1]: See patchwork tracking for RFCv3, v1 and v2. Prior to RFCv3 the series
didn't have the dt-bindings addition, I introduced it with RFCv3 when splitting
the series into many small changes:
https://patchwork.kernel.org/project/netdevbpf/patch/9b504e3e88807bfb62022c0877451933d30abeb5.1680105013.git.daniel@makrotopia.org/
https://patchwork.kernel.org/project/netdevbpf/patch/fef2cb2fe3d2b70fa46e93107a0c862f53bb3bfa.1680180959.git.daniel@makrotopia.org/
https://patchwork.kernel.org/project/netdevbpf/patch/dffacdb59aea462c9f7d4242cf9563a04cf79807.1680483896.git.daniel@makrotopia.org/
On 3.04.2023 20:42, Daniel Golle wrote:
> Hi Arınç,
>
> On Mon, Apr 03, 2023 at 08:08:19PM +0300, Arınç ÜNAL wrote:
>> On 3.04.2023 04:16, Daniel Golle wrote:
>>> The MediaTek MT7988 SoC comes with a built-in switch very similar to
>>> previous MT7530 and MT7531. However, the switch address space is mapped
>>> into the SoCs memory space rather than being connected via MDIO.
>>> Using MMIO simplifies register access and also removes the need for a bus
>>> lock, and for that reason also makes interrupt handling more light-weight.
>>>
>>> Note that this is different from previous SoCs like MT7621 and MT7623N
>>> which also came with an integrated MT7530-like switch which yet had to be
>>> accessed via MDIO.
>>>
>>> Split-off the part of the driver registering an MDIO driver, then add
>>> another module acting as MMIO/platform driver.
>>>
>>> The whole series has been tested on various MediaTek boards:
>>> * MT7623A + MT7530 (BPi-R2)
>>> * MT7986A + MT7531 (BPi-R3)
>>> * MT7988A reference board
>>
>> You did not address the incorrect information I pointed out here. Now that
>
> I'm sorry, that was certainly not intentional and I may have missed
> your comments. Actually it doesn't look like they have made it to the
> netdev list archive or patchwork either.
>
>> the patch series is applied, people reading this on the merge branch commit
>> will be misled by the misinformation.
>
> I've changed Kconfig stuff according to your recommendation and also
> addressed possible misleading USXGMII and 10GBase-KR support by
> introducing MT7988-specific functions and using 'internal' PHY mode.
> So which of your comments have not been addressed?
https://lore.kernel.org/netdev/[email protected]/
>
>>
>>>
>>> Changes since v1:
>>> * use 'internal' PHY mode where appropriate
>>> * use regmap_update_bits in mt7530_rmw
>>> * improve dt-bindings
>>
>> As a maintainer of the said dt-bindings, I pointed out almost 7 things for
>> you to change. Of those 7 points, you only did one, a trivial grammar
>> change. The patch series is applied now so one of us maintainers (you are
>> one too now) need to fix it with additional patches.
>
> I was also surprised the series made it to net-next so quickly, but it
> wasn't me applying it, I merly posted v2 with all comments I received
> addressed.
>
> Me and supposedly also netdevbpf maintainers use patchwork to track
> patches and whether comments have been addressed. Can you point me to
> emails with the comments which haven't been addressed there? Looking in
> patchwork for the dt-bindings patch [1] I don't see any comments there.
https://lore.kernel.org/netdev/[email protected]/
>
>
> Thank you for reviewing!
>
>
> Daniel
>
>
> [1]: See patchwork tracking for RFCv3, v1 and v2. Prior to RFCv3 the series
> didn't have the dt-bindings addition, I introduced it with RFCv3 when splitting
> the series into many small changes:
> https://patchwork.kernel.org/project/netdevbpf/patch/9b504e3e88807bfb62022c0877451933d30abeb5.1680105013.git.daniel@makrotopia.org/
> https://patchwork.kernel.org/project/netdevbpf/patch/fef2cb2fe3d2b70fa46e93107a0c862f53bb3bfa.1680180959.git.daniel@makrotopia.org/
> https://patchwork.kernel.org/project/netdevbpf/patch/dffacdb59aea462c9f7d4242cf9563a04cf79807.1680483896.git.daniel@makrotopia.org/
Although I've been a maintainer for the dt-bindings schema for quite
some time, I was somehow missed as a recipient on RFC v3.
Arınç
On Mon, Apr 03, 2023 at 08:50:11PM +0300, Arınç ÜNAL wrote:
> On 3.04.2023 20:42, Daniel Golle wrote:
> > Hi Arınç,
> >
> > On Mon, Apr 03, 2023 at 08:08:19PM +0300, Arınç ÜNAL wrote:
> > > On 3.04.2023 04:16, Daniel Golle wrote:
> > > > The MediaTek MT7988 SoC comes with a built-in switch very similar to
> > > > previous MT7530 and MT7531. However, the switch address space is mapped
> > > > into the SoCs memory space rather than being connected via MDIO.
> > > > Using MMIO simplifies register access and also removes the need for a bus
> > > > lock, and for that reason also makes interrupt handling more light-weight.
> > > >
> > > > Note that this is different from previous SoCs like MT7621 and MT7623N
> > > > which also came with an integrated MT7530-like switch which yet had to be
> > > > accessed via MDIO.
> > > >
> > > > Split-off the part of the driver registering an MDIO driver, then add
> > > > another module acting as MMIO/platform driver.
> > > >
> > > > The whole series has been tested on various MediaTek boards:
> > > > * MT7623A + MT7530 (BPi-R2)
> > > > * MT7986A + MT7531 (BPi-R3)
> > > > * MT7988A reference board
> > >
> > > You did not address the incorrect information I pointed out here. Now that
> >
> > I'm sorry, that was certainly not intentional and I may have missed
> > your comments. Actually it doesn't look like they have made it to the
> > netdev list archive or patchwork either.
> >
> > > the patch series is applied, people reading this on the merge branch commit
> > > will be misled by the misinformation.
> >
> > I've changed Kconfig stuff according to your recommendation and also
> > addressed possible misleading USXGMII and 10GBase-KR support by
> > introducing MT7988-specific functions and using 'internal' PHY mode.
> > So which of your comments have not been addressed?
>
> https://lore.kernel.org/netdev/[email protected]/
Strange that both emails didn't make it into patchwork.
>
> >
> > >
> > > >
> > > > Changes since v1:
> > > > * use 'internal' PHY mode where appropriate
> > > > * use regmap_update_bits in mt7530_rmw
> > > > * improve dt-bindings
> > >
> > > As a maintainer of the said dt-bindings, I pointed out almost 7 things for
> > > you to change. Of those 7 points, you only did one, a trivial grammar
> > > change. The patch series is applied now so one of us maintainers (you are
> > > one too now) need to fix it with additional patches.
> >
> > I was also surprised the series made it to net-next so quickly, but it
> > wasn't me applying it, I merly posted v2 with all comments I received
> > addressed.
> >
> > Me and supposedly also netdevbpf maintainers use patchwork to track
> > patches and whether comments have been addressed. Can you point me to
> > emails with the comments which haven't been addressed there? Looking in
> > patchwork for the dt-bindings patch [1] I don't see any comments there.
>
> https://lore.kernel.org/netdev/[email protected]/
>
> >
> >
> > Thank you for reviewing!
> >
> >
> > Daniel
> >
> >
> > [1]: See patchwork tracking for RFCv3, v1 and v2. Prior to RFCv3 the series
> > didn't have the dt-bindings addition, I introduced it with RFCv3 when splitting
> > the series into many small changes:
> > https://patchwork.kernel.org/project/netdevbpf/patch/9b504e3e88807bfb62022c0877451933d30abeb5.1680105013.git.daniel@makrotopia.org/
> > https://patchwork.kernel.org/project/netdevbpf/patch/fef2cb2fe3d2b70fa46e93107a0c862f53bb3bfa.1680180959.git.daniel@makrotopia.org/
> > https://patchwork.kernel.org/project/netdevbpf/patch/dffacdb59aea462c9f7d4242cf9563a04cf79807.1680483896.git.daniel@makrotopia.org/
>
> Although I've been a maintainer for the dt-bindings schema for quite some
> time, I was somehow missed as a recipient on RFC v3.
Yeah, that was my mistake. get_maintainers.pl comes up with unreadable
unicode garbage, probably something is wrong in my local Perl setup.
So I always manually replace your name with readable UTF-8, but I missed
that for RFC v3.
On 3.04.2023 21:13, Daniel Golle wrote:
> On Mon, Apr 03, 2023 at 08:50:11PM +0300, Arınç ÜNAL wrote:
>> On 3.04.2023 20:42, Daniel Golle wrote:
>>> Hi Arınç,
>>>
>>> On Mon, Apr 03, 2023 at 08:08:19PM +0300, Arınç ÜNAL wrote:
>>>> On 3.04.2023 04:16, Daniel Golle wrote:
>>>>> The MediaTek MT7988 SoC comes with a built-in switch very similar to
>>>>> previous MT7530 and MT7531. However, the switch address space is mapped
>>>>> into the SoCs memory space rather than being connected via MDIO.
>>>>> Using MMIO simplifies register access and also removes the need for a bus
>>>>> lock, and for that reason also makes interrupt handling more light-weight.
>>>>>
>>>>> Note that this is different from previous SoCs like MT7621 and MT7623N
>>>>> which also came with an integrated MT7530-like switch which yet had to be
>>>>> accessed via MDIO.
>>>>>
>>>>> Split-off the part of the driver registering an MDIO driver, then add
>>>>> another module acting as MMIO/platform driver.
>>>>>
>>>>> The whole series has been tested on various MediaTek boards:
>>>>> * MT7623A + MT7530 (BPi-R2)
>>>>> * MT7986A + MT7531 (BPi-R3)
>>>>> * MT7988A reference board
>>>>
>>>> You did not address the incorrect information I pointed out here. Now that
>>>
>>> I'm sorry, that was certainly not intentional and I may have missed
>>> your comments. Actually it doesn't look like they have made it to the
>>> netdev list archive or patchwork either.
>>>
>>>> the patch series is applied, people reading this on the merge branch commit
>>>> will be misled by the misinformation.
>>>
>>> I've changed Kconfig stuff according to your recommendation and also
>>> addressed possible misleading USXGMII and 10GBase-KR support by
>>> introducing MT7988-specific functions and using 'internal' PHY mode.
>>> So which of your comments have not been addressed?
>>
>> https://lore.kernel.org/netdev/[email protected]/
>
> Strange that both emails didn't make it into patchwork.
I don't understand how how patchwork handles the conversation on the
cover letter. I was never able to see them on patchwork but lore.kernel.org.
My review for patch 15 was received on patchworks as it should. It was
missing "net-next" on the subject so perhaps that's why you missed it.
https://patchwork.kernel.org/project/netdevbpf/patch/80a853f182eac24735338f3c1f505e5f580053ca.1680180959.git.daniel@makrotopia.org/#25278482
Why don't you just check your inbox? We're emailing each other in the end.
>
>>
>>>
>>>>
>>>>>
>>>>> Changes since v1:
>>>>> * use 'internal' PHY mode where appropriate
>>>>> * use regmap_update_bits in mt7530_rmw
>>>>> * improve dt-bindings
>>>>
>>>> As a maintainer of the said dt-bindings, I pointed out almost 7 things for
>>>> you to change. Of those 7 points, you only did one, a trivial grammar
>>>> change. The patch series is applied now so one of us maintainers (you are
>>>> one too now) need to fix it with additional patches.
>>>
>>> I was also surprised the series made it to net-next so quickly, but it
>>> wasn't me applying it, I merly posted v2 with all comments I received
>>> addressed.
>>>
>>> Me and supposedly also netdevbpf maintainers use patchwork to track
>>> patches and whether comments have been addressed. Can you point me to
>>> emails with the comments which haven't been addressed there? Looking in
>>> patchwork for the dt-bindings patch [1] I don't see any comments there.
>>
>> https://lore.kernel.org/netdev/[email protected]/
>>
>>>
>>>
>>> Thank you for reviewing!
>>>
>>>
>>> Daniel
>>>
>>>
>>> [1]: See patchwork tracking for RFCv3, v1 and v2. Prior to RFCv3 the series
>>> didn't have the dt-bindings addition, I introduced it with RFCv3 when splitting
>>> the series into many small changes:
>>> https://patchwork.kernel.org/project/netdevbpf/patch/9b504e3e88807bfb62022c0877451933d30abeb5.1680105013.git.daniel@makrotopia.org/
>>> https://patchwork.kernel.org/project/netdevbpf/patch/fef2cb2fe3d2b70fa46e93107a0c862f53bb3bfa.1680180959.git.daniel@makrotopia.org/
>>> https://patchwork.kernel.org/project/netdevbpf/patch/dffacdb59aea462c9f7d4242cf9563a04cf79807.1680483896.git.daniel@makrotopia.org/
>>
>> Although I've been a maintainer for the dt-bindings schema for quite some
>> time, I was somehow missed as a recipient on RFC v3.
>
> Yeah, that was my mistake. get_maintainers.pl comes up with unreadable
> unicode garbage, probably something is wrong in my local Perl setup.
> So I always manually replace your name with readable UTF-8, but I missed
> that for RFC v3.
Did you try writing the output of get_maintainers.pl to a file, then
feed the file directly to git send-email as recipients?
That may bypass that issue. It's also currently how I send my patches.
https://arinc9.notion.site/get_maintainers-and-git-send-email-e8edd99d962041eca874966021acefe6
Arınç
Hi Daniel,
On Mon, Apr 03, 2023 at 02:19:40AM +0100, Daniel Golle wrote:
> Add driver for the built-in Gigabit Ethernet switch which can be found
> in the MediaTek MT7988 SoC.
>
> The switch shares most of its design with MT7530 and MT7531, but has
> it's registers mapped into the SoCs register space rather than being
> connected externally or internally via MDIO.
>
> Introduce a new platform driver to support that.
>
> Signed-off-by: Daniel Golle <[email protected]>
> Reviewed-by: Andrew Lunn <[email protected]>
> ---
> MAINTAINERS | 2 +
> drivers/net/dsa/Kconfig | 12 +++
> drivers/net/dsa/Makefile | 1 +
> drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
[...]
> diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
> new file mode 100644
> index 0000000000000..1a3d4b692f349
> --- /dev/null
> +++ b/drivers/net/dsa/mt7530-mmio.c
> @@ -0,0 +1,101 @@
[...]
> + priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
Please use devm_reset_control_get_exclusive() directly.
> + if (IS_ERR(priv->rstc)) {
> + dev_err(&pdev->dev, "Couldn't get our reset line\n");
> + return PTR_ERR(priv->rstc);
Not sure if this can actually happen, but there is no need to warn on
-EPROBE_DEFER. You could use return dev_err_probe(...) here.
regards
Philipp
On Tue, Apr 25, 2023 at 05:51:37PM +0200, Philipp Zabel wrote:
> Hi Daniel,
>
> On Mon, Apr 03, 2023 at 02:19:40AM +0100, Daniel Golle wrote:
> > Add driver for the built-in Gigabit Ethernet switch which can be found
> > in the MediaTek MT7988 SoC.
> >
> > The switch shares most of its design with MT7530 and MT7531, but has
> > it's registers mapped into the SoCs register space rather than being
> > connected externally or internally via MDIO.
> >
> > Introduce a new platform driver to support that.
> >
> > Signed-off-by: Daniel Golle <[email protected]>
> > Reviewed-by: Andrew Lunn <[email protected]>
> > ---
> > MAINTAINERS | 2 +
> > drivers/net/dsa/Kconfig | 12 +++
> > drivers/net/dsa/Makefile | 1 +
> > drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
> [...]
> > diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
> > new file mode 100644
> > index 0000000000000..1a3d4b692f349
> > --- /dev/null
> > +++ b/drivers/net/dsa/mt7530-mmio.c
> > @@ -0,0 +1,101 @@
> [...]
> > + priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
>
> Please use devm_reset_control_get_exclusive() directly.
>
> > + if (IS_ERR(priv->rstc)) {
> > + dev_err(&pdev->dev, "Couldn't get our reset line\n");
> > + return PTR_ERR(priv->rstc);
>
> Not sure if this can actually happen, but there is no need to warn on
> -EPROBE_DEFER. You could use return dev_err_probe(...) here.
Thank you for your comments. The series has already been picked to
net-next. Unless you want to send the suggested changes yourself, I will
prepare another series with your suggestions, and also apply them to
mt7530-mdio.c.
Hi Daniel,
On Tue, Apr 25, 2023 at 05:11:36PM +0100, Daniel Golle wrote:
> On Tue, Apr 25, 2023 at 05:51:37PM +0200, Philipp Zabel wrote:
[...]
> > Please use devm_reset_control_get_exclusive() directly.
> >
> > > + if (IS_ERR(priv->rstc)) {
> > > + dev_err(&pdev->dev, "Couldn't get our reset line\n");
> > > + return PTR_ERR(priv->rstc);
> >
> > Not sure if this can actually happen, but there is no need to warn on
> > -EPROBE_DEFER. You could use return dev_err_probe(...) here.
>
> Thank you for your comments. The series has already been picked to
> net-next. Unless you want to send the suggested changes yourself, I will
> prepare another series with your suggestions, and also apply them to
> mt7530-mdio.c.
That would be great, thank you.
regards
Philipp