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

📄 nicevbend.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "ln") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ* nicEvbEndLoad    (    char* initString		/* string to be parse by the driver */    )    {    NICEVB_END_DEVICE	*pDrvCtrl;    DRV_LOG (DRV_DEBUG_LOAD, "Loading nic...\n", 1, 2, 3, 4, 5, 6);    if (initString == NULL)        return (NULL);        if (initString[0] == NULL)        {        bcopy((char *)NIC_EVB_DEV_NAME, initString, NIC_EVB_DEV_NAME_LEN);        return (0);        }        /* allocate the device structure */    pDrvCtrl = (NICEVB_END_DEVICE *)calloc (sizeof (NICEVB_END_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* init device object */    pDrvCtrl->pRxCluster = NULL;    pDrvCtrl->flags = 0x00;            /* parse the init string, filling in the device structure */    if (nicEvbInitParse (pDrvCtrl, initString) == ERROR)	goto errorExit;        /* Have the BSP hand us our address. */    SYS_ENET_ADDR_GET(pDrvCtrl,(char*)&(pDrvCtrl->enetAddr));    /* initialize the END and MIB2 parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, NIC_EVB_DEV_NAME,		    pDrvCtrl->unit, &nicEvbFuncTable,                      "ST-NIC Enhanced Network Driver") == ERROR     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], NIC_EVB_EADR_LEN, ETHERMTU,                      NIC_EVB_SPEED)		    == ERROR)	goto errorExit;    /* Perform memory allocation */    if (nicEvbInitMem (pDrvCtrl) == ERROR)	goto errorExit;    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->end,                   IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);        DRV_LOG (DRV_DEBUG_LOAD, "Done loading nicEvb...\n", 1, 2, 3, 4, 5, 6);    return (&pDrvCtrl->end);    errorExit:        {        nicEvbUnload (pDrvCtrl);        return NULL;        }    }/********************************************************************************* nicEvbInitParse - parse the initialization string** Parse the input string.  Fill in values in the driver control structure.* The initialization string format is:* <unit>:<base_adrs>:<vecnum>:<intLvl>** .IP <unit>* Device unit number, a small integer.* .IP <base_adrs>* Base address for NIC device* .IP <vecNum>* Interrupt vector number (used with sysIntConnect() ).* .IP <intLvl>* Interrupt level.** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS nicEvbInitParse    (    NICEVB_END_DEVICE * pDrvCtrl,    char * initString    )    {    char *	tok;    char *	pHolder = NULL;    long	address;        /* Parse the initString */    /* Unit number. */    tok = strtok_r (initString, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->unit = atoi (tok);    /* NIC address. */        tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    address = strtoul (tok, NULL, 16);    pDrvCtrl->pNic = (NIC_DEVICE* )address;    /* Interrupt vector. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->ivec = atoi (tok);    /* Interrupt level. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->ilevel = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "Processed all arugments\n", 1, 2, 3, 4, 5, 6);    DRV_LOG (DRV_DEBUG_LOAD, "Address %p Level %u ivec %d\n",               pDrvCtrl->pNic, pDrvCtrl->ilevel, pDrvCtrl->ivec, 4, 5, 6);        return OK;    }/********************************************************************************* nicEvbInitMem - initialize memory for Lance chip** Using data in the control structure, setup and initialize the memory* areas needed.  If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/LOCAL STATUS nicEvbInitMem    (    NICEVB_END_DEVICE * pDrvCtrl	/* device to be initialized */    )    {    M_CL_CONFIG		mclBlkConfig;    CL_DESC		clDesc;		/* cluster description */    pDrvCtrl->rringSize = NIC_RBR_LEN;	/* size of the whole ring */    pDrvCtrl->rringLen = pDrvCtrl->rringSize * NIC_BUF_SZ; /* rec ring len */        pDrvCtrl->rmdIndex = 0;		/* init recv buf index */    pDrvCtrl->nextPkt = CURR;		/* reset to initial value */    /* for remote DMA access */        pDrvCtrl->dmaSem = semMCreate (SEM_Q_PRIORITY);            /*     * Allocate receive buffers from our own private pool.     */    /* Initialize net buffer pool for tx/rx buffers */    bzero ((char *)&mclBlkConfig, sizeof(mclBlkConfig));    bzero ((char *)&clDesc, sizeof(clDesc));        if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    mclBlkConfig.mBlkNum  = pDrvCtrl->rringSize * 8;    clDesc.clNum	  = pDrvCtrl->rringSize * 8;    mclBlkConfig.clBlkNum = clDesc.clNum;    mclBlkConfig.memSize = (mclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) +                          (mclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));    if ((mclBlkConfig.memArea = (char *) memalign (sizeof(long),                                                   mclBlkConfig.memSize)) == NULL)        return (ERROR);        clDesc.clSize  = NIC_BUF_SZ;    clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 4)) + 4);   clDesc.memArea = memalign (sizeof(long), clDesc.memSize);   pDrvCtrl->pRxCluster = (NIC_CLUSTER)clDesc.memArea;      if (clDesc.memArea == NULL)        {        DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6);        return (ERROR);        }    /* Initialize the net buffer pool with transmit buffers */        if (netPoolInit(pDrvCtrl->end.pNetPool, &mclBlkConfig,                    &clDesc, 1, NULL) == ERROR)                {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }    #ifdef DRV_DEBUG    nicNetPool = *pDrvCtrl->end.pNetPool;#endif    /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet(pDrvCtrl->end.pNetPool, NIC_BUF_SZ, FALSE);        /* Setup the receive ring */    return OK;    }/********************************************************************************* nicEvbStart - 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 nicEvbStart    (    NICEVB_END_DEVICE *pDrvCtrl    )    {    STATUS result;    pDrvCtrl->txCleaning = FALSE;    pDrvCtrl->txBlocked = FALSE;        SYS_INT_CONNECT (pDrvCtrl, nicEvbInt, (int)pDrvCtrl, &result);        if (result == ERROR)	return ERROR;        DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    /* reset the device */    nicEvbReset (pDrvCtrl);    nicEvbConfig (pDrvCtrl);		/* device config */    /* mark the interface -- up */    END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));        SYS_INT_ENABLE (pDrvCtrl->ivec);        DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* nicEvbConfig - configure the NIC chip and program address** This routine follows the algorythm in the ST-NIC manual for enabling* a NIC device on an active network.  Essentially, this routine initializes* the NIC device.** RETURNS: N/A.*/LOCAL void nicEvbConfig    (    NICEVB_END_DEVICE * pDrvCtrl	/* device to be configured */        )    {    NIC_DEVICE* pNic = pDrvCtrl->pNic;    UCHAR*	pEnetAddr = pDrvCtrl->enetAddr;        nicEvbWriteCr (pNic, RPAGE0 | STP | ABORT);    nicEvbResetDelay ();    nicEvbWriteReg (pNic, &pNic->Dcr, NOTLS | FIFO8, RPAGE0);    /* clear remote DMA byte count registers */    nicEvbWriteReg (pNic, &pNic->Rbcr0, 0, RPAGE0);                 nicEvbWriteReg (pNic, &pNic->Rbcr1, 0, RPAGE0);    /* accept broadcast and multicast, but not runt */    /* MULTI */    nicEvbWriteReg (pNic, &pNic->Rcr, AB, RPAGE0);        nicEvbWriteReg (pNic, &pNic->Rcr, (AB | AM), RPAGE0);    nicEvbWriteReg (pNic, &pNic->Tcr, MODE1, RPAGE0);	/* int loopback mode */    nicEvbWriteReg (pNic, &pNic->Pstart, PSTART, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Pstop, PSTOP, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Bnry, BNRY, RPAGE0);    nicEvbWriteReg (pNic, &pNic->Isr, 0xff, RPAGE0);	/* clr pending ints */    nicEvbWriteReg (pNic, &pNic->Imr, PRXE | OVWE, RPAGE0); /* enable int */        /* set up page 1 registers */    nicEvbWriteReg (pNic, &pNic->Par0, pEnetAddr [0], RPAGE1);    nicEvbWriteReg (pNic, &pNic->Par1, pEnetAddr [1], RPAGE1);    nicEvbWriteReg (pNic, &pNic->Par2, pEnetAddr [2], RPAGE1);    nicEvbWriteReg (pNic, &pNic->Par3, pEnetAddr [3], RPAGE1);    nicEvbWriteReg (pNic, &pNic->Par4, pEnetAddr [4], RPAGE1);    nicEvbWriteReg (pNic, &pNic->Par5, pEnetAddr [5], RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar0, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar1, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar2, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar3, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar4, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar5, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar6, 0x00, RPAGE1);    nicEvbWriteReg (pNic, &pNic->nic_pg1.mar7, 0x00, RPAGE1);        nicEvbWriteReg (pNic, &pNic->Curr, CURR, RPAGE1);    nicEvbWriteCr (pNic, RPAGE0 | ABORT | STA);		/* back to page 0 */    nicEvbWriteReg (pNic, &pNic->Tcr, MODE0, RPAGE0);	/* Tx normal mode */    }/********************************************************************************* nicEvbResetDelay - performs the delay required before resetting the chip ** This routine performs a 1.6 ms delay for PowerPC architecture if * using the internal PPC time base (the number of time base increment to* count for 1.6 msec is defined by the value nicRestartDelay which must * be set in the BSP), or waits for one system clock tick otherwise.** RETURNS: N/A.*/ LOCAL void nicEvbResetDelay (void)    {#ifdef  NIC_USE_PPCTIMEBASE    UINT32 tbu1, tbu2;    UINT32 tbl1, tbl2;#endif#ifdef  NIC_USE_PPCTIMEBASE    vxTimeBaseGet (&tbu1, &tbl1);    while (1)  {        vxTimeBaseGet (&tbu2, &tbl2);        if ((tbu2-tbu1) != 0)            vxTimeBaseGet (&tbu1, &tbl1);        else	    if ((tbl2 - tbl1) > nicEvbRestartDelay)            	break;        }#else    taskDelay (1);                      /* wait at least 1.6 mSec */#endif    }/********************************************************************************* nicEvbWriteCr - write to the NIC command register** RETURNS: N/A.*/LOCAL void nicEvbWriteCr    (    NIC_DEVICE		*pNic,    UINT8		value    )    {    int			level = intLock ();    do {        pNic->Cr = value;        } while	(!((*(volatile UINT8 *)NIC_DMA) & ACC_MASK));    intUnlock (level);    }/********************************************************************************* nicEvbWriteReg - write to a NIC register** RETURNS: N/A.*/LOCAL void nicEvbWriteReg     (    NIC_DEVICE *	pNic,    volatile UINT8 *	pReg,    UINT8		value,    UINT8		page    )    {    volatile UINT8 *	nicDma = (volatile UINT8 *) NIC_DMA;    UINT8		cr;    int			level = intLock ();    do {	cr = pNic->Cr;	} while (!((*nicDma) & ACC_MASK));    if ((cr & PBMASK) != page)	do {	    pNic->Cr = (cr & 0x3f) | page;	    } while (!((*nicDma) & ACC_MASK));    do {	*pReg = value;	} while (!((*nicDma) & ACC_MASK));    intUnlock (level);    }/********************************************************************************* nicReadReg - read from a NIC register** RETURNS: the register value.*/

⌨️ 快捷键说明

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