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

📄 sn83932end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
        pTXD->frag [count].frag_size = totalLength;        count++;        /* Record the buffer's free routine for later invocation */        pDrvCtrl->freeBuf[pTXD->number].pfreeRtn  = (FUNCPTR)netClFree;        pDrvCtrl->freeBuf[pTXD->number].pSpare1= pDrvCtrl->endData.pNetPool;        pDrvCtrl->freeBuf[pTXD->number].pSpare2=pBuf;        }    else        /*          * 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	 */        {        pChunk =pMblk;        for(count=0;pChunk != NULL;)             {            /* if all the data is contained in the first mblk */            if((pChunk->mBlkHdr.mLen == pMblk->mBlkPktHdr.len) 	       && pChunk==pMblk)                No_Mblk=TRUE;            if (pChunk->mBlkHdr.mLen <= 0)	        {                pChunk =pChunk->mBlkHdr.mNext;                continue;	        }  	    /*	     * Check if frame contains a broadcast/multicast destination             * address.  Update appropriate MIB variable accordingly.	     */            if ((count == 0)  &&  (pChunk->mBlkHdr.mData[5] & 0x01))	        END_M2_OUTNUCAST (&pDrvCtrl->endData);            else                END_M2_OUTUCAST (&pDrvCtrl->endData);            /* ensure data is flushed */            CACHE_USER_FLUSH (pChunk->mBlkHdr.mData,pChunk->mBlkHdr.mLen);            /*             * set the data pointers and the correponding size of 	     * each fragment 	     */            addr = (u_long) CACHE_DMA_VIRT_TO_PHYS (pChunk->mBlkHdr.mData);            pTXD->frag [count].frag_ptr0 = (u_long) addr & UMASK;            pTXD->frag [count].frag_ptr1 = (u_long) addr >> 16;            pTXD->frag [count].frag_size = pChunk->mBlkHdr.mLen;            /* keep track of total packet length */            totalLength += pChunk->mBlkHdr.mLen;            if(No_Mblk)                {                count=1;                break;                }             /* loop through */             pChunk =pChunk->mBlkHdr.mNext;             count++;             }        /* Record the buffer's free routine for later invocation */        pDrvCtrl->freeBuf[pTXD->number].pfreeRtn = (FUNCPTR)netMblkClChainFree;        pDrvCtrl->freeBuf[pTXD->number].pSpare1= pMblk;        pDrvCtrl->freeBuf[pTXD->number].pSpare2=NULL;        }    /* Set total packet size & fragment count */    pTXD->pkt_size = max (ETHERSMALL, totalLength);   /* set packet size */    pTXD->frag_count = count;                     /* set fragment count */    if (totalLength < ETHERSMALL)        {        pTXD->frag[count-1].frag_size += (ETHERSMALL - totalLength);	totalLength = ETHERSMALL;	}    /* Update MIB variable accordingly */    END_M2_OUTOCTETS (&pDrvCtrl->endData, totalLength);    /* Reset the actual pLink field of the last transmitted descriptor */    pDrvCtrl->pTXDLast->frag[pDrvCtrl->pTXDLast->frag_count].frag_ptr0			&= ~TX_EOL;    /* copy link field to where device will expect it  & set the EOL bit */    pTXD->frag [count].frag_ptr0 =        (u_long) CACHE_DMA_VIRT_TO_PHYS (pTXD->pLink) | TX_EOL;    /* Adjust pointer to next TXD. */    pDrvCtrl->pTXDFree = (TX_DESC *)((u_long)pTXD->pLink & ~TX_EOL);    pDrvCtrl->pTXDLast = pTXD;    /* start the transmitter but make sure the load-cam bit is not set */    while (pDrvCtrl->pDev->cr & LCAM)        continue;    pDrvCtrl->pDev->cr = TXP;    /* Release Transmit semaphore */    END_TX_SEM_GIVE (&pDrvCtrl->endData);    return OK;    }/********************************************************************************* sn83932PollSend - the driver send routine**	This routine is valid only when called while the device is in Polling*	mode.  The NetBuffer passed in must not be in a chained configuration.*	If either of these rules are broken, the driver returns EINVAL.*	The transmit descriptor is filled with the relevant data and the*	transmitter started.  The transmit descriptor status is then polled for*	completion.  The transmit descriptor is cleared and the data buffer*	is freed.*	Note:  The same descriptor is used for each invocation of this function.**	RETURNS:  OK,*		  EINVAL - invalid usage*		  EAGAIN - error in transmission or busy* NOMANUAL*/LOCAL STATUS sn83932PollSend    (    DRV_CTRL * pDrvCtrl,    M_BLK_ID pMblk    )    {    TX_DESC *pTXD;    u_long  addr;    int retval;    volatile u_short stat = 0;    /* Sanity Check */    if (pDrvCtrl == NULL)	return EINVAL;    /* Buffer chaining not supported in Poll Mode */    if (!(pDrvCtrl->flags & SN_POLLING) || (pMblk->mBlkHdr.mNext!=NULL))	return (EINVAL);    if (pDrvCtrl->txBlocked)        return (END_ERR_BLOCK);        /* See if transmit descriptor is available  */    pTXD = pDrvCtrl->pTXDFree;    if (pTXD->flag == IN_USE)    	{/* No Room */	return (EAGAIN);    	}    /* Mark the descriptor as "in use" to reserve it */    pTXD->flag   = IN_USE;    pTXD->status = 0;    /* ensure data is flushed */    CACHE_USER_FLUSH (pMblk->mBlkHdr.mData, pMblk->mBlkHdr.mLen);    /* Set up descriptor */    pTXD->pkt_size = max (ETHERSMALL, pMblk->mBlkHdr.mLen);    pTXD->frag_count = 1;    /* Assign to a fragment */    addr = (u_long) CACHE_DMA_VIRT_TO_PHYS (pMblk->mBlkHdr.mData);    pTXD->frag [0].frag_ptr0 = (u_long) addr & UMASK;    pTXD->frag [0].frag_ptr1 = (u_long) addr >> 16;    pTXD->frag [0].frag_size = pTXD->pkt_size;     /* copy link field to where device will expect it  & set the EOL bit */    pTXD->frag [pTXD->frag_count].frag_ptr0 =        (u_long) CACHE_DMA_VIRT_TO_PHYS (pTXD->pLink) | TX_EOL;    /* Set the transmitter on */    pDrvCtrl->pDev->cr = TXP;    /* Poll for transmit completion */    do  {        CACHE_DMA_INVALIDATE (&pTXD->status, sizeof (pTXD->status));	stat = pTXD->status;    }while (!stat);     /* Update MIB variables */    END_M2_OUTOCTETS (&pDrvCtrl->endData, pTXD->pkt_size);    /* Determine if unicast or not */    if (pMblk->mBlkHdr.mData[5] & 0x01)	END_M2_OUTNUCAST (&pDrvCtrl->endData);    else	END_M2_OUTUCAST (&pDrvCtrl->endData);    /* Check for successful transmission */    if (stat & PTX)	retval = OK; /* Successful Send */    else	{  /* Error in Sending */	END_M2_OUTERRORS (&pDrvCtrl->endData);	retval = EAGAIN;	}    /* Free this Descriptor  for another poll request */    pTXD->flag = NOT_IN_USE;    pTXD->status = 0;    /* Adjust pointer to next TXD. */    pDrvCtrl->pTXDFree = (TX_DESC *)((u_long)pTXD->pLink & ~TX_EOL);    pDrvCtrl->pTXDLast = pTXD;    pDrvCtrl->pTXDReclaim = pDrvCtrl->pTXDFree;    return (retval);    }/******************************************************************************* snTxReclaim - reclaims transmit descriptors that the device has serviced**	 - Only valid if device is not in Polling Mode -**/LOCAL void snTxReclaim     (    DRV_CTRL *pDrvCtrl,    int maxReclaims    )    {    TX_DESC *pTXD;    int  intLevel;    int numReclaims=0;    /* No business here if we're in Poll Mode */    if (pDrvCtrl->flags & SN_POLLING)	return;    /* Check if someone else is in the midst of reclaiming */    if (pDrvCtrl->flags & SN_RECLAIMING)        {        SN_LOGMSG("someone else is busy reclaiming\n",0,0,0,0,0,0);        return;        }    /* Close reclaiming to all others */    pDrvCtrl->flags |= SN_RECLAIMING;    pTXD = pDrvCtrl->pTXDReclaim;                  /* get ptr to desc */    CACHE_DMA_INVALIDATE (&pTXD->status, sizeof (u_long));    /*     * The device is deemed to be done with the descriptor if the     * the descriptor had been flagged as "given" to the device,     * and the descriptor status field is set.     */    /*     * Check if descriptor was used status may return 0 if xmit error      * occurred      */    while ((pTXD->flag == IN_USE) &&	   ((pTXD->status & PTX) || !(pDrvCtrl->pDev->cr & TXP)))        {        if ( pTXD->status & PTX )            {            /* Packet was transmitted successfully. *	    * Release the data buffer(s) */	    /* Release buffer associated with each fragment in the TXD */	    (pDrvCtrl->freeBuf[pTXD->number].pfreeRtn) 	                      (pDrvCtrl->freeBuf[pTXD->number].pSpare1,	                       pDrvCtrl->freeBuf[pTXD->number].pSpare2);            /* done with the desc, so clean it up */            pTXD->flag    = NOT_IN_USE;            pTXD->status  = 0;            }        else             {     /* ERROR! */	    END_M2_OUTERRORS (&pDrvCtrl->endData);	    intLevel = intLock();	    pTXD->status = 0;	    /* Make sure LCAM bit is not set or we'll lock up */	    while (pDrvCtrl->pDev->cr & LCAM)	        continue;            pDrvCtrl->pDev->cr = TXP;           /* restart transmitter */	    intUnlock (intLevel);	    /* Get out now! */            break;		    }/* ERROR */        /* Advance to the next TXD. */        pTXD = (TX_DESC *)((u_long)pTXD->pLink & ~TX_EOL);        /* Update the reclaim pointer for next time. */        pDrvCtrl->pTXDReclaim = pTXD;	/* Check if we've taken too long */	if (numReclaims++ ==  maxReclaims)	    break;        /* invalidate the cache for this TXD */        CACHE_DMA_INVALIDATE (&pTXD->status, sizeof (pTXD->status));        } /* while */    pDrvCtrl->flags &= ~SN_RECLAIMING;    }/*============================================================================* *		R E C E I V E   R O U T I N E S *============================================================================*//****************************************************************************** sn83932PollRecv - Returns the next packet waiting to be processed.  If no*	packet exists, EAGAIN indication is returned instead.** RETURNS:  OK or EAGAIN**/LOCAL STATUS sn83932PollRecv    (    DRV_CTRL *pDrvCtrl,    M_BLK_ID pMblk     )    {         /* Sanity Check */    if (pDrvCtrl == NULL || !(pDrvCtrl->flags & SN_POLLING))	return EINVAL;    if (pMblk == NULL || pMblk->mBlkHdr.mData == NULL)	return (EINVAL);         /* Process the received packet and give it to the mux */    if (snProcessRxPkts (pDrvCtrl, 1, pMblk) == 0)	return EAGAIN;    else	return OK;    }/********************************************************************************* snProcessRxPkts - Process the received packets up to the maximum*	as indicated by the supplied argument.  For each recieved*	indication, the packet is extracted, the appropriate MIB variables*	are updated and the packet is then sent up to the Mux.  This*	device does not support buffer loaning and therefore is not*	utilized.  Once the packet is sent to the mux, the receive*	descriptor pointers are adjusted appropriately.**	RETURNS	-  Number of packets processed exclusive of errors *		  */	LOCAL int snProcessRxPkts     (    DRV_CTRL * pDrvCtrl,	        /* ptr to device's control info */    int maxPackets,		/* Max number of packets to process */    M_BLK_ID pMblk 		/* Optional net buffer for packet */    )    {    END_OBJ *pEnd;			/* ptr to our End structure */    RX_DESC *pRXD;			/* ptr to current descriptor */    SONIC *pDev;                       	/* ptr to the device regs */    char *pPktHdr;			/* ptr to packet */    int recvLen;			/* size of packet received */    int ndx;                           	/* index into RRA desc array */    int packetCount;			/* num of packets processed */    int POLL_MODE=1;                    /* if in Poll mode */    CL_BLK_ID pClBlk;                   /* cluster block pointer */    UCHAR *pCluster;                    /* cluster pointer */    BOOL error=FALSE;                   /* set in case of bad packet or out of					mblks, cluster blks or cluster */    /* Note the devices's End address */    pEnd = &pDrvCtrl->endData;    /* check if NOT Poll mode */    if(pMblk==NULL)    POLL_MODE=0;    /* If a buffer is provided, then only one packet may be processed  */    if (pMblk != NULL)	maxPackets = 1; #ifdef LED_DEBUG    if (!(pDrvCtrl->flags & SN_POLLING))        PutLED ('r',1);#endif    /* Process all received packets up to the supplied MAX */    for (packetCount = 0; packetCount < maxPackets; )        {        recvLen = 0;        /* get the next receive descriptor */    	pRXD = pDrvCtrl->pRXDNext;    	CACHE_DMA_INVALIDATE (pRXD, RX_DESC_SIZ);        /* Check if next slot has a packet */        if (pRXD->in_use == IN_USE)	    {

⌨️ 快捷键说明

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