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

📄 templateend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 3 页
字号:
                      "END Template Driver.") == ERROR     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], 6, END_BUFSIZ,                      END_SPEED)		    == ERROR)	goto errorExit;    /* Perform memory allocation/distribution */    if (templateMemInit (pDrvCtrl) == ERROR)	goto errorExit;    /* reset and reconfigure the device */    templateReset (pDrvCtrl);    templateConfig (pDrvCtrl);    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->end,		    IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);    DRV_LOG (DRV_DEBUG_LOAD, "Done loading Template...", 1, 2, 3, 4, 5, 6);    return (&pDrvCtrl->end);errorExit:    if (pDrvCtrl != NULL)	free ((char *)pDrvCtrl);    return NULL;    }/********************************************************************************* templateParse - parse the init string** Parse the input string.  Fill in values in the driver control structure.** The muxLib.o module automatically prepends the unit number to the user's* initialization string from the BSP (configNet.h).** .IP <unit>* Device unit number, a small integer.* .IP <vecNum>* Interrupt vector number* .IP <intLvl>* Interrupt level* .LP** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS templateParse    (    END_DEVICE * pDrvCtrl,	/* device pointer */    char * initString		/* information string */    )    {    char*	tok;    char*	pHolder = NULL;    /* Parse the initString */    /* Unit number. (from muxLib.o) */    tok = strtok_r (initString, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->unit = atoi (tok);    /* 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);    return OK;    }/********************************************************************************* templateMemInit - initialize memory for the chip** This routine is highly specific to the device.** Design choices available:** Use default system buffers, or create device specific buffer pools.** Use contiguous buffers for device frame descriptors and the data, or* use descriptor buffers separate from the data buffers.** Use the same buffering scheme for Rx and Tx, or each side uses it's* own buffering scheme.** RETURNS: OK or ERROR.*/LOCAL STATUS templateMemInit    (    END_DEVICE * pDrvCtrl	/* device to be initialized */    )    {    int count = 0;    /* TODO - allocate and initialize any shared memory areas */    /*     * This is how we would set up an END netPool using netBufLib(1).     * This code is pretty generic.     */    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /*     * Note, Separating the descriptor from the data buffer can be     * advantageous for architectures that need cached data buffers but     * don't have snooping units to make the caches fully coherent.     * It is a disadvantage for architectures that do have snooping, becuase     * they need to do twice the number of netBufLib operations for each     * data frame.  This template driver assumes the descriptor and data     * buffer are contiguous.     */    /* number of driver Descriptor/data buffers */    templateClDescTbl[0].clNum = 16;    /* Setup mbuf/cluster block pool with more mbufs than clBlks */    templateMclBlkConfig.clBlkNum = templateClDescTbl[0].clNum;    templateMclBlkConfig.mBlkNum = templateMclBlkConfig.clBlkNum * 4;    /* Calculate the total memory for all the M-Blks and CL-Blks. */    templateMclBlkConfig.memSize = (templateMclBlkConfig.mBlkNum *				    (MSIZE + sizeof (long))) +			      (templateMclBlkConfig.clBlkNum *				    (CL_BLK_SZ + sizeof(long)));    /* allocate mbuf/Cluster blocks from normal memory */    if ((templateMclBlkConfig.memArea = (char *) memalign (sizeof(long),                                                  templateMclBlkConfig.memSize))        == NULL)        return (ERROR);    /* Round cluster size up to a multiple of a cache line */    templateClDescTbl[0].clSize =		ROUND_UP(templateClDescTbl[0].clSize,_CACHE_ALIGN_SIZE);    /* Calculate the memory size of all the clusters. */    templateClDescTbl[0].memSize = (templateClDescTbl[0].clNum				    * templateClDescTbl[0].clSize);    /* Allocate the memory for the clusters from cache safe memory. */    templateClDescTbl[0].memArea =        (char *) cacheDmaMalloc (templateClDescTbl[0].memSize);    /* cacheDmaMalloc memory is assumed to be cache line aligned ! */    /* use cacheDmaFuncs for cacheDmaMalloc memory */    pDrvCtrl->pCacheFuncs = &cacheDmaFuncs;    if (templateClDescTbl[0].memArea == NULL)        {        DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable\n",		1, 2, 3, 4, 5, 6);        return (ERROR);        }    /* Initialize the memory pool. */    if (netPoolInit(pDrvCtrl->end.pNetPool, &templateMclBlkConfig,                    &templateClDescTbl[0], templateClDescTblNumEnt,		    NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",		1, 2, 3, 4, 5, 6);        return (ERROR);        }    /*     * If you need clusters to store received packets into then get them     * here ahead of time.  This template driver only uses the cluster pool     * for receiving.  Here it takes all the clusters out of the pool and     * attaches them to the device.  The device will fill them with incoming     * packets and trigger an interrupt.  This will schedule the     * templateHandleRcvInt routine.  It will unlink the cluster and send     * it to the stack.  When the stack is done with the data, the cluster     * is freed and returned to the cluster pool to be used by the device     * again.     */    if ((pDrvCtrl->pClPoolId =		netClPoolIdGet (pDrvCtrl->end.pNetPool, sizeof (RFD), FALSE))        == NULL)        return (ERROR);    while (count < templateClDescTbl[0].clNum)        {	char * pTempBuf;        if ((pTempBuf = (char *)netClusterGet(pDrvCtrl->end.pNetPool,                                              pDrvCtrl->pClPoolId))            == NULL)            {            DRV_LOG (DRV_DEBUG_LOAD, "Could not get a buffer\n",                     1, 2, 3, 4, 5, 6);            return (ERROR);            }        /* TODO - Store the pointer in some appropriate structure. */        }    DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);    return OK;    }/********************************************************************************* templateStart - 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 templateStart    (    END_DEVICE * pDrvCtrl	/* device ID */    )    {    STATUS result;    SYS_INT_CONNECT (pDrvCtrl, templateInt, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);    /* TODO  - start the device, enabling interrupts */    return (OK);    }/********************************************************************************* templateInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void templateInt    (    END_DEVICE  *pDrvCtrl	/* interrupting device */    )    {    UCHAR stat;    DRV_LOG (DRV_DEBUG_INT, "Got an interrupt!\n", 1, 2, 3, 4, 5, 6);    /* Read the device status register */    stat = templateStatusRead (pDrvCtrl);    /* If false interrupt, return. */    if (!(stat & TEMPLATE_VALID_INT)) /* test for valid interrupt */	{        return;	/* return immediately, no error message */	}    /*     * enable interrupts, clear receive and/or transmit interrupts, and clear     * any errors that may be set.     */    /* TODO - Check for errors */    /* Have netTask handle any input packets */    if ((stat & TEMPLATE_RINT) && (stat & TEMPLATE_RXON))        {        if (!(pDrvCtrl->rxHandling))            {            pDrvCtrl->rxHandling = TRUE;            netJobAdd ((FUNCPTR)templateHandleRcvInt, (int)pDrvCtrl,                       0,0,0,0);            }        }    /* TODO - handle transmit interrupts */    }/********************************************************************************* templatePacketGet - get next received message** Get next received message.  Returns NULL if none are* ready.** RETURNS: ptr to next packet, or NULL if none ready.*/LOCAL PKT* templatePacketGet    (    END_DEVICE  *pDrvCtrl	/* device structure */    )    {    /*     * TODO - get next received packet. Packet address must be a valid     * virtual address, not a physical address.     */    return (PKT *)NULL;    }/********************************************************************************* templateRecv - process the next incoming packet** Handle one incoming packet.  The packet is checked for errors.** RETURNS: N/A.*/LOCAL STATUS templateRecv    (    END_DEVICE *pDrvCtrl,	/* device structure */    PKT* pPkt			/* packet to process */    )    {    int         len = 0;    M_BLK_ID 	pMblk;    char*       pCluster = NULL;    char*       pNewCluster;    CL_BLK_ID	pClBlk;    /* Add one to our unicast data. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    /*     * We implicitly are loaning here, if copying is necessary this     * step may be skipped, but the data must be copied before being     * passed up to the protocols.     */    pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);    if (pNewCluster == NULL)        {	DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRXD;        }    /* Grab a cluster block to marry to the cluster we received. */    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)        {        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRXD;        }    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)        {        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRXD;        }    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    /* TODO - Invalidate any RFD dma buffers */    /* TODO - Packet must be checked for errors. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    len = TEMPLATE_PKT_LEN_GET (pPkt);    pCluster = TEMPLATE_PKT_VIRT_GET (pPkt);    pMblk->mBlkHdr.mLen = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    /* make the packet data coherent */    END_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, len);    DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);    /* TODO - Done with processing, clean up and pass it up. */    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);cleanRXD:    return (OK);    }/********************************************************************************* templateHandleRcvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** The double loop is to protect against a race condition where the interrupt* code see rxHandling as TRUE, but it is then turned off by task code.* This race is not fatal, but does cause occassional delays until a second* packet is received and then triggers the netTask to call this routine again.** RETURNS: N/A.*/LOCAL void templateHandleRcvInt    (    END_DEVICE *pDrvCtrl	/* interrupting device */    )    {    PKT* pPkt;    do        {        pDrvCtrl->rxHandling = TRUE;        while ((pPkt = templatePacketGet (pDrvCtrl)) != NULL)            templateRecv (pDrvCtrl, pPkt);        pDrvCtrl->rxHandling = FALSE;        }    while (templatePacketGet (pDrvCtrl) != NULL);    }/********************************************************************************* templateSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.** RETURNS: OK, ERROR, or END_ERR_BLOCK.*/LOCAL STATUS templateSend    (    END_DEVICE * pDrvCtrl,	/* device ptr */    M_BLK_ID     pMblk		/* data to send */    )    {    int         oldLevel = 0;    BOOL        freeNow = TRUE;    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & TEMPLATE_POLLING))	END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);    /* TODO - Flush the data buffer(s), if it might be cached */    /* TODO - If necessary, get a Tx Frame Descriptor (TFD) */    /*     * TODO - If resources are not available,     * release the semaphore and return END_ERR_BLOCK.     * Do not free packet     */    /* TODO - Translate buffer virtual address to a remove bus physical addr */    /* place a transmit request */    if (!(pDrvCtrl->flags & TEMPLATE_POLLING))        oldLevel = intLock ();	/* protect templateInt */    /* TODO - initiate device transmit, FLUSH TFD */    /* Advance our management index(es) */    if (!(pDrvCtrl->flags & TEMPLATE_POLLING))	END_TX_SEM_GIVE (&pDrvCtrl->end);    if (!(pDrvCtrl->flags & TEMPLATE_POLLING))        intUnlock (oldLevel);

⌨️ 快捷键说明

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