/* * -------------------------------------------------------------------------- * Implements filter driver's FilterAttach function. * * This function allocates the switch context, and initializes its necessary * members. * -------------------------------------------------------------------------- */ NDIS_STATUS OvsExtAttach(NDIS_HANDLE ndisFilterHandle, NDIS_HANDLE filterDriverContext, PNDIS_FILTER_ATTACH_PARAMETERS attachParameters) { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_FILTER_ATTRIBUTES ovsExtAttributes; POVS_SWITCH_CONTEXT switchContext = NULL; UNREFERENCED_PARAMETER(filterDriverContext); OVS_LOG_TRACE("Enter: ndisFilterHandle %p", ndisFilterHandle); ASSERT(filterDriverContext == (NDIS_HANDLE)gOvsExtDriverObject); if (attachParameters->MiniportMediaType != NdisMedium802_3) { status = NDIS_STATUS_INVALID_PARAMETER; goto cleanup; } if (gOvsExtDriverHandle == NULL) { OVS_LOG_TRACE("Exit: OVSEXT driver is not loaded."); ASSERT(FALSE); goto cleanup; } NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext) { NdisReleaseSpinLock(gOvsCtrlLock); OVS_LOG_TRACE("Exit: Failed to create OVS Switch, only one datapath is" "supported, %p.", gOvsSwitchContext); goto cleanup; } if (gOvsInAttach) { NdisReleaseSpinLock(gOvsCtrlLock); /* Just fail the request. */ OVS_LOG_TRACE("Exit: Failed to create OVS Switch, since another attach" "instance is in attach process."); goto cleanup; } gOvsInAttach = TRUE; NdisReleaseSpinLock(gOvsCtrlLock); status = OvsInitIpHelper(ndisFilterHandle); if (status != STATUS_SUCCESS) { OVS_LOG_ERROR("Exit: Failed to initialize IP helper."); goto cleanup; } status = OvsCreateSwitch(ndisFilterHandle, &switchContext); if (status != NDIS_STATUS_SUCCESS) { OvsCleanupIpHelper(); goto cleanup; } ASSERT(switchContext); /* * Register the switch context with NDIS so NDIS can pass it back to the * Filterxxx callback functions as the 'FilterModuleContext' parameter. */ RtlZeroMemory(&ovsExtAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); ovsExtAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; ovsExtAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); ovsExtAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; ovsExtAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(OVS_SWITCH_CONTEXT); status = NdisFSetAttributes(ndisFilterHandle, switchContext, &ovsExtAttributes); if (status != NDIS_STATUS_SUCCESS) { OVS_LOG_ERROR("Failed to set attributes."); OvsCleanupIpHelper(); goto cleanup; } /* Setup the state machine. */ switchContext->controlFlowState = OvsSwitchAttached; switchContext->dataFlowState = OvsSwitchPaused; gOvsSwitchContext = switchContext; KeMemoryBarrier(); cleanup: gOvsInAttach = FALSE; if (status != NDIS_STATUS_SUCCESS) { if (switchContext != NULL) { OvsDeleteSwitch(switchContext); } } OVS_LOG_TRACE("Exit: status %x", status); return status; }
int divert_filter_send(PADAPT pAdapt, PNDIS_PACKET Packet, int in) { #define HDR_SIZE 54 int len, cnt; PNDIS_BUFFER buf; char crap[HDR_SIZE]; int rc = 0, rd; struct ether_header *pEthHdr; // See ../B2Winet/ethernet.h struct ip *pIPHeader; struct tcphdr *tcp; struct divert_packet *dp; int off = 0; // 14; NDISPROT_ETH_HEADER UNALIGNED *pEthHeader; NdisAcquireSpinLock(&pAdapt->Lock); NdisQueryPacket(Packet, NULL, &cnt, &buf, &len); if (len < HDR_SIZE) goto Out; FltReadOnPacket(Packet, crap, HDR_SIZE, 0, &rd); if (rd < HDR_SIZE) goto Out; pEthHdr = (struct ether_header*) crap; pEthHeader = pEthHdr; if (ntohs( pEthHdr->ether_type ) != ETHERTYPE_IP) goto Out; if (in && get_pa(pEthHeader->SrcAddr)) goto Out; pIPHeader = (struct ip * ) (pEthHdr + 1); if (pIPHeader->ip_p != IPPROTO_TCP) goto Out; tcp = (struct tcphr*) (pIPHeader + 1); #if 0 if (ntohs(tcp->th_dport) == 666) rc = 1; #endif lock(); if (!_open) goto F**k; dp = get_packet(); if (!dp) { DbgPrint("divert_packet() - outta space dude\n"); goto F**k; } dp->dp_len = len - off; FltReadOnPacket(Packet, dp->dp_packet, dp->dp_len, off, &rd); // rd = dp->dp_len; if (rd != dp->dp_len) goto F**k; dp->dp_flags = 1; kick_pending(); rc = 1; F**k: unlock(); Out: NdisReleaseSpinLock(&pAdapt->Lock); return rc; #undef HDR_SIZE }
/* ======================================================================== 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]); } }
REPEATER_CLIENT_ENTRY *RTMPLookupRepeaterCliEntry( IN PVOID pData, IN BOOLEAN bRealMAC, IN PUCHAR pAddr, IN BOOLEAN bIsPad, OUT PUCHAR pIsLinkValid) { ULONG HashIdx; UCHAR tempMAC[6]; REPEATER_CLIENT_ENTRY *pEntry = NULL; REPEATER_CLIENT_ENTRY_MAP *pMapEntry = NULL; if (bIsPad == TRUE) { NdisAcquireSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock); } else { NdisAcquireSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock); } COPY_MAC_ADDR(tempMAC, pAddr); HashIdx = MAC_ADDR_HASH_INDEX(tempMAC); *pIsLinkValid = TRUE; if (bRealMAC == TRUE) { if (bIsPad == TRUE) { pMapEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptMapHash[HashIdx]; } else pMapEntry = *((((REPEATER_ADAPTER_DATA_TABLE *)pData)->MapHash) + HashIdx) ; while (pMapEntry) { pEntry = pMapEntry->pReptCliEntry; if (MAC_ADDR_EQUAL(pEntry->OriginalAddress, tempMAC)) { if (pEntry->CliValid == FALSE) { *pIsLinkValid = FALSE; pEntry = NULL; } break; } else { pEntry = NULL; pMapEntry = pMapEntry->pNext; } } } else { if (bIsPad == TRUE) { pEntry = ((PRTMP_ADAPTER)pData)->ApCfg.ReptCliHash[HashIdx]; } else { pEntry = *((((REPEATER_ADAPTER_DATA_TABLE *)pData)->CliHash) + HashIdx) ; } while (pEntry) { if (MAC_ADDR_EQUAL(pEntry->CurrentAddress, tempMAC)) { if (pEntry->CliValid == FALSE) { *pIsLinkValid = FALSE; pEntry = NULL; } break; } else pEntry = pEntry->pNext; } } if (bIsPad == TRUE) { NdisReleaseSpinLock(&((PRTMP_ADAPTER)pData)->ApCfg.ReptCliEntryLock); } else { NdisReleaseSpinLock(((REPEATER_ADAPTER_DATA_TABLE *)pData)->EntryLock); } return pEntry; }
MAC_TABLE_ENTRY *RTMPInsertRepeaterMacEntry( IN RTMP_ADAPTER *pAd, IN UCHAR *pAddr, IN struct wifi_dev *wdev, IN UCHAR apIdx, IN UCHAR cliIdx, IN BOOLEAN CleanAll) { UCHAR HashIdx; int i; MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; BOOLEAN Cancelled; /* if FULL, return*/ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) return NULL; /* allocate one MAC entry*/ NdisAcquireSpinLock(&pAd->MacTabLock); i = (MAX_NUMBER_OF_MAC + ((MAX_EXT_MAC_ADDR_SIZE + 1) * (apIdx - MIN_NET_DEVICE_FOR_APCLI))); if (cliIdx != 0xFF) i = i + cliIdx + 1; /* pick up the first available vacancy*/ pEntry = &pAd->MacTab.Content[i]; if (pEntry == NULL) { printk("###### %s pEntry == NULL, i = %d\n", __func__, i); } if (pEntry && IS_ENTRY_NONE(pEntry)) { /* ENTRY PREEMPTION: initialize the entry */ if (pEntry->RetryTimer.Valid) RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); if (pEntry->EnqueueStartForPSKTimer.Valid) RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); if (CleanAll == TRUE) { pEntry->MaxSupportedRate = RATE_11; pEntry->CurrTxRate = RATE_11; NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY)); pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; } SET_ENTRY_APCLI(pEntry); pEntry->wdev = wdev; pEntry->wcid = i; pEntry->isCached = FALSE; pEntry->bIAmBadAtheros = FALSE; RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE); RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) RTMPInitTimer(pAd, &pEntry->eTxBfProbeTimer, GET_TIMER_FUNCTION(eTxBfProbeTimerExec), pEntry, FALSE); #endif /* TXBF_SUPPORT */ pEntry->pAd = pAd; pEntry->CMTimerRunning = FALSE; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; pEntry->RSNIE_Len = 0; NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; pEntry->apidx = (apIdx - MIN_NET_DEVICE_FOR_APCLI); pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx]; pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->apidx].wdev.AuthMode; pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->apidx].wdev.WepStatus; pEntry->wdev_idx = pEntry->apidx; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { pEntry->WpaState = AS_NOTUSE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; } else { pEntry->WpaState = AS_PTKSTART; pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; } pEntry->GTKState = REKEY_NEGOTIATING; pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; COPY_MAC_ADDR(pEntry->Addr, pAddr); //COPY_MAC_ADDR(pEntry->HdrAddr1, pAddr); //COPY_MAC_ADDR(pEntry->HdrAddr2, pAd->ApCfg.ApCliTab[pEntry->apidx].CurrentAddress); //COPY_MAC_ADDR(pEntry->HdrAddr3, pAddr); COPY_MAC_ADDR(pEntry->bssid, pAddr); pEntry->Sst = SST_NOT_AUTH; pEntry->AuthState = AS_NOT_AUTH; pEntry->Aid = (USHORT)i; /*0;*/ pEntry->CapabilityInfo = 0; pEntry->PsMode = PWR_ACTIVE; pEntry->PsQIdleCount = 0; pEntry->NoDataIdleCount = 0; pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; pEntry->ContinueTxFailCnt = 0; pEntry->TimeStamp_toTxRing = 0; InitializeQueueHeader(&pEntry->PsQueue); #ifdef PS_ENTRY_MAITENANCE pEntry->continuous_ps_count = 0; #endif /* PS_ENTRY_MAITENANCE */ pAd->MacTab.Size ++; /* Set the security mode of this entry as OPEN-NONE in ASIC */ RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i); /* Add this entry into ASIC RX WCID search table */ RTMP_STA_ENTRY_ADD(pAd, pEntry); #ifdef WSC_AP_SUPPORT pEntry->bWscCapable = FALSE; pEntry->Receive_EapolStart_EapRspId = 0; #endif /* WSC_AP_SUPPORT */ #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) NdisAllocateSpinLock(pAd, &pEntry->TxSndgLock); #endif /* TXBF_SUPPORT */ #ifdef PEER_DELBA_TX_ADAPT Peer_DelBA_Tx_Adapt_Init(pAd, pEntry); #endif /* PEER_DELBA_TX_ADAPT */ #ifdef DROP_MASK_SUPPORT drop_mask_init_per_client(pAd, pEntry); #endif /* DROP_MASK_SUPPORT */ #ifdef FIFO_EXT_SUPPORT if (pAd->chipCap.FlgHwFifoExtCap) { UCHAR tblIdx; if ((cliIdx != 0xFF) && IsFifoExtTblAvailable(pAd, &tblIdx)) FifoExtTblUpdateEntry(pAd, tblIdx, i); } #endif DBGPRINT(RT_DEBUG_TRACE, ("%s - allocate entry #%d, Aid = %d, Wcid = %d Addr(%02x:%02x:%02x:%02x:%02x:%02x) Total= %d\n",__FUNCTION__, i, pEntry->Aid, pEntry->wcid, PRINT_MAC(pEntry->Addr), pAd->MacTab.Size)); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s - exist entry #%d, Aid = %d, Total= %d\n", __FUNCTION__, i, pEntry->Aid, pAd->MacTab.Size)); NdisReleaseSpinLock(&pAd->MacTabLock); return pEntry; } /* add this MAC entry into HASH table */ if (pEntry) { pEntry->pNext = NULL; HashIdx = MAC_ADDR_HASH_INDEX(pAddr); if (pAd->MacTab.Hash[HashIdx] == NULL) { pAd->MacTab.Hash[HashIdx] = pEntry; } else { pCurrEntry = pAd->MacTab.Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } NdisReleaseSpinLock(&pAd->MacTabLock); return pEntry; }
VOID CMDHandler( IN PRTMP_ADAPTER pAd) { PCmdQElmt cmdqelmt; PUCHAR pData; NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; // ULONG Now = 0; NTSTATUS ntStatus; // unsigned long IrqFlags; while (pAd && pAd->CmdQ.size > 0) { NdisStatus = NDIS_STATUS_SUCCESS; NdisAcquireSpinLock(&pAd->CmdQLock); RTThreadDequeueCmd(&pAd->CmdQ, &cmdqelmt); NdisReleaseSpinLock(&pAd->CmdQLock); if (cmdqelmt == NULL) break; pData = cmdqelmt->buffer; if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { switch (cmdqelmt->command) { case CMDTHREAD_CHECK_GPIO: { #ifdef CONFIG_STA_SUPPORT UINT32 data; #endif // CONFIG_STA_SUPPORT // #ifdef RALINK_ATE if(ATE_ON(pAd)) { ATEDBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n")); break; } #endif // RALINK_ATE // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // Read GPIO pin2 as Hardware controlled radio state RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data); if (data & 0x04) { pAd->StaCfg.bHwRadio = TRUE; } else { pAd->StaCfg.bHwRadio = FALSE; } if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) { pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); if(pAd->StaCfg.bRadio == TRUE) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n")); MlmeRadioOn(pAd); // Update extra information pAd->ExtraInfo = EXTRA_INFO_CLEAR; } else { DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n")); MlmeRadioOff(pAd); // Update extra information pAd->ExtraInfo = HW_RADIO_OFF; } } } #endif // CONFIG_STA_SUPPORT // } break; #ifdef CONFIG_STA_SUPPORT case CMDTHREAD_QKERIODIC_EXECUT: { StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL); } break; #endif // CONFIG_STA_SUPPORT // case CMDTHREAD_RESET_BULK_OUT: { UINT32 MACValue; UCHAR Index; int ret=0; PHT_TX_CONTEXT pHTTXContext; // RTMP_TX_RING *pTxRing; unsigned long IrqFlags; DBGPRINT(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid)); // All transfers must be aborted or cancelled before attempting to reset the pipe. //RTUSBCancelPendingBulkOutIRP(pAd); // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 Index = 0; do { if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) break; RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue); if ((MACValue & 0xf00000/*0x800000*/) == 0) break; Index++; RTMPusecDelay(10000); }while(Index < 100); MACValue = 0; RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); // 2nd, to prevent Read Register error, we check the validity. if ((MACValue & 0xc00000) == 0) RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); // 3rd, to prevent Read Register error, we check the validity. if ((MACValue & 0xc00000) == 0) RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); MACValue |= 0x80000; RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 RTMPusecDelay(1000); MACValue &= (~0x80000); RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); DBGPRINT(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n")); // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 //RTMPusecDelay(5000); if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG) { RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); } RTUSBKickBulkOut(pAd); DBGPRINT(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n")); } else { pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]); //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE) { pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE; pHTTXContext->IRPPending = TRUE; pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1; // no matter what, clean the flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); #ifdef RALINK_ATE if(ATE_ON(pAd)) { ret = ATEResetBulkOut(pAd); } else #endif // RALINK_ATE // { RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0) { RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE; pHTTXContext->IRPPending = FALSE; pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0; RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_OUT:Submit Tx URB failed %d\n", ret)); } else { RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); DBGPRINT(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid])); DBGPRINT(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); DBGPRINT(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->rtusb_urb_status)); } } } else { //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid)); if (pAd->bulkResetPipeid == 0) { UCHAR pendingContext = 0; PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]); PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext); PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext); if (pHTTXContext->IRPPending) pendingContext |= 1; else if (pMLMEContext->IRPPending) pendingContext |= 2; else if (pNULLContext->IRPPending) pendingContext |= 4; else if (pPsPollContext->IRPPending) pendingContext |= 8; else pendingContext = 0; DBGPRINT(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext)); } // no matter what, clean the flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid)); } RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); //RTUSBKickBulkOut(pAd); } } /* // Don't cancel BULKIN. while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { if (atomic_read(&pAd->PendingRx) > 0) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n")); RTUSBCancelPendingBulkInIRP(pAd); } RTMPusecDelay(100000); } if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { UCHAR i; RTUSBRxPacket(pAd); pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer for (i = 0; i < (RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); pRxContext->pAd = pAd; pRxContext->InUse = FALSE; pRxContext->IRPPending = FALSE; pRxContext->Readable = FALSE; pRxContext->ReorderInUse = FALSE; } RTUSBBulkReceive(pAd); DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n")); }*/ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n")); break; case CMDTHREAD_RESET_BULK_IN: DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n")); // All transfers must be aborted or cancelled before attempting to reset the pipe. { UINT32 MACValue; #ifdef RALINK_ATE if (ATE_ON(pAd)) { ATEResetBulkIn(pAd); } else #endif // RALINK_ATE // { //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n")); RTUSBCancelPendingBulkInIRP(pAd); RTMPusecDelay(100000); pAd->PendingRx = 0; } } // Wait 10ms before reading register. RTMPusecDelay(10000); ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue); if ((NT_SUCCESS(ntStatus) == TRUE) && (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))))) { UCHAR i; if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))) break; pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset; DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n", pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail)); for (i = 0; i < RX_RING_SIZE; i++) { DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n" , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable)); } /* DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n")); pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer for (i = 0; i < (RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); pRxContext->pAd = pAd; pRxContext->InUse = FALSE; pRxContext->IRPPending = FALSE; pRxContext->Readable = FALSE; pRxContext->ReorderInUse = FALSE; }*/ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++) { //RTUSBBulkReceive(pAd); PRX_CONTEXT pRxContext; PURB pUrb; int ret = 0; unsigned long IrqFlags; RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE)) { RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); break; } pRxContext->InUse = TRUE; pRxContext->IRPPending = TRUE; pAd->PendingRx++; pAd->BulkInReq++; RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); // Init Rx context descriptor RTUSBInitRxDesc(pAd, pRxContext); pUrb = pRxContext->pUrb; if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { // fail RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); pRxContext->InUse = FALSE; pRxContext->IRPPending = FALSE; pAd->PendingRx--; pAd->BulkInReq--; RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->rtusb_urb_status)); } else { // success //DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", // pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->rtusb_urb_status)); ASSERT((pRxContext->InUse == pRxContext->IRPPending)); } } } else { // Card must be removed if (NT_SUCCESS(ntStatus) != TRUE) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n")); } else { DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags)); } } } DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n")); break; case CMDTHREAD_SET_ASIC_WCID: { RT_SET_ASIC_WCID SetAsicWcid; USHORT offset; UINT32 MACValue, MACRValue = 0; SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData)); if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE) return; offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE; DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid)); MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]); DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue)); RTUSBWriteMACRegister(pAd, offset, MACValue); // Read bitmask RTUSBReadMACRegister(pAd, offset+4, &MACRValue); if ( SetAsicWcid.DeleteTid != 0xffffffff) MACRValue &= (~SetAsicWcid.DeleteTid); if (SetAsicWcid.SetTid != 0xffffffff) MACRValue |= (SetAsicWcid.SetTid); MACRValue &= 0xffff0000; MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4]; MACValue |= MACRValue; RTUSBWriteMACRegister(pAd, offset+4, MACValue); DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue)); } break; /* Security Related for Asic command */ case CMDTHREAD_SET_WCID_SEC_INFO: { PRT_ASIC_WCID_SEC_INFO pInfo; pInfo = (PRT_ASIC_WCID_SEC_INFO)pData; RTMPSetWcidSecurityInfo(pAd, pInfo->BssIdx, pInfo->KeyIdx, pInfo->CipherAlg, pInfo->Wcid, pInfo->KeyTabFlag); } break; case CMDTHREAD_SET_ASIC_WCID_IVEIV: { PRT_ASIC_WCID_IVEIV_ENTRY pInfo; pInfo = (PRT_ASIC_WCID_IVEIV_ENTRY)pData; AsicUpdateWCIDIVEIV(pAd, pInfo->Wcid, pInfo->Iv, pInfo->Eiv); } break; case CMDTHREAD_SET_ASIC_WCID_ATTR: { PRT_ASIC_WCID_ATTR_ENTRY pInfo; pInfo = (PRT_ASIC_WCID_ATTR_ENTRY)pData; AsicUpdateWcidAttributeEntry(pAd, pInfo->BssIdx, pInfo->KeyIdx, pInfo->CipherAlg, pInfo->Wcid, pInfo->KeyTabFlag); } break; case CMDTHREAD_SET_ASIC_SHARED_KEY: { PRT_ASIC_SHARED_KEY pInfo; pInfo = (PRT_ASIC_SHARED_KEY)pData; AsicAddSharedKeyEntry(pAd, pInfo->BssIndex, pInfo->KeyIdx, &pInfo->CipherKey); } break; case CMDTHREAD_SET_ASIC_PAIRWISE_KEY: { PRT_ASIC_PAIRWISE_KEY pInfo; pInfo = (PRT_ASIC_PAIRWISE_KEY)pData; AsicAddPairwiseKeyEntry(pAd, pInfo->WCID, &pInfo->CipherKey); } break; case CMDTHREAD_SET_PORT_SECURED: { #ifdef CONFIG_STA_SUPPORT STA_PORT_SECURED(pAd); #endif // CONFIG_STA_SUPPORT // } break; case CMDTHREAD_REMOVE_PAIRWISE_KEY: { UCHAR Wcid = *((PUCHAR)(pData)); AsicRemovePairwiseKeyEntry(pAd, Wcid); } break; case CMDTHREAD_SET_CLIENT_MAC_ENTRY: { PRT_SET_ASIC_WCID pInfo; pInfo = (PRT_SET_ASIC_WCID)pData; AsicUpdateRxWCIDTable(pAd, pInfo->WCID, pInfo->Addr); } break; // add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet case CMDTHREAD_UPDATE_PROTECT: { AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); } break; // end johnli case CMDTHREAD_802_11_COUNTER_MEASURE: break; #ifdef CONFIG_STA_SUPPORT case CMDTHREAD_SET_PSM_BIT: IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { USHORT *pPsm = (USHORT *)pData; MlmeSetPsmBit(pAd, *pPsm); } break; case CMDTHREAD_FORCE_WAKE_UP: IF_DEV_CONFIG_OPMODE_ON_STA(pAd) AsicForceWakeup(pAd, TRUE); break; case CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP: { USHORT TbttNumToNextWakeUp; USHORT NextDtim = pAd->StaCfg.DtimPeriod; ULONG Now; NdisGetSystemUpTime(&Now); NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod; TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; RTMP_SET_PSM_BIT(pAd, PWR_SAVE); // if WMM-APSD is failed, try to disable following line AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); } break; #endif // CONFIG_STA_SUPPORT // default: DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command)); break; } } if (cmdqelmt->CmdFromNdis == TRUE) { if (cmdqelmt->buffer != NULL) os_free_mem(pAd, cmdqelmt->buffer); os_free_mem(pAd, cmdqelmt); } else { if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0)) os_free_mem(pAd, cmdqelmt->buffer); os_free_mem(pAd, cmdqelmt); } } /* end of while */ }
/* ======================================================================== 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*/ RTUSB_UNLINK_URB(pHTTXContext->pUrb); /* Sleep 200 microseconds to give cancellation time to work*/ RTMPusecDelay(200); } #ifdef RALINK_ATE pHTTXContext->bCopySavePad = 0; pHTTXContext->CurWritePosition = 0; pHTTXContext->CurWriteRealPos = 0; pHTTXContext->bCurWriting = FALSE; pHTTXContext->NextBulkOutPosition = 0; pHTTXContext->ENextBulkOutPosition = 0; #endif /* RALINK_ATE */ 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); 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]); } }
NTSTATUS ssh_interceptor_iodevice_dispatch_ioctl(PDEVICE_OBJECT device, PIRP irp) { #ifdef HAS_IOCTL_HANDLERS PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(irp); ULONG ioctl_code = io_stack->Parameters.DeviceIoControl.IoControlCode; SshInterceptorIoDevice io_dev = SSH_NTDEV_TO_SSHDEV(device); SshIoDeviceIoctlHandler handler = NULL; PLIST_ENTRY entry; NdisAcquireSpinLock(&io_dev->ioctl_handler_list_lock); entry = io_dev->ioctl_handler_list.Flink; while (entry != &io_dev->ioctl_handler_list) { SshIoDeviceIoctlHandler h; h = CONTAINING_RECORD(entry, SshIoDeviceIoctlHandlerStruct, link); if (h->ioctl_code == ioctl_code) { handler = h; InterlockedIncrement(&handler->ref_count); break; } entry = entry->Flink; } NdisReleaseSpinLock(&io_dev->ioctl_handler_list_lock); if (handler != NULL) { SshIoDeviceIoctlRequest ioctl; ioctl = ssh_calloc(1, sizeof(*ioctl)); if (ioctl == NULL) { irp->IoStatus.Status = STATUS_UNSUCCESSFUL; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } /* Initialize te IOCTL request */ ioctl->public_data.device = io_dev; ioctl->public_data.ioctl_code = ioctl_code; ioctl->public_data.context = handler; ioctl->public_data.cancel_id = ioctl; ioctl->public_data.input_buf_len = io_stack->Parameters.DeviceIoControl.InputBufferLength; ioctl->public_data.output_buf_len = io_stack->Parameters.DeviceIoControl.OutputBufferLength; switch (ioctl_code & 0x00000003) { case METHOD_BUFFERED: ioctl->public_data.input_buf = irp->AssociatedIrp.SystemBuffer; ioctl->public_data.output_buf = irp->AssociatedIrp.SystemBuffer; break; case METHOD_NEITHER: ioctl->public_data.input_buf = io_stack->Parameters.DeviceIoControl.Type3InputBuffer; ioctl->public_data.output_buf = irp->UserBuffer; break; case METHOD_IN_DIRECT: case METHOD_OUT_DIRECT: default: SSH_NOTREACHED; break; } ioctl->public_data.bytes_read = 0; ioctl->public_data.bytes_written = 0; ioctl->private_data.irp = irp; NdisAcquireSpinLock(&io_dev->ioctl_req_list_lock); InsertTailList(&io_dev->active_ioctl_req_list, &ioctl->private_data.link); NdisReleaseSpinLock(&io_dev->ioctl_req_list_lock); irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(irp); #pragma warning(disable: 4311 4312) IoSetCancelRoutine(irp, ssh_interceptor_iodevice_cancel_queued_ioctl); #pragma warning(default: 4311 4312) (*(handler->ioctl_handler))(handler->context, &ioctl->public_data); return STATUS_PENDING; } #endif /* HAS_IOCTL_HANDLERS */ irp->IoStatus.Status = STATUS_NOT_SUPPORTED; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_NOT_SUPPORTED; }
static void ssh_interceptor_iodevice_do_reads(SshInterceptorIoDevice io_dev) { SshDeviceBuffer buffer; PIO_STACK_LOCATION irp_stack = NULL; char *dest = NULL; char *base_addr = NULL; PIRP irp = NULL; NdisAcquireSpinLock(&io_dev->output_queue_lock); buffer = io_dev->current_read_buf; NdisReleaseSpinLock(&io_dev->output_queue_lock); /* Complete as many queued output buffers and pending reads as possible */ while (TRUE) { PLIST_ENTRY entry; unsigned bytes_copied; /* Try to find some data to write */ if (buffer == NULL) { NdisAcquireSpinLock(&io_dev->output_queue_lock); if (!IsListEmpty(&io_dev->output_queue)) { entry = RemoveHeadList(&io_dev->output_queue); buffer = CONTAINING_RECORD(entry, SshDeviceBufferStruct, link); /* If this is an unreliable message, it must also be removed from the unreliable_output_queue! */ if (buffer->reliable == 0) RemoveEntryList(&buffer->unreliable_list_link); } io_dev->current_read_buf = buffer; NdisReleaseSpinLock(&io_dev->output_queue_lock); /* Exit the loop if no data was available in output queue */ if (buffer == NULL) goto complete; } /* Try to find queued read IRP */ if (irp == NULL) { entry = NdisInterlockedRemoveHeadList(&io_dev->read_queue, &io_dev->read_queue_lock); if (entry) { irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); irp_stack = IoGetCurrentIrpStackLocation(irp); /* There is no need to check for canceled status, because cancelation is protected by the same lock as the queue itself. We may actually pop off an IRP for which cancel has already been issued, but we can complete it as usual. */ #pragma warning(disable: 4311 4312) IoSetCancelRoutine(irp, NULL); #pragma warning(default: 4311 4312) irp->IoStatus.Information = 0; irp->IoStatus.Status = STATUS_SUCCESS; base_addr = ssh_iodevice_map_buffer(irp->MdlAddress); if (base_addr == NULL) { /* Mapping of user-mode buffer could fail if the system is very low on resources. */ IoCompleteRequest(irp, IO_NETWORK_INCREMENT); irp = NULL; continue; } dest = base_addr; } else { /* No read IRPs available, exit the loop */ goto complete; } } /* We copy either the whole buffer or part of it if there isn't enough space left in the currently processed read IRP. */ bytes_copied = buffer->len; if (irp->IoStatus.Information + bytes_copied > irp_stack->Parameters.Read.Length) { bytes_copied = irp_stack->Parameters.Read.Length - (unsigned int)irp->IoStatus.Information; } NdisMoveMemory(dest, buffer->addr + buffer->offset, bytes_copied); buffer->offset += bytes_copied; buffer->len -= bytes_copied; if (buffer->len == 0) { NdisAcquireSpinLock(&io_dev->output_queue_lock); io_dev->current_read_buf = NULL; NdisReleaseSpinLock(&io_dev->output_queue_lock); ssh_iodevice_buffer_free(io_dev, buffer); buffer = NULL; } irp->IoStatus.Information += bytes_copied; dest += bytes_copied; /* If the IRP is now "full", complete the request */ if (irp->IoStatus.Information == irp_stack->Parameters.Read.Length) { ssh_iodevice_unmap_buffer(base_addr, irp->MdlAddress); IoCompleteRequest(irp, IO_NETWORK_INCREMENT); irp = NULL; base_addr = NULL; } } complete: /* We should also complete the partially filled IRP, if any */ if (irp) { ssh_iodevice_unmap_buffer(base_addr, irp->MdlAddress); IoCompleteRequest(irp, IO_NETWORK_INCREMENT); } }
VOID ElnkStagedAllocation( IN PELNK_ADAPTER Adapter ) /*++ Routine Description: This routine attempts to take a packet through a stage of allocation. Arguments: Adapter - The adapter that the packets are coming through. Return Value: None. --*/ { UINT CbIndex; PNDIS_PACKET FirstPacket = Adapter->FirstStagePacket; if ELNKDEBUG DPrint1("StagedAllocation\n"); // // For each stage, we check to see that it is open, // that somebody else isn't already processing, // and that there is some work from the previous // stage to do. // ASSERT (Adapter->StageOpen && !Adapter->AlreadyProcessingStage && Adapter->FirstStagePacket); // // If we successfully acquire a command block, this // is the index to it. // Adapter->AlreadyProcessingStage = TRUE; // // We look to see if there is an available Command Block. // If there isn't then stage 2 will close. // IF_LOG('p'); if (ElnkAcquireCommandBlock( Adapter, &CbIndex )) { IF_LOG('a'); // // Remove from queue // Adapter->FirstStagePacket = PELNK_RESERVED_FROM_PACKET(FirstPacket)->Next; if (!Adapter->FirstStagePacket) { Adapter->LastStagePacket = NULL; } NdisReleaseSpinLock(&Adapter->Lock); // // We have a command block. Assign all packet // buffers to the command block. // ElnkAssignPacketToCommandBlock( Adapter, FirstPacket, CbIndex ); // // We need exclusive access to the Command Queue so // that we can move this packet on to the next stage. // NdisAcquireSpinLock(&Adapter->Lock); ElnkPutPacketOnFinishTrans( Adapter, FirstPacket ); ElnkSubmitCommandBlock( Adapter, CbIndex ); Adapter->AlreadyProcessingStage = FALSE; } else { Adapter->AlreadyProcessingStage = FALSE; Adapter->StageOpen = FALSE; IF_LOG('P'); return; } IF_LOG('P'); }
NDIS_STATUS ElnkSend( IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet ) /*++ Routine Description: The ElnkSend request instructs a MAC to transmit a packet through the adapter onto the medium. Arguments: MacBindingHandle - The context value returned by the MAC when the adapter was opened. In reality, it is a pointer to ELNK_OPEN. Packet - A pointer to a descriptor for the packet that is to be transmitted. Return Value: The function value is the status of the operation. --*/ { // // Holds the status that should be returned to the caller. // NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING; // // Pointer to the adapter. // PELNK_ADAPTER Adapter; if ELNKDEBUG DPrint2("ElnkSend Packet = %x\n",Packet); Adapter = PELNK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); NdisAcquireSpinLock(&Adapter->Lock); Adapter->References++; if (!Adapter->ResetInProgress) { PELNK_OPEN Open; Open = PELNK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); if (!Open->BindingShuttingDown) { UINT TotalPacketSize; // // Increment the references on the open while we are // accessing it in the interface. // Open->References++; NdisReleaseSpinLock(&Adapter->Lock); // // It is reasonable to do a quick check and fail if the packet // is larger than the maximum an ethernet can handle. // NdisQueryPacket( Packet, NULL, NULL, NULL, &TotalPacketSize ); NdisAcquireSpinLock(&Adapter->Lock); if ((!TotalPacketSize) || (TotalPacketSize > MAXIMUM_ETHERNET_PACKET_SIZE)) { Open->References--; StatusToReturn = NDIS_STATUS_RESOURCES; } else { PELNK_RESERVED Reserved = PELNK_RESERVED_FROM_PACKET(Packet); PNDIS_BUFFER FirstBuffer; PUCHAR BufferVA; UINT Length; // // Set Reserved->Loopback. // NdisQueryPacket(Packet, NULL, NULL, &FirstBuffer, NULL); // // Get VA of first buffer // NdisQueryBuffer( FirstBuffer, (PVOID *)&BufferVA, &Length ); if (Open->ProtOptionFlags & NDIS_PROT_OPTION_NO_LOOPBACK){ Reserved->Loopback = FALSE; } else { Reserved->Loopback = EthShouldAddressLoopBack(Adapter->FilterDB, BufferVA); } Reserved->MacBindingHandle = MacBindingHandle; // // Put on the stage queue. // if (!Adapter->LastStagePacket) { Adapter->FirstStagePacket = Packet; } else { PELNK_RESERVED_FROM_PACKET(Adapter->LastStagePacket)->Next = Packet; } Adapter->LastStagePacket = Packet; Reserved->Next = NULL; Adapter->TransmitsQueued++; // // Only try to push it through the stage queues // if somebody else isn't already doing it and // there is some hope of moving some packets // ahead. // while (!Adapter->AlreadyProcessingStage && Adapter->FirstStagePacket && Adapter->StageOpen ) { ElnkStagedAllocation(Adapter); } } // // We leave the reference for the pending send. // } else { StatusToReturn = NDIS_STATUS_CLOSING; } } else { StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; } ELNK_DO_DEFERRED(Adapter); return StatusToReturn; }
NDIS_STATUS PtDeregisterDevice( VOID ) /*++ Routine Description: Deregister the ioctl interface. This is called whenever a miniport instance is halted. When the last miniport instance is halted, we request NDIS to delete the device object Arguments: NdisDeviceHandle - Handle returned by NdisMRegisterDevice Return Value: NDIS_STATUS_SUCCESS if everything worked ok --*/ { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; DBGPRINT(("==>PassthruDeregisterDevice\n")); NdisAcquireSpinLock(&GlobalLock); ASSERT(MiniportCount > 0); --MiniportCount; if (0 == MiniportCount) { // // All miniport instances have been halted. Deregister // the control device. // ASSERT(ControlDeviceState == PS_DEVICE_STATE_READY); // // Block PtRegisterDevice() while we release the control // device lock and deregister the device. // ControlDeviceState = PS_DEVICE_STATE_DELETING; NdisReleaseSpinLock(&GlobalLock); if (NdisDeviceHandle != NULL) { Status = NdisMDeregisterDevice(NdisDeviceHandle); NdisDeviceHandle = NULL; } NdisAcquireSpinLock(&GlobalLock); ControlDeviceState = PS_DEVICE_STATE_READY; } NdisReleaseSpinLock(&GlobalLock); DBGPRINT(("<== PassthruDeregisterDevice: %x\n", Status)); return Status; }
NDIS_STATUS PtRegisterDevice( VOID ) /*++ Routine Description: Register an ioctl interface - a device object to be used for this purpose is created by NDIS when we call NdisMRegisterDevice. This routine is called whenever a new miniport instance is initialized. However, we only create one global device object, when the first miniport instance is initialized. This routine handles potential race conditions with PtDeregisterDevice via the ControlDeviceState and MiniportCount variables. NOTE: do not call this from DriverEntry; it will prevent the driver from being unloaded (e.g. on uninstall). Arguments: None Return Value: NDIS_STATUS_SUCCESS if we successfully register a device object. --*/ { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; UNICODE_STRING DeviceName; UNICODE_STRING DeviceLinkUnicodeString; PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1]; DBGPRINT(("==>PtRegisterDevice\n")); NdisAcquireSpinLock(&GlobalLock); ++MiniportCount; if (1 == MiniportCount) { ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING); // // Another thread could be running PtDeregisterDevice on // behalf of another miniport instance. If so, wait for // it to exit. // while (ControlDeviceState != PS_DEVICE_STATE_READY) { NdisReleaseSpinLock(&GlobalLock); NdisMSleep(1); NdisAcquireSpinLock(&GlobalLock); } ControlDeviceState = PS_DEVICE_STATE_CREATING; NdisReleaseSpinLock(&GlobalLock); NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH)); DispatchTable[IRP_MJ_CREATE] = NdisProtOpen; DispatchTable[IRP_MJ_CLEANUP] = NdisProtCleanup; DispatchTable[IRP_MJ_CLOSE] = NdisProtClose; // DispatchTable[IRP_MJ_READ] = NdisProtRead; DispatchTable[IRP_MJ_READ] = divert_read; // DispatchTable[IRP_MJ_WRITE] = PtDispatch; DispatchTable[IRP_MJ_WRITE] = divert_write; // DispatchTable[IRP_MJ_DEVICE_CONTROL] = NdisProtIoControl; DispatchTable[IRP_MJ_DEVICE_CONTROL] = PtDispatch; NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING); NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING); // // Create a device object and register our dispatch handlers // Status = NdisMRegisterDevice( NdisWrapperHandle, &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0], &ControlDeviceObject, &NdisDeviceHandle ); ControlDeviceObject->Flags |= DO_DIRECT_IO; NdisAcquireSpinLock(&GlobalLock); ControlDeviceState = PS_DEVICE_STATE_READY; } NdisReleaseSpinLock(&GlobalLock); DBGPRINT(("<==PtRegisterDevice: %x\n", Status)); return (Status); }
MAC_TABLE_ENTRY *MacTableInsertEntry( IN RTMP_ADAPTER *pAd, IN UCHAR *pAddr, IN struct wifi_dev *wdev, IN UINT32 ent_type, IN UCHAR OpMode, IN BOOLEAN CleanAll) { UCHAR HashIdx; int i, FirstWcid; MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) return NULL; FirstWcid = 1; /* allocate one MAC entry*/ NdisAcquireSpinLock(&pAd->MacTabLock); for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup*/ { /* pick up the first available vacancy*/ if (IS_ENTRY_NONE(&pAd->MacTab.Content[i])) { pEntry = &pAd->MacTab.Content[i]; mac_entry_reset(pAd, pEntry, CleanAll); /* ENTRY PREEMPTION: initialize the entry */ pEntry->wdev = wdev; pEntry->wcid = i; pEntry->func_tb_idx = wdev->func_idx; pEntry->bIAmBadAtheros = FALSE; pEntry->pAd = pAd; pEntry->CMTimerRunning = FALSE; COPY_MAC_ADDR(pEntry->Addr, pAddr); pEntry->Sst = SST_NOT_AUTH; pEntry->AuthState = AS_NOT_AUTH; pEntry->Aid = (USHORT)i; pEntry->CapabilityInfo = 0; pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; pEntry->PsMode = PWR_ACTIVE; pEntry->NoDataIdleCount = 0; pEntry->ContinueTxFailCnt = 0; #ifdef WDS_SUPPORT pEntry->LockEntryTx = FALSE; #endif /* WDS_SUPPORT */ pEntry->TimeStamp_toTxRing = 0; // TODO: shiang-usw, remove upper setting becasue we need to migrate to tr_entry! pAd->MacTab.tr_entry[i].PsMode = PWR_ACTIVE; pAd->MacTab.tr_entry[i].NoDataIdleCount = 0; pAd->MacTab.tr_entry[i].ContinueTxFailCnt = 0; pAd->MacTab.tr_entry[i].LockEntryTx = FALSE; pAd->MacTab.tr_entry[i].TimeStamp_toTxRing = 0; pAd->MacTab.tr_entry[i].PsDeQWaitCnt = 0; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; pEntry->GTKState = REKEY_NEGOTIATING; pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; pEntry->RSNIE_Len = 0; NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (ent_type == ENTRY_APCLI) { SET_ENTRY_APCLI(pEntry); //SET_ENTRY_AP(pEntry);//Carter, why set entry to APCLI then set to AP???? COPY_MAC_ADDR(pEntry->bssid, pAddr); pEntry->AuthMode = pAd->ApCfg.ApCliTab[pEntry->func_tb_idx].wdev.AuthMode; pEntry->WepStatus = pAd->ApCfg.ApCliTab[pEntry->func_tb_idx].wdev.WepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { pEntry->WpaState = AS_NOTUSE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; } else { pEntry->WpaState = AS_PTKSTART; pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; } break; } #endif /* APCLI_SUPPORT */ #ifdef WDS_SUPPORT if (ent_type == ENTRY_WDS) { SET_ENTRY_WDS(pEntry); COPY_MAC_ADDR(pEntry->bssid, pAd->ApCfg.MBSSID[MAIN_MBSSID].wdev.bssid); pEntry->AuthMode = Ndis802_11AuthModeOpen; pEntry->WepStatus = Ndis802_11EncryptionDisabled; break; } #endif /* WDS_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (ent_type == ENTRY_CLIENT) { /* be a regular-entry*/ if ((pEntry->func_tb_idx < pAd->ApCfg.BssidNum) && (pEntry->func_tb_idx < MAX_MBSSID_NUM(pAd)) && ((pEntry->func_tb_idx < HW_BEACON_MAX_NUM)) && (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].MaxStaNum != 0) && (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].StaCount >= pAd->ApCfg.MBSSID[pEntry->func_tb_idx].MaxStaNum)) { DBGPRINT(RT_DEBUG_WARN, ("%s: The connection table is full in ra%d.\n", __FUNCTION__, pEntry->func_tb_idx)); NdisReleaseSpinLock(&pAd->MacTabLock); return NULL; } ASSERT((wdev == &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev)); SET_ENTRY_CLIENT(pEntry); pEntry->pMbss = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx]; MBSS_MR_APIDX_SANITY_CHECK(pAd, pEntry->func_tb_idx); COPY_MAC_ADDR(pEntry->bssid, wdev->bssid); pEntry->AuthMode = wdev->AuthMode; pEntry->WepStatus = wdev->WepStatus; pEntry->GroupKeyWepStatus = wdev->GroupKeyWepStatus; if (pEntry->AuthMode < Ndis802_11AuthModeWPA) pEntry->WpaState = AS_NOTUSE; else pEntry->WpaState = AS_INITIALIZE; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; pEntry->StaIdleTimeout = pAd->ApCfg.StaIdleTimeout; pAd->ApCfg.MBSSID[pEntry->func_tb_idx].StaCount++; pAd->ApCfg.EntryClientCount++; break; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); tr_tb_set_entry(pAd, i, pEntry); RTMPInitTimer(pAd, &pEntry->EnqueueStartForPSKTimer, GET_TIMER_FUNCTION(EnqueueStartForPSKExec), pEntry, FALSE); #ifdef CONFIG_AP_SUPPORT { if (IS_ENTRY_CLIENT(pEntry)) /* Only Client entry need the retry timer.*/ { RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); #ifdef DOT11W_PMF_SUPPORT RTMPInitTimer(pAd, &pEntry->SAQueryTimer, GET_TIMER_FUNCTION(PMF_SAQueryTimeOut), pEntry, FALSE); RTMPInitTimer(pAd, &pEntry->SAQueryConfirmTimer, GET_TIMER_FUNCTION(PMF_SAQueryConfirmTimeOut), pEntry, FALSE); #endif /* DOT11W_PMF_SUPPORT */ } #ifdef APCLI_SUPPORT if (IS_ENTRY_APCLI(pEntry)) RTMPInitTimer(pAd, &pEntry->RetryTimer, GET_TIMER_FUNCTION(WPARetryExec), pEntry, FALSE); #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef STREAM_MODE_SUPPORT /* Enable Stream mode for first three entries in MAC table */ #endif /* STREAM_MODE_SUPPORT */ #ifdef UAPSD_SUPPORT /* Ralink WDS doesn't support any power saving.*/ if (IS_ENTRY_CLIENT(pEntry) ) { /* init U-APSD enhancement related parameters */ UAPSD_MR_ENTRY_INIT(pEntry); } #endif /* UAPSD_SUPPORT */ pAd->MacTab.Size ++; /* Set the security mode of this entry as OPEN-NONE in ASIC */ RTMP_REMOVE_PAIRWISE_KEY_ENTRY(pAd, (UCHAR)i); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) MT_ADDREMOVE_KEY(pAd, 1, pEntry->apidx, 0, pEntry->wcid, PAIRWISEKEYTABLE, &pEntry->PairwiseKey, pEntry->Addr); #endif /* Add this entry into ASIC RX WCID search table */ RTMP_STA_ENTRY_ADD(pAd, pEntry); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WSC_AP_SUPPORT pEntry->bWscCapable = FALSE; pEntry->Receive_EapolStart_EapRspId = 0; #endif /* WSC_AP_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("%s(): alloc entry #%d, Total= %d\n", __FUNCTION__, i, pAd->MacTab.Size)); break; } }
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 // }
Boolean __fastcall ssh_interceptor_iodevice_create_device(SshInterceptorIoDevice io_dev) { SshInterceptor interceptor; PDRIVER_OBJECT driver; PSECURITY_DESCRIPTOR new_sd; PDRIVER_DISPATCH *fn_table; NTSTATUS st; #ifndef SSH_IM_INTERCEPTOR PDEVICE_OBJECT device; #else PDRIVER_DISPATCH major_function[IRP_MJ_MAXIMUM_FUNCTION + 1]; #endif /* SSH_IM_INTERCEPTOR */ SSH_ASSERT(io_dev != NULL); SSH_ASSERT(io_dev->interceptor != NULL); interceptor = io_dev->interceptor; SSH_ASSERT(interceptor->driver_object != NULL); driver = interceptor->driver_object; NdisAcquireSpinLock(&io_dev->output_queue_lock); if (io_dev->destroy_after_close) { SSH_DEBUG(SSH_D_NICETOKNOW, ("Clearing delayed destroy flag...")); io_dev->destroy_after_close = FALSE; } NdisReleaseSpinLock(&io_dev->output_queue_lock); if (InterlockedCompareExchange(&io_dev->io_device_created, 1, 0) != 0) { SSH_DEBUG(SSH_D_HIGHSTART, ("I/O device already exists; ignoring this call")); return TRUE; } SSH_DEBUG(SSH_D_HIGHSTART, ("Creating I/O device and symbolic link...")); #ifndef SSH_IM_INTERCEPTOR #pragma warning(disable : 28175) fn_table = driver->MajorFunction; #pragma warning(default : 28175) #else memset(&major_function, 0, sizeof(major_function)); fn_table = major_function; #endif /* SSH_IM_INTERCEPTOR */ /* Create the I/O device and symbolic link and limit the access permissions of the I/O device. */ /* Initialize dispatch function table */ fn_table[IRP_MJ_CREATE] = ssh_interceptor_iodevice_dispatch_create; fn_table[IRP_MJ_CLOSE] = ssh_interceptor_iodevice_dispatch_close; fn_table[IRP_MJ_CLEANUP] = ssh_interceptor_iodevice_dispatch_cleanup; fn_table[IRP_MJ_READ] = ssh_interceptor_iodevice_dispatch_read; fn_table[IRP_MJ_WRITE] = ssh_interceptor_iodevice_dispatch_write; fn_table[IRP_MJ_DEVICE_CONTROL] = ssh_interceptor_iodevice_dispatch_ioctl; #ifdef SSH_IM_INTERCEPTOR /* Try to register our I/O device with NDIS */ st = NdisMRegisterDevice(io_dev->interceptor->wrapper_handle, &io_dev->device_name, &io_dev->symlink_name, fn_table, &io_dev->device, &io_dev->handle); if (!NT_SUCCESS(st)) { SSH_DEBUG(SSH_D_FAIL, ("NdisMRegisterDevice() failed - %08x", st)); return FALSE; } #else /* not SSH_IM_INTERCEPTOR */ st = IoCreateDevice(driver, sizeof(void *), &io_dev->device_name, FILE_DEVICE_NETWORK, 0, (BOOLEAN)io_dev->exclusive_access, &device); if (!NT_SUCCESS(st)) { SSH_DEBUG(SSH_D_FAIL, ("IoCreateDevice() failed - %08x", st)); return FALSE; } io_dev->device = device; *((SshInterceptorIoDevice *)device->DeviceExtension) = io_dev; #endif /* not SSH_IM_INTERCEPTOR */ io_dev->device->AlignmentRequirement = FILE_QUAD_ALIGNMENT; io_dev->device->Flags |= DO_DIRECT_IO; /* Remove world access to newly created device object */ #pragma warning(disable : 28175) if (ssh_access_permissions_limit(io_dev->device->SecurityDescriptor, &new_sd) != FALSE) { io_dev->orig_sd = io_dev->device->SecurityDescriptor; io_dev->device->SecurityDescriptor = new_sd; } else { SSH_DEBUG(SSH_D_FAIL, ("ssh_access_permissions_limit() failed!")); } #pragma warning(default : 28175) #ifndef SSH_IM_INTERCEPTOR /* Create symbolic link to make device accessible from Win32 */ st = IoCreateSymbolicLink(&io_dev->symlink_name, &io_dev->device_name); if (!NT_SUCCESS(st)) { SSH_DEBUG(SSH_D_FAIL, ("IoCreateSymbolicLink() failed (%08X): %ls -> %ls", st, io_dev->symlink_name.Buffer, io_dev->device_name.Buffer)); IoDeleteDevice(io_dev->device); return FALSE; } #endif /* SSH_IM_INTERCEPTOR */ return TRUE; }
/* ======================================================================== 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; RTMP_OS_TASK *pTask = &pAd->cmdQTask; #ifdef KTHREAD_SUPPORT if (pTask->kthread_task == NULL) #else CHECK_PID_LEGALITY(pTask->taskPID) ; else #endif return (NDIS_STATUS_RESOURCES); status = os_alloc_mem(pAd, (PUCHAR *)(&cmdqelmt), sizeof(CmdQElmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) return (NDIS_STATUS_RESOURCES); cmdqelmt->buffer = NULL; if (pInformationBuffer != NULL) { status = os_alloc_mem(pAd, (PUCHAR *)&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 & RTMP_TASK_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) os_free_mem(pAd, cmdqelmt->buffer); os_free_mem(pAd, cmdqelmt); } else RTCMDUp(pAd); return(NDIS_STATUS_SUCCESS); }
Boolean ssh_interceptor_iodevice_send(SshInterceptorIoDevice io_dev, unsigned len, unsigned char *addr, Boolean reliable) { SshDeviceBuffer buf = NULL; Boolean st = FALSE; SSH_ASSERT(addr != NULL); /* Check that we have a valid packet */ SSH_ASSERT(len > 0); SSH_ASSERT(len <= 0x7FFFFFFF); /* Our length field is "only" 31 bits long */ /* No need to use spin lock (yet), because nothing bad happens if the I/O device will be closed between this check and the moment when we acquire an output queue spin lock. */ if (InterlockedCompareExchange(&io_dev->opened_instances, 0, 0) != 0) buf = ssh_iodevice_buffer_alloc(io_dev, reliable); if (buf) { buf->len = len; buf->addr = addr; buf->offset = 0; if (reliable) buf->reliable = 1; else buf->reliable = 0; NdisAcquireSpinLock(&io_dev->output_queue_lock); /* This time it's important that we read correct value from 'io_dev->open', so we must protect also this check with a spin lock */ if (InterlockedCompareExchange(&io_dev->opened_instances, 0, 0) != 0) { InsertTailList(&io_dev->output_queue, &buf->link); if (reliable == FALSE) InsertTailList(&io_dev->unreliable_output_queue, &buf->unreliable_list_link); /* Notify the worker thread */ ssh_task_notify(&io_dev->worker_thread, SSH_TASK_SIGNAL_NOTIFY); st = TRUE; } NdisReleaseSpinLock(&io_dev->output_queue_lock); } if (st != TRUE) { ssh_free(addr); if (buf != NULL) { buf->addr = NULL; ssh_iodevice_buffer_free(io_dev, buf); } } return st; }
/* ======================================================================== Routine Description: Process MGMT ring DMA done interrupt, running in DPC level Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID RTMPHandleMgmtRingDmaDoneInterrupt( IN PRTMP_ADAPTER pAd) { PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket; /* int i;*/ UCHAR FREE = 0; PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; UINT8 TXWISize = pAd->chipCap.TXWISize; NdisAcquireSpinLock(&pAd->MgmtRingLock); RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) { FREE++; #ifdef RT_BIG_ENDIAN pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #else pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); #endif /* pTxD->DMADONE = 0; */ pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; if (pPacket == NULL) { INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); continue; } #define LMR_FRAME_GET() (GET_OS_PKT_DATAPTR(pPacket) + TXWISize) #ifdef UAPSD_SUPPORT #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { UAPSD_QoSNullTxMgmtTxDoneHandle(pAd, pPacket, LMR_FRAME_GET()); } #endif /* CONFIG_AP_SUPPORT */ #endif /* UAPSD_SUPPORT */ #ifdef CONFIG_AP_SUPPORT #endif /* CONFIG_AP_SUPPORT */ if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, RTMP_PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, RTMP_PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; /* flush dcache if no consistent memory is supported */ RTMP_DCACHE_FLUSH(pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocPa, RXD_SIZE); INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD); #endif } NdisReleaseSpinLock(&pAd->MgmtRingLock); }
void ssh_interceptor_iodevice_complete_ioctl(SshInterceptorIoDevice iodevice, SshIoctlRequest ioctl_req, SshIoctlStatus status) { SshIoDeviceIoctlRequest ioctl; SshIoDeviceIoctlHandler handler; PIRP irp; SSH_ASSERT(iodevice != NULL); SSH_ASSERT(ioctl_req != NULL); SSH_ASSERT(ioctl_req->device == iodevice); ioctl = CONTAINING_RECORD(ioctl_req, SshIoDeviceIoctlRequestStruct, public_data); NdisAcquireSpinLock(&iodevice->ioctl_req_list_lock); RemoveEntryList(&ioctl->private_data.link); NdisReleaseSpinLock(&iodevice->ioctl_req_list_lock); handler = ioctl->public_data.context; irp = ioctl->private_data.irp; #pragma warning(disable: 4311 4312) IoSetCancelRoutine(irp, NULL); #pragma warning(default: 4311 4312) switch (status) { case SSH_IOCTL_RESULT_SUCCESS: irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = ioctl->public_data.bytes_written; IoCompleteRequest(irp, IO_NO_INCREMENT); break; case SSH_IOCTL_RESULT_FAILURE: irp->IoStatus.Status = STATUS_UNSUCCESSFUL; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); break; case SSH_IOCTL_RESULT_CANCELLED: irp->IoStatus.Status = STATUS_CANCELLED; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); break; default: SSH_NOTREACHED; break; } InterlockedDecrement(&handler->ref_count); ssh_free(ioctl); }
VOID RTMPInsertRepeaterEntry( IN PRTMP_ADAPTER pAd, IN UCHAR apidx, IN PUCHAR pAddr) { INT CliIdx, idx; UCHAR HashIdx; BOOLEAN Cancelled; UCHAR tempMAC[MAC_ADDR_LEN]; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PREPEATER_CLIENT_ENTRY pReptCliEntry = NULL, pCurrEntry = NULL; PREPEATER_CLIENT_ENTRY_MAP pReptCliMap; UCHAR SPEC_ADDR[6][3] = {{0x02, 0x0F, 0xB5}, {0x02, 0x09, 0x5B}, {0x02, 0x14, 0x6C}, {0x02, 0x18, 0x4D}, {0x02, 0x1B, 0x2F}, {0x02, 0x1E, 0x2A}}; MAC_TABLE_ENTRY *pMacEntry = NULL; DBGPRINT(RT_DEBUG_TRACE, (" %s.\n", __FUNCTION__)); pMacEntry = MacTableLookup(pAd, pAddr); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) { if (pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) { DBGPRINT(RT_DEBUG_ERROR, (" wireless client is not ready !!!\n")); return; } } NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); if (pAd->ApCfg.RepeaterCliSize >= MAX_EXT_MAC_ADDR_SIZE) { DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } for (CliIdx = 0; CliIdx < MAX_EXT_MAC_ADDR_SIZE; CliIdx++) { pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx]; if ((pReptCliEntry->CliEnable) && (MAC_ADDR_EQUAL(pReptCliEntry->OriginalAddress, pAddr) || MAC_ADDR_EQUAL(pReptCliEntry->CurrentAddress, pAddr))) { DBGPRINT(RT_DEBUG_ERROR, ("\n receive mac :%02x:%02x:%02x:%02x:%02x:%02x !!!\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5])); DBGPRINT(RT_DEBUG_ERROR, (" duplicate Insert !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } if (pReptCliEntry->CliEnable == FALSE) break; } if (CliIdx >= MAX_EXT_MAC_ADDR_SIZE) { DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx]; pReptCliMap = &pAd->ApCfg.ApCliTab[apidx].RepeaterCliMap[CliIdx]; /* ENTRY PREEMPTION: initialize the entry */ RTMPCancelTimer(&pReptCliEntry->ApCliAuthTimer, &Cancelled); RTMPCancelTimer(&pReptCliEntry->ApCliAssocTimer, &Cancelled); pReptCliEntry->CtrlCurrState = APCLI_CTRL_DISCONNECTED; pReptCliEntry->AuthCurrState = APCLI_AUTH_REQ_IDLE; pReptCliEntry->AssocCurrState = APCLI_ASSOC_IDLE; pReptCliEntry->CliConnectState = 0; pReptCliEntry->CliValid = FALSE; pReptCliEntry->bEthCli = FALSE; pReptCliEntry->MacTabWCID = 0xFF; pReptCliEntry->AuthReqCnt = 0; pReptCliEntry->AssocReqCnt = 0; pReptCliEntry->CliTriggerTime = 0; pReptCliEntry->pNext = NULL; pReptCliMap->pReptCliEntry = pReptCliEntry; pReptCliMap->pNext = NULL; COPY_MAC_ADDR(pReptCliEntry->OriginalAddress, pAddr); COPY_MAC_ADDR(tempMAC, pAddr); #ifdef SMART_MESH NdisZeroMemory(pAd->vMacAddrPrefix,sizeof(pAd->vMacAddrPrefix)); #endif /* SMART_MESH */ if (pAd->ApCfg.MACRepeaterOuiMode == 1) { DBGPRINT(RT_DEBUG_ERROR, (" todo !!!\n")); } else if (pAd->ApCfg.MACRepeaterOuiMode == 2) { INT IdxToUse; for (idx = 0; idx < 6; idx++) { if (RTMPEqualMemory(SPEC_ADDR[idx], pAddr, 3)) break; } /* If there is a matched one, use the next one; otherwise, use the first one. */ if (idx >= 0 && idx < 5) IdxToUse = idx + 1; else IdxToUse = 0; NdisCopyMemory(tempMAC, SPEC_ADDR[IdxToUse], 3); #ifdef SMART_MESH INT vMacIdx; if (IdxToUse >= 0 && IdxToUse < 5) vMacIdx = IdxToUse + 1; else vMacIdx = 0; NdisCopyMemory(pAd->vMacAddrPrefix, SPEC_ADDR[vMacIdx], sizeof(pAd->vMacAddrPrefix)); #endif /* SMART_MESH */ } else { NdisCopyMemory(tempMAC, pAd->ApCfg.ApCliTab[apidx].wdev.if_addr, 3); } COPY_MAC_ADDR(pReptCliEntry->CurrentAddress, tempMAC); pReptCliEntry->CliEnable = TRUE; pReptCliEntry->CliConnectState = 1; pReptCliEntry->pNext = NULL; NdisGetSystemUpTime(&pReptCliEntry->CliTriggerTime); RTMPInsertRepeaterAsicEntry(pAd, CliIdx, tempMAC); HashIdx = MAC_ADDR_HASH_INDEX(tempMAC); if (pAd->ApCfg.ReptCliHash[HashIdx] == NULL) { pAd->ApCfg.ReptCliHash[HashIdx] = pReptCliEntry; } else { pCurrEntry = pAd->ApCfg.ReptCliHash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pReptCliEntry; } HashIdx = MAC_ADDR_HASH_INDEX(pReptCliEntry->OriginalAddress); if (pAd->ApCfg.ReptMapHash[HashIdx] == NULL) pAd->ApCfg.ReptMapHash[HashIdx] = pReptCliMap; else { PREPEATER_CLIENT_ENTRY_MAP pCurrMapEntry; pCurrMapEntry = pAd->ApCfg.ReptMapHash[HashIdx]; while (pCurrMapEntry->pNext != NULL) pCurrMapEntry = pCurrMapEntry->pNext; pCurrMapEntry->pNext = pReptCliMap; } pAd->ApCfg.RepeaterCliSize++; NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); NdisZeroMemory(&ApCliCtrlMsg, sizeof(APCLI_CTRL_MSG_STRUCT)); ApCliCtrlMsg.Status = MLME_SUCCESS; COPY_MAC_ADDR(&ApCliCtrlMsg.SrcAddr[0], tempMAC); ApCliCtrlMsg.BssIdx = apidx; ApCliCtrlMsg.CliIdx = CliIdx; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_MT2_AUTH_REQ, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, apidx); }
/* main handler, called when data arrives at bchannels */ VOID mtl__rx_bchan_handler ( MTL_CHAN *chan, USHORT bchan, ULONG IddRxFrameType, IDD_XMSG *msg ) { MTL *mtl; MTL_HDR hdr; MTL_AS *as; USHORT FragmentFlags, CopyLen; MTL_RX_TBL *RxTable; D_LOG(D_ENTRY, ("mtl__rx_bchan_handler: chan: 0x%p, bchan: %d, msg: 0x%p", chan, bchan, msg)); /* assigned mtl using back pointer */ mtl = chan->mtl; // // acquire the lock fot this mtl // NdisAcquireSpinLock(&mtl->lock); /* if not connected, ignore */ if ( !mtl->is_conn ) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: packet on non connected mtl, ignored")); goto exit_code; } RxTable = &mtl->rx_tbl; D_LOG(D_ENTRY, ("mtl__rx_bchan_handler: mtl: 0x%p, buflen: %d, bufptr: 0x%p", \ mtl, msg->buflen, msg->bufptr)); // // if we are in detect mode // if (!mtl->RecvFramingBits) { UCHAR DetectData[3]; /* extract header, check for fields */ IddGetDataFromAdapter(chan->idd, (PUCHAR)&hdr, (PUCHAR)msg->bufptr, sizeof(MTL_HDR)); // NdisMoveMemory ((PUCHAR)&hdr, (PUCHAR)msg->bufptr, sizeof(MTL_HDR)); // // this is used for inband signalling - ignore it // if (hdr.sig_tot == 0x50) goto exit_code; // // if this is dkf we need offset of zero for detection to work // if ( ((hdr.sig_tot & 0xF0) == 0x50) && (hdr.ofs != 0) ) goto exit_code; // // extract some data from the frame // IddGetDataFromAdapter(chan->idd, (PUCHAR)&DetectData, (PUCHAR)&msg->bufptr[4], 2); // NdisMoveMemory((PUCHAR)&DetectData, (PUCHAR)&msg->bufptr[4], 2); D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: hdr: 0x%x 0x%x 0x%x", hdr.sig_tot, \ hdr.seq, hdr.ofs)); D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: DetectData: 0x%x 0x%x", DetectData[0], DetectData[1])); if ( (IddRxFrameType & IDD_FRAME_PPP) || ((IddRxFrameType & IDD_FRAME_DKF) && ((DetectData[0] == 0xFF) && (DetectData[1] == 0x03)))) { mtl->RecvFramingBits = PPP_FRAMING; mtl->SendFramingBits = PPP_FRAMING; RxTable->NextFree = 0; } else { mtl->RecvFramingBits = RAS_FRAMING; mtl->SendFramingBits = RAS_FRAMING; } D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Deteced WrapperFrameType: 0x%x", mtl->RecvFramingBits)); // // don't pass up detected frame for now // goto exit_code; } if (IddRxFrameType & IDD_FRAME_DKF) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: DKF")); /* size of packet has to be atleast as size of header */ if ( msg->buflen < sizeof(hdr) ) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: packet size too small, ignored")); RxTable->DKFReceiveError1++; goto exit_code; } /* extract header, check for fields */ IddGetDataFromAdapter(chan->idd, (PUCHAR)&hdr, (PUCHAR)msg->bufptr, sizeof(MTL_HDR)); D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: hdr: 0x%x 0x%x 0x%x", hdr.sig_tot, \ hdr.seq, hdr.ofs)); // // if this is not our header of if this is an inband uus // ignore it // if ( (hdr.sig_tot & 0xF0) != 0x50 || hdr.sig_tot == 0x50) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: bad header signature, ignored")); D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, [0]: 0x%x", mtl, hdr.sig_tot)); RxTable->DKFReceiveError2++; goto exit_code; } if ( (hdr.ofs >= MTL_MAC_MTU) || ((hdr.ofs + msg->buflen - sizeof(hdr)) > MTL_MAC_MTU) ) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: bad offset/buflen, ignored")); D_LOG(D_ALWAYS, ("mtl: 0x%p, Offset: %d, BufferLength: %d", mtl, hdr.ofs, msg->buflen)); RxTable->DKFReceiveError3++; goto exit_code; } NdisAcquireSpinLock(&RxTable->lock); /* build pointer to assembly descriptor & lock it */ as = RxTable->as_tbl + (hdr.seq % MTL_RX_BUFS); // // if this assembly pointer is not free (queued) then // just drop this fragment // if (as->Queued) { D_LOG(D_ALWAYS, ("DKFRx: AssemblyQueue Overrun! mtl: 0x%p, as: 0x%p, seq: %d", \ mtl, as, hdr.seq)); RxTable->DKFReceiveError4++; as->QueueOverRun++; NdisReleaseSpinLock(&RxTable->lock); goto exit_code; } /* check for new slot */ if ( !as->tot ) { new_slot: /* new entry, fill-up */ as->seq = hdr.seq; /* record sequence number */ as->num = 1; /* just received 1'st fragment */ as->ttl = 1000; /* time to live init val */ as->len = msg->buflen - sizeof(hdr); /* record received length */ as->tot = hdr.sig_tot & 0x0F; /* record number of expected fragments */ /* copy received data into buffer */ copy_data: IddGetDataFromAdapter(chan->idd, (PUCHAR)as->buf + hdr.ofs, (PUCHAR)msg->bufptr + sizeof(hdr), (USHORT)(msg->buflen - sizeof(hdr))); // NdisMoveMemory (as->buf + hdr.ofs, msg->bufptr + sizeof(hdr), msg->buflen - sizeof(hdr)); } else if ( as->seq == hdr.seq ) { /* same_seq: */ /* same sequence number, accumulate */ as->num++; as->len += (msg->buflen - sizeof(hdr)); goto copy_data; } else { /* bad_frag: */ /* * if this case, an already taken slot is hit, but with a different * sequence number. this indicates a wrap-around in as_tbl. prev * entry is freed and then this fragment is recorded as first */ D_LOG(D_ALWAYS, ("DKFRx: Bad Fragment! mtl: 0x%p, as: 0x%p, as->seq: %d, seq: %d", \ mtl, as, as->seq, hdr.seq)); D_LOG(D_ALWAYS, ("as->tot: %d, as->num: %d", as->tot, as->num)); RxTable->DKFReceiveError5++; goto new_slot; } /* if all fragments recieved for packet, time to mail it up */ if ( as->tot == as->num ) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: pkt mailed up, buf: 0x%p, len: 0x%x", \ as->buf, as->len)); QueueDescriptorForRxIndication(mtl, as); // // mark this guy as being queued // as->Queued = 1; } /* release assembly descriptor */ NdisReleaseSpinLock(&RxTable->lock); } else if (IddRxFrameType & IDD_FRAME_PPP) { D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: PPP")); NdisAcquireSpinLock(&RxTable->lock); /* build pointer to assembly descriptor & lock it */ as = RxTable->as_tbl + (RxTable->NextFree % MTL_RX_BUFS); // // if this assembly pointer is not free (queued) then // just drop this fragment // if (as->Queued) { D_LOG(D_ALWAYS, ("PPPRx: AssemblyQueue Overrun! mtl: 0x%p, as: 0x%p, NextFree: %d", \ mtl, as, RxTable->NextFree)); as->QueueOverRun++; RxTable->PPPReceiveError1++; NdisReleaseSpinLock(&RxTable->lock); goto exit_code; } FragmentFlags = msg->FragmentFlags; D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: FragmentFlags: 0x%x, CurrentRxState: 0x%x", FragmentFlags, as->State)); switch (as->State) { case RX_MIDDLE: if (FragmentFlags & H_RX_N_BEG) break; as->MissCount++; // // missed an end buffer // D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, Miss in State: %d, FragmentFlags: 0x%x, MissCount: %d", \ mtl, as->State, FragmentFlags, as->MissCount)); RxTable->PPPReceiveError2++; goto clearbuffer; break; case RX_BEGIN: case RX_END: if (FragmentFlags & H_RX_N_BEG) { // // missed a begining buffer // as->MissCount++; D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, Miss in State: %d, FragmentFlags: 0x%x, MissCount: %d", \ mtl, as->State, FragmentFlags, as->MissCount)); RxTable->PPPReceiveError3++; goto done; } clearbuffer: // // clear rx buffer // NdisZeroMemory(as->buf, sizeof(as->buf)); // // start data at begin of buffer // as->DataPtr = as->buf; // // new buffer // as->len = 0; // // set rx state // as->State = RX_MIDDLE; // // set time to live // as->ttl = 1000; // // there is always only one fragment with PPP // maybe a big one but still only one // as->tot = 1; break; default: D_LOG(D_ALWAYS, ("Invalid PPP Rx State! mtl: 0x%p, as: 0x%p State: 0x%x", \ mtl, as, as->State)); as->State = RX_BEGIN; as->tot = 0; as->MissCount++; goto done; break; } // // get the length to be copy // CopyLen = msg->buflen; D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: CopyLen: %d", CopyLen)); if (FragmentFlags & H_RX_N_END) { // // if this is not the last buffer and length is 0 // we are done // if (CopyLen == 0) goto done_copy; } else { // // if CopyLen = 0 buffer only contains 2 CRC bytes // if (CopyLen == 0) { goto done_copy; } // // buffer contains only 1 CRC byte // else if (CopyLen == (-1 & H_RX_LEN_MASK)) { // // previous buffer had a crc byte in it so remove it // as->len -= 1; goto done_copy; } // // buffer contains no crc or data bytes // else if (CopyLen == (-2 & H_RX_LEN_MASK)) { // // previous buffer had 2 crc bytes in it so remove them // as->len -= 2; goto done_copy; } } // // if larger than max rx size throw away // if (CopyLen > IDP_MAX_RX_LEN) { // // buffer to big so dump it // as->State = RX_BEGIN; as->MissCount++; RxTable->PPPReceiveError4++; /* mark as free now */ as->tot = 0; D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: mtl: 0x%p, RxToLarge: RxSize: %d, MissCount: %d", mtl, CopyLen, as->MissCount)); goto done; } as->len += CopyLen; if (as->len > MTL_MAC_MTU) { // // Frame is to big so dump it // as->State = RX_BEGIN; RxTable->PPPReceiveError5++; as->MissCount++; /* mark as free now */ as->tot = 0; D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: AssembledRxToLarge: mtl: 0x%p, AsRxSize: %d, MissCount: %d", mtl, as->len, as->MissCount)); goto done; } // // copy the data to rx descriptor // IddGetDataFromAdapter(chan->idd, (PUCHAR)as->DataPtr, (PUCHAR)msg->bufptr, CopyLen); // NdisMoveMemory(as->DataPtr, msg->bufptr, CopyLen); // // update data ptr // as->DataPtr += CopyLen; done_copy: if (!(FragmentFlags & H_RX_N_END)) { // // if this is the end of the frame indicate to wrapper // as->State = RX_END; RxTable->NextFree++; QueueDescriptorForRxIndication(mtl, as); // // mark this guy as being queued // as->Queued = 1; } done: /* release assembly descriptor */ NdisReleaseSpinLock(&RxTable->lock); } else D_LOG(D_ALWAYS, ("mtl__rx_bchan_handler: Received IddFrameType: ??????!!!!!!")); // // exit code // release spinlock and return // exit_code: NdisReleaseSpinLock(&mtl->lock); }
VOID RTMPRemoveRepeaterEntry( IN PRTMP_ADAPTER pAd, IN UCHAR apIdx, IN UCHAR CliIdx) { USHORT HashIdx; REPEATER_CLIENT_ENTRY *pEntry, *pPrevEntry, *pProbeEntry; REPEATER_CLIENT_ENTRY_MAP *pMapEntry, *pPrevMapEntry, *pProbeMapEntry; BOOLEAN bVaild; DBGPRINT(RT_DEBUG_OFF, (" %s. apIdx=%d CliIdx=%d\n", __FUNCTION__,apIdx,CliIdx)); RTMPRemoveRepeaterAsicEntry(pAd, CliIdx); NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); pEntry = &pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx]; bVaild = TRUE; HashIdx = MAC_ADDR_HASH_INDEX(pEntry->CurrentAddress); pPrevEntry = NULL; pProbeEntry = pAd->ApCfg.ReptCliHash[HashIdx]; ASSERT(pProbeEntry); if (pProbeEntry == NULL) { bVaild = FALSE; goto done; } if (pProbeEntry != NULL) { /* update Hash list*/ do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pAd->ApCfg.ReptCliHash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); } /* not found !!!*/ ASSERT(pProbeEntry != NULL); if (pProbeEntry == NULL) { bVaild = FALSE; goto done; } pMapEntry = &pAd->ApCfg.ApCliTab[apIdx].RepeaterCliMap[CliIdx]; HashIdx = MAC_ADDR_HASH_INDEX(pEntry->OriginalAddress); pPrevMapEntry = NULL; pProbeMapEntry = pAd->ApCfg.ReptMapHash[HashIdx]; ASSERT(pProbeMapEntry); if (pProbeMapEntry != NULL) { /* update Hash list*/ do { if (pProbeMapEntry == pMapEntry) { if (pPrevMapEntry == NULL) { pAd->ApCfg.ReptMapHash[HashIdx] = pMapEntry->pNext; } else { pPrevMapEntry->pNext = pMapEntry->pNext; } break; } pPrevMapEntry = pProbeMapEntry; pProbeMapEntry = pProbeMapEntry->pNext; } while (pProbeMapEntry); } /* not found !!!*/ ASSERT(pProbeMapEntry != NULL); done: pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliConnectState = 0; NdisZeroMemory(pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].OriginalAddress, MAC_ADDR_LEN); if ((bVaild == TRUE) && (pAd->ApCfg.RepeaterCliSize > 0)) pAd->ApCfg.RepeaterCliSize--; /* set the apcli interface be invalid. */ pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliValid = FALSE; pAd->ApCfg.ApCliTab[apIdx].RepeaterCli[CliIdx].CliEnable = FALSE; NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return; }
VOID IndicateRxToWrapper( MTL *mtl ) { UCHAR *BufferPtr; USHORT BufferLength = 0; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ADAPTER *Adapter; MTL_AS *as; MTL_RX_TBL *RxTable; NdisAcquireSpinLock(&mtl->lock); Adapter = mtl->Adapter; RxTable = &mtl->rx_tbl; while (!IsRxIndicationFifoEmpty(mtl)) { NdisAcquireSpinLock(&RxTable->lock); // // get the next completed rx assembly // as = GetAssemblyFromRxIndicationFifo(mtl); if (!as) { D_LOG(D_ALWAYS, ("IndicateRx: Got a NULL as from queue! mtl: 0x%p", mtl)); RxTable->IndicateReceiveError1++; NdisReleaseSpinLock(&RxTable->lock); goto exit_code; } // // if this is an old ras frame then we must strip off // the mac header Dst[6] + Src[6] + Length[2] // if (mtl->RecvFramingBits & RAS_FRAMING) { // // pass over the mac header - tommyd does not want to see this // BufferPtr = as->buf + 14; // // indicate with the size of the ethernet packet not the received size // this takes care of the old driver that does padding on small frames // BufferLength = as->buf[12]; BufferLength = BufferLength << 8; BufferLength += as->buf[13]; D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: RAS")); D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength)); } else if (mtl->RecvFramingBits & PPP_FRAMING) { // // the received buffer is the data that needs to be inidcated // BufferPtr = as->buf; // // the received length is the length that needs to be indicated // BufferLength = as->len; D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: PPP")); D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength)); } else { // // unknown framing - what to do what to do // throw it away // D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, Unknown WrapperFramming: 0x%x", mtl, mtl->RecvFramingBits)); RxTable->IndicateReceiveError2++; as->tot = 0; as->Queued = 0; NdisReleaseSpinLock(&RxTable->lock); goto exit_code; } if (BufferLength > MTL_MAC_MTU) { D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, ReceiveLength > MAX ALLOWED (1514): RxLength: %d", mtl, as->len)); RxTable->IndicateReceiveError3++; as->tot = 0; as->Queued = 0; NdisReleaseSpinLock(&RxTable->lock); goto exit_code; } // // send frame up // if (mtl->LinkHandle) { /* release assembly descriptor */ NdisReleaseSpinLock(&RxTable->lock); NdisReleaseSpinLock(&mtl->lock); NdisMWanIndicateReceive(&Status, Adapter->Handle, mtl->LinkHandle, BufferPtr, BufferLength); NdisAcquireSpinLock(&mtl->lock); NdisAcquireSpinLock(&RxTable->lock); mtl->RecvCompleteScheduled = 1; } /* mark as free now */ as->tot = 0; // // mark this guy as being free // as->Queued = 0; /* release assembly descriptor */ NdisReleaseSpinLock(&RxTable->lock); } // // exit code // release spinlock and return // exit_code: NdisReleaseSpinLock(&mtl->lock); }
VOID RTMPRepeaterInsertInvaildMacEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr) { UCHAR HashIdx, idx = 0; INVAILD_TRIGGER_MAC_ENTRY *pEntry = NULL; INVAILD_TRIGGER_MAC_ENTRY *pCurrEntry = NULL; if (pAd->ApCfg.ReptControl.ReptInVaildMacSize >= 32) return; if (MAC_ADDR_EQUAL(pAddr, ZERO_MAC_ADDR)) return; NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); for (idx = 0; idx< 32; idx++) { pEntry = &pAd->ApCfg.ReptControl.RepeaterInvaildEntry[idx]; if (MAC_ADDR_EQUAL(pEntry->MacAddr, pAddr)) { if (pEntry->bInsert) { NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return; } else { pEntry->bInsert = TRUE; break; } } /* pick up the first available vacancy*/ if (pEntry->bInsert == FALSE) { NdisZeroMemory(pEntry->MacAddr, MAC_ADDR_LEN); COPY_MAC_ADDR(pEntry->MacAddr, pAddr); pEntry->bInsert = TRUE; break; } } /* add this entry into HASH table */ if (pEntry) { HashIdx = MAC_ADDR_HASH_INDEX(pAddr); pEntry->pNext = NULL; if (pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx] == NULL) { pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx] = pEntry; } else { pCurrEntry = pAd->ApCfg.ReptControl.ReptInvaildHash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } DBGPRINT(RT_DEBUG_ERROR, (" Store Invaild MacAddr = %02x:%02x:%02x:%02x:%02x:%02x. !!!\n", PRINT_MAC(pEntry->MacAddr))); pAd->ApCfg.ReptControl.ReptInVaildMacSize++; NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return; }
// // process a wan packet for transmition to idd level // // all packets will stay on one queue and the MacReserved fields will be used // to indicate what state the packet is in // // we will use the MacReserved fields provided in the NdisWanPacket as follows: // // MacReserved1 - Store a pointer to our local tx descriptor // MacReserved2 - This will be a boolean flag that will be set when this packet // can be completed (NdisMWanSendComplete) // MacReserved3 - This will be the time to live counter for the wanpacket. // If it is not completed we will go ahead and complete it. // // MacReserved4 // VOID mtl__tx_packet( MTL *mtl, NDIS_WAN_PACKET *WanPacket ) { UINT BytesLeftToTx, FragDataLength, FragNumber, FragSize; UINT TotalPacketLength; UCHAR *FragDataPtr; MTL_TX_PKT *MtlTxPacket; MTL_HDR MtlHeader; USHORT TxFlags; ADAPTER *Adapter = mtl->Adapter; PUCHAR MyStartBuffer; CM *cm = (CM*)mtl->cm; D_LOG(D_ENTRY, ("mtl_tx_packet: entry, mtl: 0x%lx, WanPacket: 0x%lx\n", mtl, WanPacket)); NdisAcquireSpinLock(&mtl->lock); IncrementGlobalCount(GlobalSends); // // queue up the wanpacket // AddToWanPacketTxFifo(mtl, WanPacket); // // get a local packet descriptor // MtlTxPacket = GetLocalTxDescriptor(mtl); // // make sure this is a valid descriptor // if (!MtlTxPacket) { D_LOG(DIGIMTL, ("mtl__tx_proc: Got a NULL Packet off of Local Descriptor Free List\n")); // // grab wan packet fifo lock // NdisAcquireSpinLock(&mtl->WanPacketFifo.lock); MarkWanPacketForCompletion(WanPacket); // // release the wan packet fifo lock // NdisReleaseSpinLock(&mtl->WanPacketFifo.lock); goto exit_code; } // // grab wan packet fifo lock // NdisAcquireSpinLock(&mtl->WanPacketFifo.lock); SetTxDescriptorInWanPacket(WanPacket, MtlTxPacket); // // release the wan packet fifo lock // NdisReleaseSpinLock(&mtl->WanPacketFifo.lock); // // grab the descriptor lock // NdisAcquireSpinLock(&MtlTxPacket->lock); IncrementGlobalCount(MtlSends1); /* if not connected, give up */ if ( !mtl->is_conn || cm->PPPToDKF) { D_LOG(DIGIMTL, ("mtl__tx_proc: packet on non-connected mtl, ignored\n")); IncrementGlobalCount(MtlSends2); goto xmit_error; } D_LOG(DIGIMTL, ("mtl__tx_proc: LocalPkt: 0x%lx, WanPkt: 0x%lx, WanPktLen: %d\n", MtlTxPacket, WanPacket, WanPacket->CurrentLength)); // // get length of wan packet // TotalPacketLength = WanPacket->CurrentLength; // // my start buffer is WanPacket->CurrentBuffer - 14 // MyStartBuffer = WanPacket->CurrentBuffer - 14; if (mtl->SendFramingBits & RAS_FRAMING) { D_LOG(DIGIMTL, ("mtl__tx_proc: Transmit WrapperFrameType: RAS\n")); // add dest eaddr // StartBuffer + 0 // NdisMoveMemory (MyStartBuffer + DST_ADDR_INDEX, cm->DstAddr, 6); // // add source eaddr // StartBuffer + 6 // NdisMoveMemory (MyStartBuffer + SRC_ADDR_INDEX, cm->SrcAddr, 6); // // add new length to buffer // StartBuffer + 12 // MyStartBuffer[12] = TotalPacketLength >> 8; MyStartBuffer[13] = TotalPacketLength & 0xFF; // // data now begins at MyStartBuffer // MtlTxPacket->frag_buf = MyStartBuffer; // // new transmit length is a mac header larger // TotalPacketLength += 14; }
static void lock(void) { NdisAcquireSpinLock(&_lock); }
VOID OvsAcquireCtrlLock() { NdisAcquireSpinLock(gOvsCtrlLock); }
/* ======================================================================== Routine Description: USB command kernel thread. Arguments: *Context the pAd, driver control block pointer Return Value: 0 close the thread Note: ======================================================================== */ int RTUSBCmdThread(IN void *Context) { struct rt_rtmp_adapter *pAd; struct rt_rtmp_os_task *pTask; int status; status = 0; pTask = Context; pAd = pTask->priv; RtmpOSTaskCustomize(pTask); NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; NdisReleaseSpinLock(&pAd->CmdQLock); while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) { #ifdef KTHREAD_SUPPORT RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); #else /* lock the device pointers */ RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); if (status != 0) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } #endif if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) break; if (!pAd->PM_FlgSuspend) CMDHandler(pAd); } if (pAd && !pAd->PM_FlgSuspend) { /* Clear the CmdQElements. */ struct rt_cmdqelmt *pCmdQElmt = NULL; NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; while (pAd->CmdQ.size) { RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt); if (pCmdQElmt) { if (pCmdQElmt->CmdFromNdis == TRUE) { if (pCmdQElmt->buffer != NULL) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (u8 *)pCmdQElmt); } else { if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) os_free_mem(pAd, pCmdQElmt->buffer); os_free_mem(pAd, (u8 *)pCmdQElmt); } } } NdisReleaseSpinLock(&pAd->CmdQLock); } /* notify the exit routine that we're actually exiting now * * complete()/wait_for_completion() is similar to up()/down(), * except that complete() is safe in the case where the structure * is getting deleted in a parallel mode of execution (i.e. just * after the down() -- that's necessary for the thread-shutdown * case. * * complete_and_exit() goes even further than this -- it is safe in * the case that the thread of the caller is going away (not just * the structure) -- this is necessary for the module-remove case. * This is important in preemption kernels, which transfer the flow * of execution immediately upon a complete(). */ DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n")); #ifndef KTHREAD_SUPPORT pTask->taskPID = THREAD_PID_INIT_VALUE; complete_and_exit(&pTask->taskComplete, 0); #endif return 0; }
/* ======================================================================== Routine Description: Close kernel threads. Arguments: *pAd the raxx interface data pointer Return Value: NONE Note: ======================================================================== */ VOID RtmpMgmtTaskExit( IN RTMP_ADAPTER *pAd) { INT ret; RTMP_OS_TASK *pTask; /* Sleep 50 milliseconds so pending io might finish normally */ RTMPusecDelay(50000); /* We want to wait until all pending receives and sends to the */ /* device object. We cancel any */ /* irps. Wait until sends and receives have stopped. */ RTUSBCancelPendingIRPs(pAd); /* We need clear timerQ related structure before exits of the timer thread. */ RtmpTimerQExit(pAd); /* Terminate Mlme Thread */ pTask = &pAd->mlmeTask; ret = RtmpOSTaskKill(pTask); if (ret == NDIS_STATUS_FAILURE) { /* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ /* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ DBGPRINT(RT_DEBUG_ERROR, ("kill mlme task failed!\n")); } /* Terminate cmdQ thread */ pTask = &pAd->cmdQTask; RTMP_OS_TASK_LEGALITY(pTask) { NdisAcquireSpinLock(&pAd->CmdQLock); pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; NdisReleaseSpinLock(&pAd->CmdQLock); /*RTUSBCMDUp(&pAd->cmdQTask); */ ret = RtmpOSTaskKill(pTask); if (ret == NDIS_STATUS_FAILURE) { /* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ /* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ DBGPRINT(RT_DEBUG_ERROR, ("kill command task failed!\n")); } pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN; } /* Terminate timer thread */ pTask = &pAd->timerTask; ret = RtmpOSTaskKill(pTask); if (ret == NDIS_STATUS_FAILURE) { /* DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", */ /* RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); */ DBGPRINT(RT_DEBUG_ERROR, ("kill timer task failed!\n")); } #ifdef WSC_INCLUDED WscThreadExit(pAd); #endif /* WSC_INCLUDED */ }