generic: ar8216: ar8229: add phy_read/phy_write
authorChuanhong Guo <gch981213@gmail.com>
Thu, 10 Jan 2019 14:38:13 +0000 (22:38 +0800)
committerPetr Štetiar <ynezz@true.cz>
Sun, 24 Mar 2019 00:44:26 +0000 (01:44 +0100)
the added function also works for ar8216 and will be used in the
following ar7240 support.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
target/linux/generic/files/drivers/net/phy/ar8216.c
target/linux/generic/files/drivers/net/phy/ar8216.h

index e1c3dc95c30eb0ece265775a18c5222760ee79f4..c6e3a05299017136241baa0c470122eb543ec732 100644 (file)
@@ -815,6 +815,52 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv,
        }
 }
 
+static int
+ar8216_phy_read(struct ar8xxx_priv *priv, int addr, int regnum)
+{
+       u32 t, val = 0xffff;
+       int err;
+
+       if (addr >= AR8216_NUM_PORTS)
+               return 0xffff;
+       t = (regnum << AR8216_MDIO_CTRL_REG_ADDR_S) |
+           (addr << AR8216_MDIO_CTRL_PHY_ADDR_S) |
+           AR8216_MDIO_CTRL_MASTER_EN |
+           AR8216_MDIO_CTRL_BUSY |
+           AR8216_MDIO_CTRL_CMD_READ;
+
+       ar8xxx_write(priv, AR8216_REG_MDIO_CTRL, t);
+       err = ar8xxx_reg_wait(priv, AR8216_REG_MDIO_CTRL,
+                             AR8216_MDIO_CTRL_BUSY, 0, 5);
+       if (!err)
+               val = ar8xxx_read(priv, AR8216_REG_MDIO_CTRL);
+
+       return val & AR8216_MDIO_CTRL_DATA_M;
+}
+
+static int
+ar8216_phy_write(struct ar8xxx_priv *priv, int addr, int regnum, u16 val)
+{
+       u32 t;
+       int ret;
+
+       if (addr >= AR8216_NUM_PORTS)
+               return -EINVAL;
+
+       t = (addr << AR8216_MDIO_CTRL_PHY_ADDR_S) |
+           (regnum << AR8216_MDIO_CTRL_REG_ADDR_S) |
+           AR8216_MDIO_CTRL_MASTER_EN |
+           AR8216_MDIO_CTRL_BUSY |
+           AR8216_MDIO_CTRL_CMD_WRITE |
+           val;
+
+       ar8xxx_write(priv, AR8216_REG_MDIO_CTRL, t);
+       ret = ar8xxx_reg_wait(priv, AR8216_REG_MDIO_CTRL,
+                             AR8216_MDIO_CTRL_BUSY, 0, 5);
+
+       return ret;
+}
+
 static int
 ar8229_hw_init(struct ar8xxx_priv *priv)
 {
@@ -1870,6 +1916,8 @@ static const struct ar8xxx_chip ar8229_chip = {
        .hw_init = ar8229_hw_init,
        .init_globals = ar8229_init_globals,
        .init_port = ar8229_init_port,
+       .phy_read = ar8216_phy_read,
+       .phy_write = ar8216_phy_write,
        .setup_port = ar8236_setup_port,
        .read_port_status = ar8216_read_port_status,
        .atu_flush = ar8216_atu_flush,
index 0444bf7f2243bf5af8bfee3fa6ebb16cd57ed8c6..975ba23517b2ba6494afeeceb82a373632a1c961 100644 (file)
 #define   AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S  4
 #define   AR8216_GLOBAL_CPUPORT_EN             BIT(8)
 
+#define AR8216_REG_MDIO_CTRL           0x98
+#define   AR8216_MDIO_CTRL_DATA_M      BITS(0, 16)
+#define   AR8216_MDIO_CTRL_REG_ADDR_S  16
+#define   AR8216_MDIO_CTRL_PHY_ADDR_S  21
+#define   AR8216_MDIO_CTRL_CMD_WRITE   0
+#define   AR8216_MDIO_CTRL_CMD_READ    BIT(27)
+#define   AR8216_MDIO_CTRL_MASTER_EN   BIT(30)
+#define   AR8216_MDIO_CTRL_BUSY        BIT(31)
+
 #define AR8216_PORT_OFFSET(_i)         (0x0100 * (_i + 1))
 #define AR8216_REG_PORT_STATUS(_i)     (AR8216_PORT_OFFSET(_i) + 0x0000)
 #define   AR8216_PORT_STATUS_SPEED     BITS(0,2)