mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 21:58:04 +00:00
generic: ar8216: add support for separated mdio bus for phy access
Atheros FE switches have a builtin mdio master available for PHY accessing and on ar724x/ar933x builtin switches this mdio master is the only way of accessing PHYs. After this patch if there is phy_read/phy_write method available in ar8xxx_chip we register a separated mdio bus for accessing PHYs. Still adds support for mdio device probing only since this isn't needed for those switches registered using PHY probing. Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
This commit is contained in:
parent
cb7d96499c
commit
cc817392f4
@ -190,7 +190,7 @@ ar8xxx_phy_init(struct ar8xxx_priv *priv)
|
|||||||
int i;
|
int i;
|
||||||
struct mii_bus *bus;
|
struct mii_bus *bus;
|
||||||
|
|
||||||
bus = priv->mii_bus;
|
bus = priv->sw_mii_bus ?: priv->mii_bus;
|
||||||
for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
|
for (i = 0; i < AR8XXX_NUM_PHYS; i++) {
|
||||||
if (priv->chip->phy_fixup)
|
if (priv->chip->phy_fixup)
|
||||||
priv->chip->phy_fixup(priv, i);
|
priv->chip->phy_fixup(priv, i);
|
||||||
@ -1683,6 +1683,21 @@ ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar8xxx_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr)
|
||||||
|
{
|
||||||
|
struct ar8xxx_priv *priv = bus->priv;
|
||||||
|
return priv->chip->phy_read(priv, phy_addr, reg_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar8xxx_phy_write(struct mii_bus *bus, int phy_addr, int reg_addr,
|
||||||
|
u16 reg_val)
|
||||||
|
{
|
||||||
|
struct ar8xxx_priv *priv = bus->priv;
|
||||||
|
return priv->chip->phy_write(priv, phy_addr, reg_addr, reg_val);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct switch_attr ar8xxx_sw_attr_globals[] = {
|
static const struct switch_attr ar8xxx_sw_attr_globals[] = {
|
||||||
{
|
{
|
||||||
.type = SWITCH_TYPE_INT,
|
.type = SWITCH_TYPE_INT,
|
||||||
@ -2471,6 +2486,7 @@ ar8xxx_mdiodev_probe(struct mdio_device *mdiodev)
|
|||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
struct ar8xxx_priv *priv;
|
struct ar8xxx_priv *priv;
|
||||||
struct switch_dev *swdev;
|
struct switch_dev *swdev;
|
||||||
|
struct device_node *mdio_node;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
match = of_match_device(ar8xxx_mdiodev_of_match, &mdiodev->dev);
|
match = of_match_device(ar8xxx_mdiodev_of_match, &mdiodev->dev);
|
||||||
@ -2493,6 +2509,21 @@ ar8xxx_mdiodev_probe(struct mdio_device *mdiodev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto free_priv;
|
goto free_priv;
|
||||||
|
|
||||||
|
if (priv->chip->phy_read && priv->chip->phy_write) {
|
||||||
|
priv->sw_mii_bus = devm_mdiobus_alloc(&mdiodev->dev);
|
||||||
|
priv->sw_mii_bus->name = "ar8xxx-mdio";
|
||||||
|
priv->sw_mii_bus->read = ar8xxx_phy_read;
|
||||||
|
priv->sw_mii_bus->write = ar8xxx_phy_write;
|
||||||
|
priv->sw_mii_bus->priv = priv;
|
||||||
|
priv->sw_mii_bus->parent = &mdiodev->dev;
|
||||||
|
snprintf(priv->sw_mii_bus->id, MII_BUS_ID_SIZE, "%s",
|
||||||
|
dev_name(&mdiodev->dev));
|
||||||
|
mdio_node = of_get_child_by_name(priv->pdev->of_node, "mdio-bus");
|
||||||
|
ret = of_mdiobus_register(priv->sw_mii_bus, mdio_node);
|
||||||
|
if (ret)
|
||||||
|
goto free_priv;
|
||||||
|
}
|
||||||
|
|
||||||
swdev = &priv->dev;
|
swdev = &priv->dev;
|
||||||
swdev->alias = dev_name(&mdiodev->dev);
|
swdev->alias = dev_name(&mdiodev->dev);
|
||||||
ret = register_switch(swdev, NULL);
|
ret = register_switch(swdev, NULL);
|
||||||
@ -2548,6 +2579,8 @@ ar8xxx_mdiodev_remove(struct mdio_device *mdiodev)
|
|||||||
|
|
||||||
unregister_switch(&priv->dev);
|
unregister_switch(&priv->dev);
|
||||||
ar8xxx_mib_stop(priv);
|
ar8xxx_mib_stop(priv);
|
||||||
|
if(priv->sw_mii_bus)
|
||||||
|
mdiobus_unregister(priv->sw_mii_bus);
|
||||||
ar8xxx_free(priv);
|
ar8xxx_free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,6 +433,8 @@ struct ar8xxx_chip {
|
|||||||
u32 *status, enum arl_op op);
|
u32 *status, enum arl_op op);
|
||||||
int (*sw_hw_apply)(struct switch_dev *dev);
|
int (*sw_hw_apply)(struct switch_dev *dev);
|
||||||
void (*phy_rgmii_set)(struct ar8xxx_priv *priv, struct phy_device *phydev);
|
void (*phy_rgmii_set)(struct ar8xxx_priv *priv, struct phy_device *phydev);
|
||||||
|
int (*phy_read)(struct ar8xxx_priv *priv, int addr, int regnum);
|
||||||
|
int (*phy_write)(struct ar8xxx_priv *priv, int addr, int regnum, u16 val);
|
||||||
|
|
||||||
const struct ar8xxx_mib_desc *mib_decs;
|
const struct ar8xxx_mib_desc *mib_decs;
|
||||||
unsigned num_mibs;
|
unsigned num_mibs;
|
||||||
@ -442,6 +444,7 @@ struct ar8xxx_chip {
|
|||||||
struct ar8xxx_priv {
|
struct ar8xxx_priv {
|
||||||
struct switch_dev dev;
|
struct switch_dev dev;
|
||||||
struct mii_bus *mii_bus;
|
struct mii_bus *mii_bus;
|
||||||
|
struct mii_bus *sw_mii_bus;
|
||||||
struct phy_device *phy;
|
struct phy_device *phy;
|
||||||
struct device *pdev;
|
struct device *pdev;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user