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

📄 auend.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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, "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, "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;	}    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);        /* 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 an ioctl request.** RETURNS OK or ERROR value*/LOCAL int auIoctl    (    AU_DRV_CTRL * 	pDrvCtrl, /* device to be initialized */    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--;		/* HELP: WHY ??? */		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 and switching into* 32 bit mode.** RETURNS: OK/ERROR*/LOCAL int auReset    (    AU_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    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 memory pointers */    pDrvCtrl->rmdIndex = 0;    for (i = 0; i < pDrvCtrl->rringSize; ++i)        {	        AU_RX_STATUS(i) = 0;        AU_RX_ADDRESS(i) = 0;	}    /* setup Tx memory pointers */    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();    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 /* device to be initialized */    )    {      DRV_LOG (DRV_DEBUG_LOAD, "auRestartSetup\n", 1, 2, 3, 4, 5, 6);    /* reset the device */    auReset (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);    /* reconfigure the device */    auConfig (pDrvCtrl);    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 /* device to be initialized */    )    {    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 /* device to be initialized */    )    {    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, "Setting promiscuous mode on!\n",                 1, 2, 3, 4, 5, 6);        /* chip will be in promiscuous mode */        pDrvCtrl->flags |= AU_PROMISCUOUS_FLAG;         }    else        {        DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\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);        }    /* 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, "mac   addr %08x %08x\n",	     AU_MAC_ADDRESS_HIGH,	     AU_MAC_ADDRESS_LOW, 0, 0, 0, 0);    DRV_LOG (DRV_DEBUG_LOAD, "multi addr %08x %08x\n",	     AU_MULTICAST_HASH_ADDRESS_HIGH,	     AU_MULTICAST_HASH_ADDRESS_LOW, 0, 0, 0, 0);    /* Configure MII */    /* Setup RxD and TxD pointers */    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();    }/******************************************************************************** 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() routine) and sets the* device's filter correctly.** RETURNS: N/A*/LOCAL void auAddrFilterSet    (    AU_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    )    {    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, /* device to be initialized */    M_BLK_ID 		pMblk    )    {

⌨️ 快捷键说明

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