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

📄 sn83932end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (initString[0] == 0)        {        bcopy ((char *)SN_DEV_NAME, initString, SN_DEV_NAME_LEN);        return (0);        }    if (snInitParse (&initParm, initString) == ERROR)	return NULL;     /* Sanity check the unit number */    if (initParm.unit < 0 || initParm.unit >= MAX_UNITS)        return NULL;    /* allocate the device structure */    pDrvCtrl = (DRV_CTRL *)calloc (sizeof(DRV_CTRL), 1);    if (pDrvCtrl == NULL)        return (NULL);    if (pDrvCtrl->endData.attached == TRUE)        return (&pDrvCtrl->endData);    /* save the inputted parameters */    pDrvCtrl->unit = initParm.unit;    pDrvCtrl->ivec = initParm.ivec;    pDrvCtrl->pDev = (SONIC *) initParm.devaddr;    /* Initialize the default interrupt mask configuration in control block */    pDrvCtrl->imr = SN_IMR_INIT;    /* EndData Initialization */    if (END_OBJ_INIT (&pDrvCtrl->endData, (DEV_OBJ *)pDrvCtrl, "sn",                      pDrvCtrl->unit,	&snFuncTable,                      "Sonic 83932 Enhanced Network Driver") == ERROR)		               return (NULL);    /* get an Ethernet addr from BSP and intialize the MIB2 */    if (sysEnetAddrGet (initParm.unit, pDrvCtrl->enetAddr) == ERROR)        return (NULL);    if (END_MIB_INIT (&pDrvCtrl->endData, M2_ifType_ethernet_csmacd,		      (UCHAR *)pDrvCtrl->enetAddr,6,ETHERMTU, SN_SPEED) 		      == ERROR)	return (NULL);    /* Allocate, initialize and set up shared memory region */    if (snInitMem (pDrvCtrl) == ERROR)	return (NULL);    /***** Perform device initialization *****/    snChipReset (pDrvCtrl);                 /* reset device */    sysEnetInit (pDrvCtrl->unit);           /* do any board specific set up */    sysEnetIntDisable (pDrvCtrl->unit);     /* board specific int disable */    snChipInit (pDrvCtrl);		    /* init the device */    /* Set flags */    END_OBJ_READY (&pDrvCtrl->endData,		   (IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST));    return (&pDrvCtrl->endData);    }/********************************************************************************* snInitParse - parse parameter values from initString according to the*	following format:**    int    unit,       * unit number **    char * pDevRegs,   * addr of device's regs **    int    ivec        * vector number **** RETURNS: OK or ERROR*/LOCAL STATUS snInitParse    (    INIT_PARM * pParms,      /* pointer contains the data in the initstring */    char *      pinitString    )    {    char *	ptok;			/* token for the initString */    char *	pHolder=NULL;           /* temp string holder */    ptok = strtok_r(pinitString, ":", &pHolder);    if (ptok == NULL)        return ERROR;    pParms->unit = atoi(ptok);    ptok=strtok_r(NULL, ":", &pHolder);    if (ptok == NULL)        return ERROR;     pParms->devaddr = strtoul (ptok, NULL, 16);    ptok=strtok_r(NULL, ":", &pHolder);    if (ptok == NULL)        return ERROR;    pParms->ivec = atoi (ptok);        return OK;    }/********************************************************************************* sn83932Start - start the device** This function connects interrupt, calls BSP to enable them,  and starts the* device running in interrupt mode.** RETURNS: OK or ERROR* NOMANUAL*/LOCAL STATUS sn83932Start    (    DRV_CTRL * pDrvCtrl    )    {#ifdef DEBUG    SN_LOGMSG ("sn83932Start...\n",0,0,0,0,0,0);#endif    /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;    if (pDrvCtrl->online)	return OK;    /* Connect the interrupt vector */    if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(pDrvCtrl->ivec),		       sn83932Int, (int)pDrvCtrl) != OK)	return ERROR;    /* Enable device interrupts at system level */    sysEnetIntEnable (pDrvCtrl->unit);    /* Initialize the physical address in the CAM */    snCamMacLoad (pDrvCtrl);    /* Bring up the device */    snChipStart (pDrvCtrl);    /* Denote it as online */    pDrvCtrl->online = TRUE;    /* mark the interface as up */    END_FLAGS_SET (&pDrvCtrl->endData, (IFF_UP | IFF_RUNNING));#ifdef DEBUG    SN_LOGMSG ("end of sn83932Start...\n",0,0,0,0,0,0);#endif    return (OK);    } /* End of sn83932Start() *//********************************************************************************* sn83932Stop - Stop the device** This routine disables interrupts and resets the device.** RETURNS: OK or ERROR* NOMANUAL*/LOCAL STATUS sn83932Stop    (    DRV_CTRL * pDrvCtrl    )    {    /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;    sysEnetIntDisable (pDrvCtrl->unit);         /* board specific int */						/* disable */    pDrvCtrl->pDev->imr = 0;	                /* Turn off interrupts */    pDrvCtrl->online = FALSE;			/* denote unit as offline */    /* mark the interface as down */    END_FLAGS_CLR (&pDrvCtrl->endData, (IFF_UP | IFF_RUNNING));    return OK;    }/********************************************************************************* sn83932Unload - unload the device by freeing any allocated memory and*	          releasing the EndData objects from the MUX.*** RETURNS:  OK or ERROR* NOMANUAL**/LOCAL STATUS sn83932Unload    (    DRV_CTRL *pDrvCtrl    )    {    /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;    if (pDrvCtrl->endData.attached == TRUE)        {	/* Stop the device if still on line */	if (pDrvCtrl->online)	    sn83932Stop (pDrvCtrl);        /* Reset the Chip to pre-empt any further action */	snChipReset (pDrvCtrl);        /* release EndData objects */        END_OBJECT_UNLOAD (&pDrvCtrl->endData);        /* Free up malloc'd memory */        cacheDmaFree (pDrvCtrl->pMem);	/* Denote device as detached */	pDrvCtrl->endData.attached = FALSE;	}    return OK;    }/******************************************************************************** snInitMem - establish shared memory region for sonic chip** The driver and the device share areas of memory.  Each area has a* specific use.  The device imposes a nasty restriction, in that* an area's bounds must lie in the same 64k page.  The entire amount of* shared memory that is needed is much less than 64k.  Therefore, we* will group all the individual areas into one area, and attempt to* ensure that this total area lies in a single 64k page.** We must also consider data cache coherency of this shared memory.* We therefore use the special system functions that allow us to* obtain cache-safe memory, or at least allow us to maintain the* coherency of this memory ourselves.** RETURNS: OK or ERROR.*/LOCAL STATUS snInitMem    (    DRV_CTRL * pDrvCtrl    )    {    int cnt;    u_long temp;				/* Temporary address holder */    char *pCur;					/* Block local variable */    CAM_DESC * pCam;				/* CAM working descriptor */    TX_DESC * pTXD;    RX_DESC * pRXD;                              /* Rx working descriptor */    RRA_DESC * pRRAD;                            /* RRA working descriptor */    /* The first step is to calculate the size of this shared region. */     pDrvCtrl->shMemSize =                    CAM_SIZE +      /* the area used for Ethernet addrs   */                    RRA_SIZE +      /* the area that describes Rx buffers */                    RDA_SIZE +      /* the area that holds Rx descriptors */                    TDA_SIZE +      /* the area that holds Tx descriptors */                    RBA_SIZE;       /* the area that holds all Rx buffers */    /*     * That was easy.  Now we request some memory from the system.     * For now, we are taking a simple approach.  We simply request one     * big region, large enough to ensure that we can position our shared     * area in a single 64k page.  This approach will waste memory, but     * blame the board designers who picked the SONIC without realizing     * that the device has this weird restriction.     */    if (!CACHE_DMA_IS_WRITE_COHERENT ())        return (ERROR);    pDrvCtrl->pMem = cacheDmaMalloc (pDrvCtrl->shMemSize + 0x00010000);    if (pDrvCtrl->pMem == NULL)                 /* no memory, so abort */        return (ERROR);    /*     * Find start of 64k page in the region.  This becomes start of our     * region.     */    pDrvCtrl->pShMem = (char *)                       (((u_long)pDrvCtrl->pMem & 0xffff0000) + 0x00010000);    /***** Carve up the shared area into specific areas *****/    pCur = pDrvCtrl->pShMem;                /* start of shared area */    pDrvCtrl->CDA = (u_long) pCur;          /* CAM area */    pCur += CAM_SIZE;                       /* advance the pointer */    pDrvCtrl->RSA = (u_long) pCur;          /* receive resource table */    pCur += RRA_SIZE;                       /* advance the pointer */    pDrvCtrl->REA = (u_long) pCur;          /* save end pointer */    pDrvCtrl->RDA = (u_long) pCur;          /* receive descriptor area */    pCur += RDA_SIZE;                       /* advance the pointer */    pDrvCtrl->pTDA = (TX_DESC *)pCur;       /* transmit descriptor area */    pCur += TDA_SIZE;                       /* advance the pointer */    pDrvCtrl->RBA1 = (u_long) pCur;         /* Receive Buffer 1 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA2 = (u_long) pCur;         /* Receive Buffer 2 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA3 = (u_long) pCur;         /* Receive Buffer 3 */    pCur += RX_BUF_SIZE + RX_BUF_EXTRA;     /* advance the pointer */    pDrvCtrl->RBA4 = (u_long) pCur;         /* Receive Buffer 4 */    /* Init the CAM Descriptors to all broadcasts */    pCam = (CAM_DESC *)pDrvCtrl->CDA;    /* Program the descriptor entry for each CAM register */    for (cnt = 0; cnt < CAM_COUNT; cnt++, pCam++)	{    	pCam->cep  = cnt;     	pCam->cap0 = 0xffff;    	pCam->cap1 = 0xffff;    	pCam->cap2 = 0xffff;	}    pDrvCtrl->pCamEnableMask = (u_long *)pCam;    *pDrvCtrl->pCamEnableMask = 0;		/* All Addresses Disabled */    /*** init the Tx descriptors ***/    pTXD = pDrvCtrl->pTDA;                      /* get initial ptr */    bzero ((char *)pTXD, TDA_SIZE);             /* zero the whole enchilada */    for (cnt = 0; cnt < NUM_TX_DESC; cnt++)     /* loop thru each */        {	pTXD->number = cnt;        pTXD->pLink = pTXD + 1;                 /* link to next */        pTXD++;                                 /* bump to next */        }    /*     * The link field of the last desc is special; it needs to point     * back to the first desc.  So, we fix it here.     */    (--pTXD)->pLink = pDrvCtrl->pTDA;    pDrvCtrl->pTXDFree = pDrvCtrl->pTDA;              /* initial value */    pDrvCtrl->pTXDReclaim = pDrvCtrl->pTDA;           /* initial value */    pDrvCtrl->pTXDLast = pDrvCtrl->pTDA;              /* initial value */    /*** init the Rx buffer descriptors ***/    /* Build the RRA */    pRRAD = (RRA_DESC *)pDrvCtrl->RSA;           /* get ptr to first entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA1);    pRRAD->buff_ptr0 = temp & UMASK;    pRRAD->buff_ptr1 = temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = (RX_BUF_SIZE >> 1) & UMASK;    pRRAD->buff_wc1 = (RX_BUF_SIZE >> 1) >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA2);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA3);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    pRRAD++;                                    /* bump to next entry */    /* Stuff buffer ptr; least significant 16 bits, then most significant 16 */    temp = (u_long) CACHE_DMA_VIRT_TO_PHYS (pDrvCtrl->RBA4);    pRRAD->buff_ptr0 = (u_long) temp & UMASK;    pRRAD->buff_ptr1 = (u_long) temp >> 16;    /* Stuff word count; least significant 16 bits, then most significant 16 */    pRRAD->buff_wc0 = RX_BUF_SIZE >> 1 & UMASK;    pRRAD->buff_wc1 = RX_BUF_SIZE >> 1 >> 16;    /* Setup the Rx frame descriptors */    pRXD = (RX_DESC *) pDrvCtrl->RDA;           /* get initial ptr */    bzero ((char *)pRXD, RDA_SIZE);             /* zero the whole tomato */    pDrvCtrl->pRXDNext = pRXD;                  /* start from the start! */    pDrvCtrl->pRXDLast =                        /* stuff ptr to last */                    (RX_DESC *) ((u_long)pRXD + RDA_SIZE - RX_DESC_SIZ);    while (pRXD <= pDrvCtrl->pRXDLast)          /* loop thru each */        {        pRXD->in_use = IN_USE;                  /* set IN_USE by device */        pRXD->link =                            /* set link */            (RX_DESC *) CACHE_DMA_VIRT_TO_PHYS (pRXD + 1);        pRXD++;                                 /* bump to next */        }    /*     * The link field of the last desc is special; it points nowhere,     * but must mark the end-of-list.  So, we fix it here.     */    pDrvCtrl->pRXDLast->link = RX_EOL;    /* memory allocation for NetPool */    if((pDrvCtrl->endData.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /* number of clusters in each cluster pool */    SnClDescTbl[0].clNum = NUM_OPTIMAL_CLUSTER;    SnClDescTbl[1].clNum = NUM_MTU_CLUSTER;    /* number of cluster blocks */    SnMclConfig.clBlkNum = NUM_CL_BLK;    /* number of mblks */    SnMclConfig.mBlkNum = NUM_MBLK;    /* memory requirement for cluster blks and mblks */

⌨️ 快捷键说明

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