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

📄 ns83902end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
LOCAL void	ns83902ReadPort (NS83902_END_DEVICE* pDrvCtrl, 				 char *pBuf, int len);LOCAL void 	ns83902WritePort (NS83902_END_DEVICE* pDrvCtrl, 				  char *pBuf, int len);LOCAL STATUS 	ns83902InitParse (NS83902_END_DEVICE* pDrvCtrl, 				  char * initString);LOCAL STATUS 	ns83902InitMem (NS83902_END_DEVICE* pDrvCtrl);LOCAL void	ns83902EnetAddrGet (NS83902_END_DEVICE* pDrvCtrl, char* addr);LOCAL void 	ns83902RegSet (NS83902_END_DEVICE* pDrvCtrl, int reg, 			       int value, int page);LOCAL UINT8 	ns83902RegRead (NS83902_END_DEVICE* pDrvCtrl, int reg, 			       int page);/* END Specific interfaces. */END_OBJ *	ns83902EndLoad (char *initString);LOCAL STATUS	ns83902Unload (NS83902_END_DEVICE* pDrvCtrl);LOCAL STATUS	ns83902Start (NS83902_END_DEVICE* pDrvCtrl);LOCAL STATUS	ns83902Stop (NS83902_END_DEVICE* pDrvCtrl);LOCAL int	ns83902Ioctl (NS83902_END_DEVICE* pDrvCtrl, int cmd, 			      caddr_t data);LOCAL STATUS	ns83902Send (NS83902_END_DEVICE* pDrvCtrl, M_BLK *pMblk);LOCAL STATUS	ns83902MCastAddrAdd (NS83902_END_DEVICE *pDrvCtrl, 				     char* pAddress);LOCAL STATUS	ns83902MCastAddrDel (NS83902_END_DEVICE *pDrvCtrl, 				     char* pAddress);LOCAL STATUS	ns83902MCastAddrGet (NS83902_END_DEVICE *pDrvCtrl,                                      MULTI_TABLE *pTable);LOCAL STATUS	ns83902PollSend (NS83902_END_DEVICE *pDrvCtrl, M_BLK *pMblk);LOCAL STATUS	ns83902PollReceive (NS83902_END_DEVICE *pDrvCtrl, M_BLK *pMblk);LOCAL STATUS	ns83902PollStart (NS83902_END_DEVICE *pDrvCtrl);LOCAL STATUS	ns83902PollStop (NS83902_END_DEVICE *pDrvCtrl);/* * Declare our function table.  This is static across all driver * instances. */LOCAL NET_FUNCS ns83902FuncTable =    {    (FUNCPTR)ns83902Start,		/* Function to start the device. */    (FUNCPTR)ns83902Stop,		/* Function to stop the device. */    (FUNCPTR)ns83902Unload,		/* Unloading function */    (FUNCPTR)ns83902Ioctl,		/* Ioctl function */    (FUNCPTR)ns83902Send,		/* Send function */    (FUNCPTR)ns83902MCastAddrAdd,	/* Multicast address add */    (FUNCPTR)ns83902MCastAddrDel,	/* Multicast address delete */    (FUNCPTR)ns83902MCastAddrGet,	/* Multicast table retrieve */    (FUNCPTR)ns83902PollSend,		/* Polling send function  */    (FUNCPTR)ns83902PollReceive,	/* Polling receive function */    endEtherAddressForm,		/* Put address info into a packet.  */    endEtherPacketDataGet,		/* Get a pointer to packet data. */    endEtherPacketAddrGet,		/* Get packet addresses. */    NULL				/* Bind function */    };/******************************************************************************** ns83902EndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>.* 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* ns83902EndLoad    (    char* initString			/* string to be parsed */    )    {    NS83902_END_DEVICE	*pDrvCtrl;    DRV_LOG (NS83902_DEBUG_LOAD, "Loading ns83902End...\n", 1, 2, 3, 4, 5, 6);    if (initString == NULL)        return (NULL);        if (initString[0] == '\0')        {        bcopy((char *)NS83902_DEV_NAME, initString, NS83902_DEV_NAME_LEN);        return (0);        }        /* allocate the device structure */    pDrvCtrl = (NS83902_END_DEVICE *)calloc (sizeof (NS83902_END_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (ns83902InitParse (pDrvCtrl, initString) == ERROR)	goto errorExit;        /* Have the BSP hand us our address. */    ns83902EnetAddrGet (pDrvCtrl, (char*) &(pDrvCtrl->enetAddr));    DRV_LOG (NS83902_DEBUG_LOAD, "ENET Addr: %x:%x:%x:%x:%x:%x \n",             pDrvCtrl->enetAddr[0], pDrvCtrl->enetAddr[1], 	     pDrvCtrl->enetAddr[2], pDrvCtrl->enetAddr[3], 	     pDrvCtrl->enetAddr[4], pDrvCtrl->enetAddr[5]);    /* initialize the END and MIB2 parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, NS83902_DEV_NAME,		    pDrvCtrl->unit, &ns83902FuncTable,                      "ST-NIC Enhanced Network Driver") == ERROR     || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], NS83902_EADR_LEN, ETHERMTU,                      NS83902_SPEED)		    == ERROR)	goto errorExit;    /* set buffer address; reserve 8 pages for TX */    pDrvCtrl->txStartPage = 0;    pDrvCtrl->rxStartPage = pDrvCtrl->txStartPage + 8;    pDrvCtrl->nextPage    = pDrvCtrl->rxStartPage;    /* size of the whole ring */    pDrvCtrl->rringSize = pDrvCtrl->rxStopPage - pDrvCtrl->rxStartPage + 1;    /* Perform memory allocation */    if (ns83902InitMem (pDrvCtrl) == ERROR)	{	DRV_LOG (NS83902_DEBUG_LOAD, "Error in InitMem...\n", 1, 2, 3, 4, 5, 6);	goto errorExit;	}    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->endObj,                   IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);        DRV_LOG (NS83902_DEBUG_LOAD, "Done loading ns83902End...\n", 1, 2, 3, 4, 5, 6);    /* save the device address */#ifdef NS83902_DEBUG    ns83902EndDevice = pDrvCtrl;    ns83902DmaSemId  = pDrvCtrl->endObj.txSem;#endif    return (&pDrvCtrl->endObj);errorExit:    ns83902Unload (pDrvCtrl);    return NULL;    }/********************************************************************************* ns83902InitParse - parse the initialization string** Parse the input string and fill in values in the driver control structure.** RETURNS: OK, or ERROR if any arguments are invalid.*/LOCAL STATUS ns83902InitParse    (    NS83902_END_DEVICE * pDrvCtrl,    char * initString    )    {    char *	tok;    char *	pHolder = NULL;    long	address;    UINT8	options;        /* 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 = (char*) 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);    /* Remote DMA I/O address. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->ioPort = (char *) strtoul (tok, NULL, 16);    /* Get ring buffer size in pages */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->rxStopPage = strtoul (tok, NULL, 16) / NS83902_PAGE_SIZE;    /* Get target options */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    options = strtoul (tok, NULL, 16);    pDrvCtrl->wide = options & NS83902_WIDE_MASK;    pDrvCtrl->regInterval = 1 << ((options & NS83902_INTERVAL_MASK) >> 1);    DRV_LOG (NS83902_DEBUG_LOAD, "Processed all arugments\n", 1, 2, 3, 4, 5, 6);    DRV_LOG (NS83902_DEBUG_LOAD, "Address %p Lvl %u Vec %d Port %p Ring %p \n",               (int)pDrvCtrl->pNic, pDrvCtrl->ilevel, pDrvCtrl->ivec, 	       (int)pDrvCtrl->ioPort, pDrvCtrl->rxStopPage, 6);        DRV_LOG (NS83902_DEBUG_LOAD, "Transfer width: %s \n",                (int)(pDrvCtrl->wide ? "word":"byte"), 2, 3, 4, 5, 6);    DRV_LOG (NS83902_DEBUG_LOAD, "Register interval: %d \n", 	       pDrvCtrl->regInterval, 2, 3, 4, 5, 6);    return OK;    }/********************************************************************************* ns83902InitMem - initialize memory for NIC 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 ns83902InitMem    (    NS83902_END_DEVICE * pDrvCtrl		/* device to be initialized */    )    {    /* allocate netpool */    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /* Set number of M-Blks and CL-Blks*/    ns83902MclBlkConfig.mBlkNum	= pDrvCtrl->rringSize;    ns83902MclBlkConfig.clBlkNum= pDrvCtrl->rringSize / 2;    ns83902ClDescTbl[0].clNum	= ns83902MclBlkConfig.clBlkNum;    /* Calculate the total memory for all the M-Blks and CL-Blks. */    ns83902MclBlkConfig.memSize = ns83902MclBlkConfig.mBlkNum * 				   (MSIZE + sizeof (long)) +				  ns83902MclBlkConfig.clBlkNum * 				   (CL_BLK_SZ + sizeof(long));    /* allocate memory for M-Blks and CL-Blks */    ns83902MclBlkConfig.memArea	= (char *) memalign (sizeof(long),				   ns83902MclBlkConfig.memSize);    if (ns83902MclBlkConfig.memArea == NULL)	return (ERROR);        /* Calculate the memory size of all the clusters. */    ns83902ClDescTbl[0].clSize  = NS83902_RX_BUF_SZ;    ns83902ClDescTbl[0].memSize = sizeof(long) + ns83902ClDescTbl[0].clNum * 				  (ns83902ClDescTbl[0].clSize + 8);    /* Allocate memory for clusters */    ns83902ClDescTbl[0].memArea = (char *) memalign (sizeof(long),				   ns83902ClDescTbl[0].memSize);       if (ns83902ClDescTbl[0].memArea == NULL)	{	DRV_LOG (NS83902_DEBUG_LOAD, "system memory unavailable\n", 		 1, 2, 3, 4, 5, 6);	return (ERROR);	}    /* Save clusters start address for later use */    pDrvCtrl->pCluster = (NS83902_CLUSTER) ns83902ClDescTbl[0].memArea;    /* Initialize the net buffer pool with buffers */    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &ns83902MclBlkConfig, 		     &ns83902ClDescTbl[0], ns83902ClDescTblNumEnt, NULL) == ERROR)	{	DRV_LOG (NS83902_DEBUG_LOAD, "Could not init buffering\n",		 1, 2, 3, 4, 5, 6);	return (ERROR);	}        /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, 					  NS83902_RX_BUF_SZ, FALSE);    if (pDrvCtrl->pClPoolId  == NULL)	return (ERROR);#ifdef NS83902_DEBUG    ns83902NetPool = *pDrvCtrl->endObj.pNetPool;    ns83902ClPoolId = pDrvCtrl->pClPoolId;#endif    return (OK);    }/********************************************************************************* ns83902Start - 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 ns83902Start    (    NS83902_END_DEVICE *pDrvCtrl    )    {    STATUS result;    /* Clear statuses */    pDrvCtrl->rxHandling = FALSE;    pDrvCtrl->txBlocked = FALSE;    pDrvCtrl->rxOvw = FALSE;    pDrvCtrl->txResend = FALSE;        /* reset the device */    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_STP | CR_ABORT, CR_RPAGE0);    /* connect interrupt handler */    SYS_INT_CONNECT (pDrvCtrl, ns83902Int, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    DRV_LOG (NS83902_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    /* device config */    ns83902Config (pDrvCtrl);    /* mark the interface -- up */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));        SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (NS83902_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* ns83902Config - 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 ns83902Config    (    NS83902_END_DEVICE * pDrvCtrl	/* device to be configured */        )    {    UCHAR*	pEnetAddr = pDrvCtrl->enetAddr;    UCHAR	dcr;    /* Page 0 */    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_STP | CR_ABORT, CR_RPAGE0);    /* Enable broadcast, Endian, Word Size */#if (_BYTE_ORDER == _BIG_ENDIAN)    dcr = DCR_NOTLS | DCR_FIFO8 | DCR_BOS;#else    dcr = DCR_NOTLS | DCR_FIFO8;#endif    if (pDrvCtrl->wide == TRUE)  	dcr |= DCR_WTS;    NS83902_REG_SET (pDrvCtrl, NS83902_DCR, dcr, CR_RPAGE0);    /* Clear the remote byte count reg. */    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR0, 0, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_RBCR1, 0, CR_RPAGE0);    /* Set to monitor and loopback mode */    NS83902_REG_SET (pDrvCtrl, NS83902_RCR, RCR_MON, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_TCR, TCR_MODE1, CR_RPAGE0);    /* Accept Broadcast */    NS83902_REG_SET (pDrvCtrl, NS83902_RCR, (RCR_AB | RCR_AM), CR_RPAGE0);					    /* Set the transmit page and receive page */    NS83902_REG_SET (pDrvCtrl, NS83902_PSTART, pDrvCtrl->rxStartPage, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_PSTOP, pDrvCtrl->rxStopPage, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_TPSR, pDrvCtrl->txStartPage, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_BNRY, pDrvCtrl->rxStopPage - 1, CR_RPAGE0);    /* Clear the pending interrupts and mask. */    NS83902_REG_SET (pDrvCtrl, NS83902_ISR, 0xff, CR_RPAGE0);    NS83902_REG_SET (pDrvCtrl, NS83902_IMR, IMR_DISABLE, CR_RPAGE0);    /* set MAC Address */    NS83902_REG_SET (pDrvCtrl, NS83902_PAR0, pEnetAddr [0], CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_PAR1, pEnetAddr [1], CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_PAR2, pEnetAddr [2], CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_PAR3, pEnetAddr [3], CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_PAR4, pEnetAddr [4], CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_PAR5, pEnetAddr [5], CR_RPAGE1);    /* Initialize the multicast list to accept all. */    NS83902_REG_SET (pDrvCtrl, NS83902_MAR0, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR1, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR2, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR3, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR4, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR5, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR6, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_MAR7, 0x00, CR_RPAGE1);    NS83902_REG_SET (pDrvCtrl, NS83902_CURR, pDrvCtrl->rxStartPage, CR_RPAGE1);    /* Page 0 */    NS83902_REG_SET (pDrvCtrl, NS83902_CR, CR_STP | CR_ABORT, CR_RPAGE0);    /* set the interrupt mask */

⌨️ 快捷键说明

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