📄 auend.c
字号:
(
AU_DRV_CTRL * pDrvCtrl /* pointer to DRV_CTRL structure */
)
{
PHY_INFO * pPhyInfo = NULL;
DRV_LOG (DRV_DEBUG_MII, "auPhyPreInit...\n", 0, 0, 0, 0, 0, 0);
/* set MII defaults */
pDrvCtrl->pMiiPhyTbl = NULL;
pDrvCtrl->miiPhyFlags = (AU_USR_MII_10MB | AU_USR_MII_HD |
AU_USR_MII_100MB | AU_USR_MII_FD);
/* get memory for the phyInfo structure */
if ((pDrvCtrl->pPhyInfo = calloc (sizeof (PHY_INFO), 1)) == NULL)
return (ERROR);
pPhyInfo = pDrvCtrl->pPhyInfo;
/* set some default values */
pDrvCtrl->pPhyInfo->pDrvCtrl = (void *) pDrvCtrl;
pDrvCtrl->pPhyInfo->phyAnOrderTbl = pDrvCtrl->pMiiPhyTbl;
pDrvCtrl->pPhyInfo->phyAddr = auPhyFind (pDrvCtrl);
/*
* in case of link failure, set a default mode for the PHY
* if we intend to use a different media, this flag should
* be cleared
*/
pDrvCtrl->pPhyInfo->phyFlags |= MII_PHY_DEF_SET;
/* clear bus scan flag to speed up boot process */
pDrvCtrl->pPhyInfo->phyFlags &= ~MII_ALL_BUS_SCAN;
/* set callback and delay params */
pDrvCtrl->pPhyInfo->phyWriteRtn = (FUNCPTR) auMiiWrite;
pDrvCtrl->pPhyInfo->phyReadRtn = (FUNCPTR) auMiiRead;
pDrvCtrl->pPhyInfo->phyDelayRtn = (FUNCPTR) taskDelay;
pDrvCtrl->pPhyInfo->phyMaxDelay = MII_PHY_DEF_DELAY;
pDrvCtrl->pPhyInfo->phyDelayParm = 1;
/* in case the cable is not there, leave the PHY ready to auto-negotiate */
pDrvCtrl->pPhyInfo->phyDefMode = PHY_AN_ENABLE;
/* handle some user-to-physical flags */
if (!(DRV_PHY_FLAGS_ISSET (AU_USR_MII_NO_AN)))
MII_PHY_FLAGS_SET (MII_PHY_AUTO);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_AUTO);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_AN_TBL))
MII_PHY_FLAGS_SET (MII_PHY_TBL);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_TBL);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_100MB))
MII_PHY_FLAGS_SET (MII_PHY_100);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_100);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_FD))
MII_PHY_FLAGS_SET (MII_PHY_FD);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_10MB))
MII_PHY_FLAGS_SET (MII_PHY_10);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_10);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_HD))
MII_PHY_FLAGS_SET (MII_PHY_HD);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_HD);
if (DRV_PHY_FLAGS_ISSET (AU_USR_MII_BUS_MON))
MII_PHY_FLAGS_SET (MII_PHY_MONITOR);
else
MII_PHY_FLAGS_CLEAR (MII_PHY_MONITOR);
MII_PHY_FLAGS_SET (MII_PHY_PRE_INIT);
DRV_LOG (DRV_DEBUG_LOAD, ("auPhyPreInit: pPhyInfo = 0x%x read=0x%x
write=0x%x tbl=0x%x addr=0x%x
flags=0x%x \n"),
(int) pDrvCtrl->pPhyInfo,
(int) pDrvCtrl->pPhyInfo->phyReadRtn,
(int) pDrvCtrl->pPhyInfo->phyWriteRtn,
(int) pDrvCtrl->pPhyInfo->phyAnOrderTbl,
(int) pDrvCtrl->pPhyInfo->phyAddr,
(int) pDrvCtrl->pPhyInfo->phyFlags);
DRV_LOG (DRV_DEBUG_MII, "auPhyPreInit...done\n", 0, 0, 0, 0, 0, 0);
return (OK);
}
/***************************************************************************
*
* auMiiRead - read a PHY device register via MII
*
* RETURNS: the contents of a PHY device register in retVal arg, OK always
*/
LOCAL STATUS auMiiRead
(
AU_DRV_CTRL * pDrvCtrl,
UINT8 phyAdrs, /* PHY address to access */
UINT8 phyReg, /* PHY register to read */
UINT16 * pRetVal
)
{
int timeout;
/* write phy address and phy register to MII control reg */
AU_MII_CONTROL = (phyAdrs << 11) | (phyReg << 6);
/* waiting for completion of access */
timeout = 20;
while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)
{
taskDelay (1);
if (--timeout == 0)
{
DRV_LOG (DRV_DEBUG_MII, "auMiiRead: PHY(%02x) reg(%02x) access timeout\n",
phyAdrs, phyReg, 0, 0, 0, 0);
return (ERROR);
}
}
/* get data from MII data register */
*pRetVal = AU_MII_DATA;
DRV_LOG (DRV_DEBUG_MII, "auMiiRead: adr=%02x reg=%02x data=%04x\n",
phyAdrs, phyReg, *pRetVal, 0, 0, 0);
return (OK);
}
/***************************************************************************
*
* auMiiWrite - write to a PHY device register via MII
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS auMiiWrite
(
AU_DRV_CTRL * pDrvCtrl,
UINT8 phyAdrs, /* PHY address to access */
UINT8 phyReg, /* PHY register to write */
UINT16 data /* Data to write */
)
{
int timeout;
DRV_LOG (DRV_DEBUG_MII, "auMiiWrite: adr=%02x reg=%02x data=%04x\n",
phyAdrs, phyReg, data, 0, 0, 0);
/* wait for completion of previous access */
timeout = 20;
while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)
{
taskDelay (1);
if (--timeout == 0)
{
DRV_LOG (DRV_DEBUG_MII, "auMiiWrite: PHY(%02x) reg(%02x) access timeout\n",
phyAdrs, phyReg, 0, 0, 0, 0);
return (ERROR);
}
}
/* put data into data register before perform MII op */
AU_MII_DATA = data;
AU_MII_CONTROL = ((phyAdrs << 11) | (phyReg << 6)
| AU_MII_CONTROL_WRITE);
/* wait for completion */
timeout = 20;
while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)
{
taskDelay (1);
if (--timeout == 0)
{
DRV_LOG (DRV_DEBUG_MII, "auMiiWrite: PHY(%02x) reg(%02x) access timeout\n",
phyAdrs, phyReg, 0, 0, 0, 0);
return (ERROR);
}
}
return (OK);
}
/***************************************************************************
*
* auPhyFind - Find the first PHY.
*
* RETURNS: Address of PHY or 0xFF if not found.
*/
LOCAL UINT8 auPhyFind
(
AU_DRV_CTRL *pDrvCtrl
)
{
UINT16 miiData;
UINT8 phyAddr;
DRV_LOG (DRV_DEBUG_MII, "auMiiPhyFind...\n",
0, 0, 0, 0, 0, 0);
/* searching valid phy */
for (phyAddr = 0; phyAddr < (UINT8)AU_MAX_PHY; phyAddr++)
{
auMiiRead (pDrvCtrl, phyAddr, MII_PHY_ID1, &miiData);
/* Verify PHY address read */
if ((miiData != 0xFFFF) && (miiData != 0)) /* Found PHY */
{
DRV_LOG (DRV_DEBUG_MII, "auMiiPhyFind: PHY @ %x found\n", phyAddr, 0,0,0,0,0);
return (phyAddr);
}
}
DRV_LOG (DRV_DEBUG_LOAD, "auMiiPhyFind: No PHY found\n", 0,0,0,0,0,0);
return (0xFF);
}
/*******************************************************************************
*
* auStart - start the device
*
* This function calls BSP functions to connect interrupts and start the
* device running in interrupt mode.
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS auStart
(
AU_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
STATUS result;
pDrvCtrl->txCleaning = FALSE;
pDrvCtrl->txBlocked = FALSE;
if (auMiiInit (pDrvCtrl) == ERROR)
return (ERROR);
/* connect ISR */
SYS_INT_CONNECT (pDrvCtrl, auInt, (int)pDrvCtrl, &result);
if (result == ERROR)
return ERROR;
DRV_LOG (DRV_DEBUG_LOAD, "auStart: Interrupt connected.\n", 1, 2, 3, 4, 5, 6);
/* mark the interface as up */
END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
/* enable interrupt */
SYS_INT_ENABLE (pDrvCtrl);
DRV_LOG (DRV_DEBUG_LOAD, "auStart: Interrupt enabled.\n", 1, 2, 3, 4, 5, 6);
return (OK);
}
/*******************************************************************************
*
* auInt - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*/
LOCAL void auInt
(
AU_DRV_CTRL * pDrvCtrl /* driver control structure */
)
{
int i;
int txDone = FALSE;
int rxDone = FALSE;
DRV_LOG (DRV_DEBUG_INT, "auInt: control=%08x rising=%08x, req0 %08x\n",
AU_MAC_CONTROL, AU_INTC_RISING_EDGE_CLEAR(0),
AU_INTC_REQUEST0_INT(0), 0, 0, 0);
/* Acknowledge interrupt */
SYS_INT_DISABLE(pDrvCtrl);
SYS_WB_FLUSH();
/* Examine receive DMA buffers */
for (i = 0; i < pDrvCtrl->rringSize; ++i)
{
if (AU_RX_ADDRESS(i) & (1 << 1))
rxDone = TRUE;
}
/* Examine transmit DMA buffers */
for (i = 0; i < pDrvCtrl->tringSize; ++i)
{
if (AU_TX_ADDRESS(i) & (1 << 1))
txDone = TRUE;
}
/* Have netTask handle all packets */
if (rxDone || txDone)
{
netJobAdd ((FUNCPTR)auHandleInt,(int)pDrvCtrl, 0, 0, 0, 0);
}
if (pDrvCtrl->txBlocked)
{
pDrvCtrl->txBlocked = FALSE;
netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0, 0, 0);
}
}
/*******************************************************************************
*
* auHandleInt - task level interrupt service for all packets
*
* This routine is called at task level indirectly by the interrupt
* service routine to do any message received processing.
*/
LOCAL void auHandleInt
(
AU_DRV_CTRL * pDrvCtrl /* driver control structure */
)
{
/* Handle zero or more previously transmitted frames */
while (AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) & (1<<1))
{
AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) = 0;
/* equal to use % */
pDrvCtrl->tmdLastIndex = (pDrvCtrl->tmdLastIndex + 1) &
(pDrvCtrl->tringSize - 1);
}
SYS_WB_FLUSH();
/* Handle zero or more newly received frames */
while (AU_RX_ADDRESS(pDrvCtrl->rmdIndex) & (1<<1))
{
auRecv (pDrvCtrl);
}
/* Re-enable interrupts */
SYS_INT_ENABLE(pDrvCtrl);
SYS_WB_FLUSH();
}
/*******************************************************************************
*
* auRecv - process the next incoming packet
*
* RETURNS: OK/ERROR
*/
LOCAL STATUS auRecv
(
AU_DRV_CTRL * pDrvCtrl /* driver control structure */
)
{
int len;
M_BLK_ID pMblk;
char * pCluster;
char * pBuf;
CL_BLK_ID pClBlk;
UINT32 status;
int rmdIndex;
/* Extract packet particulators */
rmdIndex = pDrvCtrl->rmdIndex;
status = AU_RX_STATUS(rmdIndex);
len = AU_RX_STATUS (rmdIndex) & 0x3fff; /* get packet length */
pBuf = pDrvCtrl->pRxMem[rmdIndex];
DRV_LOG (DRV_DEBUG_RX, "auRecv: index=%d status=%08x len=%d\n",
rmdIndex, status, len, 0, 0, 0);
DRV_LOG (DRV_DEBUG_RX, "auRecv: dst=%02x:%02x:%02x:%02x:%02x:%02x\n",
pBuf[0]&0xff, pBuf[1]&0xff, pBuf[2]&0xff,
pBuf[3]&0xff, pBuf[4]&0xff, pBuf[5]&0xff);
DRV_LOG (DRV_DEBUG_RX, "auRecv: src=%02x:%02x:%02x:%02x:%02x:%02x\n",
pBuf[6]&0xff, pBuf[7]&0xff, pBuf[8]&0xff,
pBuf[9]&0xff, pBuf[10]&0xff, pBuf[11]&0xff);
DRV_LOG (DRV_DEBUG_RX, "auRecv: type(len)=%02x %02x\n",
pBuf[12]&0xff, pBuf[13]&0xff, 0,0,0,0);
/* If error flag OR if packet is not completely in one buffer */
if (!len)
{
DRV_LOG (DRV_DEBUG_RX, "auRecv: RMD error!\n", 1, 2, 3, 4, 5, 6);
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
goto cleanRXD; /* skip to clean up */
}
/* If we cannot get a buffer to loan then bail out. */
pCluster = netClusterGet (pDrvCtrl->endObj.pNetPool,
pDrvCtrl->pClPoolId);
if (pCluster == NULL)
{
DRV_LOG (DRV_DEBUG_RX, "auRecv: Cannot loan buffer!\n", 1, 2, 3, 4, 5, 6);
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;
muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError);
goto cleanRXD;
}
if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
{
netClFree (pDrvCtrl->endObj.pNetPool, pCluster);
DRV_LOG (DRV_DEBUG_RX, "auRecv: Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -