void mpdu_transmit(packet_bd* tx_queue) {

	wlan_ipc_msg ipc_msg_to_low;
	tx_frame_info* tx_mpdu = (tx_frame_info*) TX_PKT_BUF_TO_ADDR(tx_pkt_buf);
	station_info* station = (station_info*)(tx_queue->metadata_ptr);


	if(is_tx_buffer_empty()){

		//For now, this is just a one-shot DMA transfer that effectively blocks
		while(XAxiCdma_IsBusy(&cdma_inst)) {}
		XAxiCdma_SimpleTransfer(&cdma_inst, (u32)(tx_queue->buf_ptr), (u32)TX_PKT_BUF_TO_ADDR(tx_pkt_buf), ((tx_packet_buffer*)(tx_queue->buf_ptr))->frame_info.length + sizeof(tx_frame_info) + PHY_TX_PKT_BUF_PHY_HDR_SIZE, NULL, NULL);
		while(XAxiCdma_IsBusy(&cdma_inst)) {}


		if(station == NULL){
			//Broadcast transmissions have no station information, so we default to a nominal rate
			tx_mpdu->AID = 0;
			tx_mpdu->rate = WLAN_MAC_RATE_6M;
		} else {
			//Request the rate to use for this station
			tx_mpdu->AID = station->AID;
			tx_mpdu->rate = wlan_mac_util_get_tx_rate(station);
			//tx_mpdu->rate = default_unicast_rate;
		}

		tx_mpdu->state = TX_MPDU_STATE_READY;
		tx_mpdu->retry_count = 0;

		ipc_msg_to_low.msg_id = IPC_MBOX_MSG_ID(IPC_MBOX_TX_MPDU_READY);
		ipc_msg_to_low.arg0 = tx_pkt_buf;
		ipc_msg_to_low.num_payload_words = 0;

		if(unlock_pkt_buf_tx(tx_pkt_buf) != PKT_BUF_MUTEX_SUCCESS){
			warp_printf(PL_ERROR,"Error: unable to unlock tx pkt_buf %d\n",tx_pkt_buf);
		} else {
			set_cpu_low_not_ready();
			/* WMP START */
			tx_pkt_buf_prev_acc = 0;
			/* WMP END */
			ipc_mailbox_write_msg(&ipc_msg_to_low);
		}
	} else {
		warp_printf(PL_ERROR, "Bad state in mpdu_transmit. Attempting to transmit but tx_buffer %d is not empty\n",tx_pkt_buf);
	}

	return;
}
Exemplo n.º 2
0
int XAxiCdma_Transfer(XAxiCdma *InstancePtr, u32 SrcAddr, u32 DstAddr, int byte_Length, XAxiCdma_CallBackFn SimpleCallBack, void *CallbackRef)
{
 int Status, CDMA_Status;

 Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32) SrcAddr , (u32) DstAddr, byte_Length, NULL, NULL);

   if (Status != XST_SUCCESS) 
   {
			CDMA_Status = XAxiCdma_GetError(InstancePtr);
			if (CDMA_Status != 0x0) {
				XAxiCdma_Reset(InstancePtr);
				//xil_xil_printf("Error Code = %x\r\r\n",CDMA_Status);
			}
			return XST_FAILURE;
	}

	  	while (XAxiCdma_IsBusy(InstancePtr)); // Wait

		CDMA_Status = XAxiCdma_GetError(InstancePtr);
		if (CDMA_Status != 0x0) {
			XAxiCdma_Reset(InstancePtr);
			//xil_xil_printf("Error Code = %x\r\r\n",CDMA_Status);
			return XST_FAILURE;
		}

  return XST_SUCCESS;

}
int wlan_mac_cdma_start_transfer(void* dest, void* src, u32 size){
	//This is a wrapper function around the central DMA simple transfer call. It's arguments
	//are intended to be similar to memcpy. Note: This function does not block on the transfer.

	int return_value;

	while(XAxiCdma_IsBusy(&cdma_inst)) {}
	return_value = XAxiCdma_SimpleTransfer(&cdma_inst, (u32)src, (u32)dest, size, NULL, NULL);

	return return_value;
}
Exemplo n.º 4
0
/**
 * This function configures KeyHole Write/Read Feature
 *
 * @param	InstancePtr is the driver instance we are working on
 *
 * @param	Direction is WRITE/READ
 * @Select	Select is the option to enable (TRUE) or disable (FALSE).
 *
 * @return	- XST_SUCCESS for success
 *		- XST_DEVICE_BUSY when transfer is in progress
 *		- XST_NO_FEATURE when not configured with feature
 *
 * @note	None.
 *
 *****************************************************************************/
int XAxiCdma_SelectKeyHole(XAxiCdma *InstancePtr, u32 Direction, u32 Select)
{
	u32 Value;

	if (XAxiCdma_IsBusy(InstancePtr)) {
		xdbg_printf(XDBG_DEBUG_ERROR,
		    "KeyHole: Transfer is in Progress\n\r");
		return XST_DEVICE_BUSY;
	}

	Value = XAxiCdma_ReadReg(InstancePtr->BaseAddr, 
				XAXICDMA_CR_OFFSET);

	if (Select) {
		if (XPAR_AXICDMA_0_M_AXI_MAX_BURST_LEN == 16) {
			if (Direction == XAXICDMA_KEYHOLE_WRITE)
				Value |= XAXICDMA_CR_KHOLE_WR_MASK;
			else
				Value |= XAXICDMA_CR_KHOLE_RD_MASK;
		} else {
			xdbg_printf(XDBG_DEBUG_ERROR,
				"KeyHole: Max Burst length should be 16\n\r");
			return XST_NO_FEATURE;
		}
	}
	else {
		if (Direction == XAXICDMA_KEYHOLE_WRITE)
			Value &= ~XAXICDMA_CR_KHOLE_WR_MASK;
		else
			Value &= ~XAXICDMA_CR_KHOLE_RD_MASK; 
	}

	XAxiCdma_WriteReg(InstancePtr->BaseAddr,
			XAXICDMA_CR_OFFSET, Value);

	return XST_SUCCESS;
}
Exemplo n.º 5
0
/**
 * This function does one simple transfer submission
 *
 * It checks in the following sequence:
 *	- if engine is busy, cannot submit
 *	- if software is still handling the completion of the previous simple
 *		transfer, cannot submit
 *	- if engine is in SG mode and cannot switch to simple mode, cannot submit
 *
 * @param	InstancePtr is the pointer to the driver instance
 * @param	SrcAddr is the address of the source buffer
 * @param	DstAddr is the address of the destination buffer
 * @param	Length is the length of the transfer
 * @param	SimpleCallBack is the callback function for the simple transfer
 * @param	CallBackRef is the callback reference pointer
 *
 * @return
 *		- XST_SUCCESS for success of submission
 *		- XST_FAILURE for submission failure, maybe caused by:
 *			Another simple transfer is still going
 *   . 		Another SG transfer is still going
 *		- XST_INVALID_PARAM if:
 *		Length out of valid range [1:8M]
 *		Or, address not aligned when DRE is not built in
 *
 * @note	Only set the callback function if using interrupt to signal
 *		the completion.If used in polling mode, please set the callback
 * 		function to be NULL.
 *
 *****************************************************************************/
u32 XAxiCdma_SimpleTransfer(XAxiCdma *InstancePtr, UINTPTR SrcAddr, UINTPTR DstAddr,
	int Length, XAxiCdma_CallBackFn SimpleCallBack, void *CallBackRef)
{
	u32 WordBits;

	if ((Length < 1) || (Length > XAXICDMA_MAX_TRANSFER_LEN)) {
		return XST_INVALID_PARAM;
	}

	WordBits = (u32)(InstancePtr->WordLength - 1);

	if ((SrcAddr & WordBits) || (DstAddr & WordBits)) {

		if (!InstancePtr->HasDRE) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "Unaligned transfer without DRE %x/%x\r\n",
			    (unsigned int)SrcAddr, (unsigned int)DstAddr);

			return XST_INVALID_PARAM;
		}
	}

	/* If the engine is doing transfer, cannot submit
	 */
	if (XAxiCdma_IsBusy(InstancePtr)) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Engine is busy\r\n");

		return XST_FAILURE;
	}

	/* The driver is still handling the previous simple transfer
	 */
	if (InstancePtr->SimpleNotDone) {
		xdbg_printf(XDBG_DEBUG_ERROR, "Simple ongoing\r\n");

		return XST_FAILURE;
	}

	/* If the engine is in scatter gather mode, try switch to simple mode
	 */
	if (!XAxiCdma_IsSimpleMode(InstancePtr)) {

		if (XAxiCdma_SwitchMode(InstancePtr, XAXICDMA_SIMPLE_MODE) !=
		    XST_SUCCESS) {

			xdbg_printf(XDBG_DEBUG_ERROR,
			    "Cannot switch to simple mode\r\n");

			return XST_FAILURE;
		}
	}

	/* Setup the flag so that others will not step on us
	 *
	 * This flag is only set if callback function is used and if the
	 * system is in interrupt mode; otherwise, when the hardware is done
	 * with the transfer, the driver is done with the transfer
	 */
	if ((SimpleCallBack != NULL) ||
	       ((XAxiCdma_IntrGetEnabled(InstancePtr) &
	        XAXICDMA_XR_IRQ_SIMPLE_ALL_MASK) != 0x0)) {

		InstancePtr->SimpleNotDone = 1;
	}

	InstancePtr->SimpleCallBackFn = SimpleCallBack;
	InstancePtr->SimpleCallBackRef = CallBackRef;

	XAxiCdma_WriteReg(InstancePtr->BaseAddr, XAXICDMA_SRCADDR_OFFSET,
			  LOWER_32_BITS(SrcAddr));
	if (InstancePtr->AddrWidth > 32)
		XAxiCdma_WriteReg(InstancePtr->BaseAddr,
				  XAXICDMA_SRCADDR_MSB_OFFSET,
				  UPPER_32_BITS(SrcAddr));

	XAxiCdma_WriteReg(InstancePtr->BaseAddr, XAXICDMA_DSTADDR_OFFSET,
			  LOWER_32_BITS(DstAddr));
	if (InstancePtr->AddrWidth > 32)
		XAxiCdma_WriteReg(InstancePtr->BaseAddr,
				  XAXICDMA_DSTADDR_MSB_OFFSET,
				  UPPER_32_BITS(DstAddr));

	/* Writing to the BTT register starts the transfer
	 */
	XAxiCdma_WriteReg(InstancePtr->BaseAddr, XAXICDMA_BTT_OFFSET,
		Length);

	return XST_SUCCESS;
}
Exemplo n.º 6
0
/*
 * Change the hardware mode
 *
 * If to switch to SG mode, check whether needs to setup the current BD
 * pointer register.
 *
 * @param	InstancePtr is the driver instance we are working on
 * @param	Mode is the mode to switch to.
 *
 * @return
 *		- XST_SUCCESS if mode switch is successful
 *		- XST_DEVICE_BUSY if the engine is busy, so cannot switch mode
 *		- XST_INVALID_PARAM if pass in invalid mode value
 *		- XST_FAILURE if:Hardware is simple mode only build
 *		Mode switch failed
 *
 * @note	None.
 *
 *****************************************************************************/
int XAxiCdma_SwitchMode(XAxiCdma *InstancePtr, int Mode)
{

	if (Mode == XAXICDMA_SIMPLE_MODE) {

		if (XAxiCdma_IsSimpleMode(InstancePtr)) {
			return XST_SUCCESS;
		}

		if (XAxiCdma_IsBusy(InstancePtr)) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "SwitchMode: engine is busy\r\n");
			return XST_DEVICE_BUSY;
		}

		/* Keep the CDESC so that CDESC will be
		 * reloaded when switch to SG mode again
		 *
		 * We know CDESC is valid because the hardware can only
		 * be in SG mode if a SG transfer has been submitted.
		 */
		InstancePtr->BdaRestart = XAxiCdma_BdRingNext(InstancePtr,
		    XAxiCdma_BdRingGetCurrBd(InstancePtr));

		/* Update the CR register to switch to simple mode
		 */
		XAxiCdma_WriteReg(InstancePtr->BaseAddr, XAXICDMA_CR_OFFSET,
		  (XAxiCdma_ReadReg(InstancePtr->BaseAddr, XAXICDMA_CR_OFFSET)
		  & ~XAXICDMA_CR_SGMODE_MASK));

		/* Hardware mode switch is quick, should succeed right away
		 */
		if (XAxiCdma_IsSimpleMode(InstancePtr)) {

			return XST_SUCCESS;
		}
		else {
			return XST_FAILURE;
		}
	}
	else if (Mode == XAXICDMA_SG_MODE) {

		if (!XAxiCdma_IsSimpleMode(InstancePtr)) {
			return XST_SUCCESS;
		}

		if (InstancePtr->SimpleOnlyBuild) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "SwitchMode: hardware simple mode only\r\n");
			return XST_FAILURE;
		}

		if (XAxiCdma_IsBusy(InstancePtr)) {
			xdbg_printf(XDBG_DEBUG_ERROR,
			    "SwitchMode: engine is busy\r\n");
			return XST_DEVICE_BUSY;
		}

		/* Update the CR register to switch to SG mode
		 */
		XAxiCdma_WriteReg(InstancePtr->BaseAddr, XAXICDMA_CR_OFFSET,
		  (XAxiCdma_ReadReg(InstancePtr->BaseAddr, XAXICDMA_CR_OFFSET)
		  | XAXICDMA_CR_SGMODE_MASK));

		/* Hardware mode switch is quick, should succeed right away
		 */
		if (!XAxiCdma_IsSimpleMode(InstancePtr)) {

			/* Update the CDESC register, because the hardware is
			 * to start from the CDESC
			 */
			XAxiCdma_BdSetCurBdPtr(InstancePtr,
				(UINTPTR)InstancePtr->BdaRestart);

			return XST_SUCCESS;
		}
		else {
			return XST_FAILURE;
		}
	}
	else {	/* Invalid mode */
		return XST_INVALID_PARAM;
	}
}
/**
* This function transfers data from Source Address to Destination Address
* using the AXI CDMA.
* User has to specify the Source Address, Destination Address and Transfer
* Length in AXICDMA_SRC_ADDR, AXICDMA_DEST_ADDR and AXICDMA_LENGTH defines
* respectively.
*
* @param	DeviceId is device ID of the XAxiCdma Device.
*
* @return	- XST_SUCCESS if successful
*		- XST_FAILURE.if unsuccessful.
*
* @note		If the hardware system is not built correctly, this function
*		may never return to the caller.
*
******************************************************************************/
int DmaDataTransfer (u16 DeviceID)
{
	int Status;
	volatile int Error;
	XAxiCdma_Config *ConfigPtr;

	Error = 0;

	/*
	 * Make sure we have a valid addresses for Src and Dst.
	 */
	if (AXICDMA_SRC_ADDR == 0) {
		return XST_FAILURE;
	}

	if (AXICDMA_DEST_ADDR == 0) {
		return XST_FAILURE;
	}

	/*
	 * Initialize the AXI CDMA IP.
	 */
	ConfigPtr = XAxiCdma_LookupConfig(DeviceID);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}

	Status = XAxiCdma_CfgInitialize(&CdmaInstance,
				ConfigPtr, ConfigPtr->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Reset the AXI CDMA device.
	 */
	XAxiCdma_Reset(&CdmaInstance);

	/*
	 * Disable AXI CDMA Interrupts
	 */
	XAxiCdma_IntrDisable(&CdmaInstance, XAXICDMA_XR_IRQ_ALL_MASK);

	/*
	 * Start Transferring Data from source to destination in polled mode
	 */
	XAxiCdma_SimpleTransfer (&CdmaInstance, AXICDMA_SRC_ADDR,
					AXICDMA_DEST_ADDR, AXICDMA_LENGTH, 0, 0);

	/*
	 * Poll Status register waiting for either Completion or Error
	 */
	while (XAxiCdma_IsBusy(&CdmaInstance));

	Error = XAxiCdma_GetError(&CdmaInstance);

	if (Error != 0x0) {

		xil_printf("AXI CDMA Transfer Error =  %8.8x\r\n");
		return XST_FAILURE;
	}

	xil_printf("AXI CDMA Transfer is Complete\r\n");


	return XST_SUCCESS;
}
Exemplo n.º 8
0
/* Function will spin until dma is done. On error, reset device */
Hbool dma_getdone( XAxiCdma *dma )
{
   return (Hbool) (XAxiCdma_IsBusy(dma));
}
Exemplo n.º 9
0
u32 GetRequestCmd(P_HOST_CMD hostCmd)
{
	u32 hostAddr, isDmaError;
	P_REQUEST_IO reqInfoAddr = (P_REQUEST_IO)(REQUEST_IO_BASE_ADDR);

	barAddrPtr.UpperAddr = Xil_In32(CONFIG_SPACE_REQUEST_BASE_ADDR_U);
	barAddrPtr.LowerAddr = Xil_In32(CONFIG_SPACE_REQUEST_BASE_ADDR_L);
	//DebugPrint("BarAddrPtr.UpperAddr = 0x%x\n\r", BarAddrPtr.UpperAddr);
	//DebugPrint("BarAddrPtr.LowerAddr = 0x%x\n\r", BarAddrPtr.LowerAddr);
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	while(1)
	{
		XAxiPcie_SetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtr);
		XAxiPcie_GetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtrForTest);
		if(barAddrPtr.LowerAddr == barAddrPtrForTest.LowerAddr)
		{
			if(barAddrPtr.UpperAddr == barAddrPtrForTest.UpperAddr)
			{
				break;
			}
		}
	}

	hostAddr = Xil_In32(CONFIG_SPACE_REQUEST_BASE_ADDR_L) & DMA_ADDR_MASK;
	hostAddr = XPAR_AXIPCIE_0_AXIBAR_0 + hostAddr;

	//wait until cdma is idle
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	do
	{
		isDmaError = XAxiCdma_SimpleTransfer(&devCdma, hostAddr, (u32)reqInfoAddr, sizeof(REQUEST_IO), NULL, NULL);
		if(isDmaError)
			DebugPrint("%s, %d\n\r", __FUNCTION__, __LINE__);
	}
	while(isDmaError);

	//wait until dma operation is done
	DebugPrint("getting requst cmd... ");
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	DebugPrint("done!\n\r");

	*((u32*)(&hostCmd->reqInfo)) = Xil_In32((u32)(reqInfoAddr));
	hostCmd->reqInfo.currentSect = Xil_In32((u32)(&reqInfoAddr->currentSect));
	hostCmd->reqInfo.ReqSect = Xil_In32((u32)(&reqInfoAddr->ReqSect));
	hostCmd->reqInfo.HostScatterAddrU = Xil_In32((u32)(&reqInfoAddr->HostScatterAddrU));
	hostCmd->reqInfo.HostScatterAddrL = Xil_In32((u32)(&reqInfoAddr->HostScatterAddrL));
	hostCmd->reqInfo.HostScatterLen = Xil_In32((u32)(&reqInfoAddr->HostScatterLen));

	DebugPrint("Cmd = 0x%x\n\r", hostCmd->reqInfo.Cmd);
	DebugPrint("currentSect = 0x%x\n\r", hostCmd->reqInfo.currentSect);
	DebugPrint("ReqSect = 0x%x\n\r", hostCmd->reqInfo.ReqSect);
	DebugPrint("HostScatterAddrU = 0x%x\n\r", hostCmd->reqInfo.HostScatterAddrU);
	DebugPrint("HostScatterAddrL = 0x%x\n\r", hostCmd->reqInfo.HostScatterAddrL);
	DebugPrint("HostScatterLen = 0x%x\n\r\n\r", hostCmd->reqInfo.HostScatterLen);

	return TRUE;
}
Exemplo n.º 10
0
void CompleteCmd(P_HOST_CMD hostCmd)
{
	u32 hostAddr, isDmaError;

	barAddrPtr.UpperAddr = Xil_In32(CONFIG_SPACE_COMPLETION_BASE_ADDR_U);
	barAddrPtr.LowerAddr = Xil_In32(CONFIG_SPACE_COMPLETION_BASE_ADDR_L);
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	XAxiPcie_SetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtr);

	//DebugPrint("Completion IO addr: 0x%x\n\r", Xil_In32(COMPLETION_IO_BASE_ADDR));

	pCompletionIO->CmdStatus = hostCmd->CmdStatus;
	pCompletionIO->ErrorStatus = hostCmd->ErrorStatus;
	pCompletionIO->Done = 0;

	pCompletionIO->debug_ReqCount++;


	hostAddr = Xil_In32(CONFIG_SPACE_COMPLETION_BASE_ADDR_L) & DMA_ADDR_MASK;
	hostAddr = XPAR_AXIPCIE_0_AXIBAR_0 + hostAddr;

	//DebugPrint("i = 0x%x\n\r", hostAddr);
	//wait until cdma is idle
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}

	do
	{
		isDmaError = XAxiCdma_SimpleTransfer(&devCdma, COMPLETION_IO_BASE_ADDR, hostAddr, sizeof(COMPLETION_IO), NULL, NULL);
		if(isDmaError)
			DebugPrint("%s, %d\n\r", __FUNCTION__, __LINE__);
	}
	while(isDmaError);


	//DebugPrint("posting completion cmd without deadface... ");
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	//DebugPrint("done!\n\r");

	pCompletionIO->Done = 0xdeadface;

	do
	{
		isDmaError = XAxiCdma_SimpleTransfer(&devCdma, COMPLETION_IO_BASE_ADDR, hostAddr, sizeof(COMPLETION_IO), NULL, NULL);
		if(isDmaError)
			DebugPrint("%s, %d\n\r", __FUNCTION__, __LINE__);
	}
	while(isDmaError);
	
	//DebugPrint("posting completion cmd with deadface... ");
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	//DebugPrint("done!\n\r");

	DebugPrint("return CompleteCmd\n\r\n\r\n\r");
}
Exemplo n.º 11
0
void DmaHostToDevice(P_HOST_CMD hostCmd, u32 deviceAddr, u32 reqSize, u32 scatterLength)
{
	u32 hostAddr;
	u32 flag;
	u32 deviceAddrOffset;
	u32 curScatterRegionNum;
	u32 curDmaSize;
	u32 remainedCurrentScatterRegionSize;
	u32 acc;
	u32 isDmaError;

	/////////////////////////////////////////////////////////////////////
	//get HOST_SCATTER_REGION array from HOST
	/////////////////////////////////////////////////////////////////////
	barAddrPtr.UpperAddr = hostCmd->reqInfo.HostScatterAddrU;
	barAddrPtr.LowerAddr = hostCmd->reqInfo.HostScatterAddrL;

	//DebugPrint("scatterRegionAddrU = 0x%x\n\r", barAddrPtr.UpperAddr);
	//DebugPrint("scatterRegionAddrL = 0x%x\n\r", barAddrPtr.LowerAddr);
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	while(1)
	{
		XAxiPcie_SetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtr);
		XAxiPcie_GetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtrForTest);
		if(barAddrPtr.LowerAddr == barAddrPtrForTest.LowerAddr)
		{
			if(barAddrPtr.UpperAddr == barAddrPtrForTest.UpperAddr)
			{
				break;
			}
		}
	}

	hostAddr = hostCmd->reqInfo.HostScatterAddrL & DMA_ADDR_MASK;
	hostAddr = XPAR_AXIPCIE_0_AXIBAR_0 + hostAddr;

	//wait until cdma is idle
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	DebugPrint("hostAddr = 0x%x\n\r", hostAddr);
	//get host scatter region

	do
	{
		isDmaError = XAxiCdma_SimpleTransfer(&devCdma, hostAddr, HOST_SCATTER_REGION_BASE_ADDR,
					sizeof(HOST_SCATTER_REGION) * scatterLength, NULL, NULL);
		if(isDmaError)
			DebugPrint("%s, %d\n\r", __FUNCTION__, __LINE__);
	}
	while(isDmaError);

	DebugPrint("getting HOST_SCATTER_REGION data... ");
	while(XAxiCdma_IsBusy(&devCdma))
	{
	}
	DebugPrint("done!\n\r");

	/////////////////////////////////////////////////////////////////////
	//start data dma
	/////////////////////////////////////////////////////////////////////

	flag = 0;
	deviceAddrOffset = 0;
	curScatterRegionNum = 0;
	acc = 0;

	while(curScatterRegionNum < scatterLength)
	{
		remainedCurrentScatterRegionSize = pHostScaterRegion[curScatterRegionNum].Length - acc;
		DebugPrint("remainedCurrentScatterRegionSize = 0x%x\n\r", remainedCurrentScatterRegionSize);
		if(flag == 0)//normal transfer
		{
			DebugPrint("flag 0\n\r");
			//set host address
			barAddrPtr.UpperAddr = pHostScaterRegion[curScatterRegionNum].DmaAddrU;
			barAddrPtr.LowerAddr = pHostScaterRegion[curScatterRegionNum].DmaAddrL;

			hostAddr = barAddrPtr.LowerAddr & DMA_ADDR_MASK;
			hostAddr = XPAR_AXIPCIE_0_AXIBAR_0 + hostAddr;

			//if blabla~
			if(((XPAR_AXIPCIE_0_AXIBAR_HIGHADDR_0 + 1) - hostAddr) < remainedCurrentScatterRegionSize)//
			{
				flag = 1;
				curDmaSize = (XPAR_AXIPCIE_0_AXIBAR_HIGHADDR_0 + 1) - hostAddr;
				acc += curDmaSize;
			}
			//if blabla~
			else
			{
				curDmaSize = remainedCurrentScatterRegionSize;
				curScatterRegionNum += 1;
			}
		}
		else//partial transfer
		{
			DebugPrint("flag 1\n\r");
			//set host address
			if((barAddrPtr.LowerAddr + curDmaSize) < barAddrPtr.LowerAddr)
			{
				barAddrPtr.UpperAddr += 1;
			}
			barAddrPtr.LowerAddr += curDmaSize;

			hostAddr = barAddrPtr.LowerAddr & DMA_ADDR_MASK;
			hostAddr = XPAR_AXIPCIE_0_AXIBAR_0 + hostAddr;

			//if blabla~
			if(((XPAR_AXIPCIE_0_AXIBAR_HIGHADDR_0 + 1) - hostAddr) < remainedCurrentScatterRegionSize)//
			{
				curDmaSize = (XPAR_AXIPCIE_0_AXIBAR_HIGHADDR_0 + 1) - hostAddr;
				acc += curDmaSize;
			}
			//if blabla~
			else//last
			{
				curDmaSize = remainedCurrentScatterRegionSize;
				flag = 0;
				acc = 0;
				curScatterRegionNum += 1;
			}
		}

		DebugPrint("dmaAddrU = 0x%x\n\r", barAddrPtr.UpperAddr);
		DebugPrint("dmaAddrL = 0x%x\n\r", barAddrPtr.LowerAddr);
		while(XAxiCdma_IsBusy(&devCdma))
		{
		}
		while(1)
		{
			XAxiPcie_SetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtr);
			XAxiPcie_GetLocalBusBar2PcieBar(&devPcie, 0x00, &barAddrPtrForTest);
			if(barAddrPtr.LowerAddr == barAddrPtrForTest.LowerAddr)
			{
				if(barAddrPtr.UpperAddr == barAddrPtrForTest.UpperAddr)
				{
					break;
				}
			}
		}

		while(XAxiCdma_IsBusy(&devCdma))
		{
		}
		do
		{
			isDmaError = XAxiCdma_SimpleTransfer(&devCdma, hostAddr, deviceAddr + deviceAddrOffset,
													curDmaSize, NULL, NULL);
			if(isDmaError)
				DebugPrint("%s, %d\n\r", __FUNCTION__, __LINE__);
		}
		while(isDmaError);

		while(XAxiCdma_IsBusy(&devCdma))
		{
		}
		deviceAddrOffset += curDmaSize;
	}

	DebugPrint("%x\n\r", Xil_In32(deviceAddr));
}
void wlan_mac_cdma_finish_transfer(){
	while(XAxiCdma_IsBusy(&cdma_inst)) {}
	return;
}
/*
* This function does one simple transfer in polled mode
*
* @param	InstancePtr is a pointer to the XAxiCdma instance
* @param	Length is the transfer length
* @param	Retries is how many times to retry on submission
*
* @return
*		- XST_SUCCESS if transfer is successful
*		- XST_FAILURE if either the transfer fails or the data has
*		  error
*
* @note		None
*
******************************************************************************/
static int DoSimplePollTransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{
	int Index;
	u8  *SrcPtr;
	u8  *DestPtr;
	int Status;

	/* Initialize the source buffer bytes with a pattern and the
	 * the destination buffer bytes to zero
	 */
	SrcPtr = (u8 *)SrcBuffer;
	DestPtr = (u8 *)DestBuffer;
	for (Index = 0; Index < BUFFER_BYTESIZE; Index++) {
		SrcPtr[Index] = Index & 0xFF;
		DestPtr[Index] = 0;
	}

	/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
	 * is enabled
	 */
	Xil_DCacheFlushRange((u32)&SrcBuffer, Length);

	/* Try to start the DMA transfer
	 */
	while (Retries) {
		Retries -= 1;

		Status = XAxiCdma_SimpleTransfer(InstancePtr, (u32)SrcBuffer,
			(u32)DestBuffer, Length, NULL, NULL);
		if (Status == XST_SUCCESS) {
			break;
		}
	}

	/* Return failure if failed to submit the transfer
	 */
	if (!Retries) {
		return XST_FAILURE;
	}

	/* Wait until the DMA transfer is done
	 */
	while (XAxiCdma_IsBusy(InstancePtr)) {
		/* Wait */
	}

	/* If the hardware has errors, this example fails
	 * This is a poll example, no interrupt handler is involved.
	 * Therefore, error conditions are not cleared by the driver.
	 */
	Error = XAxiCdma_GetError(InstancePtr);
	if (Error != 0x0) {
		int TimeOut = RESET_LOOP_COUNT;

		/* Need to reset the hardware to restore to the correct state
		 */
		XAxiCdma_Reset(InstancePtr);

		while (TimeOut) {
			if (XAxiCdma_ResetIsDone(InstancePtr)) {
				break;
			}
			TimeOut -= 1;
		}

		/* Reset has failed, print a message to notify the user
		 */
		return XST_FAILURE;
	}

	/* Transfer completes successfully, check data
	 */
	Status = CheckData(SrcPtr, DestPtr, Length);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}