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

📄 ne2000end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    NE2000END_DEVICE 	*pDrvCtrl;#ifdef DEBUG    printf ("ne2000EndLoad(%s)\n", initString);    printf ("\tinitString '%s'\n", initString ? initString : "");    printf ("\tpBSP       '%s'\n", pBSP ? pBSP : "");#endif    if (initString == NULL)        return (NULL);        if (initString[0] == '\0')        {        bcopy((char *)NE2000_DEV_NAME, initString, NE2000_DEV_NAME_LEN);        return (NULL);        }    /* allocate the device structure */    pDrvCtrl = (NE2000END_DEVICE *) calloc (sizeof(NE2000END_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (ne2000Parse (pDrvCtrl, initString) == ERROR)	goto errorExit;    /* stop device */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP);    SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 | 0x08);    /*      * Ask the BSP to provide the ethernet address.      */    SYS_ENET_ADDR_GET (pDrvCtrl);    /* initialize the END parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, NE2000_DEV_NAME,		      pDrvCtrl->unit, &ne2000FuncTable,		      "ne2000 Enhanced Network Driver") == ERROR)	goto errorExit;    /* initialize the MIB2 parts of the structure */    if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,		      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,                      END_SPEED) == ERROR)	goto errorExit;    /* Perform memory allocation/distribution */    if (ne2000MemInit (pDrvCtrl) == ERROR)	goto errorExit;    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->endObj,		    IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);    return (&pDrvCtrl->endObj);errorExit:    if (pDrvCtrl != NULL)	free ((char *)pDrvCtrl);    return (NULL);    }/******************************************************************************** ne2000Parse - parse the init string** Parse the input string.  Fill in values in the driver control structure.** The initialization string format is:* .CS*   "unit:adrs:vecnum:intLvl:byteAccess:usePromEnetAddr:offset"* .CE** .IP <unit>* Device unit number, a small integer.* .IP <adrs>* Base address* .IP <vecNum>* Interrupt vector number (used with sysIntConnect)* .IP <intLvl>* Interrupt level (used with sysLanIntEnable)* .IP <byteAccess>* Use 8-bit access mode.* .IP <usePromEnetAddr>* get ethernet address from PROM.* .IP <offset>* offset for memory alignment* .LP** RETURNS: OK or ERROR for invalid arguments.*/STATUS ne2000Parse    (    NE2000END_DEVICE * pDrvCtrl,    char * initString    )    {    char*	tok;    char*	holder = NULL;        /* Parse the initString */    /* Unit number. */    tok = strtok_r (initString, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->unit = atoi (tok);    /* Base address. */    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->base = strtoul (tok, NULL, 16);    /* Interrupt vector. */    tok = strtok_r (NULL, ":", &holder);    if (tok == NULL)	return (ERROR);    pDrvCtrl->ivec = strtoul (tok, NULL, 16);    /* Interrupt level. */    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;		value--;		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);    /* mark the interface as up (SPR #32034) */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));    /* 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 */#ifdef DEBUG     static buf [256];#endif    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;	}    ENDLOGMSG (("\tMulticast mode %s\n",	    (rxFilter & RCON_GROUP) ? "on" : "off",	    0, 0, 0, 0, 0));    /* 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));    ENDLOGMSG (("\tsetting rxFilter = 0x%x\n", rxFilter,2,3,4,5,6));    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 */

⌨️ 快捷键说明

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