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

📄 auend.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Enable the MAC */

    AU_MAC_ENABLE = AU_MAC_ENABLE_CLOCKS_ONLY;
    SYS_WB_FLUSH();
    AU_MAC_ENABLE = AU_MAC_ENABLE_NORMAL & ~AU_MAC_ENABLE_TS;
    SYS_WB_FLUSH();

    /* Configure the MAC */

#if (_BYTE_ORDER == _BIG_ENDIAN)
    AU_MAC_CONTROL = AU_MAC_CONTROL_EM_BIG | AU_MAC_CONTROL_DO;
#else
    AU_MAC_CONTROL = AU_MAC_CONTROL_DO;
#endif

    enetAddr = pDrvCtrl->enetAddr;
    AU_MAC_ADDRESS_HIGH = (enetAddr[5] << 8) | enetAddr[4];
    AU_MAC_ADDRESS_LOW = ((enetAddr[3] << 24)
			      | (enetAddr[2] << 16)
			      | (enetAddr[1] << 8)
			      | (enetAddr[0] << 0));

    DRV_LOG (DRV_DEBUG_LOAD, "auConfig: MAC addr is(%08x %08x)\n",
	     AU_MAC_ADDRESS_HIGH,
	     AU_MAC_ADDRESS_LOW, 0, 0, 0, 0);
    DRV_LOG (DRV_DEBUG_LOAD, "auConfig: Initial multi addr is (%08x %08x)\n",
	     AU_MULTICAST_HASH_ADDRESS_HIGH,
	     AU_MULTICAST_HASH_ADDRESS_LOW, 0, 0, 0, 0);

    /* Configure MII */

    /* Setup RxD and TxD pointers: / and % */

    pDrvCtrl->rmdIndex = (AU_RX_ADDRESS(0) >> 2) & 0x03;
    pDrvCtrl->tmdIndex = (AU_TX_ADDRESS(0) >> 2) & 0x03;
    pDrvCtrl->tmdLastIndex = pDrvCtrl->tmdIndex;

#ifdef AU_PROMISCUOS_MODE
    /* Handle promiscuous mode */
    if (pDrvCtrl->flags & AU_PROMISCUOUS_FLAG)
	AU_MAC_CONTROL |= AU_MAC_CONTROL_PR;
#endif

    for (i = 0; i < pDrvCtrl->rringSize; ++i)
        AU_RX_ADDRESS(i) 
          = ((UINT32) AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRxMem[i])) | 1;

    /* Enable transmit and receive */

    AU_MAC_CONTROL |= AU_MAC_CONTROL_TE | AU_MAC_CONTROL_RE;
    SYS_WB_FLUSH();

    DRV_LOG (DRV_DEBUG_LOAD, "auConfig...done\n", 1, 2, 3, 4, 5, 6);
    }

/******************************************************************************
*
* auAddrFilterSet - set the address filter for multicast addresses
*
* This routine goes through all of the multicast addresses on the list of
* addresses (added with the auAddrAdd()(auMCastAddrAdd??) routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A
*/

LOCAL void auAddrFilterSet
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    ETHER_MULTI * 	pCurr;
    UINT8 *		pCp;
    UINT8 		byte;
    UINT32 		crc;
    int 		len;
    int 		count;

    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);

    while (pCurr != NULL)
	{
	pCp = (UINT8 *)&pCurr->addr;

	crc = 0xffffffff;

	for (len = AU_LA_LEN; --len >= 0;)
	    {
	    byte = *pCp++;

            for (count = 0; count < AU_LAF_LEN; count++)
		{
		if ((byte & 0x01) ^ (crc & 0x01))
		    {
		    crc >>= 1;
		    crc = crc ^ AU_CRC_POLYNOMIAL;
		    }
		else
		    {
		    crc >>= 1;
		    }
		byte >>= 1;
		}
	    }

	/* Just want the 6 most significant bits. */

	crc = AU_CRC_TO_LAF_IX (crc);

	pCurr = END_MULTI_LST_NEXT(pCurr);
	}
    }

/*******************************************************************************
*
* auPollReceive - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device. This routine return OK if it is successful in getting the packet
*
* RETURNS: OK or EAGAIN.
*/

LOCAL STATUS auPollReceive
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* driver control structure */
    M_BLK_ID 		pMblk
    )
    {
    int                 len;
    char *              pBuf;
    UINT32              status;
    UINT32              ERROR_MASK=0x812bc000;
    int                 rmdIndex;

    DRV_LOG (DRV_DEBUG_POLL_RX, "auPollReceive: Poll Rx...\n", 1, 2, 3, 4, 5, 6);

    /* Handle zero or more newly received frames */

    if (!(AU_RX_ADDRESS(pDrvCtrl->rmdIndex) & (1<<1)))
        {
        pDrvCtrl->rmdIndex = (pDrvCtrl->rmdIndex + 1) & (pDrvCtrl->rringSize - 1);
        /* goto cleanRx; */
        return (EAGAIN);
        }

    /* Extract packet particulators */

    rmdIndex = pDrvCtrl->rmdIndex;

    /* Read the device status register */

    status = AU_RX_STATUS(rmdIndex);
    len = AU_RX_STATUS (rmdIndex) & 0x3fff; /* get packet length */
    pBuf = pDrvCtrl->pRxMem[rmdIndex];

    if (status & (ERROR_MASK & ~0x0))
        {
        DRV_LOG (DRV_DEBUG_POLL_RX, "auPollReceive: Poll Rx error, status=0x%x\n", status, 2, 3, 4, 5, 6);
	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);

        /* restart chip on fatal error.??? */

        if (status & ERROR_MASK & 0x0)        /* memory error */
            {
	    END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); 
            DRV_LOG (DRV_DEBUG_POLL_RX, "auPollReceive: Poll Rx restart\n", 1, 2, 3, 4, 5, 6);
            auRestart (pDrvCtrl);
            return (EAGAIN);
            }

        /* goto cleanRx;  */

        goto cleanRx;
        }

    if (!len)
        {
        DRV_LOG (DRV_DEBUG_RX, "auPollReceive: RMD error!\n", 1, 2, 3, 4, 5, 6);
        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);
        goto cleanRx;                          /* skip to clean up */
        }

    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);

    /* Upper layer provides the buffer. */

    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))
	{
        DRV_LOG (DRV_DEBUG_POLL_RX, "auPollReceive: bad mblk,len:%d flags:%d\n",
                 pMblk->mBlkHdr.mLen, pMblk->mBlkHdr.mFlags, 3, 4, 5, 6);
	return (EAGAIN);
	}

    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;
    bcopy (pBuf, pMblk->mBlkHdr.mData, len);

    pMblk->mBlkHdr.mLen = len;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = len;

    cleanRx:

    /* Restore the receiver buffer */

    DRV_LOG (DRV_DEBUG_RX, "auPollReceive: error occurs, clean index %d %08x\n",
             rmdIndex, AU_RX_ADDRESS(rmdIndex) & 0x1f, 0, 0, 0, 0);

    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_POLL_RX, "auPollReceive: Poll Rx...done\n", 1, 2, 3, 4, 5, 6);

    return (OK);
    }

/*******************************************************************************
*
* auPollSend - routine to send a packet in polled mode.
*
* This routine is called by a user to try and send a packet on the
* device.
*
* RETURNS: OK or EAGAIN.
*/

LOCAL STATUS auPollSend
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* driver control structure */
    M_BLK_ID 		pMblk
    )
    {
    char *       	pBuf;
    int			index;
    int         	len = 0;
    UINT32 addr;

    DRV_LOG (DRV_DEBUG_POLL_TX, "auPollSend: Poll Tx...\n", 1, 2, 3, 4, 5, 6);

    /* Advance our management index (first) */

    index = pDrvCtrl->tmdIndex;

    if (AU_TX_ADDRESS(index) & 0x01) 
        {
        DRV_LOG (DRV_DEBUG_POLL_TX, "auPollSend: Out of tmds.\n", 1, 2, 3, 4, 5, 6);
        
        if (!pDrvCtrl->txCleaning) 
	    auTRingScrub (pDrvCtrl);
	return (EAGAIN);
        }

    pBuf = pDrvCtrl->pTxMem[index];
    
    if (pBuf == NULL)
         return (EAGAIN);

    /* copy and release the packet */

    len = netMblkToBufCopy (pMblk, pBuf, NULL);

    if (len < ETHERSMALL)
	{
	/* Pad to ETHERSMALL with zeros, required by H/W */
	bzero (&pBuf[len], ETHERSMALL - len);
	len = ETHERSMALL;
	}

    addr  = ((UINT32)AU_CACHE_VIRT_TO_PHYS(pDrvCtrl->pTxMem[index]) | 1);
    AU_TX_LENGTH(index) = len;
    AU_TX_STATUS(index) = 0;
    AU_TX_ADDRESS(index) = addr;
    SYS_WB_FLUSH();

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);

    /* Spin until we think we've sent it.  */
    
    while (!(AU_TX_ADDRESS(index) & (1<<1)));
    AU_TX_ADDRESS(index) = 0;
    AU_TX_STATUS(index) = 0;
    AU_TX_LENGTH(index) = 0;

    SYS_WB_FLUSH();
    
    index = (pDrvCtrl->tmdIndex + 1) & (pDrvCtrl->tringSize - 1);
    pDrvCtrl->tmdIndex = index;
    pDrvCtrl->tmdLastIndex = (pDrvCtrl->tmdLastIndex + 1) &
                              (pDrvCtrl->tringSize - 1);

    DRV_LOG (DRV_DEBUG_POLL_TX, "auPollSend: Poll Tx...done\n", 1, 2, 3, 4, 5, 6);

    return (OK);
    }

/*****************************************************************************
*
* auMCastAddrAdd - add a multicast address for the device
*
* This routine adds a multicast address to whatever the driver
* is already listening for.  It then resets the address filter.
*
* RETURNS: OK
*/

LOCAL STATUS auMCastAddrAdd
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* control structure */
    char * 		pAddress
    )
    {
#ifdef AU_END_MULTICAST
    int 		error;

    if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList,
		pAddress)) == ENETRESET)
	    auConfig (pDrvCtrl);
#endif
    return (OK);
    }

/*****************************************************************************
*
* auMCastAddrDel - delete a multicast address for the device
*
* This routine removes a multicast address from whatever the driver
* is listening for.  It then resets the address filter.
*
* RETURNS: OK.
*/

LOCAL STATUS auMCastAddrDel
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* control structure */
    char * 		pAddress
    )
    {
#if AU_END_MULTICAST
    int 		error;

    if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList,
	     (char *)pAddress)) == ENETRESET)
	    auConfig (pDrvCtrl);
#endif
    return (OK);
    }

/*****************************************************************************
*
* auMCastAddrGet - get the multicast address list for the device
*
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OK/ERROR
*/

LOCAL STATUS auMCastAddrGet
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* control structure */
    MULTI_TABLE * 	pTable
    )
    {
    int 		error;

    error = etherMultiGet (&pDrvCtrl->endObj.multiList, pTable);

    return (error);
    }

/*******************************************************************************
*
* auStop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR
*/

LOCAL STATUS auStop
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    STATUS 		result = OK;

    /* Stop the device. */

    auReset (pDrvCtrl);

    /* disable interrupt */

    SYS_INT_DISABLE (pDrvCtrl);

    /* mark the interface as down */

    END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));

    /* disconnect the interrupt handler */

    SYS_INT_DISCONNECT (pDrvCtrl, auInt, (int)pDrvCtrl, &result);

    if (result == ERROR)
	{
	DRV_LOG (DRV_DEBUG_LOAD, "auStop: Could not disconnect interrupt!\n",
                 1, 2, 3, 4, 5, 6);
	}

    return (result);
    }

/******************************************************************************
*
* auUnload - unload a driver from the system
*
* This function first brings down the device, and then frees any
* stuff that was allocated by the driver in the load function. The controller
* structure should be free by who ever is calling this function.
*
* RETURNS: OK
*/

LOCAL STATUS auUnload
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    END_OBJECT_UNLOAD (&pDrvCtrl->endObj);

    /* Free the shared DMA memory. */

    if (pDrvCtrl->pRxMem)
	{
	cacheDmaFree (pDrvCtrl->pRxMemBase);
	pDrvCtrl->pRxMemBase = NULL;
	}
    
    if (pDrvCtrl->pTxMem)
	{
	cache

⌨️ 快捷键说明

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