/* Copyright  2016 MediaTek Inc.
 * Author: Nelson Chang <nelson.chang@mediatek.com>
 * Author: Carlos Huang <carlos.huang@mediatek.com>
 * Author: Harry Huang <harry.huang@mediatek.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include "raether.h"

void enable_auto_negotiate(struct END_DEVICE *ei_local)
{
	u32 reg_value;
	pr_info("=================================\n");
	pr_info("enable_auto_negotiate\n");

	/* FIXME: we don't know how to deal with PHY end addr */
	reg_value = sys_reg_read(ESW_PHY_POLLING);
	reg_value |= (1 << 31);
	reg_value &= ~(0x1f);
	reg_value &= ~(0x1f << 8);

	if (ei_local->architecture & (GE2_RGMII_AN | GE2_SGMII_AN)) {
		/* setup PHY address for auto polling (Start Addr). */
		/*avoid end phy address = 0 */
		reg_value |= ((mac_to_gigaphy_mode_addr2 - 1) & 0x1f);
		/* setup PHY address for auto polling (End Addr). */
		reg_value |= (mac_to_gigaphy_mode_addr2 << 8);
	} else if (ei_local->architecture & (GE1_RGMII_AN | GE1_SGMII_AN | LEOPARD_EPHY)) {
		/* setup PHY address for auto polling (Start Addr). */
		reg_value |= (mac_to_gigaphy_mode_addr << 0);
		/* setup PHY address for auto polling (End Addr). */
		reg_value |= ((mac_to_gigaphy_mode_addr + 1) << 8);
	}

	sys_reg_write(ESW_PHY_POLLING, reg_value);
}

void ra2880stop(struct END_DEVICE *ei_local)
{
	unsigned int reg_value;

	pr_info("ra2880stop()...");

	reg_value = sys_reg_read(DMA_GLO_CFG);
	reg_value &= ~(TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
	sys_reg_write(DMA_GLO_CFG, reg_value);

	pr_info("Done\n");
}

void set_mac_address(unsigned char p[6])
{
	unsigned long reg_value;

	reg_value = (p[0] << 8) | (p[1]);
	sys_reg_write(GDMA1_MAC_ADRH, reg_value);

	reg_value = (unsigned long)((p[2] << 24) | (p[3] << 16) | (p[4] << 8) | p[5]);
	sys_reg_write(GDMA1_MAC_ADRL, reg_value);
}

void set_mac2_address(unsigned char p[6])
{
	unsigned long reg_value;

	reg_value = (p[0] << 8) | (p[1]);
	sys_reg_write(GDMA2_MAC_ADRH, reg_value);

	reg_value = (unsigned long)((p[2] << 24) | (p[3] << 16) | (p[4] << 8) | p[5]);
	sys_reg_write(GDMA2_MAC_ADRL, reg_value);
}

static int getnext(const char *src, int separator, char *dest)
{
	char *c;
	int len;

	if (!src || !dest)
		return -1;

	c = strchr(src, separator);
	if (!c) {
		strcpy(dest, src);
		return -1;
	}
	len = c - src;
	strncpy(dest, src, len);
	dest[len] = '\0';
	return len + 1;
}

int str_to_ip(unsigned int *ip, const char *str)
{
	int len;
	const char *ptr = str;
	char buf[128];
	unsigned char c[4];
	int i;
	int ret;

	for (i = 0; i < 3; ++i) {
		len = getnext(ptr, '.', buf);
		if (len == -1)
			return 1;	/* parse error */

		ret = kstrtoul(buf, 10, (unsigned long *)&c[i]);
		if (ret)
			return ret;

		ptr += len;
	}
	ret = kstrtoul(ptr, 0, (unsigned long *)&c[3]);
	if (ret)
		return ret;

	*ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];

	return 0;
}

void set_ge1_force_1000(void)
{
	sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x100, 0x2105e33b);
}

void set_ge2_force_1000(void)
{
	sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x2105e33b);
}

void set_ge1_an(void)
{
	sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x100, 0x21056300);
}

void set_ge2_an(void)
{
	sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x21056300);
}

void set_ge2_gmii(void)
{
	void __iomem *virt_addr;
	unsigned int reg_value;

	virt_addr = ioremap(ETHSYS_BASE, 0x20);
	reg_value = sys_reg_read(virt_addr + 0x14);
	/*[15:14] =0 RGMII, [8] = 0 SGMII disable*/
	reg_value = reg_value & (~0xc100);
	reg_value = reg_value | 0x4000;
	sys_reg_write(virt_addr + 0x14, reg_value);
	iounmap(virt_addr);
}

void set_ge0_gmii(void)
{
	void __iomem *virt_addr;
	unsigned int reg_value;

	virt_addr = ioremap(ETHSYS_BASE, 0x20);
	reg_value = sys_reg_read(virt_addr + 0x14);
	/*[15:14] =0 RGMII, [8] = 0 SGMII disable*/
	reg_value = reg_value & (~0xc000);
	reg_value = reg_value | 0x400;
	sys_reg_write(virt_addr + 0x14, reg_value);
	iounmap(virt_addr);
}

void set_ge2_force_link_down(void)
{
	sys_reg_write(ETHDMASYS_ETH_MAC_BASE + 0x200, 0x2105e300);
}
