/*
 * Copyright (c) 2016 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.
 *
 */

/*
 * 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 <asm/addrspace.h>
#include <atheros.h>
#include "athr_s27_phy.h"
#include "ath_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 _UNKNOWN_SPEED 0
#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_LAN 1
#define ENET_UNIT_WAN 0

#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 MODULE_NAME "ATHRS27"
/*
 * 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;

/*
 * Per-PHY information, indexed by PHY unit number.
 */
static athrPhyInfo_t athrPhyInfo[] = {

    {TRUE,   /* port 1 -- LAN port 1 */
     FALSE,
     ENET_UNIT_LAN,
     0,
     ATHR_PHY0_ADDR,
     ATHR_LAN_PORT_VLAN
    },

    {TRUE,   /* port 2 -- LAN port 2 */
     FALSE,
     ENET_UNIT_LAN,
     0,
     ATHR_PHY1_ADDR,
     ATHR_LAN_PORT_VLAN
    },

    {TRUE,   /* port 3 -- LAN port 3 */
     FALSE,
     ENET_UNIT_LAN,
     0,
     ATHR_PHY2_ADDR,
     ATHR_LAN_PORT_VLAN
    },


   {TRUE,   /* port 4 --  LAN port 4 */
     FALSE,
     ENET_UNIT_LAN,
     0,
     ATHR_PHY3_ADDR,
     ATHR_LAN_PORT_VLAN   /* Send to all ports */
    },

    {TRUE,  /* port 5 -- WAN Port 5 */
     FALSE,
     ENET_UNIT_WAN,
     0,
     ATHR_PHY4_ADDR,
     ATHR_LAN_PORT_VLAN    /* Send to all ports */
    },

    {FALSE,   /* port 0 -- cpu port 0 */
     TRUE,
     ENET_UNIT_LAN,
     0,
     0x00,
     ATHR_LAN_PORT_VLAN
    },

};


#define ATHR_GLOBALREGBASE    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_LAN))

/* Forward references */
BOOL athrs27_phy_is_link_alive(int phyUnit);
uint32_t athrs27_reg_read(uint32_t reg_addr);
void athrs27_reg_write(uint32_t reg_addr, uint32_t reg_val);
unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr);
void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data);


void athrs27_powersave_off(int phy_addr)
{
    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0x29);
    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x36c0);

}
void athrs27_sleep_off(int phy_addr)
{
    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_ADDRESS,0xb);
    s27_wr_phy(phy_addr,ATHR_DEBUG_PORT_DATA,0x3c00);
}

void athrs27_force_100M(int phyAddr,int duplex)
{
   /*
    *  Force MDI and MDX to alternate ports
    *  Phy 0,2 and 4 -- MDI
    *  Phy 1 and 3 -- MDX
    */

    if(phyAddr%2) {
        s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
    }
    else {
        s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
    }

    s27_wr_phy(phyAddr,0x1d,0x29);
    s27_wr_phy(phyAddr,0x1e,0x0);
    s27_wr_phy(phyAddr,0x10,0xc60);
    s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0xa000|(duplex << 8)));
}

void athrs27_force_10M(int phyAddr,int duplex)
{

    athrs27_powersave_off(phyAddr);
    athrs27_sleep_off(phyAddr);

    s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,(0x8000 |(duplex << 8)));
}

int athrs27_reg_init(void)
{
#if S27_PHY_DEBUG
    uint32_t rd_val;
#endif

    /* if using header for register configuration, we have to     */
    /* configure s27 register after frame transmission is enabled */
    athrs27_reg_rmw(0x8,(1<<28));  /* Set WAN port is connected to GE0 */

#if defined(S27_FORCE_100M)
    athrs27_force_100M(ATHR_PHY4_ADDR,1);
#elif  defined(S27_FORCE_10M)
    athrs27_force_10M(ATHR_PHY4_ADDR,1);
#else
    s27_wr_phy(ATHR_PHY4_ADDR,ATHR_PHY_CONTROL,0x9000);

#endif
#ifdef S27_PHY_DEBUG
    printf(MODULE_NAME":OPERATIONAL_MODE_REG0:%x\n",athrs27_reg_read(OPERATIONAL_MODE_REG0));
    printf(MODULE_NAME":REG 0x4-->:%x\n",athrs27_reg_read(0x4));
    printf(MODULE_NAME":REG 0x2c-->:%x\n",athrs27_reg_read(0x2c));
    printf(MODULE_NAME":REG 0x8-->:%x\n",athrs27_reg_read(0x8));
#endif

    return 0;
}

int athrs27_reg_init_lan(void)
{
    int i = 60;
#if S26_PHY_DEBUG
    uint32_t rd_val;
#endif
    int       phyUnit;
    uint32_t  phyBase = 0;
    BOOL      foundPhy = FALSE;
    uint32_t  phyAddr = 0;


    /* reset switch */
    printf(MODULE_NAME ": resetting s27\n");
    athrs27_reg_write(0x0, athrs27_reg_read(0x0)|0x80000000);

    while(i--) {
        sysMsDelay(100);
        if(!(athrs27_reg_read(0x0)&0x80000000))
            break;
    }
    printf(MODULE_NAME ": s27 reset done\n");
    athrs27_reg_write(PORT_STATUS_REGISTER0,0x4e);

    athrs27_reg_rmw(OPERATIONAL_MODE_REG0,(1<<6));  /* Set GMII mode */

    if (is_emu() || is_wasp()) {
       athrs27_reg_rmw(0x2c,((1<<26)| (1<<16) | 0x1)); /* FiX ME: EBU debug */
    }

    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {

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

#if defined(S27_FORCE_100M)
        athrs27_force_100M(phyAddr,1);
#elif defined(S27_FORCE_10M)
        athrs27_force_10M(phyAddr,1);
#else
        s27_wr_phy(phyAddr,ATHR_PHY_CONTROL,0x9000);
#endif

#if S27_PHY_DEBUG
        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_FUNC_CONTROL);
        printf("S27 ATHR_PHY_FUNC_CONTROL (%d):%x\n",phyAddr,rd_val);
        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_ID1);
        printf("S27 PHY ID  (%d) :%x\n",phyAddr, rd_val);
        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_SPEC_STATUS);
        printf("S27 PHY CTRL  (%d) :%x\n",phyAddr, rd_val);
        rd_val = s27_rd_phy(phyAddr,ATHR_PHY_STATUS);
        printf("S27 ATHR PHY STATUS  (%d) :%x\n",phyAddr, rd_val);
#endif
    }

    /*
     * status[1:0]=2'h2;   - (0x10 - 1000 Mbps , 0x01 - 100Mbps, 0x0 - 10 Mbps)
     * status[2]=1'h1;     - Tx Mac En
     * status[3]=1'h1;     - Rx Mac En
     * status[4]=1'h1;     - Tx Flow Ctrl En
     * status[5]=1'h1;     - Rx Flow Ctrl En
     * status[6]=1'h1;     - Duplex Mode
     */
    athrs27_reg_write(PORT_STATUS_REGISTER1, 0x200);  /* LAN - 1 */
    athrs27_reg_write(PORT_STATUS_REGISTER2, 0x200);  /* LAN - 2 */
    athrs27_reg_write(PORT_STATUS_REGISTER3, 0x200);  /* LAN - 3 */
    athrs27_reg_write(PORT_STATUS_REGISTER4, 0x200);  /* LAN - 4 */

    if (is_emu()) {
        athrs27_reg_write(PORT_STATUS_REGISTER1, 0x4C);  /* LAN - 1 */
        athrs27_reg_write(PORT_STATUS_REGISTER2, 0x4c);  /* LAN - 2 */
        athrs27_reg_write(PORT_STATUS_REGISTER3, 0x4c);  /* LAN - 3 */
        athrs27_reg_write(PORT_STATUS_REGISTER4, 0x4c);  /* LAN - 4 */
    }

    /* QM Control */
    athrs27_reg_write(0x38, 0xc000050e);

    /*
     * status[11]=1'h0;    - CPU Disable
     * status[7] = 1'b1;   - Learn One Lock
     * status[14] = 1'b0;  - Learn Enable
     */
#ifdef ATHEROS_HEADER_EN
    athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4804);
#else
   /* Atheros Header Disable */
    athrs27_reg_write(PORT_CONTROL_REGISTER0, 0x4004);
#endif

    /* Tag Priority Mapping */
    athrs27_reg_write(0x70, 0xfa50);

    /* Enable ARP packets to CPU port */
    athrs27_reg_write(S27_ARL_TBL_CTRL_REG,(athrs27_reg_read(S27_ARL_TBL_CTRL_REG) | 0x100000));

   /* Enable Broadcast packets to CPU port */
    athrs27_reg_write(S27_FLD_MASK_REG,(athrs27_reg_read(S27_FLD_MASK_REG) |
                           S27_ENABLE_CPU_BROADCAST | S27_ENABLE_CPU_BCAST_FWD ));

    return 0;
}

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

    phyBase = ATHR_PHYBASE(phyUnit);
    phyAddr = ATHR_PHYADDR(phyUnit);
    phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_SPEC_STATUS);

    if (phyHwStatus & ATHR_STATUS_LINK_PASS)
        return TRUE;

    return FALSE;
}

/******************************************************************************
*
* athrs27_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
athrs27_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;
//#if S27_PHY_DEBUG
    uint32_t  rd_val = 0;
//#endif
    uint32_t  ar7240_revid;


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

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

        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }
        if (!is_emu()) {
           s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);

           s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
                         | ATHR_CTRL_SOFTWARE_RESET);
        }
        else  {
		printf("############ is emulation ############\n");

           if(ATHR_ETHUNIT(phyUnit) == ENET_UNIT_WAN) {
               s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,ATHR_ADVERTISE_ALL);
               s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
                         | ATHR_CTRL_SOFTWARE_RESET);
           }
           else {

               s27_wr_phy(phyAddr, ATHR_AUTONEG_ADVERT,(ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE |
                            ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL));
               s27_wr_phy(phyAddr,0x9, 0x0); //donot advertise 1000Mbps mode
               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,0x0);
               s27_wr_phy(phyAddr, ATHR_PHY_CONTROL,ATHR_CTRL_AUTONEGOTIATION_ENABLE
                         | ATHR_CTRL_SOFTWARE_RESET);
           }
       }
       rd_val = s27_rd_phy(phyAddr,ATHR_PHY_CONTROL);
       printf("%s ATHR_PHY_CONTROL %d :%x\n",__func__,phyAddr,rd_val);
       rd_val = s27_rd_phy(phyAddr,ATHR_PHY_SPEC_STATUS);
       printf("%s ATHR_PHY_SPEC_STAUS %d :%x\n",__func__,phyAddr,rd_val);
    }
    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.
     */
    if (ethUnit == ENET_UNIT_LAN)
        sysMsDelay(1000);
    else
        sysMsDelay(3000);

    /*
     * 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_ETHUNIT(phyUnit) == ENET_UNIT_WAN)
            continue;

        timeout=20;
        for (;;) {
            phyHwStatus =  s27_rd_phy(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);
        }
        /* extend the cable length */
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x14);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xf52);

       /* Force Class A setting phys */
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 4);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xebbb);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 5);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0x2c47);

        /* fine-tune PHYs */
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x3c);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0x1c1);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_ADDRESS, 0x37);
        s27_wr_phy(phyUnit, ATHR_DEBUG_PORT_DATA, 0xd600);


#ifdef S27_VER_1_0
        /* turn off power saving */
        s27_wr_phy(phyUnit, 29, 41);
        s27_wr_phy(phyUnit, 30, 0);
        printf("def_ S27_VER_1_0\n");
#endif
    }

    /*
     * 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 (athrs27_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,
            s27_rd_phy(ATHR_PHYADDR(phyUnit),ATHR_PHY_SPEC_STATUS)));
    }

    return (liveLinks > 0);
}

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

    if (ethUnit == ENET_UNIT_LAN)
        return TRUE;

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

        if (athrs27_phy_is_link_alive(phyUnit)) {

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

            do {
                phyHwStatus = s27_rd_phy (phyAddr, ATHR_PHY_SPEC_STATUS);
                        if(phyHwStatus & ATHR_STATUS_RESOVLED)
                                break;
                sysMsDelay(10);
            } while(--ii);
            if (phyHwStatus & ATHER_STATUS_FULL_DUPLEX) {
                return TRUE;
            }
        }
    }

    return FALSE;
}
/******************************************************************************
*
* athrs27_phy_speed - Determines the speed of phy ports associated with the
* specified device.
*
* RETURNS:
*               ATHR_PHY_SPEED_10T, AG7240_PHY_SPEED_100T;
*               ATHR_PHY_SPEED_1000T;
*/

int
athrs27_phy_speed(int ethUnit,int phyUnit)
{
    uint16_t  phyHwStatus;
    uint32_t  phyBase;
    uint32_t  phyAddr;
    int       ii = 200;
    int       phySpeed = _UNKNOWN_SPEED;
    for (phyUnit=0; phyUnit < ATHR_PHY_MAX; phyUnit++) {
        if (!ATHR_IS_ETHUNIT(phyUnit, ethUnit)) {
            continue;
        }


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

        if (athrs27_phy_is_link_alive(phyUnit)) {

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

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

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

        phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_ADDRESS, 0x18);

        if(phySpeed == _100BASET) {
            phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0xba8);
        } else {
            phy_reg_write(1,phyAddr, ATHR_DEBUG_PORT_DATA, 0x2ea);
        }
    }

    if (ethUnit == ENET_UNIT_LAN)
         phySpeed = _1000BASET;

    return phySpeed;
}

/*****************************************************************************
*
* 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
athrs27_phy_is_up(int ethUnit)
{

    uint16_t      phyHwStatus, phyHwControl;
    athrPhyInfo_t *lastStatus;
    int           linkCount   = 0;
    int           lostLinks   = 0;
    int           gainedLinks = 0;
    uint32_t      phyBase;
    uint32_t      phyAddr;
    int           phyUnit;

    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 = s27_rd_phy(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));
                printf("enet%d port%d down\n",ethUnit, phyUnit);
                lastStatus->isPhyAlive = FALSE;
            }
        } else { /* last known link status was DEAD */
            /* Check for reset complete */
            if(is_emu())
            {
                phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);
                if(phyAddr%2) {
                    s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x820);
                }
                else {
                    s27_wr_phy(phyAddr,ATHR_PHY_FUNC_CONTROL,0x800);
                }

                if((phyHwStatus & 0x4)==0)
                {
                   s27_wr_phy(phyAddr,0x9,0x0);
                   if(phyAddr !=0x4)
                       s27_wr_phy(phyAddr,0x4,0x41);
                   s27_wr_phy(phyAddr,0x0,0x9000);
                }
            }

            phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
            if (!ATHR_RESET_DONE(phyHwStatus))
                continue;

             phyHwControl = s27_rd_phy(phyAddr, ATHR_PHY_CONTROL);
             phyHwStatus = s27_rd_phy(phyAddr, ATHR_PHY_STATUS);

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

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

unsigned int athrs27_reg_read(unsigned int s27_addr)
{
    unsigned int addr_temp;
    unsigned int s27_rd_csr_low, s27_rd_csr_high, s27_rd_csr;
    unsigned int data,unit = 0;
    unsigned int phy_address, reg_address;

    addr_temp = s27_addr >>2;
    data = addr_temp >> 7;

    phy_address = 0x1f;
    reg_address = 0x10;

    if (is_ar7240()) {
        unit = 0;
    }
    else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
        unit = 1;
    }

    phy_reg_write(unit,phy_address, reg_address, data);

    phy_address = (0x17 & ((addr_temp >> 4) | 0x10));
    reg_address = ((addr_temp << 1) & 0x1e);
    s27_rd_csr_low = (uint32_t) phy_reg_read(unit,phy_address, reg_address);

    reg_address = reg_address | 0x1;
    s27_rd_csr_high = (uint32_t) phy_reg_read(unit,phy_address, reg_address);
    s27_rd_csr = (s27_rd_csr_high << 16) | s27_rd_csr_low ;

    return(s27_rd_csr);
}

void athrs27_reg_write(unsigned int s27_addr, unsigned int s27_write_data)
{
    unsigned int addr_temp;
    unsigned int data;
    unsigned int phy_address, reg_address,unit = 0;

    addr_temp = (s27_addr ) >>2;
    data = addr_temp >> 7;

    phy_address = 0x1f;
    reg_address = 0x10;

    if (is_ar7240()) {
        unit = 0;
    }
    else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
        unit = 1;
    }
    phy_reg_write(unit,phy_address, reg_address, data);

    phy_address = (0x17 & ((addr_temp >> 4) | 0x10));

    reg_address = (((addr_temp << 1) & 0x1e) | 0x1);
    data = (s27_write_data >> 16) & 0xffff;
    phy_reg_write(unit,phy_address, reg_address, data);

    reg_address = ((addr_temp << 1) & 0x1e);
    data = s27_write_data  & 0xffff;
    phy_reg_write(unit,phy_address, reg_address, data);

}

void athrs27_reg_rmw(unsigned int s27_addr, unsigned int s27_write_data)
{
    int val = athrs27_reg_read(s27_addr);
    athrs27_reg_write(s27_addr,(val | s27_write_data));
}

unsigned int s27_rd_phy(unsigned int phy_addr, unsigned int reg_addr)
{
  int unit, val = 0;

  if (is_ar7240()) {
    unit = 0;
  } else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
    unit = 1;
  }
  val = (uint32_t) phy_reg_read(unit, phy_addr, reg_addr);
  return val;
}

void s27_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data)
{
  int unit;

  if (is_ar7240()) {
    unit = 0;
  } else if(is_ar7241() || is_ar7242() || is_wasp() || is_qca953x() || is_qca956x()) {
    unit = 1;
  }

  phy_reg_write(unit, phy_addr, reg_addr, write_data);
}
int athrs27_mdc_check()
{
    int i;

    for (i=0; i<4000; i++) {
        if(athrs27_reg_read(0x10c) != 0x18007fff)
            return -1;
    }
    return 0;
}

