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

📄 sndshdlcend.c

📁 4510b的vxworks的BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
    pDrvCtrl->baudRate = atoi (tok);

	/*Baud Rate */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL)
		return ERROR;
    pDrvCtrl->dataFormat = atoi (tok);

    ENDLOGMSG (("Processed all arugments\n", 1, 2, 3, 4, 5, 6));

    return OK;
    }

/*******************************************************************************
*
* sndsHdlcEndMemInit - initialize memory for the chip
*
* This routine is highly specific to the device.  
*
* RETURNS: OK or ERROR.
*/

STATUS sndsHdlcEndMemInit
    (
    HDLC_END_DEVICE * pDrvCtrl	/* device to be initialized */
    )
    {
    
    /*allocate and initialized any shared memory areas */

    /*
     * This is how we would set up and END netPool using netBufLib(1).
     * This code is pretty generic.
     */
    
    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
        return (ERROR);

    pDrvCtrl->hdlcEndMclConfig.mBlkNum = END_MBLK_NUM;
	pDrvCtrl->hdlcEndClDescTbl[0].clSize = SNDS_CL_SIZE;
    pDrvCtrl->hdlcEndClDescTbl[0].clNum = END_CL_NUM;
    pDrvCtrl->hdlcEndMclConfig.clBlkNum = pDrvCtrl->hdlcEndClDescTbl[0].clNum;

    /* Calculate the total memory for all the M-Blks and CL-Blks. */

    pDrvCtrl->hdlcEndMclConfig.memSize = (pDrvCtrl->hdlcEndMclConfig.mBlkNum * (MSIZE + sizeof (long))) +
                          (pDrvCtrl->hdlcEndMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));

    if ((pDrvCtrl->hdlcEndMclConfig.memArea = (char *) memalign (sizeof(long),
		pDrvCtrl->hdlcEndMclConfig.memSize)) == NULL)
        return (ERROR);
    
    /* Calculate the memory size of all the clusters. */

    pDrvCtrl->hdlcEndClDescTbl[0].memSize = (pDrvCtrl->hdlcEndClDescTbl[0].clNum *
		(pDrvCtrl->hdlcEndClDescTbl[0].clSize + 8)) + sizeof(int);		

    /* Allocate the memory for the clusters from cache safe memory. */
    pDrvCtrl->hdlcEndClDescTbl[0].memArea =
        (char *) malloc (pDrvCtrl->hdlcEndClDescTbl[0].memSize);

    if ((int)pDrvCtrl->hdlcEndClDescTbl[0].memArea == NULL)
        {
        return (ERROR);
        }
    
    /* Initialize the memory pool. */

    if (netPoolInit(pDrvCtrl->end.pNetPool, &(pDrvCtrl->hdlcEndMclConfig),
		&(pDrvCtrl->hdlcEndClDescTbl[0]), CLDESCTBL_NUM_ENT, NULL) == ERROR)
        {
        return (ERROR);
        }

   return OK;
    }

/*******************************************************************************
*
* sndsHdlcEndStart - 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 sndsHdlcEndStart
    (
    HDLC_END_DEVICE *pDrvCtrl	/* device to be started */
    )
    {
	HDLC_HCON	hdlchcon;

	/*Connect Tx and Rx Interrupts*/
	intConnect((VOIDFUNCPTR *)INUM_TO_IVEC(pDrvCtrl->hdlcVecTx), sndsHdlcTxInt, (UINT32)pDrvCtrl);
 	intConnect((VOIDFUNCPTR *)INUM_TO_IVEC(pDrvCtrl->hdlcVecRx), sndsHdlcRxInt, (UINT32)pDrvCtrl);
	
	/* Enable the Interrupts */
	intEnable(pDrvCtrl->hdlcVecTx);
	intEnable(pDrvCtrl->hdlcVecRx);
	
	/* Enable to Rx Data*/
	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);
	hdlchcon.hcon_reg.rxen = 1;
	hdlchcon.hcon_reg.drxen = 1;
	hdlchcon.hcon_reg.txen = 1;
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);

	END_FLAGS_SET(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
    return (OK);
    }


/*******************************************************************************
*
* sndsHdlcEndHandleRcvInt - 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.
*
* RETURNS: N/A.
*/

LOCAL void sndsHdlcEndHandleRcvInt
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* interrupting device */
	UINT32 status	/* Receive status */
    )
    {
	HDLC_HSTAT	hdlchstat;
	SNDSHDLCBD	*pRxBD;
	UINT32 *	pFrameData;
	UINT32		frameLength;

	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HDMARXPTR, *(UINT32 *)(&pRxBD));
	hdlchstat.hstat_resetval = status;
	
	if((*(UINT32*)(&(pDrvCtrl->gpRxBDStart->StatusLength))) == 0)
		return;

	
	do
		{
		if(hdlchstat.hstat_reg.drxnl == 1)
			return;
		frameLength = (pDrvCtrl->gpRxBDStart->StatusLength) & 0xffff;
		
		if(hdlchstat.hstat_reg.drxfd == 1)
			{
			
			pFrameData = (UINT32 *)(pDrvCtrl->gpRxBDStart->BufferDataPtr);
			sndsHdlcEndRecv (pDrvCtrl, (char *)pFrameData, frameLength);
			}
		pDrvCtrl->gpRxBDStart->BufferDataPtr |= BOWNERSHIP_DMA ;		
		*(UINT32*)(&(pDrvCtrl->gpRxBDStart->StatusLength)) = 0;

		pDrvCtrl->gpRxBDStart = pDrvCtrl->gpRxBDStart->NextBD;
		} while(pDrvCtrl->gpRxBDStart != pRxBD);
    }
/*******************************************************************************
*
* sndsHdlcEndRecv - process the next incoming packet
*
* Handle one incoming packet.  The packet is checked for errors.
*
* RETURNS: N/A.
*/

LOCAL STATUS sndsHdlcEndRecv
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* device structure */
    char* pData,			/* packet to process */
	UINT32 len				/* Length of received data */
    )
    {
    M_BLK_ID 	pMblk;
    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->end.pNetPool->clTbl[0]);

    if (pNewCluster == NULL)
        {
		END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
		goto cleanRXD;
        }

	bcopy (pData, pNewCluster, len);	/* Copy received data to net buffer */
	
    /* Grab a cluster block to marry to the cluster we received. */

    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
        {
        netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
		END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
		goto cleanRXD;
        }
    
    /*
     * OK we've got a spare, let's get an M_BLK_ID and marry it to the
     * one in the ring.
     */

    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
        {
        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); 
        netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
		END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
		goto cleanRXD;
        }

    /* Join the cluster to the MBlock */

    netClBlkJoin (pClBlk, pNewCluster, SNDS_CL_SIZE, NULL, 0, 0, 0);
    netMblkClJoin (pMblk, pClBlk);

    pMblk->mBlkHdr.mData += 0;
    pMblk->mBlkHdr.mLen = len;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = len;

    /* Call the upper layer's receive routine. */
	
    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);

cleanRXD:

    return (OK);
    }

/*******************************************************************************
*
* sndsHdlcEndSend - 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 or ERROR.
*/

LOCAL STATUS sndsHdlcEndSend
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* device ptr */
    M_BLK_ID pNBuff		/* data to send */
    )
    {
    int         len=0;
    int         oldLevel;
    BOOL    freeNow = TRUE;

	SNDSHDLCBD	*pTxBD;
	HDLC_HCON	hdlchcon;
	
	
	pTxBD = pDrvCtrl->gpTxBDStart;
	if (pTxBD->BufferDataPtr & BOWNERSHIP_DMA)
		return ERROR;
	len = pNBuff->mBlkPktHdr.len;
	
	/*
     * Obtain exclusive access to transmitter.  This is necessary because
     * we might have more than one stack transmitting at once.
     */
	END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER);
	
	/*set pointers in Local Structures to point to data */
	if (netMblkToBufCopy(pNBuff, (void *)pTxBD->BufferDataPtr, NULL) == ERROR)
		return(ERROR);
		
	pTxBD->StatusLength = len;
	pTxBD->BufferDataPtr |= BOWNERSHIP_DMA;
	pTxBD->Reserved = (LITTLE | LASTBF); 	/*  Little endian mode, last buffer in frame */
	
	oldLevel=intLock();
	
	/*Initiate Device Transmit*/

	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);
	hdlchcon.hcon_reg.dtxen = 1;
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);

	intUnlock(oldLevel);
	pDrvCtrl->gpTxBDStart = pDrvCtrl->gpTxBDStart->NextBD;

	END_TX_SEM_GIVE(&pDrvCtrl->end);

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);

    /*
     * Cleanup.  The driver must either free the packet now or
     * set up a structure so it can be freed later after a transmit
     * interrupt occurs.
     */
	
    if (freeNow)
        netMblkClChainFree (pNBuff);
    return (OK);
    }

/*******************************************************************************
*
* sndsHdlcEndIoctl - the driver I/O control routine
*
* Process an ioctl request.
*
* RETURNS: A command specific response, usually OK or ERROR.
*/

LOCAL int sndsHdlcEndIoctl
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* device receiving command */
    int cmd,			/* ioctl command code */
    caddr_t data		/* command argument */
    )
    {
    int error = 0;
    long value;

    switch (cmd)
        {
        case EIOCSADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),
		   END_HADDR_LEN(&pDrvCtrl->end));
            break;

        case EIOCGADDR:
	    if (data == NULL)
		return (EINVAL);
            bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,
		    END_HADDR_LEN(&pDrvCtrl->end));
            break;

        case EIOCSFLAGS:
	    value = (long)data;
	    if (value < 0)
		{
		value = -(--value);
		END_FLAGS_CLR (&pDrvCtrl->end, value);
		}
	    else
		{
		END_FLAGS_SET (&pDrvCtrl->end, value);
		}
	    sndsHdlcEndConfig (pDrvCtrl);
            break;

        case EIOCGFLAGS:
	    *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);
            break;
        case EIOCGMIB2:
            if (data == NULL)
                return (EINVAL);
            bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data,
                  sizeof(pDrvCtrl->end.mib2Tbl));
            break;
        case EIOCGFBUF:
            if (data == NULL)
                return (EINVAL);
            *(int *)data = 0;	/*END_MIN_FBUF;*/
            break;
        default:
            error = EINVAL;
        }

    return (error);
    }

/******************************************************************************
*
* sndsHdlcEndConfig - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A.
*/

LOCAL void sndsHdlcEndConfig
    (
    HDLC_END_DEVICE *pDrvCtrl	/* device to be re-configured */
    )
    {
    }

/******************************************************************************
*
* sndsHdlcEndAddrFilterSet - set the address filter for multicast addresses
*
* This routine goes through all of the multicast addresses on the list
* of addresses (added with the endAddrAdd() routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A.
*/

LOCAL void sndsHdlcEndAddrFilterSet
    (
    HDLC_END_DEVICE *pDrvCtrl	/* device to be updated */
    )
    {
    }

/*******************************************************************************
*
* sndsHdlcEndPollRcv - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device.
*
* RETURNS: OK upon success.  EAGAIN is returned when no packet is available.
*/

LOCAL STATUS sndsHdlcEndPollRcv
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* device to be polled */
    M_BLK_ID* pMblk		/* ptr to buffer */
    )
    {
    return (OK);
    }

/*******************************************************************************
*
* sndsHdlcEndPollSend - routine to send a packet in polled mode.
*
* This routine is called by a user to try and send a packet on the
* device.
*
* RETURNS: OK upon success.  EAGAIN if device is busy.
*/

LOCAL STATUS sndsHdlcEndPollSend
    (
    HDLC_END_DEVICE* pDrvCtrl,	/* device to be polled */
    M_BLK_ID* pMblk		/* packet to send */
    )
    {
    return (OK);
    }

/*****************************************************************************
*
* sndsHdlcEndMCastAdd - add a multicast address for the device
*
* This routine adds a multicast address to whatever the driver
* is already listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndMCastAdd
    (
    HDLC_END_DEVICE *pDrvCtrl,	/* device pointer */
    char* pAddress		/* new address to add */
    )
    {
    int error;

    if ((error = etherMultiAdd (&pDrvCtrl->end.multiList,
		pAddress)) == ENETRESET)
	sndsHdlcEndConfig (pDrvCtrl);

    return (OK);
    }

/*****************************************************************************
*
* sndsHdlcEndMCastDel - delete a multicast address for the device
*
* This routine removes a multicast address from whatever the driver
* is listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/

⌨️ 快捷键说明

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