⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auend.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    (
    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 + -