VOID MtPsRecovery( RTMP_ADAPTER *pAd) { MAC_TABLE_ENTRY *pMacEntry; STA_TR_ENTRY *tr_entry; UINT32 i; for (i=1; i < MAX_LEN_OF_MAC_TABLE; i++) { pMacEntry = &pAd->MacTab.Content[i]; tr_entry = &pAd->MacTab.tr_entry[i]; if (IS_ENTRY_CLIENT(pMacEntry)) { if (tr_entry->ps_state == APPS_RETRIEVE_CR_PADDING) { tr_entry->ps_state = APPS_RETRIEVE_IDLE; } else if ((tr_entry->ps_state == APPS_RETRIEVE_START_PS) || (tr_entry->ps_state == APPS_RETRIEVE_GOING)) { if (tr_entry->ps_queue.Number) { MtEnqTxSwqFromPsQueue(pAd, i, tr_entry); } if (pAd->MacTab.tr_entry[i].PsMode == PWR_ACTIVE) { tr_entry->ps_state = APPS_RETRIEVE_IDLE; MtHandleRxPsPoll(pAd, &pMacEntry->Addr[0], i, TRUE); } else tr_entry->ps_state = APPS_RETRIEVE_DONE; } else if(tr_entry->ps_state == APPS_RETRIEVE_WAIT_EVENT) { RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&i, sizeof(UINT32)); } } } }
/* ======================================================================== Routine Description: Parse and handle country region in beacon from associated AP. Arguments: pAdCB - WLAN control block pointer pVIE - Beacon elements LenVIE - Total length of Beacon elements Return Value: NONE Note: ======================================================================== */ VOID CFG80211_BeaconCountryRegionParse( IN VOID *pAdCB, IN NDIS_802_11_VARIABLE_IEs *pVIE, IN UINT16 LenVIE) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB; UCHAR *pElement = (UCHAR *)pVIE; UINT32 LenEmt; while(LenVIE > 0) { pVIE = (NDIS_802_11_VARIABLE_IEs *)pElement; if (pVIE->ElementID == IE_COUNTRY) { /* send command to do regulation hint only when associated */ RTEnqueueInternalCmd(pAd, CMDTHREAD_REG_HINT_11D, pVIE->data, pVIE->Length); break; } /* End of if */ LenEmt = pVIE->Length + 2; if (LenVIE <= LenEmt) break; /* length is not enough */ /* End of if */ pElement += LenEmt; LenVIE -= LenEmt; } /* End of while */ } /* End of CFG80211_BeaconCountryRegionParse */
static void rtusb_null_frame_done_tasklet(unsigned long data) { PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; purbb_t pUrb; NTSTATUS Status; unsigned long irqFlag; pUrb = (purbb_t)data; /* pNullContext = (PTX_CONTEXT)pUrb->context; */ pNullContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); Status = RTMP_USB_URB_STATUS_GET(pUrb); pAd = pNullContext->pAd; /* Status = pUrb->status; */ /* Reset Null frame context flags */ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); pNullContext->IRPPending = FALSE; pNullContext->InUse = FALSE; pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; if (Status == USB_ST_NOERROR) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); } else /* STATUS_OTHER */ { if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status)); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); } else { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); } } /* Always call Bulk routine, even reset bulk. */ /* The protectioon of rest bulk should be in BulkOut routine */ RTUSBKickBulkOut(pAd); }
static void rtusb_hcca_dma_done_tasklet(unsigned long data) { PRTMP_ADAPTER pAd; PHT_TX_CONTEXT pHTTXContext; UCHAR BulkOutPipeId = 4; purbb_t pUrb; DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n")); pUrb = (purbb_t)data; /* pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; */ pHTTXContext = (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); pAd = pHTTXContext->pAd; rtusb_dataout_complete((unsigned long)pUrb); if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { /* do nothing and return directly. */ } else { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) { RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); } else { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && (pHTTXContext->bCurWriting == FALSE)) { RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); } RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); RTUSBKickBulkOut(pAd); } } DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n")); return; }
/* ======================================================================== Routine Description: Handle a alarm. Arguments: pAd - WLAN control block pointer Return Value: None Note: You can use different methods to handle QBSS Load alarm here. Current methods are: 1. Change 20/40 to 20-only. 2. Change channel to the clear channel. ======================================================================== */ static VOID QBSS_LoadAlarm( IN RTMP_ADAPTER *pAd) { /* suspend alarm until channel switch */ QBSS_LoadAlarmSuspend(pAd); pAd->QloadAlarmNumber ++; /* check if we have already been 20M bandwidth */ #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) && (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0)) { MAC_TABLE *pMacTable; UINT32 StaId; DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Change to 20 bw...\n")); /* disassociate stations without D3 2040Coexistence function */ pMacTable = &pAd->MacTab; for(StaId=1; StaId<MAX_LEN_OF_MAC_TABLE; StaId++) { MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId]; BOOLEAN bDisconnectSta = FALSE; if (!IS_ENTRY_CLIENT(pEntry)) continue; /* End of if */ if (pEntry->Sst != SST_ASSOC) continue; /* End of if */ if (pEntry->BSS2040CoexistenceMgmtSupport) bDisconnectSta = TRUE; /* End of if */ if (bDisconnectSta) { /* send wireless event - for ageout */ RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0); { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; HEADER_802_11 DeAuthHdr; USHORT Reason; /* send out a DISASSOC request frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, (" MlmeAllocateMemory fail ..\n")); /*NdisReleaseSpinLock(&pAd->MacTabLock); */ continue; } Reason = REASON_DEAUTH_STA_LEAVING; MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr, #ifdef P2P_SUPPORT pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, #endif /* P2P_SUPPORT */ pAd->ApCfg.MBSSID[pEntry->apidx].Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DeAuthHdr, 2, &Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Deauth the station " "%02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); continue; } /* End of if */ } /* End of for */ /* for 11n */ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0; /* always 20M */ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; /* mark alarm flag */ pAd->FlgQloadAlarm = TRUE; QBSS_LoadAlarmResume(pAd); } else #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ { /* we are in 20MHz bandwidth so try to switch channel */ DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Switch channel...\n")); /* send command to switch channel */ RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, NULL, 0); } /* End of if */ } /* End of QBSS_LoadAlarm */
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 MtPsSendToken( RTMP_ADAPTER *pAd, UINT32 WlanIdx) { MAC_TABLE_ENTRY *pEntry = NULL; STA_TR_ENTRY *tr_entry; NDIS_STATUS token_status; struct wtbl_entry tb_entry; union WTBL_1_DW3 *dw3; UINT32 Reg = 0; BOOLEAN pfgForce = 0; unsigned char q_idx; if (pAd->chipCap.hif_type != HIF_MT) { return; } DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s(wcid=%d): Driver didn't receive PsRetrieveStartRsp from FW.\n",__FUNCTION__, WlanIdx)); pEntry = &pAd->MacTab.Content[WlanIdx]; tr_entry = &pAd->MacTab.tr_entry[WlanIdx]; NdisZeroMemory(&tb_entry, sizeof(tb_entry)); dw3 = (union WTBL_1_DW3 *)&tb_entry.wtbl_1.wtbl_1_d3.word; if (mt_wtbl_get_entry234(pAd, WlanIdx, &tb_entry) == FALSE) { DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s():Cannot found WTBL2/3/4, wcid=%d\n",__FUNCTION__, WlanIdx)); return; } RTMP_IO_READ32(pAd, tb_entry.wtbl_addr[0]+12, &dw3->word); MtReadPseRdTabAccessReg(pAd, pEntry->wcid, &Reg); pfgForce = ( BOOLEAN ) GET_PSE_RTA_RD_RULE_F(Reg); if (pfgForce == 0) { DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s(ps_state = %d): PS Redirect mode didn't be enabled. Driver doesn't need to send token.\n",__FUNCTION__, tr_entry->ps_state)); DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s: Reset ps_state to IDLE.\n",__FUNCTION__)); tr_entry->ps_state = APPS_RETRIEVE_IDLE; return; } DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("---->%s: Start to send TOKEN frames.\n", __FUNCTION__)); tr_entry->ps_state = APPS_RETRIEVE_GOING; tr_entry->ps_qbitmap = 0; for (q_idx = 0; q_idx < NUM_OF_TX_RING; q_idx++) { token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx); if (!token_status) tr_entry->ps_qbitmap |= (1 << q_idx); else DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s(%d) Fail: Send TOKEN Frame, AC=%d\n", __FUNCTION__, __LINE__, q_idx)); } if (tr_entry->ps_qbitmap == 0) { tr_entry->ps_state = APPS_RETRIEVE_WAIT_EVENT; RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&WlanIdx, sizeof(UINT32)); DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("(ps_state = %d) token enqueue failed for all queues ==> send CMDTHREAD_PS_CLEAR cmd.\n", tr_entry->ps_state)); } }
/* ========================================================================== Description: Update the station current power save mode. Calling this routine also prove the specified client is still alive. Otherwise AP will age-out this client once IdleCount exceeds a threshold. ========================================================================== */ BOOLEAN MtPsIndicate(RTMP_ADAPTER *pAd, UCHAR *pAddr, UCHAR wcid, UCHAR Psm) { MAC_TABLE_ENTRY *pEntry; UCHAR old_psmode; STA_TR_ENTRY *tr_entry; if (wcid >= MAX_LEN_OF_MAC_TABLE) { return PWR_ACTIVE; } pEntry = &pAd->MacTab.Content[wcid]; tr_entry = &pAd->MacTab.tr_entry[wcid]; /* Change power save mode first because we will call RTMPDeQueuePacket() in RtmpHandleRxPsPoll(). Or when Psm = PWR_ACTIVE, we will not do Aggregation in RTMPDeQueuePacket(). */ old_psmode = pEntry->PsMode; pEntry->NoDataIdleCount = 0; pEntry->PsMode = Psm; pAd->MacTab.tr_entry[wcid].PsMode = Psm; if ((old_psmode == PWR_SAVE) && (Psm == PWR_ACTIVE)) { /* STA wakes up. */ if(tr_entry->ps_state == APPS_RETRIEVE_DONE) { tr_entry->ps_state = APPS_RETRIEVE_IDLE; DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): STA wakes up!\n", __FUNCTION__, __LINE__)); MtHandleRxPsPoll(pAd, pAddr, wcid, TRUE); } else DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, wrong ps_state=%d ???\n", __FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state)); } else if ((old_psmode == PWR_ACTIVE) && (Psm == PWR_SAVE)) { /* STA goes to sleep. */ if (tr_entry->ps_state == APPS_RETRIEVE_IDLE) { #ifdef MT_PS DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, ps_state=%d start retrieving!!\n", __FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state)); #if defined(MT7603) && defined(RTMP_PCI_SUPPORT) if (MtStartPSRetrieve(pAd, wcid) == TRUE) { tr_entry->ps_state = APPS_RETRIEVE_START_PS; } else { struct tx_swq_fifo *ps_fifo_swq; INT enq_idx; ps_fifo_swq = &pAd->apps_cr_q; enq_idx = ps_fifo_swq->enqIdx; if (ps_fifo_swq->swq[enq_idx] == 0) { ps_fifo_swq->swq[enq_idx] = wcid; INC_RING_INDEX(ps_fifo_swq->enqIdx, TX_SWQ_FIFO_LEN); tr_entry->ps_state = APPS_RETRIEVE_CR_PADDING; } else { INT idx; tr_entry->ps_state = APPS_RETRIEVE_DONE; DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! ps_fifo_swq->deqIdx=%d, ps_fifo_swq->enqIdx=%d\n", __FUNCTION__,ps_fifo_swq->deqIdx,ps_fifo_swq->enqIdx)); for (idx =0; idx < TX_SWQ_FIFO_LEN;idx++) { DBGPRINT(RT_DEBUG_ERROR, (",[%d] =%d\n", idx, ps_fifo_swq->swq[idx])); if ((idx % 16) == 0) DBGPRINT(RT_DEBUG_ERROR, ("\n")); } DBGPRINT(RT_DEBUG_ERROR, ("\n")); } } #else /* !MT7603 && RTMP_PCI_SUPPORT */ RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_RETRIEVE_START, pEntry, sizeof(MAC_TABLE_ENTRY)); #endif /* MT7603 && RTMP_PCI_SUPPORT */ #else /* MT_PS */ tr_entry->ps_state = APPS_RETRIEVE_DONE; #endif /* !MT_PS */ } else DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d):wcid=%d, old_psmode=%d, now_psmode=%d, wrong ps_state=%d ???\n", __FUNCTION__, __LINE__, wcid, old_psmode, Psm, tr_entry->ps_state)); } else { DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): ps state is not changed, do nothing here.\n", __FUNCTION__, __LINE__)); } return old_psmode; }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd) { HEADER_802_11 Hdr80211; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0; #ifdef CONFIG_STA_SUPPORT USHORT Status; PHEADER_802_11 pHdr80211; #endif // CONFIG_STA_SUPPORT // UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (MONITOR_ON(pAd)) return; } #endif // CONFIG_STA_SUPPORT // #ifdef RALINK_ATE // Nothing to do in ATE mode. if (ATE_ON(pAd)) return; #endif // RALINK_ATE // if (pAd->MlmeAux.Channel == 0) { if ((pAd->CommonCfg.BBPCurrentBW == BW_40) && ( #ifdef CONFIG_STA_SUPPORT INFRA_ON(pAd) || ADHOC_ON(pAd) || #endif // CONFIG_STA_SUPPORT // (0))) { AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); BBPValue |= 0x10; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); } else { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { /* If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. */ if (ADHOC_ON(pAd)) { NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); } // // To prevent data lost. // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done // if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); if (NStatus == NDIS_STATUS_SUCCESS) { pHdr80211 = (PHEADER_802_11) pOutBuffer; MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); pHdr80211->Duration = 0; pHdr80211->FC.Type = BTYPE_DATA; pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); // Send using priority queue MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n")); MlmeFreeMemory(pAd, pOutBuffer); RTMPusecDelay(5000); } } pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0); #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0); #endif // RT_CFG80211_SUPPORT // #endif // LINUX // } #endif // CONFIG_STA_SUPPORT // } else {
INT Set_P2P_Cancel_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { POS_COOKIE pObj; PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; PWSC_CTRL pWscControl = NULL; INT val = (INT)simple_strtol(arg, 0, 10); pObj = (POS_COOKIE) pAd->OS_Cookie; if (pObj->ioctl_if_type != INT_P2P) return FALSE; if (val == 1) { pP2PCtrl->P2PConnectState = P2P_CONNECT_IDLE; if (!MAC_ADDR_EQUAL(&ZERO_MAC_ADDR[0], &pP2PCtrl->ConnectingMAC[0])) { UCHAR p2pindex; p2pindex = P2pGroupTabSearch(pAd, pP2PCtrl->ConnectingMAC); if (p2pindex < MAX_P2P_GROUP_SIZE) { if (pAd->P2pTable.Client[p2pindex].Rule == P2P_IS_GO) pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_DISCOVERY_GO; else pAd->P2pTable.Client[p2pindex].P2pClientState = P2PSTATE_DISCOVERY; pAd->P2pTable.Client[p2pindex].StateCount = 0; } NdisZeroMemory(pP2PCtrl->ConnectingMAC, MAC_ADDR_LEN); } if (P2P_GO_ON(pAd)) { UINT32 i, p2pEntryCnt=0; MAC_TABLE_ENTRY *pEntry; INT IsAPConfigured; pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl; IsAPConfigured = pWscControl->WscConfStatus; if (pWscControl->bWscTrigger) { WscStop(pAd, FALSE, pWscControl); pWscControl->WscPinCode = 0; WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, MAIN_MBSSID, NULL, 0, AP_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, (MAIN_MBSSID | MIN_NET_DEVICE_FOR_P2P_GO), NULL, 0, AP_MODE); APUpdateBeaconFrame(pAd, pObj->ioctl_if); } for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++) { pEntry = &pAd->MacTab.Content[i]; if (IS_P2P_GO_ENTRY(pEntry) && (pEntry->WpaState == AS_PTKINITDONE)) p2pEntryCnt++; } DBGPRINT(RT_DEBUG_ERROR, ("%s:: Total= %d. p2pEntry = %d.\n", __FUNCTION__, pAd->MacTab.Size, p2pEntryCnt)); if ((p2pEntryCnt == 0) && (pAd->flg_p2p_OpStatusFlags == P2P_GO_UP)) { #ifdef RTMP_MAC_USB RTEnqueueInternalCmd(pAd, CMDTHREAD_SET_P2P_LINK_DOWN, NULL, 0); #endif /* RTMP_MAC_USB */ } } else if (P2P_CLI_ON(pAd)) { pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl; pWscControl->WscPinCode = 0; if (pWscControl->bWscTrigger) WscStop(pAd, TRUE, pWscControl); P2pLinkDown(pAd, P2P_DISCONNECTED); } P2pStopScan(pAd); pP2PCtrl->bPeriodicListen = TRUE; /* Reset bConfirmByUI to its default value */ pP2PCtrl->bConfirmByUI = CONFIRM_BY_UI_DEFAULT; if (INFRA_ON(pAd) || P2P_GO_ON(pAd) || P2P_CLI_ON(pAd)) { INT ch; // TODO: shiang-6590, why we set bw as 40 when BBPCurrentBW == BW_40?? if (pAd->CommonCfg.BBPCurrentBW == BW_40) { rtmp_bbp_set_bw(pAd, BW_40); ch = pAd->CommonCfg.CentralChannel; } else { ch = pAd->CommonCfg.Channel; } AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); } } DBGPRINT(RT_DEBUG_TRACE, ("%s:: Cancel P2P action\n", __FUNCTION__)); return TRUE; }
/* ========================================================================== Description: Scan next channel ========================================================================== */ VOID ScanNextChannel( IN PRTMP_ADAPTER pAd) { HEADER_802_11 Hdr80211; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0; #ifdef CONFIG_STA_SUPPORT USHORT Status; #endif // CONFIG_STA_SUPPORT // UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; BOOLEAN ScanPending = FALSE; #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (MONITOR_ON(pAd)) return; } ScanPending = ((pAd->StaCfg.bImprovedScan) && (pAd->StaCfg.ScanChannelCnt>=7)); #endif // CONFIG_STA_SUPPORT // #ifdef RALINK_ATE // Nothing to do in ATE mode. if (ATE_ON(pAd)) return; #endif // RALINK_ATE // if ((pAd->MlmeAux.Channel == 0) || ScanPending) { if ((pAd->CommonCfg.BBPCurrentBW == BW_40) #ifdef CONFIG_STA_SUPPORT && (INFRA_ON(pAd) || ADHOC_ON(pAd) || (pAd->OpMode == OPMODE_AP)) #endif // CONFIG_STA_SUPPORT // ) { AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); BBPValue |= 0x10; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); } else { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { /* If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. */ if (ADHOC_ON(pAd)) { NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); } // // To prevent data lost. // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done // if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE)); DBGPRINT(RT_DEBUG_TRACE, ("%s -- Send PSM Data frame\n", __FUNCTION__)); } // keep the latest scan channel, could be 0 for scan complete, or other channel pAd->StaCfg.LastScanChannel = pAd->MlmeAux.Channel; pAd->StaCfg.ScanChannelCnt = 0; // Suspend scanning and Resume TxData for Fast Scanning if ((pAd->MlmeAux.Channel != 0) && (pAd->StaCfg.bImprovedScan)) // it is scan pending { pAd->Mlme.SyncMachine.CurrState = SCAN_PENDING; Status = MLME_SUCCESS; DBGPRINT(RT_DEBUG_WARN, ("bFastRoamingScan ~~~~~~~~~~~~~ Get back to send data ~~~~~~~~~~~~~\n")); RTMPResumeMsduTransmission(pAd); } else { pAd->StaCfg.BssNr = pAd->ScanTab.BssNr; pAd->StaCfg.bImprovedScan = FALSE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); RTMPSendWirelessEvent(pAd, IW_SCAN_COMPLETED_EVENT_FLAG, NULL, BSS0, 0); #ifdef WPA_SUPPLICANT_SUPPORT RtmpOSWrielessEventSend(pAd, SIOCGIWSCAN, -1, NULL, NULL, 0); #endif // WPA_SUPPLICANT_SUPPORT // } #ifdef LINUX #ifdef RT_CFG80211_SUPPORT RTEnqueueInternalCmd(pAd, CMDTHREAD_SCAN_END, NULL, 0); #endif // RT_CFG80211_SUPPORT // #endif // LINUX // } #endif // CONFIG_STA_SUPPORT // } else {
/* ======================================================================== Routine Description: Handle a alarm. Arguments: pAd - WLAN control block pointer Return Value: None Note: You can use different methods to handle QBSS Load alarm here. Current methods are: 1. Change 20/40 to 20-only. 2. Change channel to the clear channel. ======================================================================== */ static VOID QBSS_LoadAlarm( IN struct rtmp_adapter *pAd) { /* suspend alarm until channel switch */ QBSS_LoadAlarmSuspend(pAd); pAd->QloadAlarmNumber ++; /* check if we have already been 20M bandwidth */ if ((pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset != 0) && (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth != 0)) { struct mt7612u_mac_table *pMacTable; uint32_t StaId; DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Change to 20 bw...\n")); /* disassociate stations without D3 2040Coexistence function */ pMacTable = &pAd->MacTab; for(StaId=1; StaId<MAX_LEN_OF_MAC_TABLE; StaId++) { MAC_TABLE_ENTRY *pEntry = &pMacTable->Content[StaId]; bool bDisconnectSta = false; if (!IS_ENTRY_CLIENT(pEntry)) continue; if (pEntry->Sst != SST_ASSOC) continue; if (pEntry->BSS2040CoexistenceMgmtSupport) bDisconnectSta = true; if (bDisconnectSta) { /* send wireless event - for ageout */ RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0); { u8 *pOutBuffer = NULL; int NStatus; ULONG FrameLen = 0; HEADER_802_11 DeAuthHdr; unsigned short Reason; /* send out a DISASSOC request frame */ pOutBuffer = kmalloc(MGMT_DMA_BUFFER_SIZE, GFP_ATOMIC); if (pOutBuffer == NULL) { DBGPRINT(RT_DEBUG_TRACE, (" kmalloc fail ..\n")); /*NdisReleaseSpinLock(&pAd->MacTabLock); */ continue; } Reason = REASON_DEAUTH_STA_LEAVING; MgtMacHeaderInit(pAd, &DeAuthHdr, SUBTYPE_DEAUTH, 0, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.if_addr, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DeAuthHdr, 2, &Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); kfree(pOutBuffer); } DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Deauth the station " "%02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pEntry->Addr))); MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); continue; } } /* for 11n */ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0; /* always 20M */ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; /* mark alarm flag */ pAd->FlgQloadAlarm = true; QBSS_LoadAlarmResume(pAd); } else { /* we are in 20MHz bandwidth so try to switch channel */ DBGPRINT(RT_DEBUG_TRACE, ("qbss> Alarm! Switch channel...\n")); /* send command to switch channel */ RTEnqueueInternalCmd(pAd, CMDTHREAD_CHAN_RESCAN, NULL, 0); } }
static void rtusb_mgmt_dma_done_tasklet(unsigned long data) { PRTMP_ADAPTER pAd; PTX_CONTEXT pMLMEContext; int index; PNDIS_PACKET pPacket; purbb_t pUrb; NTSTATUS Status; unsigned long IrqFlags; pUrb = (purbb_t)data; /* pMLMEContext = (PTX_CONTEXT)pUrb->context; */ pMLMEContext = (PTX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); Status = RTMP_USB_URB_STATUS_GET(pUrb); pAd = pMLMEContext->pAd; /* Status = pUrb->status; */ index = pMLMEContext->SelfIdx; ASSERT((pAd->MgmtRing.TxDmaIdx == index)); RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); if (Status != USB_ST_NOERROR) { /*Bulk-Out fail status handle */ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status)); /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); } } pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); /* Reset MLME context flags */ pMLMEContext->IRPPending = FALSE; pMLMEContext->InUse = FALSE; pMLMEContext->bWaitingBulkOut = FALSE; pMLMEContext->BulkOutSize = 0; pPacket = pAd->MgmtRing.Cell[index].pNdisPacket; pAd->MgmtRing.Cell[index].pNdisPacket = NULL; /* Increase MgmtRing Index */ INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE); pAd->MgmtRing.TxSwFreeIdx++; RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); /* No-matter success or fail, we free the mgmt packet. */ if (pPacket) RTMPFreeNdisPacket(pAd, pPacket); if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { /* do nothing and return directly. */ } else { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) { /* For Mgmt Bulk-Out failed, ignore it now. */ RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); } else { /* Always call Bulk routine, even reset bulk. */ /* The protectioon of rest bulk should be in BulkOut routine */ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); } RTUSBKickBulkOut(pAd); } } #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ }
/* ======================================================================== Routine Description: Handle received packets. Arguments: data - URB information pointer Return Value: None Note: ======================================================================== */ static void rx_done_tasklet(unsigned long data) { purbb_t pUrb; PRX_CONTEXT pRxContext; PRTMP_ADAPTER pAd; NTSTATUS Status; unsigned int IrqFlags; pUrb = (purbb_t)data; /* pRxContext = (PRX_CONTEXT)pUrb->context; */ pRxContext = (PRX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb); Status = RTMP_USB_URB_STATUS_GET(pUrb); pAd = pRxContext->pAd; /* Status = pUrb->status; */ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); pRxContext->InUse = FALSE; pRxContext->IRPPending = FALSE; pRxContext->BulkInOffset += RTMP_USB_URB_LEN_GET(pUrb); /*pUrb->actual_length; */ /*NdisInterlockedDecrement(&pAd->PendingRx); */ pAd->PendingRx--; if (Status == USB_ST_NOERROR) { pAd->BulkInComplete++; pAd->NextRxBulkInPosition = 0; if (pRxContext->BulkInOffset) /* As jan's comment, it may bulk-in success but size is zero. */ { pRxContext->Readable = TRUE; INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); } RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); } else /* STATUS_OTHER */ { pAd->BulkInCompleteFail++; /* Still read this packet although it may comtain wrong bytes. */ pRxContext->Readable = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); /* Parsing all packets. because after reset, the index will reset to all zero. */ 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_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, RTMP_USB_URB_LEN_GET(pRxContext->pUrb))); /*->actual_length)); */ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); } } ASSERT((pRxContext->InUse == pRxContext->IRPPending)); RTUSBBulkReceive(pAd); return; }