Ejemplo n.º 1
0
/**
*
* Receive a frame. Wait for a frame to arrive.
*
* @param BaseAddress is the base address of the device
* @param FramePtr is a pointer to a buffer where the frame will
*        be stored.
*
* @return
*
* The type/length field of the frame received.  When the type/length field
* contains the type , XEL_MAX_FRAME_SIZE bytes will be copied out of the
* buffer and it is up to the higher layers to sort out the frame.
*
* @note
*
* This function call is blocking in nature, i.e. it will wait until a
* frame arrives.
*
* If the ping buffer is the source of the data, the argument should be
* DeviceAddress + XEL_RXBUFF_OFFSET.
* If the pong buffer is the source of the data, the argument should be
* DeviceAddress + XEL_RXBUFF_OFFSET + XEL_BUFFER_OFFSET.
* The function does not take the different buffers into consideration.
******************************************************************************/
u16 XEmacLite_RecvFrame(u32 BaseAddress, u8 *FramePtr)
{
    u16 LengthType;
    u16 Length;
    u32 Register;

    /*
     * Wait for a frame to arrive - this is a blocking call
     */

    while (XEmacLite_mIsRxEmpty(BaseAddress));

    /*
     * Get the length of the frame that arrived
     */
    LengthType = XIo_In32(BaseAddress + XEL_RPLR_OFFSET);
    LengthType &= (XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO);

    /* check if length is valid */

    if (LengthType > XEL_MAX_FRAME_SIZE)
    {
        /* Field contain type, use max frame size and let user parse it */
        Length = XEL_MAX_FRAME_SIZE;
    }
    else
    {
        /* Use the length in the frame, plus the header and trailer */
        Length = LengthType + XEL_HEADER_SIZE + XEL_FCS_SIZE;
    }

    /*
     * Read each byte from the EMAC Lite
     */
    XEmacLite_AlignedRead((u32 *) (BaseAddress + XEL_RXBUFF_OFFSET),
                          FramePtr, Length);

    /*
     * Acknowledge the frame
     */

    Register = XIo_In32(BaseAddress + XEL_RSR_OFFSET);
    Register &= ~XEL_RSR_RECV_DONE_MASK;
    XIo_Out32(BaseAddress + XEL_RSR_OFFSET, Register);

    return LengthType;
}
Ejemplo n.º 2
0
/**
*
* Interrupt handler for the EmacLite driver. It performs the following
* processing:
*
*	- Get the interrupt status from the registers to determine the source
* 	of the interrupt.
* 	- Call the appropriate handler based on the source of the interrupt.
*
* @param	InstancePtr contains a pointer to the EmacLite device instance
*		for the interrupt.
*
* @return	None.
*
* @note		None.
*
*
******************************************************************************/
void XEmacLite_InterruptHandler(void *InstancePtr)
{

	XEmacLite *EmacLitePtr;
	int TxCompleteIntr = FALSE;
	u32 BaseAddress;
	u32 TxStatus;

	/*
	 * Verify that each of the inputs are valid.
	 */
	XASSERT_VOID(InstancePtr != NULL);

	/*
	 * Convert the non-typed pointer to an EmacLite instance pointer
	 * such that there is access to the device.
	 */
	EmacLitePtr = (XEmacLite *) InstancePtr;
	BaseAddress = EmacLitePtr->EmacLiteConfig.BaseAddress;

	if ((XEmacLite_mIsRxEmpty(BaseAddress) != TRUE) ||
		(XEmacLite_mIsRxEmpty(BaseAddress +
			XEL_BUFFER_OFFSET) != TRUE)) {
		/*
		 * Call the RX callback.
		 */
		EmacLitePtr->RecvHandler(EmacLitePtr->RecvRef);

	}

	TxStatus = XEmacLite_mGetTxStatus(BaseAddress);
	if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
		(TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {

		/*
		 * Clear the Tx Active bit in the Tx Status Register.
		 */
		TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK;
		XEmacLite_mSetTxStatus(BaseAddress, TxStatus);

		/*
		 * Update the flag indicating that there was a Tx Interrupt.
		 */
		TxCompleteIntr = TRUE;

	}

	TxStatus = XEmacLite_mGetTxStatus(BaseAddress + XEL_BUFFER_OFFSET);
	if (((TxStatus & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
		(TxStatus & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {

		/*
		 * Clear the Tx Active bit in the Tx Status Register.
		 */
		TxStatus &= ~XEL_TSR_XMIT_ACTIVE_MASK;
		XEmacLite_mSetTxStatus(BaseAddress + XEL_BUFFER_OFFSET,
					TxStatus);
		/*
		 * Update the flag indicating that there was a Tx Interrupt.
		 */
		TxCompleteIntr = TRUE;
	}

	/*
	 * If there was a TX interrupt, call the callback.
	 */
	if (TxCompleteIntr == TRUE) {

		/*
		 * Call the TX callback.
		 */
		EmacLitePtr->SendHandler(EmacLitePtr->SendRef);

	}
}