// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/prefetch.h>
#include <linux/pinctrl/consumer.h>
#include <linux/net_tstamp.h>
#include <linux/reset.h>
#include <linux/of_mdio.h>

#ifdef CONFIG_DWMAC_MESON
#include "phy_debug.h"

void __iomem *PREG_ETH_REG0;
void __iomem *PREG_ETH_REG1;

static int g_phyreg;
static void __iomem *c_ioaddr;
static ssize_t show_phy_reg(
	struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "current phy reg = 0x%x\n", g_phyreg);
}

static ssize_t set_phy_reg(
	struct device *dev,
	struct device_attribute *attr,
	const char *buf, size_t count)
{
	int ovl;
	int r = kstrtoint(buf, 0, &ovl);

	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}
	g_phyreg = ovl;
	pr_info("---ovl=0x%x\n", ovl);
	return count;
}

static ssize_t show_phy_reg_value(
	struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct phy_device *phy_dev = dev_get_drvdata(dev);
	int ret, val, i;

	for (i = 0; i < 32; i++)
		pr_info("%d: 0x%x\n", i, phy_read(phy_dev, i));
	val = phy_read(phy_dev, g_phyreg);
	ret = snprintf(buf, PAGE_SIZE, "phy reg 0x%x = 0x%x\n", g_phyreg, val);

	return ret;
}

static ssize_t set_phy_reg_value(
	struct device *dev,
	struct device_attribute *attr,
	const char *buf, size_t count)
{
	int ovl;
	int ret;

	struct phy_device *phy_dev = dev_get_drvdata(dev);

	ret = kstrtoint(buf, 0, &ovl);
	pr_info("---reg 0x%x: ovl=0x%x\n", g_phyreg, ovl);
	phy_write(phy_dev, g_phyreg, ovl);
	return count;
}

static struct device_attribute phy_reg_attrs[] = {
	__ATTR(phy_reg, 0644, show_phy_reg, set_phy_reg),
	__ATTR(phy_reg_value, 0644, show_phy_reg_value, set_phy_reg_value)
};

static struct phy_device *c_phy_dev;
void am_net_dump_phyreg(void)
{
	int reg = 0;
	int val = 0;

	if (!c_phy_dev)
		return;

	pr_info("========== ETH PHY new regs ==========\n");
	for (reg = 0; reg < 32; reg++) {
		val = phy_read(c_phy_dev, reg);
		pr_info("[reg_%d] 0x%x\n", reg, val);
	}
}

static int am_net_read_phyreg(int argc, char **argv)
{
	int reg = 0;
	int val = 0;
	int r = 0;

	if (!c_phy_dev)
		return -1;
	if (argc < 2 || !argv || !argv[0] || !argv[1]) {
		pr_err("Invalid syntax\n");
		return -1;
	}

	r = kstrtoint(argv[1], 0, &reg);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	if (reg >= 0 && reg <= 31) {
		val = phy_read(c_phy_dev, reg);
		pr_info("read phy [reg_%d] 0x%x\n", reg, val);
	} else if (reg == 32) {
		pr_info("phy features:0x%x\n", c_phy_dev->drv->features);
	} else {
		pr_info("Invalid parameter\n");
	}

	return 0;
}

static int am_net_write_phyreg(int argc, char **argv)
{
	int reg = 0;
	int val = 0;
	int r = 0;

	if (!c_phy_dev)
		return -1;

	if (argc < 3 || !argv || !argv[0] || !argv[1] || !argv[2]) {
		pr_err("Invalid syntax\n");
		return -1;
	}

	r = kstrtoint(argv[1], 0, &reg);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	r = kstrtoint(argv[2], 0, &val);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	if (reg >= 0 && reg <= 31) {
		phy_write(c_phy_dev, reg, val);
		pr_info(
			"write phy [reg_%d] 0x%x, 0x%x\n",
			reg, val, phy_read(c_phy_dev, reg));
	} else if (reg == 32) {
		if (val > 255) {
			pr_info("Invalid parameter\n");
			return 0;
		}
		c_phy_dev->drv->features &= 0xff;
		c_phy_dev->drv->features |= val << 8;
	} else if (reg == 33) {
		if (val > 255) {
			pr_info("Invalid parameter\n");
			return 0;
		}
		c_phy_dev->drv->features &= 0xff00;
		c_phy_dev->drv->features |= val;
	} else {
		pr_info("Invalid parameter\n");
	}

	return 0;
}

void am_net_dump_phy_wol_reg(void)
{
	int reg;
	int val;
	int val15;
	int val16;

	if (!c_phy_dev)
		return;

	pr_info("========== ETH PHY wol regs ==========\n");
	for (reg = 0; reg < 13; reg++) {
		/*Bit 15: READ*/
		/*Bit 14: Write*/
		/*Bit 12:11: BANK_SEL (0: DSP, 1: WOL, 3: BIST)*/
		/*Bit 10: Test Mode*/
		/*Bit 9:5: Read Address*/
		/*Bit 4:0: Write Address*/
		val = (1 << 15) | (1 << 11) | (1 << 10) | (reg << 5);
		phy_write(c_phy_dev, 0x14, val);
		val15 = phy_read(c_phy_dev, 0x15);
		val16 = phy_read(c_phy_dev, 0x16);
		val = val16 * 65536 + val15;
		pr_info("wol [reg_%d] 0x%x\n", reg, val);
	}
}

void am_net_dump_phy_bist_reg(void)
{
	int reg;
	int val;
	int val15;
	int val16;

	if (!c_phy_dev)
		return;

	pr_info("========== ETH PHY bist regs ==========\n");
	for (reg = 0; reg < 32; reg++) {
		/*Bit 15: READ*/
		/*Bit 14: Write*/
		/*Bit 12:11: BANK_SEL (0: DSP, 1: WOL, 3: BIST)*/
		/*Bit 10: Test Mode*/
		/*Bit 9:5: Read Address*/
		/*Bit 4:0: Write Address*/

		val = ((1 << 15) | (1 << 12) | (1 << 11) |
			(1 << 10) | (reg << 5));
		phy_write(c_phy_dev, 0x14, val);
		val15 = phy_read(c_phy_dev, 0x15);
		val16 = phy_read(c_phy_dev, 0x16);
		val = val16 * 65536 + val15;
		pr_info("bist [reg_%d] 0x%x\n", reg, val);
	}
}

static int read_tst_cntl_reg(int argc, char **argv)
{
	int rd_data_hi;
	int rd_addr;
	int rd_data = 0;

	if (argc < 2 || (!argv) || (!argv[0]) || (!argv[1])) {
		pr_info("Invalid syntax\n");
		return -1;
	}
	if (kstrtoint(argv[1], 16, &rd_addr) < 0)
		return -1;

	if (rd_addr >= 0 && rd_addr <= 31) {
		phy_write(
			c_phy_dev, 20,
			((1 << 15) | (1 << 10) | ((rd_addr & 0x1f) << 5)));

		rd_data = phy_read(c_phy_dev, 21);
		rd_data_hi = phy_read(c_phy_dev, 22);
		rd_data = ((rd_data_hi & 0xffff) << 16) | rd_data;
		pr_info("read tstcntl phy [reg_%d] 0x%x\n", rd_addr, rd_data);
	} else {
		pr_info("Invalid parameter\n");
	}

	return rd_data;
}

static int return_write_val(int rd_addr)
{
	int rd_data;
	int rd_data_hi;

	phy_write(
		c_phy_dev, 20,
		((1 << 15) | (1 << 10) | ((rd_addr & 0x1f) << 5)));
	rd_data = phy_read(c_phy_dev, 21);
	rd_data_hi = phy_read(c_phy_dev, 22);
	rd_data = ((rd_data_hi & 0xffff) << 16) | rd_data;

	return rd_data;
}

static int write_tst_cntl_reg(int argc, char **argv)
{
	int wr_addr, wr_data;

	if (argc < 3 || (!argv) || (!argv[0]) || (!argv[1]) || (!argv[2])) {
		pr_info("Invalid syntax\n");
		return -1;
	}

	if (kstrtoint(argv[1], 16, &wr_addr) < 0)
		return -1;

	if (kstrtoint(argv[2], 16, &wr_data) < 0)
		return -1;

	if (wr_addr >= 0 && wr_addr <= 31) {
		phy_write(c_phy_dev, 23, (wr_data & 0xffff));

		phy_write(
			c_phy_dev, 20,
			((1 << 14) | (1 << 10) | ((wr_addr << 0) & 0x1f)));

		pr_info("write phy tstcntl [reg_%d] 0x%x, 0x%x\n",
			wr_addr, wr_data, return_write_val(wr_addr));
	} else {
		pr_info("Invalid parameter\n");
	}

	return 0;
}

static void tstcntl_dump_phyreg(void)
{
	int rd_addr;
	int rd_data;
	int rd_data_hi;

	pr_info("========== ETH TST PHY regs ==========\n");
	for (rd_addr = 0; rd_addr < 32; rd_addr++) {
		phy_write(
			c_phy_dev, 20,
			((1 << 15) | (1 << 10) | ((rd_addr & 0x1f) << 5)));

		rd_data = phy_read(c_phy_dev, 21);
		rd_data_hi = phy_read(c_phy_dev, 22);
		rd_data = ((rd_data_hi & 0xffff) << 16) | rd_data;
		pr_info("tstcntl phy [reg_%d] 0x%x\n", rd_addr, rd_data);
	}
}

void am_net_dump_phy_extended_reg(void)
{
	int reg;
	int val;
	int val15;
	int val16;

	if (!c_phy_dev)
		return;

	pr_info("========== ETH PHY extended regs ==========\n");
	for (reg = 0; reg < 32; reg++) {
		/*Bit 15: READ*/
		/*Bit 14: Write*/
		/*Bit 12:11: BANK_SEL (0: DSP, 1: WOL, 3: BIST)*/
		/*Bit 10: Test Mode*/
		/*Bit 9:5: Read Address*/
		/*Bit 4:0: Write Address*/

		val = ((1 << 15) | (1 << 10) | (reg << 5));
		phy_write(c_phy_dev, 0x14, val);
		val15 = phy_read(c_phy_dev, 0x15);
		val16 = phy_read(c_phy_dev, 0x16);
		val = (val16 << 16) + val15;
		pr_info("extended [reg_%d] 0x%x\n", reg, val);
	}
}

static void am_net_dump_macreg(void)
{
	int reg;
	int val;

	pr_info("========== ETH_MAC regs ==========\n");
	for (reg = ETH_MAC_0_Configuration;
		reg <= ETH_MMC_rxicmp_err_octets; reg += 0x4) {
		val = readl(c_ioaddr + reg);
		pr_info("[0x%04x] 0x%x\n", reg, val);
	}

	pr_info("========== ETH_DMA regs ==========\n");
	for (reg = ETH_DMA_0_Bus_Mode;
		reg <= ETH_DMA_21_Curr_Host_Re_Buffer_Addr; reg += 0x4) {
		val = readl(c_ioaddr + reg);
		pr_info("[0x%04x] 0x%x\n", reg, val);
	}
}

static int am_net_read_macreg(int argc, char **argv)
{
	int reg = 0;
	int val = 0;
	int r = 0;

	if (argc < 2 || (!argv) || (!argv[0]) || (!argv[1])) {
		pr_err("Invalid syntax\n");
		return -1;
	}

	r  = kstrtoint(argv[1], 0, &reg);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	if (reg >= 0 && reg <= ETH_DMA_21_Curr_Host_Re_Buffer_Addr) {
		val = readl(c_ioaddr + reg);
		pr_info("read mac [0x4%x] 0x%x\n", reg, val);
	} else {
		pr_info("Invalid parameter\n");
	}

	return 0;
}

static int am_net_write_macreg(int argc, char **argv)
{
	int reg;
	int val;
	int r;

	if ((argc < 3) || (!argv) || (!argv[0]) || (!argv[1]) || (!argv[2])) {
		pr_err("Invalid syntax\n");
		return -1;
	}

	r = kstrtoint(argv[1], 0, &reg);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	r = kstrtoint(argv[2], 0, &val);
	if (r) {
		pr_err("kstrtoint failed\n");
		return -1;
	}

	if (reg >= 0 && reg <= ETH_DMA_21_Curr_Host_Re_Buffer_Addr) {
		writel(val, (c_ioaddr + reg));
		pr_info("write mac [0x%x] 0x%x, 0x%x\n",
			reg, val, readl(c_ioaddr + reg));
	} else {
		pr_info("Invalid parameter\n");
	}

	return 0;
}

static const char *g_phyreg_help = {
	"Usage:\n"
	"    echo d > phyreg;            //dump ethernet phy reg\n"
	"    echo r reg > phyreg;        //read ethernet phy reg\n"
	"    echo w reg val > phyreg;    //write ethernet phy reg\n"
};

static ssize_t phyreg_show(
	struct class *class, struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", g_phyreg_help);
}

static unsigned char adc_data[32 * 32];
static unsigned char adc_freq[64];

static inline void am_init_tst_mode(void)
{
	phy_write(c_phy_dev, 20, 0x0400);
	phy_write(c_phy_dev, 20, 0x0000);
	phy_write(c_phy_dev, 20, 0x0400);
}

static inline void am_close_tst_mode(void)
{
	phy_write(c_phy_dev, 20, 0x0000);
}

static void am_net_adc_show(void)
{
	int rd_data = 0;
	int rd_data_hi = 0;
	int i, j, v;
	char buf[128];

	pr_info("%s, %d enter\n", __func__, __LINE__);

	am_init_tst_mode();

	for (i = 0; i < (32 * 32); i++) {
		v = (1 << 15) | (1 << 10) | ((16 & 0x1f) << 5);
		phy_write(c_phy_dev, 20, v);
		rd_data = phy_read(c_phy_dev, 21);
		rd_data_hi = phy_read(c_phy_dev, 22);
		adc_data[i] = rd_data & 0x3f;
	}

	am_close_tst_mode();

	for (i = 0; i < 32; i++) {
		for (j = 0; j < 32; j++)
			pr_info("%02x ", adc_data[i * 32 + j]);

		pr_info("\n");
	}

	for (i = 0; i < 64; i++)
		adc_freq[i] = 0;

	for (i = 0; i < 32; i++) {
		for (j = 0; j < 32; j++) {
			if (adc_data[i * 32 + j] > 31)
				adc_freq[adc_data[i * 32 + j] - 32]++;
			else
				adc_freq[32 + adc_data[i * 32 + j]]++;

			pr_info("%02x ", adc_data[i * 32 + j]);
		}
		pr_info("\n");
	}

	for (i = 0; i < 64; i++) {
		pr_info("%d(%04d):\t", i - 32, adc_freq[i]);
		if (adc_freq[i] > 128)
			adc_freq[i] = 128;

		for (j = 0; j < adc_freq[i]; j++)
			buf[j] = '#';

		buf[j] = '\0';

		pr_info("%s\n", buf);
	}
}

static void am_net_eye_pattern_on(void)
{
	unsigned int value;

	c_phy_dev->autoneg = AUTONEG_DISABLE;
	/*stop check wol when doing eye pattern, otherwise it will reset phy*/
	enable_wol_check = 0;
	phy_write(c_phy_dev, 0, 0x2100);
	value = phy_read(c_phy_dev, 17);
	pr_info("0x11 %x\n", value);
	phy_write(c_phy_dev, 17, (value | 0x0004));
}
static void am_net_eye_pattern_off(void)
{
	unsigned int value;

	c_phy_dev->autoneg = AUTONEG_ENABLE;
	enable_wol_check = 1;
	phy_write(c_phy_dev, 0, 0x1000);
	value = phy_read(c_phy_dev, 17);
	pr_info("0x11 %x\n", value);
	phy_write(c_phy_dev, 17, (value & ~0x0004));
}

static void am_net_debug_mode(void)
{	/*disable autoneg*/
	c_phy_dev->autoneg = AUTONEG_DISABLE;
	/*disable wol check*/
	enable_wol_check = 0;
}

static ssize_t phyreg_store(
	struct class *class, struct class_attribute *attr,
	const char *buf, size_t count)
{
	int argc;
	char *buff, *p, *para;
	char *argv[4];
	char cmd;

	buff = kstrdup(buf, GFP_KERNEL);
	p = buff;
	for (argc = 0; argc < 4; argc++) {
		para = strsep(&p, " ");
		if (!para)
			break;
		argv[argc] = para;
	}
	if (argc < 1 || argc > 4)
		goto end;

	cmd = argv[0][0];
	switch (cmd) {
	case 'r':
	case 'R':
		am_net_read_phyreg(argc, argv);
		break;
	case 'w':
	case 'W':
		am_net_write_phyreg(argc, argv);
		break;
	case 'd':
	case 'D':
		am_net_dump_phyreg();
		break;
#ifdef CONFIG_MESON_ETH_WOL /* FIXED ME */
	case 'p':
		wol_test(c_phy_dev);
		break;
#endif
	case 'e':
		am_net_dump_phy_extended_reg();
		am_net_dump_phy_wol_reg();
		am_net_dump_phy_bist_reg();
		break;
	case 'c':
	case 'C':
		am_net_adc_show();
		break;
	case 't':
	case 'T':
		am_init_tst_mode();

		if (argv[0][1] == 'w' || argv[0][1] == 'W')
			write_tst_cntl_reg(argc, argv);

		if (argv[0][1] == 'r' || argv[0][1] == 'R')
			read_tst_cntl_reg(argc, argv);

		if (argv[0][1] == 'd' || argv[0][1] == 'D')
			tstcntl_dump_phyreg();

		am_close_tst_mode();
		break;
	case 'o':
	case 'O':
		if (argv[0][1] == 'n' || argv[0][1] == 'N') {
			am_net_eye_pattern_on();
			break;
		}
		if (argv[0][1] == 'f' || argv[0][1] == 'F') {
			am_net_eye_pattern_off();
			break;
		}
		if (argv[0][1] == 'd' || argv[0][1] == 'D') {
			am_net_debug_mode();
			break;
		}
		break;
	default:
		goto end;
	}

	return count;

end:
	kfree(buff);
	return 0;
}

static const char *g_macreg_help = {
	"Usage:\n"
	"    echo d > macreg;            //dump ethernet mac reg\n"
	"    echo r reg > macreg;        //read ethernet mac reg\n"
	"    echo w reg val > macreg;    //read ethernet mac reg\n"
};

static ssize_t macreg_show(
	struct class *class,
	struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", g_macreg_help);
}

static ssize_t macreg_store(
	struct class *class, struct class_attribute *attr,
	const char *buf, size_t count)
{
	int argc;
	char *buff, *p, *para;
	char *argv[4];
	char cmd;

	buff = kstrdup(buf, GFP_KERNEL);
	p = buff;
	for (argc = 0; argc < 4; argc++) {
		para = strsep(&p, " ");
		if (!para)
			break;
		argv[argc] = para;
	}
	if (argc < 1 || argc > 4)
		goto end;

	cmd = argv[0][0];
	switch (cmd) {
	case 'r':
	case 'R':
		am_net_read_macreg(argc, argv);
		break;
	case 'w':
	case 'W':
		am_net_write_macreg(argc, argv);
		break;
	case 'd':
	case 'D':
		am_net_dump_macreg();
		break;
	default:
		goto end;
	}

	return count;

end:
	kfree(buff);
	return 0;
}

static ssize_t linkspeed_show(
	struct class *class, struct class_attribute *attr, char *buf)
{
	int ret;
	char buff[100];

	if (c_phy_dev) {
		phy_print_status(c_phy_dev);

		genphy_update_link(c_phy_dev);
		if (c_phy_dev->link)
			strcpy(buff, "link status: link\n");
		else
			strcpy(buff, "link status: unlink\n");
	} else {
		strcpy(buff, "link status: unlink\n");
	}

	ret = sprintf(buf, "%s\n", buff);

	return ret;
}

int auto_cali(void)
{
	unsigned int value;
	int I1, I2, I3, I4, I5;
	int count = 99;
	char problem[20] = {0};
	char path[20] = {0};
	int cali_rise = 0;
	int cali_sel = 0;

	pr_info("auto test cali\n");
	for (cali_sel = 0; cali_sel < 4; cali_sel++) {
		readl(PREG_ETH_REG1);
		strcpy(problem, "no clock delay");
		value = readl(PREG_ETH_REG0) & (~(0x1f << 25));
		writel(value, PREG_ETH_REG0);

		I1 = 0;
		I2 = 0;
		I3 = 0;
		I4 = 0;
		I5 = 0;

		for (cali_rise = 0; cali_rise <= 1; cali_rise++) {
			count = 99;
			value = (readl(PREG_ETH_REG0) | (1 << 25) |
				(cali_rise << 26) | (cali_sel << 27));
			writel(value, PREG_ETH_REG0);
			while (count >= 0) {
				value = readl(PREG_ETH_REG1);
				if ((value >> 15) & 0x1) {
					count--;
					switch (value & 0x1f) {
					case 0x0:
						I1++;
						break;
					case 0x1:
						I2++;
						break;
					case 0x2:
						I3++;
						break;
					case 0x3:
						I4++;
						break;
					case 0x4:
						I5++;
						break;
					}
				}
			}
		pr_info(" I1 = %d; I2 = %d; I3 = %d; I4 = %d; I5 = %d;\n",
			I1, I2, I3, I4, I5);

		if (
			(I1 > 0) && (I2 > 0) && (I3 > 0) &&
			(I4 > 0) && (I5 > 0))
			strcpy(problem, "clock delay");

		pr_info(" RXDATA Line %d have %s problem\n",
			cali_sel, problem);

		strcpy(path, (I2 + I1 + I3) > (I5 + I4 + I3) ?
			"positive" : "opposite");

		if (!strncmp(problem, "clock delay", 11))
			pr_info("Need debug to  delay %s direction\n", path);
		}
	}
	return 0;
}

static int am_net_cali(int argc, char **argv, int gate)
{
	unsigned int value;
	int cali_rise = 0;
	int cali_sel = 0;
	int cali_start = 0;
	int cali_time = 0;
	int ii = 0;
	int r = 0;

	cali_start = gate;
	if (gate == 3) {
		auto_cali();
		return 0;
	}

	if (
		(argc < 4) || (!argv) || (!argv[0]) ||
		(!argv[1]) || (!argv[2]) || (!argv[3])) {
		pr_err("Invalid syntax\n");
		return -1;
	}

	r = kstrtoint(argv[1], 0, &cali_rise);
	r = kstrtoint(argv[2], 0, &cali_sel);
	r = kstrtoint(argv[3], 0, &cali_time);

	readl(PREG_ETH_REG1);
	value = readl(PREG_ETH_REG0) & (~(0x1f << 25));
	writel(value, PREG_ETH_REG0);

	value = readl(PREG_ETH_REG0) | (cali_start << 25) |
		(cali_rise << 26) | (cali_sel << 27);
	writel(value, PREG_ETH_REG0);

	pr_info("rise :%d   sel: %d  time: %d   start:%d  cbus2050 = %x\n",
		cali_rise, cali_sel, cali_time, cali_start,
			readl(PREG_ETH_REG0));
	for (ii = 0; ii < cali_time; ii++) {
		mdelay(100);
		value = readl(PREG_ETH_REG1);
		if ((value >> 15) & 0x1) {
			pr_info
			("value = %x,len = %d,idx = %d,sel=%d,rise = %d\n",
			value, (value >> 5) & 0x1f, (value & 0x1f),
			(value >> 11) & 0x7, (value >> 14) & 0x1);
			ii++;
		}
	}

	return 0;
}

static ssize_t cali_store(
	struct class *class, struct class_attribute *attr,
	const char *buf, size_t count)
{
	int argc;
	char *buff, *p, *para;
	char *argv[5];
	char cmd;

	buff = kstrdup(buf, GFP_KERNEL);
	p = buff;
/*only support g12a by now, needn't this*/
/*
 *	if (get_cpu_type() < MESON_CPU_MAJOR_ID_M8B) {
 *		pr_err("Sorry ,this cpu is not support cali!\n");
 *		goto end;
 *	}
 */
	for (argc = 0; argc < 5; argc++) {
		para = strsep(&p, " ");
		if (!para)
			break;
		argv[argc] = para;
	}

	if (argc < 1 || argc > 4)
		goto end;

	cmd = argv[0][0];
		switch (cmd) {
		case 'e':
		case 'E':
			am_net_cali(argc, argv, 1);
			break;
		case 'd':
		case 'D':
			am_net_cali(argc, argv, 0);
			break;
		case 'a':
		case 'A':
			am_net_cali(argc, argv, 3);
			break;
		default:
			goto end;
		}
		return count;
end:
	kfree(buff);
	return 0;
}

#define DRIVER_NAME "ethernet"
static struct class *phy_sys_class;

static CLASS_ATTR_RW(phyreg);
static CLASS_ATTR_RW(macreg);
static CLASS_ATTR_RO(linkspeed);
static CLASS_ATTR_WO(cali);
int gmac_create_sysfs(struct phy_device *phydev, void __iomem *ioaddr)
{
	int r;
	int t;
	int ret;

	c_phy_dev  = phydev;
	c_ioaddr = ioaddr;
	dev_set_drvdata(&phydev->mdio.dev, phydev);
	for (t = 0; t < ARRAY_SIZE(phy_reg_attrs); t++) {
		r = device_create_file(&phydev->mdio.dev, &phy_reg_attrs[t]);
		if (r) {
			dev_err(&phydev->mdio.dev, "failed to create sysfs file\n");
			return r;
		}
	}
	phy_sys_class = class_create(THIS_MODULE, DRIVER_NAME);
	ret = class_create_file(phy_sys_class, &class_attr_phyreg);
	ret = class_create_file(phy_sys_class, &class_attr_macreg);
	ret = class_create_file(phy_sys_class, &class_attr_linkspeed);
	ret = class_create_file(phy_sys_class, &class_attr_cali);
	return 0;
}

int gmac_remove_sysfs(struct phy_device *phydev)
{
	int t;

	for (t = 0; t < ARRAY_SIZE(phy_reg_attrs); t++)
		device_remove_file(&phydev->mdio.dev, &phy_reg_attrs[t]);
	class_destroy(phy_sys_class);
	c_phy_dev = NULL;
	return 0;
}
#endif
