Exemplo n.º 1
0
void process_sent_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *txring)
{
    XEmacPs_Bd *txbdset;
    XEmacPs_Bd *curbdpntr;
    s32_t n_bds;
    XStatus status;
    s32_t n_pbufs_freed = 0;
    u32_t bdindex;
    struct pbuf *p;
    u32_t *temp;
    u32_t index = 0;

    if (xemacpsif->emacps.Config.BaseAddress != XPAR_XEMACPS_0_BASEADDR) {
        index = sizeof(s32_t) * XLWIP_CONFIG_N_TX_DESC;
    }

    while (1) {
        /* obtain processed BD's */
        n_bds = XEmacPs_BdRingFromHwTx(txring,
                                       XLWIP_CONFIG_N_TX_DESC, &txbdset);
        if (n_bds == 0)  {
            return;
        }
        /* free the processed BD's */
        n_pbufs_freed = n_bds;
        curbdpntr = txbdset;
        while (n_pbufs_freed > 0) {
            bdindex = XEMACPS_BD_TO_INDEX(txring, curbdpntr);
            temp = (u32_t *)curbdpntr;
            *temp = 0;
            temp++;
            *temp = 0x80000000;
            if (bdindex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
                *temp = 0xC0000000;
            }

            p = (struct pbuf *)tx_pbufs_storage[index + bdindex];
            if (p != NULL) {
                pbuf_free(p);
            }
            tx_pbufs_storage[index + bdindex] = 0;
            curbdpntr = XEmacPs_BdRingNext(txring, curbdpntr);
            n_pbufs_freed--;
            dsb();
        }

        status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
        if (status != XST_SUCCESS) {
            LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
        }
    }
    return;
}
Exemplo n.º 2
0
void process_sent_bds(XEmacPs_BdRing *txring)
{
	XEmacPs_Bd *txbdset;
	XEmacPs_Bd *CurBdPntr;
	int n_bds;
	XStatus Status;
	int n_pbufs_freed = 0;
	unsigned int BdIndex;
	struct pbuf *p;
	unsigned int *Temp;

	while (1) {
		/* obtain processed BD's */
		n_bds = XEmacPs_BdRingFromHwTx(txring,
								XLWIP_CONFIG_N_TX_DESC, &txbdset);
		if (n_bds == 0)  {
			return;
		}
		/* free the processed BD's */
		n_pbufs_freed = n_bds;
		CurBdPntr = txbdset;
		while (n_pbufs_freed > 0) {
			BdIndex = XEMACPS_BD_TO_INDEX(txring, CurBdPntr);
			Temp = (unsigned int *)CurBdPntr;
			*Temp = 0;
			Temp++;
			*Temp = 0x80000000;
			if (BdIndex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
				*Temp = 0xC0000000;
			}

			p = (struct pbuf *)tx_pbufs_storage[BdIndex];
			if(p != NULL) {
				pbuf_free(p);
			}
			tx_pbufs_storage[BdIndex] = 0;
			CurBdPntr = XEmacPs_BdRingNext(txring, CurBdPntr);
			n_pbufs_freed--;
			dsb();
		}

		Status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
		if (Status != XST_SUCCESS) {
			LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
		}
	}
	return;
}
Exemplo n.º 3
0
/**
*
* This function demonstrates the usage of the EMACPS by sending and
* receiving a single frame in DMA interrupt mode.
* The source packet will be described by two descriptors. It will be
* received into a buffer described by a single descriptor.
*
* @param	EmacPsInstancePtr is a pointer to the instance of the EmacPs
*		driver.
*
* @return	XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note		None.
*
*****************************************************************************/
int EmacPsDmaSingleFrameIntrExample(XEmacPs *EmacPsInstancePtr)
{
	int Status;
	u32 PayloadSize = 1000;
	u32 NumRxBuf = 0;
	XEmacPs_Bd *Bd1Ptr;
	XEmacPs_Bd *Bd2Ptr;
	XEmacPs_Bd *BdRxPtr;

	/*
	 * Clear variables shared with callbacks
	 */
	FramesRx = 0;
	FramesTx = 0;
	DeviceErrors = 0;

	/*
	 * Calculate the frame length (not including FCS)
	 */
	TxFrameLength = XEMACPS_HDR_SIZE + PayloadSize;

	/*
	 * Setup packet to be transmitted
	 */
	EmacPsUtilFrameHdrFormatMAC(&TxFrame, EmacPsMAC);
	EmacPsUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	EmacPsUtilFrameSetPayloadData(&TxFrame, PayloadSize);

	Xil_DCacheFlushRange((u32)&TxFrame, TxFrameLength);

	/*
	 * Clear out receive packet memory area
	 */
	EmacPsUtilFrameMemClear(&RxFrame);
	Xil_DCacheFlushRange((u32)&RxFrame, TxFrameLength);
	/*
	 * Allocate RxBDs since we do not know how many BDs will be used
	 * in advance, use RXBD_CNT here.
	 */
	Status = XEmacPs_BdRingAlloc(&
				      (XEmacPs_GetRxRing(EmacPsInstancePtr)),
				      1, &BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup the BD. The XEmacPs_BdRingClone() call will mark the
	 * "wrap" field for last RxBD. Setup buffer address to associated
	 * BD.
	 */

	XEmacPs_BdSetAddressRx(BdRxPtr, &RxFrame);

	/*
	 * Enqueue to HW
	 */
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				     1, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing RxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Allocate, setup, and enqueue 2 TxBDs. The first BD will
	 * describe the first 32 bytes of TxFrame and the rest of BDs
	 * will describe the rest of the frame.
	 *
	 * The function below will allocate 2 adjacent BDs with Bd1Ptr
	 * being set as the lead BD.
	 */
	Status = XEmacPs_BdRingAlloc(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      2, &Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup first TxBD
	 */
	XEmacPs_BdSetAddressTx(Bd1Ptr, &TxFrame);
	XEmacPs_BdSetLength(Bd1Ptr, FIRST_FRAGMENT_SIZE);
	XEmacPs_BdClearTxUsed(Bd1Ptr);
	XEmacPs_BdClearLast(Bd1Ptr);

	/*
	 * Setup second TxBD
	 */
	Bd2Ptr = XEmacPs_BdRingNext(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      Bd1Ptr);
	XEmacPs_BdSetAddressTx(Bd2Ptr,
				 (u32) (&TxFrame) + FIRST_FRAGMENT_SIZE);
	XEmacPs_BdSetLength(Bd2Ptr, TxFrameLength - FIRST_FRAGMENT_SIZE);
	XEmacPs_BdClearTxUsed(Bd2Ptr);
	XEmacPs_BdSetLast(Bd2Ptr);

	/*
	 * Enqueue to HW
	 */
	Status = XEmacPs_BdRingToHw(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     2, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Start the device
	 */
	XEmacPs_Start(EmacPsInstancePtr);

	/* Start transmit */
	XEmacPs_Transmit(EmacPsInstancePtr);

	/*
	 * Wait for transmission to complete
	 */
	while (!FramesTx);

	/*
	 * Now that the frame has been sent, post process our TxBDs.
	 * Since we have only submitted 2 to hardware, then there should
	 * be only 2 ready for post processing.
	 */
	if (XEmacPs_BdRingFromHwTx(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				    2, &Bd1Ptr) == 0) {
		EmacPsUtilErrorTrap
			("TxBDs were not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * Examine the TxBDs.
	 *
	 * There isn't much to do. The only thing to check would be DMA
	 * exception bits. But this would also be caught in the error
	 * handler. So we just return these BDs to the free list.
	 */
	Status = XEmacPs_BdRingFree(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				     2, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}

	/*
	 * Wait for Rx indication
	 */
	while (!FramesRx);

	/*
	 * Now that the frame has been received, post process our RxBD.
	 * Since we have submitted to hardware, then there should be only 1
	 * ready for post processing.
	 */
	NumRxBuf = XEmacPs_BdRingFromHwRx(&(XEmacPs_GetRxRing
					  (EmacPsInstancePtr)), 1,
					 &BdRxPtr);
	if (0 == NumRxBuf) {
		EmacPsUtilErrorTrap("RxBD was not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * There is no device status to check. If there was a DMA error,
	 * it should have been reported to the error handler. Check the
	 * receive lengthi against the transmitted length, then verify
	 * the data.
	 */
	if ((XEmacPs_BdGetLength(BdRxPtr)) != TxFrameLength) {
		EmacPsUtilErrorTrap("Length mismatch");
		return XST_FAILURE;
	}

	if (EmacPsUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
		EmacPsUtilErrorTrap("Data mismatch");
		return XST_FAILURE;
	}

	/*
	 * Return the RxBD back to the channel for later allocation. Free
	 * the exact number we just post processed.
	 */
	Status = XEmacPs_BdRingFree(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				     NumRxBuf, BdRxPtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error freeing up RxBDs");
		return XST_FAILURE;
	}

	/*
	 * Finished this example. If everything worked correctly, all TxBDs
	 * and RxBDs should be free for allocation. Stop the device.
	 */
	XEmacPs_Stop(EmacPsInstancePtr);

	return XST_SUCCESS;
}