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

📄 sn83932end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if (data == NULL)		return EINVAL;	    *(int *)data = MIN_1STXMTBUF_SIZE;	    break;	default:#ifdef DEBUG    SN_LOGMSG ("Undefined Command - Return\n",               0, 0, 0, 0, 0, 0);#endif	    return EINVAL;        }#ifdef DEBUG    SN_LOGMSG ("Done\n", 0, 0, 0, 0, 0, 0);#endif     return 0;    }/********************************************************************************* sn83932MCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for.  * NOMANUAL**/LOCAL STATUS sn83932MCastAddrAdd    (    DRV_CTRL *	pDrvCtrl,    char *	pAddr    )    {    int		retVal;        /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;#ifdef DEBUG    SN_LOGMSG  ("sn83932McastAddrAdd - %x:%x:%x:%x:%x:%x\n",                 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);#endif    if (pDrvCtrl->endData.nMulti == MAX_MCASTS)	return ERROR;    retVal = etherMultiAdd (&pDrvCtrl->endData.multiList, pAddr);    if (retVal == ENETRESET)        {        pDrvCtrl->endData.nMulti++;        snCamMcastLoad (pDrvCtrl);	retVal = OK;        }#ifdef DEBUG    SN_LOGMSG ("Mcast Done\n", 0,0,0,0,0,0);#endif     return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* sn83932MCastAddrDel - delete a multicast address for the device** This routine deletes a multicast address from the current list of* multicast addresses.** NOMANUAL*/LOCAL STATUS sn83932MCastAddrDel    (    DRV_CTRL *	pDrvCtrl,    char * 	pAddr    )    {    int		retVal;        /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;#ifdef DEBUG    SN_LOGMSG ("sn83932astAddrDel%x:%x:%x:%x:%x:%x\n",pAddr[0], 	       pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5]);#endif                      retVal = etherMultiDel (&pDrvCtrl->endData.multiList, pAddr);    if (retVal == ENETRESET)        {        pDrvCtrl->endData.nMulti--;        snCamMcastLoad (pDrvCtrl);	retVal = OK;        }    return ((retVal == OK) ? OK : ERROR);    }/********************************************************************************* sn83932MCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>** NOMANUAL*/LOCAL STATUS sn83932MCastAddrGet    (    DRV_CTRL *	pDrvCtrl,    MULTI_TABLE * pTable    )    {        /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;#ifdef DEBUG    SN_LOGMSG ("sn83932astAddrGet\n", 0, 0, 0, 0, 0, 0);#endif    return (etherMultiGet (&pDrvCtrl->endData.multiList, pTable));    }/********************************************************************************* snPollStart - Put the device into polling mode.  We first wait until any* 	       outstanding interrupt requests are processed normally.** RETURNS:  N/A** NOMANUAL*/LOCAL void snPollStart    (     DRV_CTRL * pDrvCtrl    )    {    int intLevel;    /* if offline, then only set flag */    if (!pDrvCtrl->online)	{	pDrvCtrl->flags |= SN_POLLING;	return;	}    if (pDrvCtrl->flags & SN_POLLING)	return;    intLevel = intLock();    pDrvCtrl->pDev->imr = 0;      /*SL* &= ~SN_IMR_DATA; */    /* Mark device as polling */    pDrvCtrl->flags |= SN_POLLING;    intUnlock (intLevel);    } /********************************************************************************* snPollStop - Put the device into interrupt mode.  This is the default mode *	for the device.   Nothing is done if the device is not in polling mode. ** RETURNS:  N/A**/LOCAL void snPollStop    (     DRV_CTRL *pDrvCtrl    )    {    int  intLevel;    intLevel = intLock();    /* Mark device as polling */    pDrvCtrl->flags &= ~SN_POLLING;    /* Mask in data interrupts */    pDrvCtrl->pDev->imr = pDrvCtrl->imr;#ifdef LED_DEBUG    PutLED ('I', 0);#endif    intUnlock (intLevel);    } /********************************************************************************* snIfConfig - Config the device according to allowable interface flag*	revisions by the application.  This is called from within the*	Ioctl call to register IF flag changes.** RETURNS:  N/A**/LOCAL void snIfConfig    (     DRV_CTRL * pDrvCtrl,     int flags    )    {    u_char *pDrvFlags;			/* ptr to the device's local flags */    pDrvFlags = &pDrvCtrl->flags;    if (flags & IFF_PROMISC)	{	if (!(*pDrvFlags & SN_PROMISC))	    {/* Put device into promiscuous mode */	    pDrvCtrl->pDev->rcr |= PRO;	    *pDrvFlags |= IFF_PROMISC;	    }	}    else	{	if (flags & SN_PROMISC)	    {/* Turn off promiscuous mode */	    pDrvCtrl->pDev->rcr &= ~PRO;	    *pDrvFlags &= ~IFF_PROMISC;	    }	}    if (flags & IFF_ALLMULTI)	{	if (!(*pDrvFlags & SN_ALLMULTI))	    {/* Accept ALL multicast packets */	    pDrvCtrl->pDev->rcr |= AMC;	    *pDrvFlags |= SN_ALLMULTI;	    }	}    else	{    	if (flags & SN_ALLMULTI)	    {/* Filter multicasts according to multicast entries */	    pDrvCtrl->pDev->rcr &= ~AMC;	    *pDrvFlags &= ~SN_ALLMULTI;	    }	}    }/*============================================================================* * 			T R A N S M I T     R O U T I N E S *============================================================================*//********************************************************************************* sn83932Send - the driver send routine** This routine takes a NET_BUFFER and sends off the data within the NET_BUFFER.* The data 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.  Supports NET_BUFFER chaining. ** RETURNS: OK or ERROR.* NOMANUAL*/LOCAL STATUS sn83932Send    (    DRV_CTRL * pDrvCtrl,		       /* device record ptr */    M_BLK_ID pMblk 	         	       /* data to be sent */    )    {    TX_DESC * pTXD;                            /* Tx descriptor to be used */    u_long addr;    int totalLength = 0;                       /* keep track of total length						* of the mblk chain 						*/    M_BLK_ID pChunk;                           /* tmp mblk to travel 						* the chain 						*/    int count =0;                         BOOL No_Mblk =FALSE;                       /* set in case all the data 						* is contained in the first 						* mblk of a chain 						*/    BOOL Exceed = FALSE;                       /* set if num of mblks in a 						* chain exceed max fragments 						* a tx desc can habdle 						*/    char * pBuf = NULL;    /* Sanity Check */    if (pDrvCtrl == NULL)        {        netMblkClChainFree(pMblk); /* free the given mBlk chain */        errno = EINVAL;        return (ERROR);        }#ifdef LED_DEBUG    PutLED ('x',2)#endif    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    END_TX_SEM_TAKE (&pDrvCtrl->endData, WAIT_FOREVER);    if (pDrvCtrl->flags & SN_POLLING)        {        netMblkClChainFree(pMblk); /* free the given mBlk chain */        errno = EINVAL;        END_TX_SEM_GIVE (&pDrvCtrl->endData);        return (ERROR);        }    if (pDrvCtrl->txBlocked)        {        END_TX_SEM_GIVE (&pDrvCtrl->endData);        return (END_ERR_BLOCK);         }    /* count the number of cluster in the chain */    pChunk=pMblk;    while(pChunk!= NULL)        {        if(pChunk->mBlkHdr.mLen > 0)            count++;        pChunk=pChunk->mBlkHdr.mNext;        }    if(count >= MAX_TX_FRAGS)        {   	/* allocate a cluster from the cluster pool of MTU size */        pBuf = netClusterGet(pDrvCtrl->endData.pNetPool,			     pDrvCtrl->pClPoolId[1]);        if(pBuf == NULL)            {            END_M2_OUTDISCARDS (&pDrvCtrl->endData);            pDrvCtrl->txBlocked = TRUE;            END_TX_SEM_GIVE (&pDrvCtrl->endData);            return (END_ERR_BLOCK);            }#ifdef PULI_LED_DEBUG  PutLED('E',3);#endif        Exceed=TRUE;        }   /*free mblk*/    /* See if transmit descriptor is available */    pTXD = pDrvCtrl->pTXDFree;    if (pTXD->flag == IN_USE)    	{  /* No room  - clean-up & return */#ifdef DEBUG    SN_LOGMSG("transmit descriptor in use\n",0,0,0,0,0,0); #endif	if(Exceed)	    netClFree(pDrvCtrl->endData.pNetPool,(UINT8 *)pBuf);        END_M2_OUTDISCARDS (&pDrvCtrl->endData);        pDrvCtrl->txBlocked = TRUE;        /* Release the TX semaphore */	END_TX_SEM_GIVE (&pDrvCtrl->endData);	return (END_ERR_BLOCK);	}  /* No room */    /* Mark this descriptor as "in use" */    pTXD->flag   = IN_USE;    pTXD->status = 0;    /*     * Build a transmit descriptor.     * Loop thru each fragment in the mbuf chain and stuff our info.     */    /*     * loop through the chain until last mblk is pointing to NULL,      * consider clusters only if their length is positive number and if not,      * get the next mblk      */    if(Exceed)        {        count=0;        if(pMblk->mBlkHdr.mData[5] & 0x01)            END_M2_OUTNUCAST (&pDrvCtrl->endData);        else            END_M2_OUTUCAST (&pDrvCtrl->endData);		               /*         * copy all the data in each mblk of the chain to the newly 	 * allocate cluster	 */        totalLength = netMblkToBufCopy(pMblk,pBuf,NULL);	/*Free mblk chain after copying */        netMblkClChainFree(pMblk);        CACHE_USER_FLUSH(pBuf,totalLength);        /* set the data pointers and the correponding size of each fragment */        addr = (u_long) CACHE_DMA_VIRT_TO_PHYS (pBuf);        pTXD->frag [count].frag_ptr0 = (u_long) addr & UMASK;        pTXD->frag [count].frag_ptr1 = (u_long) addr >> 16;

⌨️ 快捷键说明

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