/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkInIRP( IN PRTMP_ADAPTER pAd) { PRX_CONTEXT pRxContext; PCMD_RSP_CONTEXT pCmdRspEventContext = &pAd->CmdRspEventContext; UINT i; DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); for ( i = 0; i < (RX_RING_SIZE); i++) { pRxContext = &(pAd->RxContext[i]); if(pRxContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pRxContext->pUrb); pRxContext->IRPPending = FALSE; pRxContext->InUse = FALSE; /*NdisInterlockedDecrement(&pAd->PendingRx);*/ /*pAd->PendingRx--;*/ } } if (pCmdRspEventContext->IRPPending == TRUE) { printk("unlink cmd rsp urb\n"); RTUSB_UNLINK_URB(pCmdRspEventContext->pUrb); pCmdRspEventContext->IRPPending = FALSE; pCmdRspEventContext->InUse = FALSE; } DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd) { struct rt_rx_context *pRxContext; u32 i; DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); for (i = 0; i < (RX_RING_SIZE); i++) { pRxContext = &(pAd->RxContext[i]); if (pRxContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pRxContext->pUrb); pRxContext->IRPPending = FALSE; pRxContext->InUse = FALSE; /*NdisInterlockedDecrement(&pAd->PendingRx); */ /*pAd->PendingRx--; */ } } DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkInIRP( IN PRTMP_ADAPTER pAd) { PRX_CONTEXT pRxContext; UINT i; DBGPRINT_RAW(RT_DEBUG_TRACE,"--->RTUSBCancelPendingBulkInIRP\n"); for ( i = 0; i < RX_RING_SIZE; i++) { pRxContext = &(pAd->RxContext[i]); if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE) { RTUSB_UNLINK_URB(pRxContext->pUrb); } atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_START); } DBGPRINT_RAW(RT_DEBUG_TRACE,"<---RTUSBCancelPendingBulkInIRP\n"); }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkInIRP( IN PRTMP_ADAPTER pAd) { PRX_CONTEXT pRxContext; UINT i; DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); for ( i = 0; i < (RX_RING_SIZE); i++) { pRxContext = &(pAd->RxContext[i]); if(pRxContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pRxContext->pUrb); pRxContext->IRPPending = FALSE; pRxContext->InUse = FALSE; //NdisInterlockedDecrement(&pAd->PendingRx); //pAd->PendingRx--; } } DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); }
/* ======================================================================== Routine Description: Arguments: Return Value: None Note: ======================================================================== */ VOID ATE_RTUSBCancelPendingBulkInIRP( IN PRTMP_ADAPTER pAd) { PRX_CONTEXT pRxContext = NULL; UINT rx_ring_index; DBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n")); for (rx_ring_index = 0; rx_ring_index < (RX_RING_SIZE); rx_ring_index++) { pRxContext = &(pAd->RxContext[rx_ring_index]); if (pRxContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pRxContext->pUrb); pRxContext->IRPPending = FALSE; pRxContext->InUse = FALSE; } } DBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n")); return; }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkOutIRP( IN PRTMP_ADAPTER pAd) { PTX_CONTEXT pTxContext; PTX_CONTEXT pMLMEContext; PTX_CONTEXT pBeaconContext; PTX_CONTEXT pNullContext; PTX_CONTEXT pPsPollContext; PTX_CONTEXT pRTSContext; UINT i, Idx; unsigned long IrqFlags; for (Idx = 0; Idx < 4; Idx++) { for (i = 0; i < TX_RING_SIZE; i++) { pTxContext = &(pAd->TxContext[Idx][i]); if (pTxContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pTxContext->pUrb); // Sleep 200 microseconds to give cancellation time to work RTMPusecDelay(200); } } } for (i = 0; i < PRIO_RING_SIZE; i++) { pMLMEContext = &(pAd->MLMEContext[i]); if(pMLMEContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pMLMEContext->pUrb); // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } for (i = 0; i < BEACON_RING_SIZE; i++) { pBeaconContext = &(pAd->BeaconContext[i]); if(pBeaconContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pBeaconContext->pUrb); // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } pNullContext = &(pAd->NullContext); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pRTSContext = &(pAd->RTSContext); if (pRTSContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pRTSContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx], IrqFlags); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], IrqFlags); } }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkOutIRP( IN PRTMP_ADAPTER pAd) { PHT_TX_CONTEXT pHTTXContext; PTX_CONTEXT pMLMEContext; PTX_CONTEXT pNullContext; PTX_CONTEXT pPsPollContext; UINT i, Idx; /* unsigned int IrqFlags;*/ /* NDIS_SPIN_LOCK *pLock;*/ /* BOOLEAN *pPending;*/ /* pLock = &pAd->BulkOutLock[MGMTPIPEIDX];*/ /* pPending = &pAd->BulkOutPending[MGMTPIPEIDX];*/ for (Idx = 0; Idx < 4; Idx++) { pHTTXContext = &(pAd->TxContext[Idx]); if (pHTTXContext->IRPPending == TRUE) { /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/ /* when the last IRP on the list has been cancelled; that's how we exit this loop*/ #ifdef USB_BULK_BUF_ALIGMENT INT ringidx;; for(ringidx=0;ringidx < BUF_ALIGMENT_RINGSIZE ;ringidx++) RTUSB_UNLINK_URB(pHTTXContext->pUrb[ringidx]); #else RTUSB_UNLINK_URB(pHTTXContext->pUrb); #endif /* USB_BULK_BUF_ALIGMENT */ /* Sleep 200 microseconds to give cancellation time to work*/ RTMPusecDelay(200); } pAd->BulkOutPending[Idx] = FALSE; } /*RTMP_IRQ_LOCK(pLock, IrqFlags);*/ for (i = 0; i < MGMT_RING_SIZE; i++) { pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; if(pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself*/ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList*/ /* when the last IRP on the list has been cancelled; that's how we exit this loop*/ RTUSB_UNLINK_URB(pMLMEContext->pUrb); pMLMEContext->IRPPending = FALSE; /* Sleep 200 microsecs to give cancellation time to work*/ RTMPusecDelay(200); } } pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; /*RTMP_IRQ_UNLOCK(pLock, IrqFlags);*/ pNullContext = &(pAd->NullContext[0]); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } }
void RTUSBWatchDog(struct rt_rtmp_adapter *pAd) { struct rt_ht_tx_context *pHTTXContext; int idx; unsigned long irqFlags; PURB pUrb; BOOLEAN needDumpSeq = FALSE; u32 MACValue; u32 TxRxQ_Pcnt; idx = 0; RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); if ((MACValue & 0xff) != 0) { DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n", MACValue)); RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); while ((MACValue & 0xff) != 0 && (idx++ < 10)) { RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); RTMPusecDelay(1); } RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); } if (pAd->watchDogRxOverFlowCnt >= 2) { DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); if ((!RTMP_TEST_FLAG (pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); needDumpSeq = TRUE; } pAd->watchDogRxOverFlowCnt = 0; } RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt); for (idx = 0; idx < NUM_OF_TX_RING; idx++) { pUrb = NULL; RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt) { int actual_length = 0, transfer_buffer_length = 0; BOOLEAN isDataPacket = FALSE; pAd->watchDogTxPendingCnt[idx]++; if ((pAd->watchDogTxPendingCnt[idx] > 2) && (!RTMP_TEST_FLAG (pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET))) ) { /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */ pHTTXContext = (struct rt_ht_tx_context *)(&pAd->TxContext[idx]); if (pHTTXContext->IRPPending) { /* Check TxContext. */ pUrb = pHTTXContext->pUrb; actual_length = pUrb->actual_length; transfer_buffer_length = pUrb->transfer_buffer_length; isDataPacket = TRUE; } else if (idx == MGMTPIPEIDX) { struct rt_tx_context *pMLMEContext, *pNULLContext, *pPsPollContext; /*Check MgmtContext. */ pMLMEContext = (struct rt_tx_context *)(pAd->MgmtRing. Cell[pAd->MgmtRing. TxDmaIdx]. AllocVa); pPsPollContext = (struct rt_tx_context *)(&pAd->PsPollContext); pNULLContext = (struct rt_tx_context *)(&pAd->NullContext); if (pMLMEContext->IRPPending) { ASSERT(pMLMEContext-> IRPPending); pUrb = pMLMEContext->pUrb; } else if (pNULLContext->IRPPending) { ASSERT(pNULLContext-> IRPPending); pUrb = pNULLContext->pUrb; } else if (pPsPollContext->IRPPending) { ASSERT(pPsPollContext-> IRPPending); pUrb = pPsPollContext->pUrb; } } RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n", idx, pAd->watchDogTxPendingCnt[idx], pAd->TransferedLength[idx], actual_length, transfer_buffer_length); if (pUrb) { if ((isDataPacket && pAd->TransferedLength[idx] == actual_length && pAd->TransferedLength[idx] < transfer_buffer_length && actual_length != 0 /* && TxRxQ_Pcnt==0 */ && pAd->watchDogTxPendingCnt[idx] > 3) || isDataPacket == FALSE || pAd->watchDogTxPendingCnt[idx] > 6) { DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx)); DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n")); /* unlink it now */ RTUSB_UNLINK_URB(pUrb); /* Sleep 200 microseconds to give cancellation time to work */ /*RTMPusecDelay(200); */ needDumpSeq = TRUE; } } else { DBGPRINT(RT_DEBUG_ERROR, ("Unknown bulkOut URB maybe hanged!\n")); } } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); } if (isDataPacket == TRUE) pAd->TransferedLength[idx] = actual_length; } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); } } /* For Sigma debug, dump the ba_reordering sequence. */ if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) { u16 Idx; struct rt_ba_rec_entry *pBAEntry = NULL; u8 count = 0; struct reordering_mpdu *mpdu_blk; Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; pBAEntry = &pAd->BATable.BARecEntry[Idx]; if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) { DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); NdisAcquireSpinLock(&pBAEntry->RxReRingLock); mpdu_blk = pBAEntry->list.next; while (mpdu_blk) { DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU)); mpdu_blk = mpdu_blk->next; count++; } DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq)); NdisReleaseSpinLock(&pBAEntry->RxReRingLock); } } }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBCancelPendingBulkOutIRP( IN PRTMP_ADAPTER pAd) { PHT_TX_CONTEXT pHTTXContext; PTX_CONTEXT pMLMEContext; PTX_CONTEXT pBeaconContext; PTX_CONTEXT pNullContext; PTX_CONTEXT pPsPollContext; PTX_CONTEXT pRTSContext; UINT i, Idx; // unsigned int IrqFlags; // NDIS_SPIN_LOCK *pLock; // BOOLEAN *pPending; // pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; // pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; for (Idx = 0; Idx < 4; Idx++) { pHTTXContext = &(pAd->TxContext[Idx]); if (pHTTXContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pHTTXContext->pUrb); // Sleep 200 microseconds to give cancellation time to work RTMPusecDelay(200); } pAd->BulkOutPending[Idx] = FALSE; } //RTMP_IRQ_LOCK(pLock, IrqFlags); for (i = 0; i < MGMT_RING_SIZE; i++) { pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; if(pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pMLMEContext->pUrb); pMLMEContext->IRPPending = FALSE; // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; //RTMP_IRQ_UNLOCK(pLock, IrqFlags); for (i = 0; i < BEACON_RING_SIZE; i++) { pBeaconContext = &(pAd->BeaconContext[i]); if(pBeaconContext->IRPPending == TRUE) { // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself // remove it from the HeadPendingSendList and NULL out HeadPendingSendList // when the last IRP on the list has been cancelled; that's how we exit this loop // RTUSB_UNLINK_URB(pBeaconContext->pUrb); // Sleep 200 microsecs to give cancellation time to work RTMPusecDelay(200); } } pNullContext = &(pAd->NullContext); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pRTSContext = &(pAd->RTSContext); if (pRTSContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pRTSContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } }
VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd) { PHT_TX_CONTEXT pHTTXContext; int idx; ULONG irqFlags; PURB pUrb; BOOLEAN needDumpSeq = FALSE; UINT32 MACValue; if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) return; idx = 0; RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); if ((MACValue & 0xff) !=0 ) { DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); while((MACValue &0xff) != 0 && (idx++ < 10)) { RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); RTMPusecDelay(1); } RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); } idx = 0; if ((MACValue & 0xff00) !=0 ) { DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a); while((MACValue &0xff00) != 0 && (idx++ < 10)) { RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); RTMPusecDelay(1); } RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); } if (pAd->watchDogRxOverFlowCnt >= 2) { DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); needDumpSeq = TRUE; } pAd->watchDogRxOverFlowCnt = 0; } for (idx = 0; idx < NUM_OF_TX_RING; idx++) { pUrb = NULL; RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt) { pAd->watchDogTxPendingCnt[idx]++; if ((pAd->watchDogTxPendingCnt[idx] > 2) && (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET))) ) { // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]); if (pHTTXContext->IRPPending) { // Check TxContext. pUrb = pHTTXContext->pUrb; } else if (idx == MGMTPIPEIDX) { PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext; //Check MgmtContext. pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext); pNULLContext = (PTX_CONTEXT)(&pAd->NullContext); if (pMLMEContext->IRPPending) { ASSERT(pMLMEContext->IRPPending); pUrb = pMLMEContext->pUrb; } else if (pNULLContext->IRPPending) { ASSERT(pNULLContext->IRPPending); pUrb = pNULLContext->pUrb; } else if (pPsPollContext->IRPPending) { ASSERT(pPsPollContext->IRPPending); pUrb = pPsPollContext->pUrb; } } RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx)); if (pUrb) { DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n")); // unlink it now RTUSB_UNLINK_URB(pUrb); // Sleep 200 microseconds to give cancellation time to work RTMPusecDelay(200); needDumpSeq = TRUE; } else { DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n")); } } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); } } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); } } #ifdef DOT11_N_SUPPORT // For Sigma debug, dump the ba_reordering sequence. if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) { USHORT Idx; PBA_REC_ENTRY pBAEntry = NULL; UCHAR count = 0; struct reordering_mpdu *mpdu_blk; Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; pBAEntry = &pAd->BATable.BARecEntry[Idx]; if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) { DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); NdisAcquireSpinLock(&pBAEntry->RxReRingLock); mpdu_blk = pBAEntry->list.next; while (mpdu_blk) { DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU)); mpdu_blk = mpdu_blk->next; count++; } DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq)); NdisReleaseSpinLock(&pBAEntry->RxReRingLock); } } #endif // DOT11_N_SUPPORT // }
VOID RTUSBCancelPendingBulkOutIRP( IN PRTMP_ADAPTER pAd) { PHT_TX_CONTEXT pHTTXContext; PTX_CONTEXT pMLMEContext; PTX_CONTEXT pBeaconContext; PTX_CONTEXT pNullContext; PTX_CONTEXT pPsPollContext; PTX_CONTEXT pRTSContext; UINT i, Idx; for (Idx = 0; Idx < 4; Idx++) { pHTTXContext = &(pAd->TxContext[Idx]); if (pHTTXContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pHTTXContext->pUrb); RTMPusecDelay(200); } pAd->BulkOutPending[Idx] = FALSE; } for (i = 0; i < MGMT_RING_SIZE; i++) { pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; if(pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { RTUSB_UNLINK_URB(pMLMEContext->pUrb); pMLMEContext->IRPPending = FALSE; RTMPusecDelay(200); } } pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; for (i = 0; i < BEACON_RING_SIZE; i++) { pBeaconContext = &(pAd->BeaconContext[i]); if(pBeaconContext->IRPPending == TRUE) { RTUSB_UNLINK_URB(pBeaconContext->pUrb); RTMPusecDelay(200); } } pNullContext = &(pAd->NullContext); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pRTSContext = &(pAd->RTSContext); if (pRTSContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pRTSContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } }
/* ======================================================================== Routine Description: Initialize receive data structures. Arguments: pAd Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_RESOURCES Note: Initialize all receive releated private buffer, include those define in RTMP_ADAPTER structure and all private data structures. The mahor work is to allocate buffer for each packet and chain buffer to NDIS packet descriptor. ======================================================================== */ NDIS_STATUS NICInitRecv( IN PRTMP_ADAPTER pAd) { UCHAR i; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); pObj = pObj; //InterlockedExchange(&pAd->PendingRx, 0); pAd->PendingRx = 0; pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer pAd->NextRxBulkInPosition = 0; for (i = 0; i < (RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); //Allocate URB pRxContext->pUrb = RTUSB_ALLOC_URB(0); if (pRxContext->pUrb == NULL) { Status = NDIS_STATUS_RESOURCES; goto out1; } // Allocate transfer buffer pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma); if (pRxContext->TransferBuffer == NULL) { Status = NDIS_STATUS_RESOURCES; goto out1; } NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); pRxContext->pAd = pAd; pRxContext->pIrp = NULL; pRxContext->InUse = FALSE; pRxContext->IRPPending = FALSE; pRxContext->Readable = FALSE; //pRxContext->ReorderInUse = FALSE; pRxContext->bRxHandling = FALSE; pRxContext->BulkInOffset = 0; } DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n")); return Status; out1: for (i = 0; i < (RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); if (NULL != pRxContext->TransferBuffer) { RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, pRxContext->TransferBuffer, pRxContext->data_dma); pRxContext->TransferBuffer = NULL; } if (NULL != pRxContext->pUrb) { RTUSB_UNLINK_URB(pRxContext->pUrb); RTUSB_FREE_URB(pRxContext->pUrb); pRxContext->pUrb = NULL; } } return Status; }
/* ======================================================================== Routine Description: Calls USB_InterfaceStop and frees memory allocated for the URBs calls NdisMDeregisterDevice and frees the memory allocated in VNetInitialize for the Adapter Object Arguments: *pAd the raxx interface data pointer Return Value: None Note: ======================================================================== */ VOID RTMPFreeTxRxRingMemory( IN PRTMP_ADAPTER pAd) { #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; } UINT i, acidx; PTX_CONTEXT pNullContext = &pAd->NullContext; PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; PTX_CONTEXT pRTSContext = &pAd->RTSContext; // PHT_TX_CONTEXT pHTTXContext; //PRTMP_REORDERBUF pReorderBuf; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; // RTMP_TX_RING *pTxRing; DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); pObj = pObj; // Free all resources for the RECEIVE buffer queue. for(i=0; i<(RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); if (pRxContext) LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); } // Free PsPoll frame resource LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); // Free NULL frame resource LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); // Free RTS frame resource LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); // Free beacon frame resource for(i=0; i<BEACON_RING_SIZE; i++) { PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]); if (pBeaconContext) LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); } // Free mgmt frame resource for(i = 0; i < MGMT_RING_SIZE; i++) { PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) { RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); pAd->MgmtRing.Cell[i].pNdisPacket = NULL; pMLMEContext->TransferBuffer = NULL; } if (pMLMEContext) { if (NULL != pMLMEContext->pUrb) { RTUSB_UNLINK_URB(pMLMEContext->pUrb); RTUSB_FREE_URB(pMLMEContext->pUrb); pMLMEContext->pUrb = NULL; } } } if (pAd->MgmtDescRing.AllocVa) NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0); // Free Tx frame resource #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) for(acidx=0; acidx<4; acidx++) #endif // CONFIG_STA_SUPPORT // { PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); if (pHTTXContext) LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER)); } if (pAd->FragFrame.pFragPacket) RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); for(i=0; i<6; i++) { NdisFreeSpinLock(&pAd->BulkOutLock[i]); } NdisFreeSpinLock(&pAd->BulkInLock); NdisFreeSpinLock(&pAd->MLMEBulkOutLock); NdisFreeSpinLock(&pAd->CmdQLock); #ifdef RALINK_ATE NdisFreeSpinLock(&pAd->GenericLock); #endif // RALINK_ATE // // Clear all pending bulk-out request flags. RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); // NdisFreeSpinLock(&pAd->MacTabLock); // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) // { // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); // } DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n")); }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd) { struct rt_ht_tx_context *pHTTXContext; struct rt_tx_context *pMLMEContext; struct rt_tx_context *pBeaconContext; struct rt_tx_context *pNullContext; struct rt_tx_context *pPsPollContext; struct rt_tx_context *pRTSContext; u32 i, Idx; /* unsigned int IrqFlags; */ /* spinlock_t *pLock; */ /* BOOLEAN *pPending; */ /* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */ /* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */ for (Idx = 0; Idx < 4; Idx++) { pHTTXContext = &(pAd->TxContext[Idx]); if (pHTTXContext->IRPPending == TRUE) { /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ /* when the last IRP on the list has been cancelled; that's how we exit this loop */ /* */ RTUSB_UNLINK_URB(pHTTXContext->pUrb); /* Sleep 200 microseconds to give cancellation time to work */ RTMPusecDelay(200); } pAd->BulkOutPending[Idx] = FALSE; } /*RTMP_IRQ_LOCK(pLock, IrqFlags); */ for (i = 0; i < MGMT_RING_SIZE; i++) { pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ /* when the last IRP on the list has been cancelled; that's how we exit this loop */ /* */ RTUSB_UNLINK_URB(pMLMEContext->pUrb); pMLMEContext->IRPPending = FALSE; /* Sleep 200 microsecs to give cancellation time to work */ RTMPusecDelay(200); } } pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */ for (i = 0; i < BEACON_RING_SIZE; i++) { pBeaconContext = &(pAd->BeaconContext[i]); if (pBeaconContext->IRPPending == TRUE) { /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ /* when the last IRP on the list has been cancelled; that's how we exit this loop */ /* */ RTUSB_UNLINK_URB(pBeaconContext->pUrb); /* Sleep 200 microsecs to give cancellation time to work */ RTMPusecDelay(200); } } pNullContext = &(pAd->NullContext); if (pNullContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pNullContext->pUrb); pRTSContext = &(pAd->RTSContext); if (pRTSContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pRTSContext->pUrb); pPsPollContext = &(pAd->PsPollContext); if (pPsPollContext->IRPPending == TRUE) RTUSB_UNLINK_URB(pPsPollContext->pUrb); for (Idx = 0; Idx < 4; Idx++) { NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); pAd->BulkOutPending[Idx] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); } }