/*   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(&eth->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(&eth->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("%s: invalid port id\n", phy_node->name);
		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_GBIT_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->supported &= PHY_BASIC_FEATURES;
	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(&eth->phy->lock, flags);
			eth->link[i] = 0;
			if (eth->soc->mdio_adjust_link)
				eth->soc->mdio_adjust_link(eth, i);
			spin_unlock_irqrestore(&eth->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(&eth->phy->lock, flags);
			eth->link[i] = 1;
			if (eth->soc->mdio_adjust_link)
				eth->soc->mdio_adjust_link(eth, i);
			spin_unlock_irqrestore(&eth->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(&eth->phy->lock, flags);
			eth->link[i] = 0;
			if (eth->soc->mdio_adjust_link)
				eth->soc->mdio_adjust_link(eth, i);
			spin_unlock_irqrestore(&eth->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, "%s", mii_np->name);
	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);
}
