/*
 * Freescale SGMII Riser Card
 *
 * This driver supports the SGMII Riser card found on the
 * "DS" style of development board from Freescale.
 *
 * This software may be used and distributed according to the
 * terms of the GNU Public License, Version 2, incorporated
 * herein by reference.
 *
 * Copyright 2008 Freescale Semiconductor, Inc.
 *
 */

#include <config.h>
#include <common.h>
#include <log.h>
#include <net.h>
#include <linux/libfdt.h>
#include <tsec.h>
#include <fdt_support.h>

void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num)
{
	int i;

	for (i = 0; i < num; i++)
		if (tsec_info[i].flags & TSEC_SGMII)
			tsec_info[i].phyaddr += SGMII_RISER_PHY_OFFSET;
}

void fsl_sgmii_riser_fdt_fixup(void *fdt)
{
	struct eth_device *dev;
	int node;
	int mdio_node;
	int i = -1;
	int etsec_num = 0;

	node = fdt_path_offset(fdt, "/aliases");
	if (node < 0)
		return;

	while ((dev = eth_get_dev_by_index(++i)) != NULL) {
		struct tsec_private *priv;
		int phy_node;
		int enet_node;
		uint32_t ph;
		char sgmii_phy[16];
		char enet[16];
		const u32 *phyh;
		const char *model;
		const char *path;

		if (!strstr(dev->name, "eTSEC"))
			continue;

		priv = dev->priv;
		if (!(priv->flags & TSEC_SGMII)) {
			etsec_num++;
			continue;
		}

		mdio_node = fdt_node_offset_by_compatible(fdt, -1,
				"fsl,gianfar-mdio");
		if (mdio_node < 0)
			return;

		sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num);
		phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy);
		if (phy_node > 0) {
			fdt_increase_size(fdt, 32);
			ph = fdt_create_phandle(fdt, phy_node);
			if (!ph)
				continue;
		}

		sprintf(enet, "ethernet%d", etsec_num++);
		path = fdt_getprop(fdt, node, enet, NULL);
		if (!path) {
			debug("No alias for %s\n", enet);
			continue;
		}

		enet_node = fdt_path_offset(fdt, path);
		if (enet_node < 0)
			continue;

		model = fdt_getprop(fdt, enet_node, "model", NULL);

		/*
		 * We only want to do this to eTSECs.  On some platforms
		 * there are more than one type of gianfar-style ethernet
		 * controller, and as we are creating an implicit connection
		 * between ethernet nodes and eTSEC devices, it is best to
		 * make the connection use as much explicit information
		 * as exists.
		 */
		if (!strstr(model, "TSEC"))
			continue;

		if (phy_node < 0) {
			/*
			 * This part is only for old device tree without
			 * sgmii_phy nodes. It's kept just for compatible
			 * reason. Soon to be deprecated if all device tree
			 * get updated.
			 */
			phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL);
			if (!phyh)
				continue;

			phy_node = fdt_node_offset_by_phandle(fdt,
					fdt32_to_cpu(*phyh));

			priv = dev->priv;

			if (priv->flags & TSEC_SGMII)
				fdt_setprop_cell(fdt, phy_node, "reg",
						priv->phyaddr);
		} else {
			fdt_setprop(fdt, enet_node, "phy-handle", &ph,
					sizeof(ph));
			fdt_setprop_string(fdt, enet_node,
					"phy-connection-type",
					phy_string_for_interface(
						PHY_INTERFACE_MODE_SGMII));
		}
	}
}
