/*
 * Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * Manage the atheros ethernet PHY.
 *
 * All definitions in this file are operating system independent!
 */

#include <config.h>
#include <linux/types.h>
#include <common.h>
#include <miiphy.h>
#include "phy.h"
#include <asm/addrspace.h>
#include <atheros.h>
#include "athrs17_phy.h"

/* PHY selections and access functions */
typedef enum {
	PHY_SRCPORT_INFO,
	PHY_PORTINFO_SIZE,
} PHY_CAP_TYPE;

typedef enum {
	PHY_SRCPORT_NONE,
	PHY_SRCPORT_VLANTAG,
	PHY_SRCPORT_TRAILER,
} PHY_SRCPORT_TYPE;

#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
#define DRV_MSG(x,a,b,c,d,e,f)
#define DRV_PRINT(DBG_SW,X)

#define ATHR_LAN_PORT_VLAN          1
#define ATHR_WAN_PORT_VLAN          2

#define ENET_UNIT_GE0 0
#define ENET_UNIT_GE1 1

#define TRUE    1
#define FALSE   0

#define ATHR_PHY0_ADDR   0x0
#define ATHR_PHY1_ADDR   0x1
#define ATHR_PHY2_ADDR   0x2
#define ATHR_PHY3_ADDR   0x3
#define ATHR_PHY4_ADDR   0x4
#define ATHR_IND_PHY 4

#define MODULE_NAME "ATHRS17"
#define S17_PHY_DEBUG 1
extern int xmii_val;

/*
 * Track per-PHY port information.
 */
typedef struct {
    BOOL   isEnetPort;       /* normal enet port */
    BOOL   isPhyAlive;       /* last known state of link */
    int    ethUnit;          /* MAC associated with this phy port */
    uint32_t phyBase;
    uint32_t phyAddr;          /* PHY registers associated with this phy port */
    uint32_t VLANTableSetting; /* Value to be written to VLAN table */
} athrPhyInfo_t;

#if defined(ATH_S17_MAC0_SGMII)
#if (CFG_ATH_GMAC_NMACS == 1) /* QCA9563 only have 1 GMAC working */
#define ENET_UNIT            ENET_UNIT_GE0
#define ENET_UNIT_WAN        ENET_UNIT_GE0
#else
#define ENET_UNIT            ENET_UNIT_GE1
#define ENET_UNIT_WAN        ENET_UNIT_GE0
#endif
#else
#define ENET_UNIT            ENET_UNIT_GE0
#define ENET_UNIT_WAN        ENET_UNIT_GE1
#endif

/*
 * Per-PHY information, indexed by PHY unit number.
 */
static athrPhyInfo_t athrPhyInfo[] = {
	{
		TRUE,   /* phy port 0 -- LAN port 0 */
		FALSE,
		ENET_UNIT,
		0,
		ATHR_PHY0_ADDR,
		ATHR_LAN_PORT_VLAN
	},
	{
		TRUE,   /* phy port 1 -- LAN port 1 */
		FALSE,
		ENET_UNIT,
		0,
		ATHR_PHY1_ADDR,
		ATHR_LAN_PORT_VLAN
	},
	{
		TRUE,   /* phy port 2 -- LAN port 2 */
		FALSE,
		ENET_UNIT,
		0,
		ATHR_PHY2_ADDR,
		ATHR_LAN_PORT_VLAN
	},
	{
		TRUE,   /* phy port 3 -- LAN port 3 */
		FALSE,
		ENET_UNIT,
		0,
		ATHR_PHY3_ADDR,
		ATHR_LAN_PORT_VLAN
	},
	{
		TRUE,   /* phy port 4 -- WAN port or LAN port 4 */
		FALSE,
#if defined(CONFIG_ATH_S17_WAN) || defined (ATH_S17_MAC0_SGMII)
		ENET_UNIT_WAN,
#else
		ENET_UNIT,
#endif
		0,
		ATHR_PHY4_ADDR,
		ATHR_LAN_PORT_VLAN   /* Send to all ports */
	},
	{
		FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */
		TRUE,
		ENET_UNIT,
		0,
		0x00,
		ATHR_LAN_PORT_VLAN    /* Send to all ports */
	},
};

static uint8_t athr17_init_flag = 0;

//#define ATHR_PHY_MAX (sizeof(ipPhyInfo) / sizeof(ipPhyInfo[0]))
#define ATHR_PHY_MAX 5

/* Range of valid PHY IDs is [MIN..MAX] */
#define ATHR_ID_MIN 0
#define ATHR_ID_MAX (ATHR_PHY_MAX-1)

/* Convenience macros to access myPhyInfo */
#define ATHR_IS_ENET_PORT(phyUnit) (athrPhyInfo[phyUnit].isEnetPort)
#define ATHR_IS_PHY_ALIVE(phyUnit) (athrPhyInfo[phyUnit].isPhyAlive)
#define ATHR_ETHUNIT(phyUnit) (athrPhyInfo[phyUnit].ethUnit)
#define ATHR_PHYBASE(phyUnit) (athrPhyInfo[phyUnit].phyBase)
#define ATHR_PHYADDR(phyUnit) (athrPhyInfo[phyUnit].phyAddr)
#define ATHR_VLAN_TABLE_SETTING(phyUnit) (athrPhyInfo[phyUnit].VLANTableSetting)


#define ATHR_IS_ETHUNIT(phyUnit, ethUnit)	\
	(ATHR_IS_ENET_PORT(phyUnit) &&		\
	 ATHR_ETHUNIT(phyUnit) == (ethUnit))

#define ATHR_IS_WAN_PORT(phyUnit) (!(ATHR_ETHUNIT(phyUnit)==ENET_UNIT_GE0))

/* Forward references */
BOOL athrs17_phy_is_link_alive(int phyUnit);
uint32_t athrs17_reg_read(uint32_t reg_addr);
void athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val);
static void phy_mode_setup(void);

#define sysMsDelay(_x) udelay((_x) * 1000)

static void phy_mode_setup(void)
{
#ifdef ATHRS17_VER_1_0
	/*work around for phy4 rgmii mode*/
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 29, 18);
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 30, 0x480c);

	/*rx delay*/
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 29, 0);
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 30, 0x824e);

	/*tx delay*/
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 29, 5);
	phy_reg_write(ATHR_PHYBASE(ATHR_IND_PHY), ATHR_PHYADDR(ATHR_IND_PHY), 30, 0x3d47);
#endif
}
/*
 * V-lan configuration given by Switch team
 * Vlan 1:PHY0,1,2,3 and Mac 0 of s17
 * Vlam 2:PHY4 and Mac 6 of s17
 */

void athrs17_vlan_config()
{
	athrs17_reg_write(S17_P0LOOKUP_CTRL_REG, 0x0014001e);
	athrs17_reg_write(S17_P0VLAN_CTRL0_REG, 0x10001);

	athrs17_reg_write(S17_P1LOOKUP_CTRL_REG, 0x0014001d);
	athrs17_reg_write(S17_P1VLAN_CTRL0_REG, 0x10001);

	athrs17_reg_write(S17_P2LOOKUP_CTRL_REG, 0x0014001b);
	athrs17_reg_write(S17_P2VLAN_CTRL0_REG, 0x10001);

	athrs17_reg_write(S17_P3LOOKUP_CTRL_REG, 0x00140017);
	athrs17_reg_write(S17_P3VLAN_CTRL0_REG, 0x10001);

	athrs17_reg_write(S17_P4LOOKUP_CTRL_REG, 0x0014000f);
	athrs17_reg_write(S17_P4VLAN_CTRL0_REG, 0x10001);

	athrs17_reg_write(S17_P5LOOKUP_CTRL_REG, 0x00140040);
	athrs17_reg_write(S17_P5VLAN_CTRL0_REG, 0x20001);

	athrs17_reg_write(S17_P6LOOKUP_CTRL_REG, 0x00140020);
	athrs17_reg_write(S17_P6VLAN_CTRL0_REG, 0x20001);


}

void athrs17_reg_init_wan(void)
{

#ifdef ATH_S17_MAC0_SGMII
	athrs17_reg_write(S17_P6PAD_MODE_REG,0x07600000);

#else
	athrs17_reg_write(S17_P6PAD_MODE_REG,
           athrs17_reg_read(S17_P6PAD_MODE_REG)|S17_MAC6_SGMII_EN);
#endif
	athrs17_reg_write(S17_P6STATUS_REG, S17_PORT_STATUS_AZ_DEFAULT);
	athrs17_reg_write(S17_SGMII_CTRL_REG , 0xc74164d0); /* SGMII control */
         
        athrs17_vlan_config();
	printf("%s done\n",__func__);

}

void athrs17_reg_init()
{
	int phy_addr = 0;
	uint32_t sgmii_ctrl_value;
	/* if using header for register configuration, we have to     */
	/* configure s17 register after frame transmission is enabled */

	if ((athrs17_reg_read(S17_MASK_CTRL_REG) & 0xFFFF) == S17C_DEVICEID){
		sgmii_ctrl_value = 0xc74164de;
	}else{
		sgmii_ctrl_value = 0xc74164d0;
	}
	if (athr17_init_flag){
		return;
	}

#if (CFG_ATH_GMAC_NMACS == 1)	
		athrs17_reg_write(S17_P0PAD_MODE_REG, S17_MAC0_SGMII_EN);
		athrs17_reg_write(S17_SGMII_CTRL_REG , sgmii_ctrl_value); /* SGMII control  */
		athrs17_reg_write(S17_GLOFW_CTRL1_REG,	0x7f7f7f7f);
#else
	if (is_drqfn()) {
		athrs17_reg_write(S17_P0PAD_MODE_REG, S17_MAC0_SGMII_EN);
		athrs17_reg_write(S17_SGMII_CTRL_REG , sgmii_ctrl_value); /* SGMII control  */
    } else {
		athrs17_reg_write(S17_GLOFW_CTRL1_REG,	0x7f7f7f7f);
		/* 
                 * If defined S17 Mac0 sgmii val of 0x4(S17_P0PAD_MODE_REG)
                 * should be configured as 0x80
                 */
#ifdef ATH_S17_MAC0_SGMII
		athrs17_reg_write(S17_P0PAD_MODE_REG,	0x80080);
#else
		athrs17_reg_write(S17_P0PAD_MODE_REG,	0x07680000);
#endif
		athrs17_reg_write(S17_P6PAD_MODE_REG,	0x01000000);		
	}
#endif	/* CFG_ATH_GMAC_NMACS == 1 */
	
/*
 * Values suggested by the swich team when s17 in sgmii configuration
 * operates in forced mode.
 * 0x10(S17_PWS_REG)=0x602613a0
 */
#ifdef ATH_SGMII_FORCED_MODE
	athrs17_reg_write(S17_PWS_REG, 0x602613a0);
#else
	athrs17_reg_write(S17_PWS_REG,	0x40000000);
#endif
	athrs17_reg_write(S17_P0STATUS_REG,	 0x0000007e);

	/* AR8327/AR8328 v1.0 fixup */
	if ((athrs17_reg_read(0x0) & 0xffff) == 0x1201) {
		for (phy_addr = 0x0; phy_addr <= ATHR_PHY_MAX; phy_addr++) {
			/* For 100M waveform */
			phy_reg_write(0, phy_addr, 0x1d, 0x0);
			phy_reg_write(0, phy_addr, 0x1e, 0x02ea);
			/* Turn On Gigabit Clock */
			phy_reg_write(0, phy_addr, 0x1d, 0x3d);
			phy_reg_write(0, phy_addr, 0x1e, 0x68a0);
		}
	}
#if CONFIG_S17_SWMAC6_CONNECTED
        printf ("Configuring Mac6 of s17 to slave scorpion\n");
	athrs17_reg_write(S17_P6PAD_MODE_REG, S17_MAC6_RGMII_EN | S17_MAC6_RGMII_TXCLK_DELAY | \
                              S17_MAC6_RGMII_RXCLK_DELAY | (1 << S17_MAC6_RGMII_TXCLK_SHIFT) | \
                              (2 << S17_MAC6_RGMII_RXCLK_SHIFT));
	athrs17_reg_write(S17_P6STATUS_REG, 0x7e);	
        athrs17_vlan_config();
#endif
	athr17_init_flag = 1;
	printf("%s: complete\n",__func__);
}

/******************************************************************************
*
* athrs17_phy_is_link_alive - test to see if the specified link is alive
*
* RETURNS:
*    TRUE  --> link is alive
*    FALSE --> link is down
*/
BOOL
athrs17_phy_is_link_alive(int phyUnit)
{
	uint16_t phyHwStatus;
	uint32_t phyBase;
	uint32_t phyAddr;

	phyBase = ATHR_PHYBASE(phyUnit);
	phyAddr = ATHR_PHYADDR(phyUnit);

	phyHwStatus = phy_reg_read(phyBase, phyAddr, ATHR_PHY_SPEC_STATUS);

	if (phyHwStatus & ATHR_STATUS_LINK_PASS)
		return TRUE;

	return FALSE;
}

/******************************************************************************
*
* athrs17_phy_setup - reset and setup the PHY associated with
* the specified MAC unit number.
*
* Resets the associated PHY port.
*
* RETURNS:
*    TRUE  --> associated PHY is alive
*    FALSE --> no LINKs on this ethernet unit
*/

BOOL
athrs17_phy_setup(int ethUnit)
{
	int       phyUnit;
	uint16_t  phyHwStatus;
	uint16_t  timeout;
	int       liveLinks = 0;
	uint32_t  phyBase = 0;
	BOOL      foundPhy = FALSE;
	uint32_t  phyAddr = 0;

	/* See if there's any configuration data for this enet */
	/* start auto negogiation on each phy */
	if (is_drqfn()) 
		ethUnit=0;
	for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}

		foundPhy = TRUE;
		phyBase = ATHR_PHYBASE(phyUnit);
		phyAddr = ATHR_PHYADDR(phyUnit);

		phy_reg_write(phyBase, phyAddr, ATHR_AUTONEG_ADVERT,
				ATHR_ADVERTISE_ALL);

		phy_reg_write(phyBase, phyAddr, ATHR_1000BASET_CONTROL,
				ATHR_ADVERTISE_1000FULL);

		/* Reset PHYs*/
		phy_reg_write(phyBase, phyAddr, ATHR_PHY_CONTROL,
				ATHR_CTRL_AUTONEGOTIATION_ENABLE
				| ATHR_CTRL_SOFTWARE_RESET);

	}

	if (!foundPhy) {
		return FALSE; /* No PHY's configured for this ethUnit */
	}

	/*
	 * After the phy is reset, it takes a little while before
	 * it can respond properly.
	 */
	sysMsDelay(1000);


	/*
	 * Wait up to 3 seconds for ALL associated PHYs to finish
	 * autonegotiation.  The only way we get out of here sooner is
	 * if ALL PHYs are connected AND finish autonegotiation.
	 */
	for (phyUnit=0; (phyUnit < ATHR_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}

		timeout=20;
		for (;;) {
			phyHwStatus = phy_reg_read(phyBase, phyAddr, ATHR_PHY_CONTROL);

			if (ATHR_RESET_DONE(phyHwStatus)) {
				DRV_PRINT(DRV_DEBUG_PHYSETUP,
						("Port %d, Neg Success\n", phyUnit));
				break;
			}
			if (timeout == 0) {
				DRV_PRINT(DRV_DEBUG_PHYSETUP,
						("Port %d, Negogiation timeout\n", phyUnit));
				break;
			}
			if (--timeout == 0) {
				DRV_PRINT(DRV_DEBUG_PHYSETUP,
						("Port %d, Negogiation timeout\n", phyUnit));
				break;
			}

			sysMsDelay(150);
		}
	}

	/*
	 * All PHYs have had adequate time to autonegotiate.
	 * Now initialize software status.
	 *
	 * It's possible that some ports may take a bit longer
	 * to autonegotiate; but we can't wait forever.  They'll
	 * get noticed by mv_phyCheckStatusChange during regular
	 * polling activities.
	 */
	for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}
#if 0
		/* Enable RGMII */
		phy_reg_write(0,phyUnit,0x1d,0x12);
		phy_reg_write(0,phyUnit,0x1e,0x8);
		/* Tx delay on PHY */
		phy_reg_write(0,phyUnit,0x1d,0x5);
		phy_reg_write(0,phyUnit,0x1e,0x100);

		/* Rx delay on PHY */
		phy_reg_write(0,phyUnit,0x1d,0x0);
		phy_reg_write(0,phyUnit,0x1e,0x8000);
#endif
		if (athrs17_phy_is_link_alive(phyUnit)) {
			liveLinks++;
			ATHR_IS_PHY_ALIVE(phyUnit) = TRUE;
		} else {
			ATHR_IS_PHY_ALIVE(phyUnit) = FALSE;
		}

		DRV_PRINT(DRV_DEBUG_PHYSETUP,
				("eth%d: Phy Specific Status=%4.4x\n",
				 ethUnit,
				 phy_reg_read(ATHR_PHYBASE(phyUnit),
					 ATHR_PHYADDR(phyUnit),
					 ATHR_PHY_SPEC_STATUS)));
	}
	phy_mode_setup();
	return (liveLinks > 0);
}

/******************************************************************************
*
* athrs17_phy_is_fdx - Determines whether the phy ports associated with the
* specified device are FULL or HALF duplex.
*
* RETURNS:
*    1 --> FULL
*    0 --> HALF
*/
int
athrs17_phy_is_fdx(int ethUnit)
{
	int       phyUnit;
	uint32_t  phyBase;
	uint32_t  phyAddr;
	uint16_t  phyHwStatus;
	int       ii = 200;


	if (is_drqfn())
		ethUnit = 0;


	for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}

		if (athrs17_phy_is_link_alive(phyUnit)) {

			phyBase = ATHR_PHYBASE(phyUnit);
			phyAddr = ATHR_PHYADDR(phyUnit);

			do {
				phyHwStatus = phy_reg_read (phyBase, phyAddr,
						ATHR_PHY_SPEC_STATUS);
				if(phyHwStatus & ATHR_STATUS_RESOVLED)
					break;
				sysMsDelay(10);
			} while(--ii);

			if (phyHwStatus & ATHER_STATUS_FULL_DEPLEX)
				return TRUE;
		}
	}

	if (ethUnit == ENET_UNIT_GE0 || ethUnit == ENET_UNIT_GE1)
		return TRUE;

	return FALSE;
}

/******************************************************************************
*
* athrs17_phy_speed - Determines the speed of phy ports associated with the
* specified device.
*
* RETURNS: _10BASET, _100BASETX, _1000BASET
*/

int
athrs17_phy_speed(int ethUnit)
{
	int       phyUnit;
	uint16_t  phyHwStatus;
	uint32_t  phyBase;
	uint32_t  phyAddr;
	int       ii = 200;

	if ((ethUnit == ENET_UNIT_GE0) || (ethUnit == ENET_UNIT_GE1))
		return _1000BASET;

	for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}

		if (athrs17_phy_is_link_alive(phyUnit)) {

			phyBase = ATHR_PHYBASE(phyUnit);
			phyAddr = ATHR_PHYADDR(phyUnit);

			do {
				phyHwStatus = phy_reg_read(phyBase, phyAddr,
						ATHR_PHY_SPEC_STATUS);
				if(phyHwStatus & ATHR_STATUS_RESOVLED)
					break;
				sysMsDelay(10);
			} while((!(phyHwStatus & ATHR_STATUS_RESOVLED)) && --ii);

			phyHwStatus = ((phyHwStatus & ATHER_STATUS_LINK_MASK) >>
					ATHER_STATUS_LINK_SHIFT);

			switch(phyHwStatus) {
			case 0: return _10BASET;
			case 1: return _100BASET;
			case 2: return _1000BASET;
			default: printf("Unkown speed read!\n");
			}
		}

	}

	return _10BASET;
}

/*****************************************************************************
*
* athr_phy_is_up -- checks for significant changes in PHY state.
*
* A "significant change" is:
*     dropped link (e.g. ethernet cable unplugged) OR
*     autonegotiation completed + link (e.g. ethernet cable plugged in)
*
* When a PHY is plugged in, phyLinkGained is called.
* When a PHY is unplugged, phyLinkLost is called.
*/

int
athrs17_phy_is_up(int ethUnit)
{
	int           phyUnit;
	uint16_t      phyHwStatus, phyHwControl;
	athrPhyInfo_t *lastStatus;
	int           linkCount   = 0;
	int           lostLinks   = 0;
	int           gainedLinks = 0;
	uint32_t      phyBase;
	uint32_t      phyAddr;

	if (is_drqfn()) 
		ethUnit = 0;
	for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
		if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
			continue;
		}

		phyBase = ATHR_PHYBASE(phyUnit);
		phyAddr = ATHR_PHYADDR(phyUnit);

		lastStatus = &athrPhyInfo[phyUnit];

		if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */
			phyHwStatus = phy_reg_read(phyBase, phyAddr, ATHR_PHY_SPEC_STATUS);

			/* See if we've lost link */
			if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
				linkCount++;
			} else {
				lostLinks++;
				DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n",
							ethUnit, phyUnit));
				lastStatus->isPhyAlive = FALSE;
			}
		} else { /* last known link status was DEAD */
			/* Check for reset complete */
			phyHwStatus = phy_reg_read(phyBase, phyAddr, ATHR_PHY_STATUS);
			if (!ATHR_RESET_DONE(phyHwStatus)) {
				continue;
			}

			phyHwControl = phy_reg_read(phyBase, phyAddr, ATHR_PHY_CONTROL);
			/* Check for AutoNegotiation complete */
			if ((!(phyHwControl & ATHR_CTRL_AUTONEGOTIATION_ENABLE))
					|| ATHR_AUTONEG_DONE(phyHwStatus)) {
				phyHwStatus = phy_reg_read(phyBase, phyAddr,
						ATHR_PHY_SPEC_STATUS);

				if (phyHwStatus & ATHR_STATUS_LINK_PASS) {
					gainedLinks++;
					linkCount++;
					DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n",
								ethUnit, phyUnit));
					lastStatus->isPhyAlive = TRUE;
				}
			}
		}
	}

	return (linkCount);

}

uint32_t
athrs17_reg_read(uint32_t reg_addr)
{
	uint32_t reg_word_addr;
	uint32_t phy_addr, tmp_val, reg_val;
	uint16_t phy_val;
	uint8_t phy_reg;

	/* change reg_addr to 16-bit word address, 32-bit aligned */
	reg_word_addr = (reg_addr & 0xfffffffc) >> 1;

	/* configure register high address */
	phy_addr = 0x18;
	phy_reg = 0x0;
	phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff);  /* bit16-8 of reg address */
	phy_reg_write(0, phy_addr, phy_reg, phy_val);

	/* For some registers such as MIBs, since it is read/clear, we should */
	/* read the lower 16-bit register then the higher one */

	/* read register in lower address */
	phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
	phy_reg = (uint8_t) (reg_word_addr & 0x1f);   /* bit4-0 of reg address */
	reg_val = (uint32_t) phy_reg_read(0, phy_addr, phy_reg);

	/* read register in higher address */
	reg_word_addr++;
	phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
	phy_reg = (uint8_t) (reg_word_addr & 0x1f);   /* bit4-0 of reg address */
	tmp_val = (uint32_t) phy_reg_read(0, phy_addr, phy_reg);
	reg_val |= (tmp_val << 16);

	return reg_val;
}

void
athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val)
{
	uint32_t reg_word_addr;
	uint32_t phy_addr;
	uint16_t phy_val;
	uint8_t phy_reg;

	/* change reg_addr to 16-bit word address, 32-bit aligned */
	reg_word_addr = (reg_addr & 0xfffffffc) >> 1;

	/* configure register high address */
	phy_addr = 0x18;
	phy_reg = 0x0;
	phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff);  /* bit16-8 of reg address */
	phy_reg_write(0, phy_addr, phy_reg, phy_val);

	/* For some registers such as ARL and VLAN, since they include BUSY bit */
	/* in lower address, we should write the higher 16-bit register then the */
	/* lower one */

	/* read register in higher address */
	reg_word_addr++;
	phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
	phy_reg = (uint8_t) (reg_word_addr & 0x1f);   /* bit4-0 of reg address */
	phy_val = (uint16_t) ((reg_val >> 16) & 0xffff);
	phy_reg_write(0, phy_addr, phy_reg, phy_val);

	/* write register in lower address */
	reg_word_addr--;
	phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
	phy_reg = (uint8_t) (reg_word_addr & 0x1f);   /* bit4-0 of reg address */
	phy_val = (uint16_t) (reg_val & 0xffff);
	phy_reg_write(0, phy_addr, phy_reg, phy_val);
}

unsigned int s17_rd_phy(unsigned int phy_addr, unsigned int reg_addr)
{
    return ((uint32_t) phy_reg_read(0, phy_addr, reg_addr));
}

void s17_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data)
{
    phy_reg_write(0, phy_addr, reg_addr, write_data);
}
