static bool set_wol_intr(DRV_HANDLE hClientObj,int en)
{
    int wol;
    
    if(!wol_intr32_pin_enabled(hClientObj))
        return false;
    if (!wol_enabled(hClientObj))
        return false;
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_17);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_STATUS);
    wol=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    if (en)
    {
        wol = (wol & ~_WOL_PLUS_INTR_DIS_MASK);
    }
    else
    {
        wol = (wol |_WOL_PLUS_INTR_DIS_MASK);
    }
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_WOL_STATUS, wol);

    
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_STATUS);
    wol=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
    return true;
}
static void set_wol(DRV_HANDLE hClientObj,int en, int master, int timer)
{   
    unsigned short wol; 
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_4);
    
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    wol=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    if (en)     
        wol |= _WOL_EN_MASK;   
    else        
        wol &= ~_WOL_EN_MASK;  
    
    if (master) 
    {
        wol |= _WOL_PLUS_MASTER_SLAVE_MASK;  // Master mode
        // set the INTR level to active HIGH
        wol |= _WOL_INTR_ACTIVE_HIGH_MASK; 
    }
    else
    {
        wol &= ~_WOL_PLUS_MASTER_SLAVE_MASK; // slave mode
        // set the INTR level to active HIGH
        wol &= ~_WOL_INTR_ACTIVE_HIGH_MASK; 
    }
    switch(timer)
    {
        case WOL_TIMER_30SEC:
            wol &= ~(_WOL_PLUS_TIMER_3MIN_SEL_MASK|_WOL_PLUS_TIMER_10MIN_SEL_MASK);
            wol |= _WOL_PLUS_TIMER_30SEC_SEL_MASK;  // timer set to 30SEC
            break;
        case WOL_TIMER_3MIN:
            wol &= ~(_WOL_PLUS_TIMER_30SEC_SEL_MASK|_WOL_PLUS_TIMER_10MIN_SEL_MASK);
            wol |= _WOL_PLUS_TIMER_3MIN_SEL_MASK;  // timer set to 3MIN
            break;
        case WOL_TIMER_10MIN:
            wol &= ~(_WOL_PLUS_TIMER_30SEC_SEL_MASK|_WOL_PLUS_TIMER_3MIN_SEL_MASK);
            wol |= _WOL_PLUS_TIMER_10MIN_SEL_MASK;  // timer set to 10MIN
            break;            
    }


    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_WOL_CNTRL, wol);

    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    wol=DRV_ETHPHY_SMIReadResultGet(hClientObj);

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
    
}
/****************************************************************************
 * Function:        DRV_EXTPHY_MDIXConfigure
 *
 * PreCondition:    - Communication to the PHY should have been established.
 *
 * Input:           handle - A valid open-instance handle, returned from the driver's open routine
 *					oFlags - the requested open flags: ETH_OPEN_MDIX_AUTO, ETH_OPEN_MDIX_NORM/ETH_OPEN_MDIX_SWAP
 *
 * Output:          ETH_RES_OK - success,
 *                  an error code otherwise
 *
 *
 * Side Effects:    None
 *
 * Overview:        This function configures the MDIX mode for the PHY.
 *
 * Note:            None
 *****************************************************************************/
ETH_RESULT_CODE DRV_EXTPHY_MDIXConfigure(DRV_HANDLE hClientObj, ETH_OPEN_FLAGS oFlags)
{
	unsigned short	phyReg;

	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_SPECIAL_CTRL, PHY_ADDRESS);
	phyReg=DRV_ETHPHY_SMIReadResultGet(hClientObj)&(_SPECIALCTRL_XPOL_MASK);	// mask off not used bits

	if(oFlags&ETH_OPEN_MDIX_AUTO)
	{	// enable Auto-MDIX
		phyReg&=~_SPECIALCTRL_AMDIXCTRL_MASK;
	}
	else
	{	// no Auto-MDIX
        phyReg|=_SPECIALCTRL_AMDIXCTRL_MASK;	// disable Auto-MDIX
        if(oFlags&ETH_OPEN_MDIX_SWAP)
        {
            phyReg|=_SPECIALCTRL_CH_SELECT_MASK;	// swap  - MDIX
        }
        else
        {
            phyReg&=~_SPECIALCTRL_CH_SELECT_MASK;	// normal - MDI
        }
	}
	
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_SPECIAL_CTRL, PHY_ADDRESS, phyReg);	

	return ETH_RES_OK;	

}
/****************************************************************************
 * Function:        read_wol_mode
 *
 * PreCondition:    Ethernet Initiazation should be completed.
 *
 * Input:         hClientObj - A valid open-instance handle, returned from the driver's open routine
 *
 * Output:         Master or slave WOL mode
 *
 *
 * Side Effects:    None
 *
 * Overview:       This api is used get WOL event operation mode whether it is operated on Master or Slave mode
 *                       and is only used for IP101GR PHY driver . 
 *                      
 *
 * Note:            None
 *****************************************************************************/
static WOL_OPERATION_MODE read_wol_mode(DRV_HANDLE hClientObj)
{  
    unsigned short mode; 
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_4);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    mode=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
    return (mode & _WOL_PLUS_MASTER_SLAVE_MASK) ? WOL_MODE_MASTER : WOL_MODE_SLAVE;
}
/****************************************************************************
 * Function:        wol_intr32_pin_enabled
 *
 * PreCondition:    Ethernet Initiazation should be completed.
 *
 * Input:         hClientObj - A valid open-instance handle, returned from the driver's open routine
 *
 * Output:         true or false
 *
 *
 * Side Effects:    None
 *
 * Overview:       This api is used to get status of WOL INTR32 pin.
 *                       and is only used for IP101GR PHY driver . 
 *                      
 *
 * Note:            None
 *****************************************************************************/
static bool wol_intr32_pin_enabled(DRV_HANDLE hClientObj)
{
    unsigned short intr;

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_16);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_INTR_STATUS);
    intr=DRV_ETHPHY_SMIReadResultGet(hClientObj);

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
    return (intr & _INTERRUPTSTATUS_INTR_MASK) ? true : false;
}
static bool wol_enabled(DRV_HANDLE hClientObj)
{
    unsigned short wol;
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_4);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    wol=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
    return (wol & _WOL_EN_MASK) ? true : false;
}
/****************************************************************************
 * Function:        DRV_EXTPHY_MMDDataRead
 *
 * PreCondition:    None
 *
 * Input:           hClientObj - A valid open-instance handle, returned from the driver's open routine
 *					mmdDevAddr - MMD device register value
 * Output:          unsigned short - 16 bit data read from MMD register.
 *
 *
 * Side Effects:    None
 *
 * Overview:        This function is used to enable the MMD control register for data read.
 *
 * Note:            None
 *****************************************************************************/
static unsigned short DRV_EXTPHY_MMDDataRead(DRV_HANDLE hClientObj,eMMDDEVADDRES mmdDevAddr)
{
    // Write 01b to MMD access control register for Data
	unsigned short	mmdStatus;
    unsigned short mmdRegData;
    
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_MMD_ACCESS_CONTROL, PHY_ADDRESS);
	mmdStatus=DRV_ETHPHY_SMIReadResultGet(hClientObj);	
	mmdStatus &= _PHY_MMD_RESERVED_MASK;
    mmdStatus |= _PHY_MMD_CNTL_ACCESS_DATA_MASK;
    // Write 3 for PCS ( for WOL configuration ) and 7 for Auto negotiation and 30 for Vendor specific
    mmdStatus |= mmdDevAddr ;
      
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_MMD_ACCESS_CONTROL, PHY_ADDRESS, mmdStatus);
    
    // write MMD access address/data register with 16 bit address of the desired MMD register
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_MMD_ACCESS_DATA_ADDR, PHY_ADDRESS);
	mmdRegData=DRV_ETHPHY_SMIReadResultGet(hClientObj);	

    return mmdRegData;
    
}
/****************************************************************************
 * Function:        DRV_EXTPHY_MMDAddressWrite
 *
 * PreCondition:    None
 *
 * Input:           hClientObj - A valid open-instance handle, returned from the driver's open routine
 *					indexNo - Specified Register index value
 *					mmdDevAddr - MMD device register value
 * Output:          none
 *
 *
 * Side Effects:    None
 *
 * Overview:        This function is used to configure the MMD control register for address write. 
 *
 * Note:            None
 *****************************************************************************/
static void DRV_EXTPHY_MMDAddressWrite(DRV_HANDLE hClientObj,unsigned short indexNo,eMMDDEVADDRES mmdDevAddr)
{
    // Write 00b to MMD access control register for Address
	unsigned short	mmdStatus;
    unsigned short mmdRegData;
    
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_MMD_ACCESS_CONTROL, PHY_ADDRESS);
	mmdStatus=DRV_ETHPHY_SMIReadResultGet(hClientObj);	
	mmdStatus &= _PHY_MMD_RESERVED_MASK;
    mmdStatus |= _PHY_MMD_CNTL_ACCESS_ADDRESS_MASK;
    // Write 3 for PCS ( for WOL configuration ) and 7 for Auto negotiation and 30 for Vendor specific
    mmdStatus |= mmdDevAddr ;
      
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_MMD_ACCESS_CONTROL, PHY_ADDRESS, mmdStatus);
    
    // write MMD access address/data register with 16 bit address of the desired MMD register
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_MMD_ACCESS_DATA_ADDR, PHY_ADDRESS);
	mmdRegData=DRV_ETHPHY_SMIReadResultGet(hClientObj)&0xFFFF;	// mask off not used bits
    mmdRegData =  indexNo;
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_MMD_ACCESS_DATA_ADDR, PHY_ADDRESS, mmdRegData);	
    
}
static void manual_set_wol(DRV_HANDLE hClientObj)
{   
    int wol; 
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_4);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    wol = DRV_ETHPHY_SMIReadResultGet(hClientObj);
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_WOL_CNTRL, (wol|_WOL_PLUS_MANUAL_SET_MASK));

    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
}
static void set_wol_intr32_pin(DRV_HANDLE hClientObj,int en)
{
    unsigned short intr;

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_16);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_INTR_STATUS);
    intr=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    if(en)
    {
        intr |= _INTERRUPTSTATUS_INTR_MASK;
    }
    else
    {
        intr &= ~_INTERRUPTSTATUS_INTR_MASK;
    }
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_INTR_STATUS, intr);

    
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_INTR_STATUS);
    intr=DRV_ETHPHY_SMIReadResultGet(hClientObj);
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
}
static void  DRV_EXTPHY_WOLInterruptMaskSet(DRV_HANDLE hClientObj,int intStaus)
{
	unsigned short	intmask;
    
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_INT_MASK, PHY_ADDRESS);
	intmask=DRV_ETHPHY_SMIReadResultGet(hClientObj)&(~0xFE01);	
    if(intStaus == WOL_INT_ENABLED)
    {
        intmask |= WOL_INT8_EN;
    }
    else
    {
        intmask &= ~WOL_INT8_EN;
    }
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_INT_MASK, PHY_ADDRESS, intmask);
}
/****************************************************************************
 * Function:        DRV_EXTPHY_MIIConfigure
 *
 * PreCondition:    - Communication to the PHY should have been established.
 *
 * Input:   		handle - A valid open-instance handle, returned from the driver's open routine   
 *					cFlags - the requested configuration flags: ETH_PHY_CFG_RMII/ETH_PHY_CFG_MII
 *
 * Output:          ETH_RES_OK - success,
 *                  an error code otherwise
 *
 *
 * Side Effects:    None
 *
 * Overview:        This function configures the PHY in one of MII/RMII operation modes.
 *
 *****************************************************************************/
ETH_RESULT_CODE DRV_EXTPHY_MIIConfigure(DRV_HANDLE hClientObj,ETHPHY_CONFIG_FLAGS cFlags)
{
	unsigned short	phyReg;
	
	
	DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_SPECIAL_MODE, PHY_ADDRESS);
	phyReg=DRV_ETHPHY_SMIReadResultGet(hClientObj)&(_SPECIALMODE_PHYAD_MASK|_SPECIALMODE_MODE_MASK);	// not used bits should be 0
	if(cFlags&ETH_PHY_CFG_RMII)
	{
		phyReg|=_SPECIALMODE_MIIMODE_MASK;
	}
	else
	{
		phyReg&=~_SPECIALMODE_MIIMODE_MASK;
	}
	DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_SPECIAL_MODE, PHY_ADDRESS, phyReg);	// update the Special Modes reg
	

	return ETH_RES_OK;	
}
/****************************************************************************
 * Function:        set_sense_any_pkt
 *
 * PreCondition:    Ethernet Initiazation should be completed.
 *
 * Input:         hClientObj - A valid open-instance handle, returned from the driver's open routine
 *
 * Output:        none
 *
 *
 * Side Effects:    None
 *
 * Overview:       This api is used set any packet  for WOL event
 *                       and is only used for IP101GR PHY driver . 
 *                      
 *
 * Note:            None
 *****************************************************************************/
static void set_sense_any_pkt(DRV_HANDLE hClientObj,int anypkt)
{
    unsigned short wol;
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_4);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_CNTRL);
    wol = DRV_ETHPHY_SMIReadResultGet(hClientObj);

    if (anypkt)
    {
        wol =  wol | _WOL_SENSE_ANY_PKT_MASK;  
    }
    else
    {
        wol =  wol & ~_WOL_SENSE_ANY_PKT_MASK;  
    }

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_WOL_CNTRL, wol);
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);
}
static eWOL_STATE check_wol_status(DRV_HANDLE hClientObj)
{
    WOL_OPERATION_MODE mode;
    unsigned short  status; 
    
    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_17);
    DRV_ETHPHY_SMIReadStart(hClientObj,PHY_REG_WOL_STATUS);
    status=DRV_ETHPHY_SMIReadResultGet(hClientObj);

    DRV_ETHPHY_SMIWriteStart(hClientObj,PHY_REG_PAGE_SEL, PAGENUM_0);

    mode = read_wol_mode(hClientObj);
    if (mode == WOL_MODE_MASTER)
    {
        if (status & _WOL_PLUS_SLEEPING_STATUS_MASK) 
            return  WOL_SLEEPING;
        else if(status & _WOL_PLUS_WAKE_STATUS_MASK)
            return WOL_WAKEUP;
        else
            return  WOL_NORMAL;
    }
    else
    { 
        status &= (_WOL_PLUS_SLEEPING_STATUS_MASK | _WOL_PLUS_SLEEP_MASK | _WOL_PLUS_WAKE_STATUS_MASK);     
        if (status == _WOL_PLUS_SLEEP_MASK) 
            return  WOL_RDY4SLP;
        else if (status == (_WOL_PLUS_WAKE_STATUS_MASK |_WOL_PLUS_SLEEPING_STATUS_MASK))
            return  WOL_RDY4WAKE;
        else if(status & _WOL_PLUS_WAKE_STATUS_MASK)
            return WOL_RDY4WAKE;
       /* else if (status & _WOL_PLUS_SLEEPING_STATUS_MASK)
            return  WOL_SLEEPING;
            */
        else
            return  WOL_NORMAL; 
    }
}