/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ======================================================================== */ NDIS_STATUS RTUSBEnqueueInternalCmd( IN PRTMP_ADAPTER pAd, IN NDIS_OID Oid, IN PVOID pInformationBuffer, IN UINT32 InformationBufferLength) { NDIS_STATUS status; PCmdQElmt cmdqelmt = NULL; status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) return (NDIS_STATUS_RESOURCES); NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt)); if(InformationBufferLength > 0) { status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); return (NDIS_STATUS_RESOURCES); } else { NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); cmdqelmt->bufferlength = InformationBufferLength; } } else { cmdqelmt->buffer = NULL; cmdqelmt->bufferlength = 0; } cmdqelmt->command = Oid; cmdqelmt->CmdFromNdis = FALSE; if (cmdqelmt != NULL) { NdisAcquireSpinLock(&pAd->CmdQLock); if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT) { EnqueueCmd((&pAd->CmdQ), cmdqelmt); status = NDIS_STATUS_SUCCESS; } else { status = NDIS_STATUS_FAILURE; } NdisReleaseSpinLock(&pAd->CmdQLock); if (status == NDIS_STATUS_FAILURE) { if (cmdqelmt->buffer) NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); } else RTUSBCMDUp(pAd); } return(NDIS_STATUS_SUCCESS); }
/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ======================================================================== */ NDIS_STATUS RTUSBEnqueueCmdFromNdis( IN PRTMP_ADAPTER pAd, IN NDIS_OID Oid, IN BOOLEAN SetInformation, IN PVOID pInformationBuffer, IN UINT32 InformationBufferLength) { NDIS_STATUS status; PCmdQElmt cmdqelmt = NULL; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; #ifndef RT30xx CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) #endif #ifdef RT30xx if (pObj->RTUSBCmdThr_pid < 0) #endif return (NDIS_STATUS_RESOURCES); status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) return (NDIS_STATUS_RESOURCES); cmdqelmt->buffer = NULL; if (pInformationBuffer != NULL) { status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { kfree(cmdqelmt); return (NDIS_STATUS_RESOURCES); } else { NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); cmdqelmt->bufferlength = InformationBufferLength; } } else cmdqelmt->bufferlength = 0; cmdqelmt->command = Oid; cmdqelmt->CmdFromNdis = TRUE; if (SetInformation == TRUE) cmdqelmt->SetOperation = TRUE; else cmdqelmt->SetOperation = FALSE; NdisAcquireSpinLock(&pAd->CmdQLock); if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT) { EnqueueCmd((&pAd->CmdQ), cmdqelmt); status = NDIS_STATUS_SUCCESS; } else { status = NDIS_STATUS_FAILURE; } NdisReleaseSpinLock(&pAd->CmdQLock); if (status == NDIS_STATUS_FAILURE) { if (cmdqelmt->buffer) NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); } else RTUSBCMDUp(pAd); return(NDIS_STATUS_SUCCESS); }
/* ======================================================================== Routine Description: Initialize transmit data structures. Arguments: pAd Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_RESOURCES Note: ======================================================================== */ NDIS_STATUS NICInitTransmit( IN PRTMP_ADAPTER pAd) { #define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \ Context->pUrb = RTUSB_ALLOC_URB(0); \ if (Context->pUrb == NULL) { \ DBGPRINT(RT_DEBUG_ERROR, msg1); \ Status = NDIS_STATUS_RESOURCES; \ goto err1; } \ \ Context->TransferBuffer = \ (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \ if (Context->TransferBuffer == NULL) { \ DBGPRINT(RT_DEBUG_ERROR, msg2); \ Status = NDIS_STATUS_RESOURCES; \ goto err2; } #define LM_URB_FREE(pObj, Context, BufferSize) \ if (NULL != Context->pUrb) { \ RTUSB_UNLINK_URB(Context->pUrb); \ RTUSB_FREE_URB(Context->pUrb); \ Context->pUrb = NULL; } \ if (NULL != Context->TransferBuffer) { \ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ Context->TransferBuffer, \ Context->data_dma); \ Context->TransferBuffer = NULL; } UCHAR i, acidx; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PTX_CONTEXT pNullContext = &(pAd->NullContext); PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); PTX_CONTEXT pRTSContext = &(pAd->RTSContext); PTX_CONTEXT pMLMEContext = NULL; // PHT_TX_CONTEXT pHTTXContext = NULL; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; PVOID RingBaseVa; // RTMP_TX_RING *pTxRing; RTMP_MGMT_RING *pMgmtRing; DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); pObj = pObj; // Init 4 set of Tx parameters for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++) { // Initialize all Transmit releated queues InitializeQueueHeader(&pAd->TxSwQueue[acidx]); // Next Local tx ring pointer waiting for buck out pAd->NextBulkOutIndex[acidx] = acidx; pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag //pAd->DataBulkDoneIdx[acidx] = 0; } //pAd->NextMLMEIndex = 0; //pAd->PushMgmtIndex = 0; //pAd->PopMgmtIndex = 0; //InterlockedExchange(&pAd->MgmtQueueSize, 0); //InterlockedExchange(&pAd->TxCount, 0); //pAd->PrioRingFirstIndex = 0; //pAd->PrioRingTxCnt = 0; do { // // TX_RING_SIZE, 4 ACs // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) for(acidx=0; acidx<4; acidx++) #endif // CONFIG_STA_SUPPORT // { #if 1 //def DOT11_N_SUPPORT PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status, ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx), done, ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx), out1); NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4); pHTTXContext->pAd = pAd; pHTTXContext->pIrp = NULL; pHTTXContext->IRPPending = FALSE; pHTTXContext->NextBulkOutPosition = 0; pHTTXContext->ENextBulkOutPosition = 0; pHTTXContext->CurWritePosition = 0; pHTTXContext->CurWriteRealPos = 0; pHTTXContext->BulkOutSize = 0; pHTTXContext->BulkOutPipeId = acidx; pHTTXContext->bRingEmpty = TRUE; pHTTXContext->bCopySavePad = FALSE; #endif // DOT11_N_SUPPORT // pAd->BulkOutPending[acidx] = FALSE; } // // MGMT_RING_SIZE // #if 0 for(i=0; i<MGMT_RING_SIZE; i++) // 8 { PTX_CONTEXT pMLMEContext = &(pAd->MLMEContext[i]); NdisZeroMemory(pMLMEContext, sizeof(TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pMLMEContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i), out2, ("<-- ERROR in Alloc TX MLMEContext[%d] TX_BUFFER !! \n", i), out2); pMLMEContext->pAd = pAd; pMLMEContext->pIrp = NULL; pMLMEContext->InUse = FALSE; pMLMEContext->IRPPending = FALSE; } #else // Allocate MGMT ring descriptor's memory pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT); RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); if (pAd->MgmtDescRing.AllocVa == NULL) { DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); Status = NDIS_STATUS_RESOURCES; goto out1; } NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); RingBaseVa = pAd->MgmtDescRing.AllocVa; // Initialize MGMT Ring and associated buffer memory pMgmtRing = &pAd->MgmtRing; for (i = 0; i < MGMT_RING_SIZE; i++) { // link the pre-allocated Mgmt buffer to MgmtRing.Cell pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT); pMgmtRing->Cell[i].AllocVa = RingBaseVa; pMgmtRing->Cell[i].pNdisPacket = NULL; pMgmtRing->Cell[i].pNextNdisPacket = NULL; //Allocate URB for MLMEContext pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); if (pMLMEContext->pUrb == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i)); Status = NDIS_STATUS_RESOURCES; goto out2; } pMLMEContext->pAd = pAd; pMLMEContext->pIrp = NULL; pMLMEContext->TransferBuffer = NULL; pMLMEContext->InUse = FALSE; pMLMEContext->IRPPending = FALSE; pMLMEContext->bWaitingBulkOut = FALSE; pMLMEContext->BulkOutSize = 0; pMLMEContext->SelfIdx = i; // Offset to next ring descriptor address RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT); } DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i)); //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; pAd->MgmtRing.TxCpuIdx = 0; pAd->MgmtRing.TxDmaIdx = 0; #endif // // BEACON_RING_SIZE // for(i=0; i<BEACON_RING_SIZE; i++) // 2 { PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]); NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i), out2, ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i), out3); pBeaconContext->pAd = pAd; pBeaconContext->pIrp = NULL; pBeaconContext->InUse = FALSE; pBeaconContext->IRPPending = FALSE; } // // NullContext // NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, ("<-- ERROR in Alloc TX NullContext urb!! \n"), out3, ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"), out4); pNullContext->pAd = pAd; pNullContext->pIrp = NULL; pNullContext->InUse = FALSE; pNullContext->IRPPending = FALSE; // // RTSContext // NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, ("<-- ERROR in Alloc TX RTSContext urb!! \n"), out4, ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"), out5); pRTSContext->pAd = pAd; pRTSContext->pIrp = NULL; pRTSContext->InUse = FALSE; pRTSContext->IRPPending = FALSE; // // PsPollContext // //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT)); //Allocate URB LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, ("<-- ERROR in Alloc TX PsPollContext urb!! \n"), out5, ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"), out6); pPsPollContext->pAd = pAd; pPsPollContext->pIrp = NULL; pPsPollContext->InUse = FALSE; pPsPollContext->IRPPending = FALSE; pPsPollContext->bAggregatible = FALSE; pPsPollContext->LastOne = TRUE; } while (FALSE); done: DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n")); return Status; /* --------------------------- ERROR HANDLE --------------------------- */ out6: LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); out5: LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); out4: LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); out3: for(i=0; i<BEACON_RING_SIZE; i++) { PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]); if (pBeaconContext) LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); } out2: if (pAd->MgmtDescRing.AllocVa) { pMgmtRing = &pAd->MgmtRing; for(i=0; i<MGMT_RING_SIZE; i++) { pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; if (pMLMEContext) LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); } NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0); pAd->MgmtDescRing.AllocVa = NULL; } out1: #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) for(acidx=0; acidx<4; acidx++) #endif // CONFIG_STA_SUPPORT // { PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]); if (pTxContext) LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER)); } // Here we didn't have any pre-allocated memory need to free. return Status; }