summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/qca8k.c
diff options
context:
space:
mode:
authorAnsuel Smith <ansuelsmth@gmail.com>2021-05-14 23:00:04 +0200
committerDavid S. Miller <davem@davemloft.net>2021-05-14 15:30:22 -0700
commit95ffeaf18b3bb90eeef52cbf7d79ccc9d0345ff5 (patch)
tree5b03d678a4367e14eed0cca9cd80e9e00a29352e /drivers/net/dsa/qca8k.c
parent0fc57e4b5e39461fc0a54aae0afe4241363a7267 (diff)
net: dsa: qca8k: add support for switch rev
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@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/qca8k.c')
-rw-r--r--drivers/net/dsa/qca8k.c53
1 files changed, 34 insertions, 19 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;