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

📄 ne2000end.c

📁 是vxworks下的网卡芯片RTL8019驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    void* pBSP			/* for BSP group */    )    {    NE2000END_DEVICE 	*pDrvCtrl;    int 		level;    UCHAR		regVal;#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;    /*     *  If the optional load string parameters configRegA or configRegB     *  are passed in with the load string then load the passed in value     *  into the appropriate register.       */    if (pDrvCtrl->configRegA != 0)        {        /* This must be an atomic transaction, so it must be intLocked */        level = intLock ();        SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_PAGE0);        SYS_IN_CHAR (pDrvCtrl, ENE_RBCR0, &regVal);        SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR0, pDrvCtrl->configRegA);        intUnlock (level);        }                     if (pDrvCtrl->configRegB != 0)        {        /* This must be an atomic transaction, so it must be intLocked */        level = intLock ();        SYS_IN_CHAR (pDrvCtrl, ENE_RBCR1, &regVal);        SYS_OUT_CHAR (pDrvCtrl, ENE_RBCR1, pDrvCtrl->configRegB);        intUnlock (level);        }             /* stop device */    SYS_OUT_CHAR (pDrvCtrl, ENE_CMD, CMD_NODMA | CMD_PAGE0 | CMD_STOP);    /*      * HELP:     * In the generic driver it always uses BUS16 here. I agree that this     * code looks better, but if the device is inactive why are we doing this     * here at all.  Why not call ne2000Config from ne2000Start and let it set     * up the chip when we actually start it ???     */    if (pDrvCtrl->byteAccess)	SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS_8			| DCON_LOOPBK_OFF);    else	SYS_OUT_CHAR (pDrvCtrl, ENE_DCON, DCON_BSIZE1 | DCON_BUS16 			| DCON_LOOPBK_OFF);    /* 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* Set Configuration Register A. Defaults to reset value. * .IP <configRegA>* Set Configuration Register B. Defaults to reset value. * .IP <configRegB>* .LP** RETURNS: OK or ERROR for invalid arguments.*/LOCAL 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);    /* Set configuration register A - optional parameter */       pDrvCtrl->configRegA = 0;    tok = strtok_r (NULL, ":", &holder);    if (tok != NULL)        pDrvCtrl->configRegA = strtoul (tok, NULL, 16);    /* Set configuration register B - optional parameter */       pDrvCtrl->configRegB = 0;    tok = strtok_r (NULL, ":", &holder);    if (tok != NULL)        pDrvCtrl->configRegB = 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);    /* preserve END_POLLING and OVERWRITE flags */    pDrvCtrl->flags &= (END_POLLING | END_OVERWRITE | END_OVERWRITE2);    /* 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.     */

⌨️ 快捷键说明

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