/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.

 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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 <common.h>
#include <asm-generic/errno.h>
#include <asm/io.h>
#include <malloc.h>
#include <net.h>
#include <phy.h>
#include <miiphy.h>
#include "ipq_phy.h"
#include "ipq_qca8075.h"

extern int ipq_mdio_write(int mii_id,
		int regnum, u16 value);
extern int ipq_mdio_read(int mii_id,
		int regnum, ushort *data);

struct phy_ops *qca8075_ops;
static u32 qca8075_id;
static u16 qca8075_phy_reg_write(u32 dev_id, u32 phy_id,
		u32 reg_id, u16 reg_val)
{
	ipq_mdio_write(phy_id, reg_id, reg_val);
	return 0;
}

static u16 qca8075_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
{
	return ipq_mdio_read(phy_id, reg_id, NULL);
}

/*
 * phy4 prfer medium
 * get phy4 prefer medum, fiber or copper;
 */
static qca8075_phy_medium_t __phy_prefer_medium_get(u32 dev_id,
                                                   u32 phy_id)
{
	u16 phy_medium;
	phy_medium =
		qca8075_phy_reg_read(dev_id, phy_id,
			QCA8075_PHY_CHIP_CONFIG);

	return ((phy_medium & QCA8075_PHY4_PREFER_FIBER) ?
		QCA8075_PHY_MEDIUM_FIBER : QCA8075_PHY_MEDIUM_COPPER);
}

/*
 *  phy4 activer medium
 *  get phy4 current active medium, fiber or copper;
 */
static qca8075_phy_medium_t __phy_active_medium_get(u32 dev_id,
                                                   u32 phy_id)
{
	u16 phy_data = 0;
	u32 phy_mode;

	phy_mode = qca8075_phy_reg_read(dev_id, phy_id,
				QCA8075_PHY_CHIP_CONFIG);
	phy_mode &= 0x000f;

	if (phy_mode == QCA8075_PHY_PSGMII_AMDET) {
		phy_data = qca8075_phy_reg_read(dev_id,
			phy_id, QCA8075_PHY_SGMII_STATUS);

		if ((phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) {
			return QCA8075_PHY_MEDIUM_COPPER;
		} else if ((phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) {
			/* PHY_MEDIUM_FIBER_BX1000 */
			return QCA8075_PHY_MEDIUM_FIBER;
		} else if ((phy_data & QCA8075_PHY4_AUTO_FX100_SELECT)) {
			 /* PHY_MEDIUM_FIBER_FX100 */
			return QCA8075_PHY_MEDIUM_FIBER;
		}
		/* link down */
		return __phy_prefer_medium_get(dev_id, phy_id);
	} else if ((phy_mode == QCA8075_PHY_PSGMII_BASET) ||
			(phy_mode == QCA8075_PHY_SGMII_BASET)) {
		return QCA8075_PHY_MEDIUM_COPPER;
	} else if ((phy_mode == QCA8075_PHY_PSGMII_BX1000) ||
			(phy_mode == QCA8075_PHY_PSGMII_FX100)) {
		return QCA8075_PHY_MEDIUM_FIBER;
	} else {
		return QCA8075_PHY_MEDIUM_COPPER;
	}
}

/*
 *  phy4 copper page or fiber page select
 *  set phy4 copper or fiber page
 */

static u8  __phy_reg_pages_sel(u32 dev_id, u32 phy_id,
		qca8075_phy_reg_pages_t phy_reg_pages)
{
	u16 reg_pages;
	reg_pages = qca8075_phy_reg_read(dev_id,
			phy_id, QCA8075_PHY_CHIP_CONFIG);

	if (phy_reg_pages == QCA8075_PHY_COPPER_PAGES) {
		reg_pages |= 0x8000;
	} else if (phy_reg_pages == QCA8075_PHY_SGBX_PAGES) {
		reg_pages &= ~0x8000;
	} else
		return -EINVAL;

	qca8075_phy_reg_write(dev_id, phy_id,
		QCA8075_PHY_CHIP_CONFIG, reg_pages);
	return 0;
}

/*
 *  phy4 reg pages selection by active medium
 *  phy4 reg pages selection
 */
static  u32 __phy_reg_pages_sel_by_active_medium(u32 dev_id,
						u32 phy_id)
{
	qca8075_phy_medium_t phy_medium;
	qca8075_phy_reg_pages_t reg_pages;

	phy_medium = __phy_active_medium_get(dev_id, phy_id);
	if (phy_medium == QCA8075_PHY_MEDIUM_FIBER) {
		reg_pages = QCA8075_PHY_SGBX_PAGES;
	} else if (phy_medium == QCA8075_PHY_MEDIUM_COPPER) {
		reg_pages = QCA8075_PHY_COPPER_PAGES;
	} else {
		return -1;
	}

	return __phy_reg_pages_sel(dev_id, phy_id, reg_pages);
}

static u8 qca8075_phy_get_link_status(u32 dev_id, u32 phy_id)
{
	u16 phy_data;
	if (phy_id == COMBO_PHY_ID)
		__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
	phy_data = qca8075_phy_reg_read(dev_id,
			phy_id, QCA8075_PHY_SPEC_STATUS);
	if (phy_data & QCA8075_STATUS_LINK_PASS)
		return 0;

	return 1;
}

static u32 qca8075_phy_get_duplex(u32 dev_id, u32 phy_id,
                      fal_port_duplex_t * duplex)
{
	u16 phy_data;

	if (phy_id == COMBO_PHY_ID) {
		__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
	}

	phy_data = qca8075_phy_reg_read(dev_id, phy_id,
				QCA8075_PHY_SPEC_STATUS);

	/*
	 * Read duplex
	 */
	if (phy_data & QCA8075_STATUS_FULL_DUPLEX)
		*duplex = FAL_FULL_DUPLEX;
	else
		*duplex = FAL_HALF_DUPLEX;

	return 0;
}

static u32 qca8075_phy_get_speed(u32 dev_id, u32 phy_id,
                     fal_port_speed_t * speed)
{
	u16 phy_data;

	if (phy_id == COMBO_PHY_ID) {
		__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
	}
	phy_data = qca8075_phy_reg_read(dev_id,
			phy_id, QCA8075_PHY_SPEC_STATUS);

	switch (phy_data & QCA8075_STATUS_SPEED_MASK) {
	case QCA8075_STATUS_SPEED_1000MBS:
		*speed = FAL_SPEED_1000;
		break;
	case QCA8075_STATUS_SPEED_100MBS:
		*speed = FAL_SPEED_100;
		break;
	case QCA8075_STATUS_SPEED_10MBS:
		*speed = FAL_SPEED_10;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static u32 qca8075_phy_mmd_write(u32 dev_id, u32 phy_id,
                     u16 mmd_num, u16 reg_id, u16 reg_val)
{
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_CTRL_REG, mmd_num);
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_DATA_REG, reg_id);
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_CTRL_REG,
			0x4000 | mmd_num);
	qca8075_phy_reg_write(dev_id, phy_id,
		QCA8075_MMD_DATA_REG, reg_val);

	return 0;
}

static u16 qca8075_phy_mmd_read(u32 dev_id, u32 phy_id,
		u16 mmd_num, u16 reg_id)
{
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_CTRL_REG, mmd_num);
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_DATA_REG, reg_id);
	qca8075_phy_reg_write(dev_id, phy_id,
			QCA8075_MMD_CTRL_REG,
			0x4000 | mmd_num);
	return qca8075_phy_reg_read(dev_id, phy_id,
			QCA8075_MMD_DATA_REG);
}

/*
 *  get phy4 medium is 100fx
 */
static u8 __medium_is_fiber_100fx(u32 dev_id, u32 phy_id)
{
	u16 phy_data;
	phy_data = qca8075_phy_reg_read(dev_id, phy_id,
				QCA8075_PHY_SGMII_STATUS);

	if (phy_data & QCA8075_PHY4_AUTO_FX100_SELECT) {
		return 1;
	}
	/* Link down */
	if ((!(phy_data & QCA8075_PHY4_AUTO_COPPER_SELECT)) &&
	    (!(phy_data & QCA8075_PHY4_AUTO_BX1000_SELECT)) &&
	    (!(phy_data & QCA8075_PHY4_AUTO_SGMII_SELECT))) {

		phy_data = qca8075_phy_reg_read(dev_id, phy_id,
					QCA8075_PHY_CHIP_CONFIG);
		if ((phy_data & QCA8075_PHY4_PREFER_FIBER)
		    && (!(phy_data & QCA8075_PHY4_FIBER_MODE_1000BX))) {
			return 1;
		}
	}
	return 0;
}

/*
 * qca8075_phy_set_hibernate - set hibernate status
 * set hibernate status
 */
static u32 qca8075_phy_set_hibernate(u32 dev_id, u32 phy_id, u8 enable)
{
	u16 phy_data;

	qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_ADDRESS,
					QCA8075_DEBUG_PHY_HIBERNATION_CTRL);

	phy_data = qca8075_phy_reg_read(dev_id, phy_id,
				QCA8075_DEBUG_PORT_DATA);

	if (enable) {
		phy_data |= 0x8000;
	} else {
		phy_data &= ~0x8000;
	}

	qca8075_phy_reg_write(dev_id, phy_id, QCA8075_DEBUG_PORT_DATA, phy_data);
	return 0;
}

/*
 * qca8075_restart_autoneg - restart the phy autoneg
 */
static u32 qca8075_phy_restart_autoneg(u32 dev_id, u32 phy_id)
{
	u16 phy_data;

	if (phy_id == COMBO_PHY_ID) {
		if (__medium_is_fiber_100fx(dev_id, phy_id))
			return -1;
		__phy_reg_pages_sel_by_active_medium(dev_id, phy_id);
	}
	phy_data = qca8075_phy_reg_read(dev_id, phy_id, QCA8075_PHY_CONTROL);
	phy_data |= QCA8075_CTRL_AUTONEGOTIATION_ENABLE;
	qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL,
			phy_data | QCA8075_CTRL_RESTART_AUTONEGOTIATION);

	return 0;
}

/*
 * qca8075_phy_get_8023az status
 * get 8023az status
 */
static u32 qca8075_phy_get_8023az(u32 dev_id, u32 phy_id, u8 *enable)
{
	u16 phy_data;
	if (phy_id == COMBO_PHY_ID) {
		if (QCA8075_PHY_MEDIUM_COPPER !=
			__phy_active_medium_get(dev_id, phy_id))
			return -1;
	}
	*enable = 0;

	phy_data = qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
					QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);

	if ((phy_data & 0x0004) && (phy_data & 0x0002))
		*enable = 1;

	return 0;
}

/*
 * qca8075_phy_set_powersave - set power saving status
 */
static u32 qca8075_phy_set_powersave(u32 dev_id, u32 phy_id, u8 enable)
{
	u16 phy_data;
	u8 status = 0;

	if (phy_id == COMBO_PHY_ID) {
		if (QCA8075_PHY_MEDIUM_COPPER !=
			__phy_active_medium_get(dev_id, phy_id))
			return -1;
	}

	if (enable) {
		qca8075_phy_get_8023az(dev_id, phy_id, &status);
		if (!status) {
			phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
							QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
			phy_data &= ~(1 << 14);
			qca8075_phy_mmd_write(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
					phy_data);
		}
		phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
						QCA8075_PHY_MMD3_NUM,
						QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
		phy_data &= ~(1 << 14);
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_CLD_CTRL5,
								phy_data);

		phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
		phy_data &= ~(1 << 15);
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);

	} else {
		phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL);
		phy_data |= (1 << 14);
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
				QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
				phy_data);

		phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_CLD_CTRL5);
		phy_data |= (1 << 14);
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
				QCA8075_PHY_MMD3_ADDR_CLD_CTRL5, phy_data);

		phy_data = qca8075_phy_mmd_read(dev_id, phy_id,
						QCA8075_PHY_MMD3_NUM,
						QCA8075_PHY_MMD3_ADDR_CLD_CTRL3);
		phy_data |= (1 << 15);
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD3_NUM,
				QCA8075_PHY_MMD3_ADDR_CLD_CTRL3, phy_data);

	}
	qca8075_phy_reg_write(dev_id, phy_id, QCA8075_PHY_CONTROL, 0x9040);
	return 0;
}

/*
 * qca8075_phy_set_802.3az
 */
 static u32 qca8075_phy_set_8023az(u32 dev_id, u32 phy_id, u8 enable)
{
	u16 phy_data;

	if (phy_id == COMBO_PHY_ID) {
		if (QCA8075_PHY_MEDIUM_COPPER !=
			 __phy_active_medium_get(dev_id, phy_id))
			return -1;
	}
	phy_data = qca8075_phy_mmd_read(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
				       QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL);
	if (enable) {
		phy_data |= 0x0006;

		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
			     QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
		if (qca8075_id == QCA8075_PHY_V1_0_5P) {
			/*
			 * Workaround to avoid packet loss and < 10m cable
			 * 1000M link not stable under az enable
			 */
			qca8075_phy_mmd_write(dev_id, phy_id,
				QCA8075_PHY_MMD3_NUM,
				QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
				AZ_TIMER_CTRL_ADJUST_VALUE);

			qca8075_phy_mmd_write(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_8023AZ_CLD_CTRL,
					AZ_CLD_CTRL_ADJUST_VALUE);
		}
	} else {
		phy_data &= ~0x0006;
		qca8075_phy_mmd_write(dev_id, phy_id, QCA8075_PHY_MMD7_NUM,
				QCA8075_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data);
		if (qca8075_id == QCA8075_PHY_V1_0_5P) {
			qca8075_phy_mmd_write(dev_id, phy_id,
					QCA8075_PHY_MMD3_NUM,
					QCA8075_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL,
					AZ_TIMER_CTRL_DEFAULT_VALUE);
		}
	}
	qca8075_phy_restart_autoneg(dev_id, phy_id);
	return 0;
}

void ess_reset(void)
{
	writel(0x1, 0x1812008);
	mdelay(10);
	writel(0x0, 0x1812008);
	mdelay(100);
}

void qca8075_ess_reset(void)
{
	int i;
	u32 status;
	/*
	 * Fix phy psgmii RX 20bit
	 */
	qca8075_phy_reg_write(0, 5, 0x0, 0x005b);
	/*
	 * Reset phy psgmii
	 */
	qca8075_phy_reg_write(0, 5, 0x0, 0x001b);
	/*
	 * Release reset phy psgmii
	 */
	qca8075_phy_reg_write(0, 5, 0x0, 0x005b);
	for (i = 0; i < QCA8075_MAX_TRIES; i++) {
		status = qca8075_phy_mmd_read(0, 5, 1, 0x28);
		if(status & 0x1)
			break;
		mdelay(10);
	}
	if (i >= QCA8075_MAX_TRIES)
		printf("qca8075 PSGMII PLL_VCO_CALIB Not Ready\n");
	mdelay(50);
	/*
	 * Check qca8075 psgmii calibration done end.
	 * Freeze phy psgmii RX CDR
	 */
	qca8075_phy_reg_write(0, 5, 0x1a, 0x2230);

	ess_reset();
	/*
	 * Check ipq psgmii calibration done start
	 */
	for (i = 0; i < QCA8075_MAX_TRIES; i++) {
		status = readl(0x000980A0);
		if (status & 0x1)
			break;
		mdelay(10);
	}
	if (i >= QCA8075_MAX_TRIES)
		printf("PSGMII PLL_VCO_CALIB Not Ready\n");
	mdelay(50);
	/*
	 * Check ipq psgmii calibration done end.
	 * Relesae phy psgmii RX CDR
	 */
	qca8075_phy_reg_write(0, 5, 0x1a, 0x3230);
	/*
	 * Release phy psgmii RX 20bit
	 */
	qca8075_phy_reg_write(0, 5, 0x0, 0x005f);
	mdelay(200);
}

void psgmii_self_test(void)
{
	int i, phy, j;
	u32 value;
	u32 phy_t_status;
	u16 status;
	u32 tx_counter_ok, tx_counter_error;
	u32 rx_counter_ok, rx_counter_error;
	u32 tx_counter_ok_high16;
	u32 rx_counter_ok_high16;
	u32 tx_ok, rx_ok;

	/*
	 * Switch to access MII reg for copper
	 */
	qca8075_phy_reg_write(0, 4, 0x1f, 0x8500);
	for (phy = 0; phy < 5; phy++) {
		/*
		 * Enable phy mdio broadcast write
		 */
		qca8075_phy_mmd_write(0, phy, 7, 0x8028, 0x801f);
	}
	/*
	 * Force no link by power down
	 */
	qca8075_phy_reg_write(0, 0x1f, 0x0, 0x1840);
	/*
	 * Packet number
	 */
	qca8075_phy_mmd_write(0, 0x1f, 7, 0x8021, 0x3000);
	qca8075_phy_mmd_write(0, 0x1f, 7, 0x8062, 0x05e0);
	/*
	 * Fix mdi status
	 */
	qca8075_phy_reg_write(0, 0x1f, 0x10, 0x6800);

	for (i = 0; i < 100; i++) {
		phy_t_status = 0;
		for (phy = 0; phy < 5; phy++) {
			value = readl(0xc00066c + (phy * 0xc));
			/*
			 * Enable mac loop back
			 */
			writel((value | (1 << 21)), (0xc00066c + (phy * 0xc)));
		}
		/*
		 * Phy single test
		 */
		for (phy = 0; phy < 5; phy++) {
			/*
			 * Enable loopback
			 */
			qca8075_phy_reg_write(0, phy, 0x0, 0x9000);
			qca8075_phy_reg_write(0, phy, 0x0, 0x4140);
			/*
			 * Check link
			 */
			j = 0;
			while (j < 100) {
				status = qca8075_phy_reg_read(0, phy, 0x11);
				if (status & (1 << 10))
					break;
				mdelay(10);
				j++;
			}
			/*
			 * Enable check
			 */
			qca8075_phy_mmd_write(0, phy, 7, 0x8029, 0x0000);
			qca8075_phy_mmd_write(0, phy, 7, 0x8029, 0x0003);
			/*
			 * Start traffic
			 */
			qca8075_phy_mmd_write(0, phy, 7, 0x8020, 0xa000);
			mdelay(200);
			/*
			 * check counter
			 */
			tx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802e);
			tx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802d);
			tx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802f);
			rx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802b);
			rx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802a);
			rx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802c);
			tx_ok = tx_counter_ok + (tx_counter_ok_high16 << 16);
			rx_ok = rx_counter_ok + (rx_counter_ok_high16 << 16);
			/*
			 * Success
			 */
			if((tx_ok == 0x3000) && (tx_counter_error == 0)) {
				phy_t_status &= (~(1 << phy));
			} else {
				phy_t_status |= (1 << phy);
			}
			/*
			 * Power down
			 */
			qca8075_phy_reg_write(0, phy, 0x0, 0x1840);
		}
		/*
		 * Reset 5-phy
		 */
		qca8075_phy_reg_write(0, 0x1f, 0x0, 0x9000);
		/*
		 * Enable 5-phy loopback
		 */
		qca8075_phy_reg_write(0, 0x1f, 0x0, 0x4140);
		/*
		 * check link
		 */
		j = 0;
		while (j < 100) {
			for (phy = 0; phy < 5; phy++) {
				status = qca8075_phy_reg_read(0, phy, 0x11);
				if (!(status & (1 << 10)))
					break;
			}
			if (phy >= 5)
				break;
			mdelay(10);
			j++;
		}
		/*
		 * Enable check
		 */
		qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0000);
		qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0003);
		/*
		 * Start traffic
		 */
		qca8075_phy_mmd_write(0, 0x1f, 7, 0x8020, 0xa000);
		mdelay(200);
		for (phy = 0; phy < 5; phy++) {
			/*
			 * Check counter
			 */
			tx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802e);
			tx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802d);
			tx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802f);
			rx_counter_ok = qca8075_phy_mmd_read(0, phy, 7, 0x802b);
			rx_counter_ok_high16 = qca8075_phy_mmd_read(0, phy, 7, 0x802a);
			rx_counter_error = qca8075_phy_mmd_read(0, phy, 7, 0x802c);
			tx_ok = tx_counter_ok + (tx_counter_ok_high16 << 16);
			rx_ok = rx_counter_ok + (rx_counter_ok_high16 << 16);
			debug("rx_ok: %d, tx_ok: %d", rx_ok, tx_ok);
                        debug("rx_counter_error: %d, tx_counter_error: %d",
						rx_counter_error, tx_counter_error);
			/*
			 * Success
			 */
			if ((tx_ok == 0x3000) && (tx_counter_error == 0)) {
				phy_t_status &= (~(1 << (phy + 8)));
			} else {
				phy_t_status |= (1 << (phy + 8));
			}
		}
		if (phy_t_status) {
			qca8075_ess_reset();
		} else {
			break;
		}
	}
	/*
	 * Configuration recover
	 */
	/*
	 * Packet number
	 */
	qca8075_phy_mmd_write(0, 0x1f, 7, 0x8021, 0x0);
	/*
	 * Disable check
	 */
	qca8075_phy_mmd_write(0, 0x1f, 7, 0x8029, 0x0);
	/*
	 * Disable traffic
	 */
	qca8075_phy_mmd_write(0, 0x1f, 7, 0x8020, 0x0);
}

void clear_self_test_config(void)
{
	int phy = 0;
	u32 value = 0;

	/*
	 * Disable phy internal loopback
	 */
	qca8075_phy_reg_write(0, 0x1f, 0x10, 0x6860);
	qca8075_phy_reg_write(0, 0x1f, 0x0, 0x9040);

	for (phy = 0; phy < 5; phy++) {
		value = readl(0xc00066c + (phy * 0xc));
		/*
		 * Disable mac loop back
		 */
		writel((value&(~(1 << 21))), (0xc00066c + (phy * 0xc)));
		/*
		 * Disable phy mdio broadcast writei
		 */
		qca8075_phy_mmd_write(0, phy, 7, 0x8028, 0x001f);
	}

}


void ipq_qca8075_dump_phy_regs(u32 phy_id)
{
	u16 phy_data;
#define REG_LEN 9
	u32 regs[REG_LEN] = { 0, 1, 2, 3, 4, 5, 6, 9, 10 };
	int i;

	for (i=0; i < REG_LEN; i++) {
		phy_data = qca8075_phy_reg_read(0x0, phy_id, regs[i]);
		printf("phy[%d] reg [%d] = 0x%x\n", phy_id, regs[i], phy_data);
	}
#undef REG_LEN
}

void ipq_qca8075_phy_map_ops(struct phy_ops **ops)
{
	*ops = qca8075_ops;
}

void qca8075_phy_serdes_reset(u32 phy_id)
{
	qca8075_phy_reg_write(0,
			phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
			QCA8075_MODE_RESET_REG,
			QCA8075_MODE_CHANAGE_RESET);
	mdelay(100);
	qca8075_phy_reg_write(0,
			phy_id + QCA8075_PHY_PSGMII_ADDR_INC,
			QCA8075_MODE_RESET_REG,
			QCA8075_MODE_RESET_DEFAULT_VALUE);

}

static  u16 qca8075_phy_interface_get_mode(u32 phy_id)
{
	u16 phy_data;

	phy_data = qca8075_phy_reg_read(0,
			phy_id + QCA8075_PHY_MAX_ADDR_INC,
			QCA8075_PHY_CHIP_CONFIG);
	phy_data &= 0x000f;
	return phy_data;
}

void qca8075_phy_interface_set_mode(u32 phy_id, u32 mode)
{
	u16 phy_data;

	phy_data = qca8075_phy_interface_get_mode(phy_id);
	if (phy_data != mode) {
		phy_data = qca8075_phy_reg_read(0,
			phy_id + QCA8075_PHY_MAX_ADDR_INC,
			QCA8075_PHY_CHIP_CONFIG);
		phy_data &= 0xfff0;
		qca8075_phy_reg_write(0,
				phy_id + QCA8075_PHY_MAX_ADDR_INC,
				QCA8075_PHY_CHIP_CONFIG,
				phy_data | mode);
		qca8075_phy_serdes_reset(0);
	}
}

int ipq_qca8075_phy_init(struct phy_ops **ops)
{
	u16 phy_data;
	u32 phy_id = 0;

	qca8075_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
	if (!qca8075_ops)
		return -ENOMEM;

	qca8075_ops->phy_get_link_status = qca8075_phy_get_link_status;
	qca8075_ops->phy_get_speed = qca8075_phy_get_speed;
	qca8075_ops->phy_get_duplex = qca8075_phy_get_duplex;
	*ops = qca8075_ops;

	qca8075_id = phy_data = qca8075_phy_reg_read(0x0, 0x0, QCA8075_PHY_ID1);
	printf ("PHY ID1: 0x%x\n", phy_data);
	phy_data = qca8075_phy_reg_read(0x0, 0x0, QCA8075_PHY_ID2);
	printf ("PHY ID2: 0x%x\n", phy_data);
	qca8075_id = (qca8075_id << 16) | phy_data;

	if (qca8075_id == QCA8075_PHY_V1_0_5P) {
		phy_data = qca8075_phy_mmd_read(0, PSGMII_ID,
			QCA8075_PHY_MMD1_NUM, QCA8075_PSGMII_FIFI_CTRL);
		phy_data &= 0xbfff;
		qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
			QCA8075_PSGMII_FIFI_CTRL, phy_data);
	}

	/*
	 * Enable phy power saving function by default
	 */
	if (qca8075_id == QCA8075_PHY_V1_1_2P)
		phy_id = 3;

	if ((qca8075_id == QCA8075_PHY_V1_0_5P) ||
	    (qca8075_id == QCA8075_PHY_V1_1_5P) ||
	    (qca8075_id == QCA8075_PHY_V1_1_2P)) {
		for (; phy_id < 5; phy_id++) {
			/*enable phy power saving function by default */
			qca8075_phy_set_8023az(0x0, phy_id, 0x1);
			qca8075_phy_set_powersave(0x0, phy_id, 0x1);
			qca8075_phy_set_hibernate(0x0, phy_id, 0x1);

			/*
			 * change malibu control_dac[2:0] of MMD7 0x801A bit[9:7] 
			 * from 111 to 101
			 */
			phy_data = qca8075_phy_mmd_read(0, phy_id,
				QCA8075_PHY_MMD7_NUM, QCA8075_PHY_MMD7_DAC_CTRL);
			phy_data &= ~QCA8075_DAC_CTRL_MASK;
			phy_data |= QCA8075_DAC_CTRL_VALUE;
			qca8075_phy_mmd_write(0, phy_id, QCA8075_PHY_MMD7_NUM,
				QCA8075_PHY_MMD7_DAC_CTRL, phy_data);

			/* add 10M and 100M link LED behavior for QFN board*/
			phy_data = qca8075_phy_mmd_read(0, phy_id, QCA8075_PHY_MMD7_NUM,
				QCA8075_PHY_MMD7_LED_1000_CTRL1);
			phy_data &= ~QCA8075_LED_1000_CTRL1_100_10_MASK;
			phy_data |= QCA8075_LED_1000_CTRL1_100_10_MASK;
			qca8075_phy_mmd_write(0 , phy_id, QCA8075_PHY_MMD7_NUM,
				QCA8075_PHY_MMD7_LED_1000_CTRL1, phy_data);
		}
	}

	/*
	 * Enable AZ transmitting ability
	 */
	qca8075_phy_mmd_write(0, PSGMII_ID, QCA8075_PHY_MMD1_NUM,
				QCA8075_PSGMII_MODE_CTRL,
				QCA8075_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE);

	/* adjust psgmii serdes tx amp */
	qca8075_phy_reg_write(0, 5, QCA8075_PSGMII_TX_DRIVER_1_CTRL,
				QCA8075_PHY_PSGMII_REDUCE_SERDES_TX_AMP);

	/* to avoid psgmii module goes into hibernation, work with psgmii self test*/
	phy_data = qca8075_phy_mmd_read(0, 4, QCA8075_PHY_MMD3_NUM, 0x805a);
	phy_data &= (~(1 << 1));
	qca8075_phy_mmd_write(0, 4, QCA8075_PHY_MMD3_NUM, 0x805a, phy_data);

	return 0;
}
