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

📄 auend.c

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

    /* restore the receiver buffer */

    DRV_LOG (DRV_DEBUG_RX, "auRecv: data trans to clusters OK, 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);

    /* Call the upper layer's receive routine. */

    END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);

    return (OK);

cleanRXD:

    /* Restore the receiver buffer */

    DRV_LOG (DRV_DEBUG_RX, "auRecv: 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);

    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,  /* driver control structure */
    M_BLK_ID 		pMblk      /* data to send */
    )
    {
    char *       	pBuf;
    int			index;
    int         	len = 0;
    UINT32 addr;

    DRV_LOG (DRV_DEBUG_TX, "auSend...\n", 1, 2, 3, 4, 5, 6);

    /* check device mode */

    if (pDrvCtrl->flags & AU_POLLING)
        {
        netMblkClChainFree (pMblk);
        errno = EINVAL;
        return (ERROR);
        }

    /*
     * Obtain exclusive access to transmitter.  This is necessary because
     * we might have more than one stack transmitting at once.
     */

    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);

    /* Advance our management index (first) */

    index = pDrvCtrl->tmdIndex;

    if (AU_TX_ADDRESS(index) & 0x03)
	{
        /* Are we still on the first chunk? */

        DRV_LOG (DRV_DEBUG_TX, "auSend: Out of TMDs! addr=%08x astat=%08x stat=%08x\n",
		 AU_TX_ADDRESS(index) & ~0x1f,
		 AU_TX_ADDRESS(index) & 0x1f,
		 AU_TX_STATUS(index), 4, 5, 6);
#ifdef DRV_DEBUG
	auDump (pDrvCtrl->unit);
#endif
        pDrvCtrl->txBlocked = TRUE;
        END_TX_SEM_GIVE (&pDrvCtrl->endObj);
        return (END_ERR_BLOCK);
        }

    pBuf = pDrvCtrl->pTxMem[index];
    DRV_LOG (DRV_DEBUG_TX, "auSend: pBuf = 0x%X\n", (int)pBuf, 2, 3, 4, 5, 6);
    if (pBuf == NULL)
        {
        pDrvCtrl->txBlocked = TRUE;
        END_TX_SEM_GIVE (&pDrvCtrl->endObj);
        return (END_ERR_BLOCK);
        }

    /* copy and release the packet */
    
    len = netMblkToBufCopy (pMblk, pBuf, NULL);
    netMblkClChainFree (pMblk);

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

    /* setting DMA regs to prepare transmit */
    
    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();

    DRV_LOG (DRV_DEBUG_TX, "auSend: index %d len %d\n",
             index, len, 3, 4, 5, 6);
    DRV_LOG (DRV_DEBUG_TX, "auSend: 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_TX, "auSend 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, "auSend: type(len)=%02x %02x\n",
	     pBuf[12]&0xff, pBuf[13]&0xff, 0,0,0,0);   
 
    /* Advance our management index */

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

    /* Bump the statistic counter. */

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

    END_TX_SEM_GIVE (&pDrvCtrl->endObj);

    DRV_LOG (DRV_DEBUG_TX, "auSend...Done\n", 1, 2, 3, 4, 5, 6);

    return (OK);
    }

/*******************************************************************************
*
* auIoctl - the driver I/O control routine
*
* Process a ioctl request.
*
* RETURNS OK or ERROR value
*/

LOCAL int auIoctl
    (
    AU_DRV_CTRL * 	pDrvCtrl, /* driver control structure */
    int 		cmd,	  /* ioctl command to execute */
    caddr_t 		data	  /* data to get or set       */
    )
    {
    long 		value;
    int 		error = 0;

    switch (cmd)
        {
        case EIOCSADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj),
		   END_HADDR_LEN (&pDrvCtrl->endObj));
            break;

        case EIOCGADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)END_HADDR (&pDrvCtrl->endObj), (char *)data,
		    END_HADDR_LEN (&pDrvCtrl->endObj));
            break;

        case EIOCSFLAGS:
	    value = (long)data;
            
	    if (value < 0)
		{
		value = -value;
		value--;		/* complement code? */
		END_FLAGS_CLR (&pDrvCtrl->endObj, value);
		}
	    else
		{
		END_FLAGS_SET (&pDrvCtrl->endObj, value);
		}
	    auConfig (pDrvCtrl);
            break;

        case EIOCGFLAGS:
	    *(int *)data = END_FLAGS_GET (&pDrvCtrl->endObj);
            break;

        case EIOCMULTIADD:
            error = auMCastAddrAdd (pDrvCtrl, (char *) data);
            break;

        case EIOCMULTIDEL:
            error = auMCastAddrDel (pDrvCtrl, (char *) data);
            break;

        case EIOCMULTIGET:
            error = auMCastAddrGet (pDrvCtrl, (MULTI_TABLE *) data);
            break;

	case EIOCPOLLSTART:
	    error = auPollStart (pDrvCtrl);
	    break;

	case EIOCPOLLSTOP:
	    error = auPollStop (pDrvCtrl);
	    break;

        case EIOCGMIB2:
            if (data == NULL)
                return (EINVAL);
            bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data,
                  sizeof(pDrvCtrl->endObj.mib2Tbl));
            break;

        case EIOCGFBUF:
            if (data == NULL)
                return (EINVAL);
            *(int *)data = AU_MIN_FBUF;
            break;

        case EIOCGMWIDTH:
            if (data == NULL)
                return (EINVAL);
            *(int *)data = 4;
            break;

        case EIOCGHDRLEN:
            if (data == NULL)
                return (EINVAL);
            *(int *)data = 14;
            break;

        default:
            error = EINVAL;
        }
    return (error);
    }

/*******************************************************************************
*
* auReset - hardware reset of chip (stop it)
*
* This routine is responsible for resetting the device.
*
* RETURNS: OK/ERROR
*/

LOCAL int auReset
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    int		i;

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

    /* Reset MAC & DMA units */

    AU_MAC_ENABLE = 0;

    /* setup Rx DMA registers */

    pDrvCtrl->rmdIndex = 0;
    for (i = 0; i < pDrvCtrl->rringSize; ++i)
        {	
        AU_RX_STATUS(i) = 0;
        AU_RX_ADDRESS(i) = 0;
	}

    /* setup Tx DMA registers */

    pDrvCtrl->tmdIndex = 0;
    pDrvCtrl->tmdLastIndex = 0;
    for (i = 0; i < pDrvCtrl->tringSize; ++i)
	{
	AU_TX_STATUS(i) = 0;
	AU_TX_LENGTH(i) = 0;
	AU_TX_ADDRESS(i) = 0;
	}

    SYS_WB_FLUSH();

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

    return (OK);
    }

/*******************************************************************************
*
* auRestartSetup - setup memory descriptors and turn on chip
*
* This routine initializes all the shared memory structures and turns on
* the chip.
*
* RETURNS OK/ERROR
*/

LOCAL STATUS auRestartSetup
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {  
    DRV_LOG (DRV_DEBUG_LOAD, "auRestartSetup...\n", 1, 2, 3, 4, 5, 6);

    /* reset the device */

    auReset (pDrvCtrl);

    DRV_LOG (DRV_DEBUG_LOAD, "auRestartSetup: MAC DMA reset complete\n", 1, 2, 3, 4, 5, 6);

    /* reconfigure the device */

    auConfig (pDrvCtrl);

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

    return (OK);
    }

/*******************************************************************************
*
* auRestart - restart the device after a fatal error
*
* This routine takes care of all the messy details of a restart.  The device
* is reset and re-initialized.  The driver state is re-synchronized.
*
* RETURNS: N/A
*/

LOCAL void auRestart
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    auRestartSetup (pDrvCtrl);

    /* set the flags to indicate readiness */

    END_OBJ_READY (&pDrvCtrl->endObj,
                    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
                    | IFF_MULTICAST);
    }

/******************************************************************************
*
* auConfig - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A
*/

LOCAL void auConfig
    (
    AU_DRV_CTRL * 	pDrvCtrl /* control structure */
    )
    {
    UCHAR *		enetAddr;
    int i;

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

    /* Set promiscuous mode if it's asked for. */

    if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_PROMISC)
        {
        DRV_LOG (DRV_DEBUG_LOAD, "auConfig: promiscuous flag set!\n",
                 1, 2, 3, 4, 5, 6);

        /* chip will be in promiscuous mode */

        pDrvCtrl->flags |= AU_PROMISCUOUS_FLAG; 
        }
    else
        {
        DRV_LOG (DRV_DEBUG_LOAD, "auConfig: promiscuous flag un-set!\n",
                 1, 2, 3, 4, 5, 6);

        pDrvCtrl->flags &= ~AU_PROMISCUOUS_FLAG; 
        }

    /* Set up address filter for multicasting. */

    if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0)
        {
        auAddrFilterSet (pDrvCtrl);
        }

⌨️ 快捷键说明

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