blob: c274554fb999b35f66c7111b44849aaaa66fbfcb [file] [log] [blame]
#include <Copyright.h>
/********************************************************************************
* qdInt.c
*
* DESCRIPTION:
* This sample shows how to call QuarterDeck Interrupt handler when QD INT
* raised, and how to take care each Interrupt Cause.
*
* DEPENDENCIES: NONE.
*
* FILE REVISION NUMBER:
*
*******************************************************************************/
#include "msSample.h"
#ifdef QD_DEBUG
#ifdef _VXWORKS
#define INT_MSG_PRINT logMsg
#else
#define INT_MSG_PRINT printf
#endif
#else /* QD_DEBUG */
#define INT_MSG_PRINT(_x,_a0,_a1,_a2,_a3,_a4,_a5) while(0){}
#endif
GT_U32 QDIntMask = GT_VTU_PROB|GT_ATU_PROB|GT_PHY_INTERRUPT;
/*
* To enable quarterDeck interrupt, you need to call eventSetActive() and
* gprtPhyIntEnable(), as following sample routine.
* sampleQDIntEnable will enable all interrupt causes.
* For Port, GT_ATU_FULL, GT_ATU_DONE, GT_PHY_INTERRUPT, and GT_EE_INTERRUPT
* are enabled.
* For every Phy (0 ~ 4), GT_SPEED_CHANGED, GT_DUPLEX_CHANGED, GT_PAGE_RECEIVED,
* GT_AUTO_NEG_COMPLETED, GT_LINK_STATUS_CHANGED, GT_SYMBOL_ERROR,
* GT_FALSE_CARRIER, GT_FIFO_FLOW, GT_CROSSOVER_CHANGED, GT_POLARITY_CHANGED,
* and GT_JABBER are enabled.
*/
GT_STATUS qdIntEnable(GT_QD_DEV *dev)
{
GT_STATUS status;
GT_U16 data;
int port;
/*
* Enable QuarterDeck interrupt for ATUFull, ATUDone, PHYInt, and EEInt.
* If writing 0 into eventSetActive(), all port interrupt will be disabled.
*/
data = QDIntMask;
if((status = eventSetActive(dev,data)) != GT_OK)
{
MSG_PRINT(("eventSetActive returned fail.\n"));
return status;
}
/*
* Enable Phy interrupt for every possible interrupt cause.
* If writing 0 into gprtPhyIntEnable(), all port interrupt will be disabled.
*/
data = GT_SPEED_CHANGED|GT_DUPLEX_CHANGED|GT_LINK_STATUS_CHANGED;
for(port=0; port<3; port++)
{
if((status = gprtPhyIntEnable(dev,port,data)) != GT_OK)
{
MSG_PRINT(("gprtPhyIntEnable returned fail.\n"));
return status;
}
}
return GT_OK;
}
/*
* Disable QuarterDeck Interrupt.
*/
GT_STATUS qdIntDisable(GT_QD_DEV *dev)
{
GT_STATUS status;
int port;
/*
* Writing 0 into eventSetActive(), all port interrupt will be disabled.
*/
if((status = eventSetActive(dev,0)) != GT_OK)
{
MSG_PRINT(("eventSetActive returned fail.\n"));
return status;
}
for(port=0; port<3; port++)
{
if((status = gprtPhyIntEnable(dev,port,0)) != GT_OK)
{
MSG_PRINT(("gprtPhyIntEnable returned fail.\n"));
return status;
}
}
return GT_OK;
}
/*
* Assume that the following function, sampleQDIntVector(), is registered
* when BSP calls intConnect for QD Interrupt.
* This sample will show how to deal with QuarterDeck Interrupt.
*/
GT_STATUS qdIntVector(GT_QD_DEV *dev)
{
GT_U16 intCause,data,phyIntCause;
GT_VTU_INT_STATUS vtuIntStatus;
GT_ATU_INT_STATUS atuIntStatus;
int port;
/*
* Disable QuarterDeck Interrupt in System Level.
* ToDo...
*/
/*
* Check if QD generated the interrupt.
*/
if(eventGetIntStatus(dev,&intCause) != GT_TRUE)
{
/* QD didn't generate the interrupt. */
return GT_FAIL;
}
/*
* QD generated interrupt with the reason in intCause.
*/
if(intCause & GT_VTU_PROB)
{
INT_MSG_PRINT("VTU PROB INT for Dev %#x.\n",(int)dev,0,0,0,0,0);
/*
* VTU member violation, miss violation, or full violation.
*/
do
{
if(gvtuGetIntStatus(dev, &vtuIntStatus) != GT_OK)
{
/* reading VTU Int Status Failed */
INT_MSG_PRINT("VTU INT Status read failure.\n",0,0,0,0,0,0);
break;
}
INT_MSG_PRINT("VTU INT : Cause %#x, SPID %i, VID %i\n",vtuIntStatus.vtuIntCause,vtuIntStatus.spid,vtuIntStatus.vid,0,0,0);
} while (vtuIntStatus.vtuIntCause);
}
if(intCause & GT_ATU_PROB)
{
/*
* ATU cannot load or learn a new mapping due to all the available
* locations for an address being locked.
* ToDo...
*/
INT_MSG_PRINT("ATU PROB INT for Dev %#x.\n",(int)dev,0,0,0,0,0);
do
{
if(gatuGetIntStatus(dev, &atuIntStatus) != GT_OK)
{
/* reading ATU Int Status Failed */
INT_MSG_PRINT("ATU INT Status read failure.\n",0,0,0,0,0,0);
break;
}
INT_MSG_PRINT("ATU INT : Cause %#x, SPID %i, DBNum %i\n",atuIntStatus.atuIntCause,atuIntStatus.spid,atuIntStatus.dbNum,0,0,0);
INT_MSG_PRINT("ATU INT : MAC %02x-%02x-%02x-%02x-%02x-%02x\n",
atuIntStatus.macAddr.arEther[0],
atuIntStatus.macAddr.arEther[1],
atuIntStatus.macAddr.arEther[2],
atuIntStatus.macAddr.arEther[3],
atuIntStatus.macAddr.arEther[4],
atuIntStatus.macAddr.arEther[5]);
} while (atuIntStatus.atuIntCause);
}
if(intCause & GT_ATU_DONE)
{
/*
* There is a transitions from a one to a zero on ATUBusy bit
* (Refer to ATU Operation Register.)
* ToDo...
*/
INT_MSG_PRINT("ATU Done INT for Dev %#x.\n",(int)dev,0,0,0,0,0);
}
#if 1
if(intCause & GT_PHY_INTERRUPT)
{
/*
* At least one of the Phy generated interrupt.
* We need to read Phy Interrupt Summary and go through each phy
* based on the summary.
*/
if(gprtGetPhyIntPortSummary(dev,&data) != GT_OK)
{
return GT_FAIL;
}
INT_MSG_PRINT("Phy INT (Port Vector %#x).\n",(int)data,0,0,0,0,0);
port = 0;
while(data)
{
if(data & 0x01)
{
/*
* Call gprtGetPhyIntStatus to get intCause
*/
if(gprtGetPhyIntStatus(dev,port,&phyIntCause) != GT_OK)
{
/*
* Something wrong with the system. Need to do the
* necessary work.
* ToDo...
*/
}
INT_MSG_PRINT("Port %i: %#x.\n",port,phyIntCause,0,0,0,0);
if(phyIntCause & GT_SPEED_CHANGED)
{
/*
* Speed has been changed.
* ToDo...
*/
INT_MSG_PRINT("SPEED CHANGE\n",0,0,0,0,0,0);
}
if(phyIntCause & GT_DUPLEX_CHANGED)
{
/*
* Duplex mode has been changed.
* ToDo...
*/
INT_MSG_PRINT("DUPLEX CHANGE\n",0,0,0,0,0,0);
}
if(phyIntCause & GT_PAGE_RECEIVED)
{
/*
* Page received.
* ToDo...
*/
INT_MSG_PRINT("PAGE RECEIVED\n",0,0,0,0,0,0);
}
if(phyIntCause & GT_AUTO_NEG_COMPLETED)
{
/*
* AutoNegotiation completed.
* ToDo...
*/
INT_MSG_PRINT("AUTO NEG COMPLETED\n",0,0,0,0,0,0);
}
if(phyIntCause & GT_LINK_STATUS_CHANGED)
{
/*
* Link Status changed.
* ToDo...
*/
INT_MSG_PRINT("LINK CHANGE\n",0,0,0,0,0,0);
}
if(phyIntCause & GT_SYMBOL_ERROR)
{
/*
* Symbol error
* ToDo...
*/
}
if(phyIntCause & GT_FALSE_CARRIER)
{
/*
* False Carrier.
* ToDo...
*/
}
if(phyIntCause & GT_FIFO_FLOW)
{
/*
* Fifo Overflow/underflow error
* ToDo...
*/
}
if(phyIntCause & GT_CROSSOVER_CHANGED)
{
/*
* MDI/MDIX crossover changed.
* ToDo...
*/
}
if(phyIntCause & GT_POLARITY_CHANGED)
{
/*
* Polarity changed.
* ToDo...
*/
}
if(phyIntCause & GT_JABBER)
{
/*
* Jabber
* ToDo...
*/
}
}
data >>= 1;
port++;
}
}
if(intCause & GT_EE_INTERRUPT)
{
/*
* EEPROM is done loading registers.
* ToDo...
*/
}
/*
* Now, all the QuarterDeck related interrupt have been cleared,
* so it's OK to enable QuarterDeck Interrupt in System Level.
* ToDo...
*/
#endif
return GT_OK;
}