// 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>

#include "phy_debug.h"

void __iomem *PREG_ETH_REG0;
void __iomem *PREG_ETH_REG1;

#define ETH_MAC_0_Configuration			(0x0000)
#define ETH_MMC_rxicmp_err_octets		(0x0284)
#define ETH_DMA_0_Bus_Mode			(0x1000)
#define ETH_DMA_21_Curr_Host_Re_Buffer_Addr	(0x1054)

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);
//extern void __iomem *ioaddr_dbg;
//EXPORT_SYMBOL(ioaddr_dbg);
int gmac_create_sysfs(struct phy_device *phydev, void __iomem *ioaddr)
{
//	int r;
//	int t;
	int ret;

	c_phy_dev  = phydev;
//	c_ioaddr = ioaddr_dbg;
	c_ioaddr = ioaddr;
	if (!c_phy_dev)
		pr_info("wzh c_phy_dev null\n");

//	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;
}
EXPORT_SYMBOL(gmac_create_sysfs);
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;
}
EXPORT_SYMBOL(gmac_remove_sysfs);
