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

📄 auend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* 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);     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;        AU_MII_CONTROL = (phyAdrs << 11) | (phyReg << 6);    timeout = 20;    while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)	{	taskDelay (1);	if (--timeout == 0)	    {	    DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n",		     0, 0, 0, 0, 0, 0);	    return (ERROR);	    }	}    *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);    timeout = 20;    while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)	{	taskDelay (1);	if (--timeout == 0)	    {	    DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n",		     0, 0, 0, 0, 0, 0);	    return (ERROR);	    }	}    AU_MII_DATA = data;    AU_MII_CONTROL = ((phyAdrs << 11) | (phyReg << 6)			  | AU_MII_CONTROL_WRITE);    timeout = 20;    while (AU_MII_CONTROL & AU_MII_CONTROL_BUSY)	{	taskDelay (1);	if (--timeout == 0)	    {	    DRV_LOG (DRV_DEBUG_MII, "PHY access timeout\n",		     0, 0, 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);    for (phyAddr = 0; phyAddr < (UINT8)AU_MAX_PHY; phyAddr++)         {         auMiiRead (pDrvCtrl, phyAddr, MII_PHY_ID0, &miiData);        /* Verify PHY address read */        if ((miiData != 0xFFFF) && (miiData != 0)) /* Found PHY */            {	    DRV_LOG (DRV_DEBUG_MII, "PHY @ %x\n", phyAddr, 0,0,0,0,0);            return (phyAddr);            }        }    DRV_LOG (DRV_DEBUG_LOAD, "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);    SYS_INT_CONNECT (pDrvCtrl, auInt, (int)pDrvCtrl, &result);    if (result == ERROR)        return ERROR;    /* mark the interface as up */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "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 /* device to be initialized */    )    {    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 buffers */    for (i = 0; i < pDrvCtrl->rringSize; ++i)	{	if (AU_RX_ADDRESS(i) & (1 << 1))	    rxDone = TRUE;	}    /* Examine transmit 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 /* device to be initialized */    )    {	/*	 * Handle zero or more previously transmitted frames	 */	while (AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) & (1<<1))	{		AU_TX_ADDRESS(pDrvCtrl->tmdLastIndex) = 0;    		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 /* device to be initialized */    )    {    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);    /* If error flag OR if packet is not completely in one buffer */    if (!len)	{	DRV_LOG (DRV_DEBUG_RX, "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, "Cannot loan!\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, "Out of Cluster Blocks!\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;	}    /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA))	== NULL)	{	netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);	netClFree (pDrvCtrl->endObj.pNetPool, pCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\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;	}    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    bcopy (pBuf, pCluster + pDrvCtrl->offset, len);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;    pMblk->mBlkHdr.mLen	  = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    AU_RX_STATUS(rmdIndex) = 0;    AU_RX_ADDRESS(rmdIndex)      = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[rmdIndex])) | 1;	SYS_WB_FLUSH();    /* Advance our management index */	    pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);	    DRV_LOG (DRV_DEBUG_RX, "auRecv clean index %d %08x\n",	     rmdIndex, AU_RX_ADDRESS(rmdIndex) & 0x1f, 0, 0, 0, 0);    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);    return (OK);cleanRXD:    /* Restore the receiver buffer */    AU_RX_STATUS(rmdIndex) = 0;    AU_RX_ADDRESS(rmdIndex)      = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[rmdIndex])) | 1;	SYS_WB_FLUSH();	    DRV_LOG (DRV_DEBUG_RX, "auRecv clean index %d %08x\n",	     rmdIndex, AU_RX_ADDRESS(rmdIndex) & 0x1f, 0, 0, 0, 0);    /* Advance our management index */    pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);    return (OK);    }/********************************************************************************* auSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.  ** RETURNS: OK or ERROR.*/LOCAL STATUS auSend    (    AU_DRV_CTRL * 	pDrvCtrl,  /* device to be initialized */    M_BLK_ID 		pMblk      /* data to send */    )    {    char *       	pBuf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -