diff options
author | Chuanhong Guo <gch981213@gmail.com> | 2019-01-10 22:38:13 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2019-03-24 01:44:26 +0100 |
commit | cf9900978af780226da2c1a178c7c6635e3793a0 (patch) | |
tree | c7ac89ba765c96dc3a5983a404c8f7d8454c2e5b /target/linux/generic/files/drivers | |
parent | cc817392f4ec9c3c3cc04bd95952cf9222fd8ad1 (diff) | |
download | upstream-cf9900978af780226da2c1a178c7c6635e3793a0.tar.gz upstream-cf9900978af780226da2c1a178c7c6635e3793a0.tar.bz2 upstream-cf9900978af780226da2c1a178c7c6635e3793a0.zip |
generic: ar8216: ar8229: add phy_read/phy_write
the added function also works for ar8216 and will be used in the
following ar7240 support.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
Diffstat (limited to 'target/linux/generic/files/drivers')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.c | 48 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.h | 9 |
2 files changed, 57 insertions, 0 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index e1c3dc95c3..c6e3a05299 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -816,6 +816,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) { int phy_if_mode; @@ -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, diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index 0444bf7f22..975ba23517 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -152,6 +152,15 @@ #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) |