qca8k internal phy driver require some special debug value to be set based on the switch revision. Rework the switch id read function to also read the chip revision. Signed-off-by: Ansuel Smith <ansuelsmth@xxxxxxxxx> Reviewed-by: Florian Fainelli <f.fainelli@xxxxxxxxx> --- drivers/net/dsa/qca8k.c | 53 ++++++++++++++++++++++++++--------------- drivers/net/dsa/qca8k.h | 7 ++++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index 10e3e1ca7e95..35ff4cf08786 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1579,12 +1579,40 @@ static const struct dsa_switch_ops qca8k_switch_ops = { .phylink_mac_link_up = qca8k_phylink_mac_link_up, }; +static int qca8k_read_switch_id(struct qca8k_priv *priv) +{ + const struct qca8k_match_data *data; + u32 val; + u8 id; + + /* get the switches ID from the compatible */ + data = of_device_get_match_data(priv->dev); + if (!data) + return -ENODEV; + + val = qca8k_read(priv, QCA8K_REG_MASK_CTRL); + if (val < 0) + return -ENODEV; + + id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK); + if (id != data->id) { + dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); + return -ENODEV; + } + + priv->switch_id = id; + + /* Save revision to communicate to the internal PHY driver */ + priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK); + + return 0; +} + static int qca8k_sw_probe(struct mdio_device *mdiodev) { - const struct qca8k_match_data *data; struct qca8k_priv *priv; - u32 id; + int ret; /* allocate the private data struct so that we can probe the switches * ID register @@ -1610,24 +1638,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev) gpiod_set_value_cansleep(priv->reset_gpio, 0); } - /* get the switches ID from the compatible */ - data = of_device_get_match_data(&mdiodev->dev); - if (!data) - return -ENODEV; - - /* read the switches ID register */ - id = qca8k_read(priv, QCA8K_REG_MASK_CTRL); - if (id < 0) - return id; - - id >>= QCA8K_MASK_CTRL_ID_S; - id &= QCA8K_MASK_CTRL_ID_M; - if (id != data->id) { - dev_err(&mdiodev->dev, "Switch id detected %x but expected %x", id, data->id); - return -ENODEV; - } + /* Check the detected switch id */ + ret = qca8k_read_switch_id(priv); + if (ret) + return ret; - priv->switch_id = id; priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); if (!priv->ds) return -ENOMEM; diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h index eceeacfe2c5d..338277978ec0 100644 --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -30,8 +30,10 @@ /* Global control registers */ #define QCA8K_REG_MASK_CTRL 0x000 -#define QCA8K_MASK_CTRL_ID_M 0xff -#define QCA8K_MASK_CTRL_ID_S 8 +#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) +#define QCA8K_MASK_CTRL_REV_ID(x) ((x) >> 0) +#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) +#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8) #define QCA8K_REG_PORT0_PAD_CTRL 0x004 #define QCA8K_REG_PORT5_PAD_CTRL 0x008 #define QCA8K_REG_PORT6_PAD_CTRL 0x00c @@ -251,6 +253,7 @@ struct qca8k_match_data { struct qca8k_priv { u8 switch_id; + u8 switch_revision; struct regmap *regmap; struct mii_bus *bus; struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS]; -- 2.30.2