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

📄 ne2000end.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->ilevel = strtoul (tok, NULL, 16);    /* 8-bit access. */    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->byteAccess = atoi (tok);    /* ethernet address from PROM. */    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->usePromEnetAddr = atoi (tok);    /* memory alignment offset */    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->offset = strtoul (tok, NULL, 16);    return (OK);    }/********************************************************************************* ne2000MemInit - initialize memory for the chip** This routine is highly specific to the device.  ** RETURNS: OK or ERROR.*/LOCAL STATUS ne2000MemInit    (    NE2000END_DEVICE * pDrvCtrl	/* device to be initialized */    )    {    M_CL_CONFIG	eneMclBlkConfig;    CL_DESC	clDesc;                      /* cluster description */    bzero ((char *)&eneMclBlkConfig, sizeof(eneMclBlkConfig));    bzero ((char *)&clDesc, sizeof(clDesc));        clDesc.clNum   = 32;    clDesc.clSize  = NE2000_BUFSIZ;	/* allow for alignment */    clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 8)) + 4);    eneMclBlkConfig.mBlkNum  = 16 * 4;    eneMclBlkConfig.clBlkNum = clDesc.clNum;    /*     * mBlk and cluster configuration memory size initialization     * memory size adjusted to hold the netPool pointer at the head.     */    eneMclBlkConfig.memSize =      (eneMclBlkConfig.mBlkNum * (MSIZE + sizeof (long)))      + (eneMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long)));    eneMclBlkConfig.memArea = (char *) memalign(sizeof (long),						eneMclBlkConfig.memSize);    if (eneMclBlkConfig.memArea == NULL)        return (ERROR);        clDesc.memArea = (char *) malloc (clDesc.memSize);    if (clDesc.memArea == NULL)	return (ERROR);        pDrvCtrl->endObj.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL));    if (pDrvCtrl->endObj.pNetPool == NULL)        return (ERROR);    /* Initialize the net buffer pool with transmit buffers */    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &eneMclBlkConfig,                     &clDesc, 1, NULL) == ERROR)        return (ERROR);    /* Save the cluster pool id */    pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,				      NE2000_BUFSIZ, FALSE);    return (OK);    }/********************************************************************************* ne2000Ioctl - the driver I/O control routine** Process an ioctl request.*/LOCAL int ne2000Ioctl    (    void*	pCookie,	/* device ptr */    int		cmd,    caddr_t	data    )    {    int error = 0;    long value;    NE2000END_DEVICE* pDrvCtrl = (NE2000END_DEVICE *) pCookie;    switch ((UINT) 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 - 1);		END_FLAGS_CLR (&pDrvCtrl->endObj, value);		}	    else		END_FLAGS_SET (&pDrvCtrl->endObj, value);	    ne2000Config (pDrvCtrl, TRUE);            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj);            break;	case EIOCPOLLSTART:	    ne2000PollStart (pDrvCtrl);	    break;	case EIOCPOLLSTOP:	    ne2000PollStop (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);#if 0	    /* XXX */            *(int *)data = END_MIN_FBUF;#endif            break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* ne2000Start - 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 ne2000Start    (    void*	pCookie    )    {    STATUS result;    NE2000END_DEVICE* pDrvCtrl = (NE2000END_DEVICE *) pCookie;    ENDLOGMSG (("ne2000Start\n", 0, 0, 0, 0, 0, 0));    SYS_INT_CONNECT (pDrvCtrl, ne2000Int, (int)pDrvCtrl, &result);    if (result == ERROR)	return (ERROR);    /* Enable interrupts */    pDrvCtrl->imask = (pDrvCtrl->flags & END_POLLING) ? 0 : NE2000_ALL_INTS;    SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask);    SYS_INT_ENABLE (pDrvCtrl);    return (OK);    }/******************************************************************************** ne2000Config - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** NOMANUAL*/LOCAL void ne2000Config    (    NE2000END_DEVICE *pDrvCtrl,    BOOL	      intEnable		/* TRUE to enable interrupts */    )    {    UCHAR	rxFilter;		/* receiver configuration */    ENDLOGMSG (("ne2000Config: enter (intEnable=%d)\n",		intEnable, 0, 0, 0, 0, 0));    /* Disable device interrupts */    pDrvCtrl->imask = 0;    SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask);    /* Set up address filter for multicasting. */	    if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0)	ne2000AddrFilterSet (pDrvCtrl);    /* TODO - shutdown device completely */    /* TODO - reset all device counters/pointers, etc. */    /* preserve END_POLLING and OVERWRITE flags */    pDrvCtrl->flags &= (END_POLLING | END_OVERWRITE | END_OVERWRITE2);    /* TODO - initialize the hardware according to flags */    /* 1. program Command Register for page 0 and for no DMA */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP);    /* 2. initialize Data Configuration Register:     *    16-bit bus, burst mode, 8-deep FIFO.     * or     *    8-bit bus, burst mode, 8-deep FIFO.     */    if (pDrvCtrl->byteAccess)	SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | 0x08);    else	SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | 0x08);    SYS_ENET_ADDR_GET (pDrvCtrl);    /* 3. clear Remote Byte Count Register */    SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, 0x00);    SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, 0x00);    /* 4. initialize Receive Configuration Register */    /* Always accept broadcast packets. */    rxFilter = RCON_BROAD;    /* Set multicast mode if it's asked for. */    if (END_MULTI_LST_CNT(&pDrvCtrl->endObj) > 0)	rxFilter |= RCON_GROUP;    /* Set promiscuous mode if it's asked for. */    if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_PROMISC)	rxFilter |= RCON_PROM;    ENDLOGMSG (("\tPromiscuous mode %s\n",	    (rxFilter & RCON_PROM) ? "on" : "off",	    0, 0, 0, 0, 0));    SYS_OUT_CHAR (pDrvCtrl, ENE_RCON, rxFilter);    /* 5. place the ENE in LOOPBACK mode 1 or 2 */    SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_LB1);    /* 6. initialize Receive Buffer Ring */    SYS_OUT_CHAR (pDrvCtrl, ENE_RSTART, NE2000_PSTART);    SYS_OUT_CHAR (pDrvCtrl, ENE_RSTOP, NE2000_PSTOP);    SYS_OUT_CHAR (pDrvCtrl, ENE_BOUND, NE2000_PSTART);    /* 7. clear Interrupt Status Register */    SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, (char)0xff);    /* 8. initialize Interrupt Mask Register */    pDrvCtrl->imask = 0;    SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask);    /* 9. program Command Register for page 1 */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE1 | CMD_STOP);    /* i) initialize physical address registers */    SYS_OUT_CHAR (pDrvCtrl, ENE_STA0, pDrvCtrl->enetAddr[0]);    SYS_OUT_CHAR (pDrvCtrl, ENE_STA1, pDrvCtrl->enetAddr[1]);    SYS_OUT_CHAR (pDrvCtrl, ENE_STA2, pDrvCtrl->enetAddr[2]);    SYS_OUT_CHAR (pDrvCtrl, ENE_STA3, pDrvCtrl->enetAddr[3]);    SYS_OUT_CHAR (pDrvCtrl, ENE_STA4, pDrvCtrl->enetAddr[4]);    SYS_OUT_CHAR (pDrvCtrl, ENE_STA5, pDrvCtrl->enetAddr[5]);    ENDLOGMSG (("enet addr %02x:%02x:%02x:%02x:%02x:%02x\n",		pDrvCtrl->enetAddr[0] & 0xff,		pDrvCtrl->enetAddr[1] & 0xff,		pDrvCtrl->enetAddr[2] & 0xff,		pDrvCtrl->enetAddr[3] & 0xff,		pDrvCtrl->enetAddr[4] & 0xff,		pDrvCtrl->enetAddr[5] & 0xff));    /* ii) initialize multicast address registers */    ne2000AddrFilterSet (pDrvCtrl);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR0, pDrvCtrl->mcastFilter[0]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR1, pDrvCtrl->mcastFilter[1]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR2, pDrvCtrl->mcastFilter[2]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR3, pDrvCtrl->mcastFilter[3]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR4, pDrvCtrl->mcastFilter[4]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR5, pDrvCtrl->mcastFilter[5]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR6, pDrvCtrl->mcastFilter[6]);    SYS_OUT_CHAR (pDrvCtrl, ENE_MAR7, pDrvCtrl->mcastFilter[7]);#ifdef DEBUG    {    static char buf[256];    sprintf(buf, "enet mcast %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",	    pDrvCtrl->mcastFilter[0] & 0xff,		    pDrvCtrl->mcastFilter[1] & 0xff,		    pDrvCtrl->mcastFilter[2] & 0xff,		    pDrvCtrl->mcastFilter[3] & 0xff,		    pDrvCtrl->mcastFilter[4] & 0xff,		    pDrvCtrl->mcastFilter[5] & 0xff,	    pDrvCtrl->mcastFilter[6] & 0xff,	    pDrvCtrl->mcastFilter[7] & 0xff);    ENDLOGMSG ((buf));    }#endif    /* iii) initialize current page pointer */    SYS_OUT_CHAR (pDrvCtrl, ENE_CURR, NE2000_PSTART + 1);    pDrvCtrl->nextPacket = NE2000_PSTART + 1;    /* set memory parameters */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE2 | CMD_STOP);    SYS_OUT_CHAR (pDrvCtrl, ENE_ENH, 0x00);       /* 0 wait states */    SYS_OUT_CHAR (pDrvCtrl, ENE_BLOCK, 0x00);     /* 0x00xxxx */    /* 10. put the ENE in START mode */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START);    /* 11. initialize Transmit Configuration Register */    SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, 0x00);    ENDLOGMSG (("ne2000Config: done\n", 0, 0, 0, 0, 0, 0));    pDrvCtrl->imask = ((pDrvCtrl->flags & END_POLLING) ? 0 : NE2000_ALL_INTS);    /* Only actually enable interrupts if not polling */    if (intEnable)	SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask);    }/********************************************************************************* ne2000OverwriteRecover - recover from receive buffer ring overflow** This procedure is mandated by National Semiconductor as the only safe* way to recover from an Overwrite Warning Error.  The first two steps* of their procedure, reading the Command Register and stopping the NIC,* were accomplished in the interrupt handler.  The rest occurs here.** This routine is scheduled to run in the net task since it must delay* to allow the STOP command to take effect.*/LOCAL void ne2000OverwriteRecover    (    NE2000END_DEVICE  *pDrvCtrl,    UCHAR cmdStatus    )    {    UCHAR stat;    BOOL  reSend;    ENDLOGMSG (("ne2000OverwriteRecover: enter (flags=%x, imask=%x)\n",		pDrvCtrl->flags,pDrvCtrl->imask,0,0,0,0));    /* We shouldn't get here without the OVERWRITE flags set */    if (!(pDrvCtrl->flags & END_OVERWRITE2))	{	ENDLOGMSG (("ne2000OverwriteRecover: bad flags\n",		    0,0,0,0,0,0));#ifdef DEBUG	SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, 0);	taskSuspend (0);#else	return;#endif	}    /* 1. read the TXP bit in the command register (already in cmdStatus) */    /* 2. issue the STOP command (done in the interrupt handler) */    /* 3. delay at least 1.6 milliseconds (1/625 second) */    taskDelay ((sysClkRateGet() + 624)/ 625);    /* we are now supposedly sure the NIC is stopped */    /* 4. clear Remote Byte Count Register */    SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, 0x00);    SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, 0x00);    /* 5. read the stored value of the TXP bit (in cmdStatus) */    if ((cmdStatus & CMD_TXP) == 0)        reSend = FALSE;    else        {	SYS_IN_CHAR (pDrvCtrl, ENE_INTSTAT, &stat);        if ((stat & (ISTAT_PTX | ISTAT_TXE)) == 0)	    {	    /* transmit was in progress but probably deferring */            reSend = TRUE;	    }        else	    {            /* transmit was completed (probably), don't repeat it */            reSend = FALSE;	    }        }    /* 6. place the NIC in loopback mode */    SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, TCON_LB1);    /* 7. issue the START command to the NIC */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_START);    /* 8. remove one or more packets from the receive buffer ring */    /* clear overwrite flag */    pDrvCtrl->flags &= ~END_OVERWRITE;    pDrvCtrl->current = ne2000GetCurr (pDrvCtrl);    ne2000HandleRcvInt (pDrvCtrl);    /* 9. reset the overwrite warning bit in the ISR */    /* reset all active interrupt conditions */    SYS_IN_CHAR (pDrvCtrl, ENE_INTSTAT, &stat);    SYS_OUT_CHAR (pDrvCtrl, ENE_INTSTAT, stat);    /* 10. take the NIC out of loopback */    SYS_OUT_CHAR (pDrvCtrl, ENE_TCON, 0x00);    /* 10a. re-enable all device interrupts */    pDrvCtrl->imask = NE2000_ALL_INTS;    SYS_OUT_CHAR (pDrvCtrl, ENE_INTMASK, pDrvCtrl->imask);    /* 11. if need to resend, do so, otherwise if anything queued, send that */    pDrvCtrl->flags &= ~END_OVERWRITE2;    if (reSend)        SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_TXP);    else	muxTxRestart (&pDrvCtrl->endObj);    ENDLOGMSG (("ne2000OverwriteRecover: done (flags=%x, imask=%x)\n",		pDrvCtrl->flags,pDrvCtrl->imask,0,0,0,0));    }/********************************************************************************* ne2000Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void ne2000Int    (    NE2000END_DEVICE  *pDrvCtrl    )    {    UCHAR val;    UCHAR intStat;    UCHAR txStat;    UCHAR rxStat;    pDrvCtrl->stats.interrupts++;    /* Read status and Acknowlegde interrupt */

⌨️ 快捷键说明

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