diff options
Diffstat (limited to 'drivers/staging/mt7621-eth/mdio.c')
-rw-r--r-- | drivers/staging/mt7621-eth/mdio.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/drivers/staging/mt7621-eth/mdio.c b/drivers/staging/mt7621-eth/mdio.c deleted file mode 100644 index 5fea6a447eed..000000000000 --- a/drivers/staging/mt7621-eth/mdio.c +++ /dev/null @@ -1,275 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org> - * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com> - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/phy.h> -#include <linux/of_net.h> -#include <linux/of_mdio.h> - -#include "mtk_eth_soc.h" -#include "mdio.h" - -static int mtk_mdio_reset(struct mii_bus *bus) -{ - /* TODO */ - return 0; -} - -static void mtk_phy_link_adjust(struct net_device *dev) -{ - struct mtk_eth *eth = netdev_priv(dev); - unsigned long flags; - int i; - - spin_lock_irqsave(ð->phy->lock, flags); - for (i = 0; i < 8; i++) { - if (eth->phy->phy_node[i]) { - struct phy_device *phydev = eth->phy->phy[i]; - int status_change = 0; - - if (phydev->link) - if (eth->phy->duplex[i] != phydev->duplex || - eth->phy->speed[i] != phydev->speed) - status_change = 1; - - if (phydev->link != eth->link[i]) - status_change = 1; - - switch (phydev->speed) { - case SPEED_1000: - case SPEED_100: - case SPEED_10: - eth->link[i] = phydev->link; - eth->phy->duplex[i] = phydev->duplex; - eth->phy->speed[i] = phydev->speed; - - if (status_change && - eth->soc->mdio_adjust_link) - eth->soc->mdio_adjust_link(eth, i); - break; - } - } - } - spin_unlock_irqrestore(ð->phy->lock, flags); -} - -int mtk_connect_phy_node(struct mtk_eth *eth, struct mtk_mac *mac, - struct device_node *phy_node) -{ - const __be32 *_port = NULL; - struct phy_device *phydev; - int phy_mode, port; - - _port = of_get_property(phy_node, "reg", NULL); - - if (!_port || (be32_to_cpu(*_port) >= 0x20)) { - pr_err("%pOFn: invalid port id\n", phy_node); - return -EINVAL; - } - port = be32_to_cpu(*_port); - phy_mode = of_get_phy_mode(phy_node); - if (phy_mode < 0) { - dev_err(eth->dev, "incorrect phy-mode %d\n", phy_mode); - eth->phy->phy_node[port] = NULL; - return -EINVAL; - } - - phydev = of_phy_connect(eth->netdev[mac->id], phy_node, - mtk_phy_link_adjust, 0, phy_mode); - if (!phydev) { - dev_err(eth->dev, "could not connect to PHY\n"); - eth->phy->phy_node[port] = NULL; - return -ENODEV; - } - - phydev->supported &= PHY_1000BT_FEATURES; - phydev->advertising = phydev->supported; - - dev_info(eth->dev, - "connected port %d to PHY at %s [uid=%08x, driver=%s]\n", - port, phydev_name(phydev), phydev->phy_id, - phydev->drv->name); - - eth->phy->phy[port] = phydev; - eth->link[port] = 0; - - return 0; -} - -static void phy_init(struct mtk_eth *eth, struct mtk_mac *mac, - struct phy_device *phy) -{ - phy_attach(eth->netdev[mac->id], phydev_name(phy), - PHY_INTERFACE_MODE_MII); - - phy->autoneg = AUTONEG_ENABLE; - phy->speed = 0; - phy->duplex = 0; - phy_set_max_speed(phy, SPEED_100); - phy->advertising = phy->supported | ADVERTISED_Autoneg; - - phy_start_aneg(phy); -} - -static int mtk_phy_connect(struct mtk_mac *mac) -{ - struct mtk_eth *eth = mac->hw; - int i; - - for (i = 0; i < 8; i++) { - if (eth->phy->phy_node[i]) { - if (!mac->phy_dev) { - mac->phy_dev = eth->phy->phy[i]; - mac->phy_flags = MTK_PHY_FLAG_PORT; - } - } else if (eth->mii_bus) { - struct phy_device *phy; - - phy = mdiobus_get_phy(eth->mii_bus, i); - if (phy) { - phy_init(eth, mac, phy); - if (!mac->phy_dev) { - mac->phy_dev = phy; - mac->phy_flags = MTK_PHY_FLAG_ATTACH; - } - } - } - } - - return 0; -} - -static void mtk_phy_disconnect(struct mtk_mac *mac) -{ - struct mtk_eth *eth = mac->hw; - unsigned long flags; - int i; - - for (i = 0; i < 8; i++) - if (eth->phy->phy_fixed[i]) { - spin_lock_irqsave(ð->phy->lock, flags); - eth->link[i] = 0; - if (eth->soc->mdio_adjust_link) - eth->soc->mdio_adjust_link(eth, i); - spin_unlock_irqrestore(ð->phy->lock, flags); - } else if (eth->phy->phy[i]) { - phy_disconnect(eth->phy->phy[i]); - } else if (eth->mii_bus) { - struct phy_device *phy = - mdiobus_get_phy(eth->mii_bus, i); - - if (phy) - phy_detach(phy); - } -} - -static void mtk_phy_start(struct mtk_mac *mac) -{ - struct mtk_eth *eth = mac->hw; - unsigned long flags; - int i; - - for (i = 0; i < 8; i++) { - if (eth->phy->phy_fixed[i]) { - spin_lock_irqsave(ð->phy->lock, flags); - eth->link[i] = 1; - if (eth->soc->mdio_adjust_link) - eth->soc->mdio_adjust_link(eth, i); - spin_unlock_irqrestore(ð->phy->lock, flags); - } else if (eth->phy->phy[i]) { - phy_start(eth->phy->phy[i]); - } - } -} - -static void mtk_phy_stop(struct mtk_mac *mac) -{ - struct mtk_eth *eth = mac->hw; - unsigned long flags; - int i; - - for (i = 0; i < 8; i++) - if (eth->phy->phy_fixed[i]) { - spin_lock_irqsave(ð->phy->lock, flags); - eth->link[i] = 0; - if (eth->soc->mdio_adjust_link) - eth->soc->mdio_adjust_link(eth, i); - spin_unlock_irqrestore(ð->phy->lock, flags); - } else if (eth->phy->phy[i]) { - phy_stop(eth->phy->phy[i]); - } -} - -static struct mtk_phy phy_ralink = { - .connect = mtk_phy_connect, - .disconnect = mtk_phy_disconnect, - .start = mtk_phy_start, - .stop = mtk_phy_stop, -}; - -int mtk_mdio_init(struct mtk_eth *eth) -{ - struct device_node *mii_np; - int err; - - if (!eth->soc->mdio_read || !eth->soc->mdio_write) - return 0; - - spin_lock_init(&phy_ralink.lock); - eth->phy = &phy_ralink; - - mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); - if (!mii_np) { - dev_err(eth->dev, "no %s child node found", "mdio-bus"); - return -ENODEV; - } - - if (!of_device_is_available(mii_np)) { - err = 0; - goto err_put_node; - } - - eth->mii_bus = mdiobus_alloc(); - if (!eth->mii_bus) { - err = -ENOMEM; - goto err_put_node; - } - - eth->mii_bus->name = "mdio"; - eth->mii_bus->read = eth->soc->mdio_read; - eth->mii_bus->write = eth->soc->mdio_write; - eth->mii_bus->reset = mtk_mdio_reset; - eth->mii_bus->priv = eth; - eth->mii_bus->parent = eth->dev; - - snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np); - err = of_mdiobus_register(eth->mii_bus, mii_np); - if (err) - goto err_free_bus; - - return 0; - -err_free_bus: - kfree(eth->mii_bus); -err_put_node: - of_node_put(mii_np); - eth->mii_bus = NULL; - return err; -} - -void mtk_mdio_cleanup(struct mtk_eth *eth) -{ - if (!eth->mii_bus) - return; - - mdiobus_unregister(eth->mii_bus); - of_node_put(eth->mii_bus->dev.of_node); - kfree(eth->mii_bus); -} |