UINT CTXVirtQueue::ReleaseTransmitBuffers(CRawCNBList& listDone) { UINT len, i = 0; CTXDescriptor *TXDescriptor; DEBUG_ENTRY(4); while(NULL != (TXDescriptor = (CTXDescriptor *) GetBuf(&len))) { m_DescriptorsInUse.Remove(TXDescriptor); if (!TXDescriptor->GetUsedBuffersNum()) { DPrintf(0, ("[%s] ERROR: nofUsedBuffers not set!\n", __FUNCTION__)); } m_FreeHWBuffers += TXDescriptor->GetUsedBuffersNum(); listDone.PushBack(TXDescriptor->GetNB()); m_Descriptors.Push(TXDescriptor); DPrintf(3, ("[%s] Free Tx: desc %d, buff %d\n", __FUNCTION__, m_Descriptors.GetCount(), m_FreeHWBuffers)); ++i; } if (i) { NdisGetCurrentSystemTime(&m_Context->LastTxCompletionTimeStamp); m_DoKickOnNoBuffer = true; } DPrintf((i ? 3 : 5), ("[%s] returning i = %d\n", __FUNCTION__, i)); return i; }
VOID RefreshUdpListEntrySafe( VOID ) /*++ Routine Description: Remove stale mapping info from UDP port map list entries. This function is thread-safe. Do NOT acquire id list spin lock around this function. --*/ { LARGE_INTEGER now; PLIST_ENTRY p, temp; NdisAcquireSpinLock(&PortListLock); if (IsListEmpty(&PortListHead)) { // List is empty, nothing to be done. NdisReleaseSpinLock(&PortListLock); return; } NdisGetCurrentSystemTime(&now); p = PortListHead.Flink; while (p != &PortListHead) { PUDP_MAP_CONTEXT Map = CONTAINING_RECORD(p, UDP_MAP_CONTEXT, ListEntry); if (IsTimeOut(&now, &(Map->MapSetTime), &UdpTimeOut)) { // Time out. Release mapping info and reset corresponding hash table entry DBGPRINT(("==> RefreshUdpListEntrySafe: map %d -> %d time out. Delete.\n", Map->OriginalPort, Map->MappedPort)); // Protect the loop from break temp = p; p = p->Flink; // Clear hash table pointer UdpPortMapOutTable[Map->OriginalPort].Map = NULL; UdpPortMapInTable[Map->MappedPort].Map = NULL; // Remove entry and clear memory RemoveEntryList(temp); PortListLength--; NdisFreeMemory(Map, 0, 0); //DBGPRINT(("==> RefreshUdpListEntrySafe: map context memory freed.\n")); // Go to next entry } else { // Go to next entry // Map set time is refreshed when this map is accessed by mapping functions, no need to refresh it here p = p->Flink; } } NdisReleaseSpinLock(&PortListLock); }
/*----------------------------------------------------------------------------*/ UINT_64 kalGetNanoTick(VOID) { LARGE_INTEGER rSystemTime; NdisGetCurrentSystemTime(&rSystemTime); return rSystemTime.QuadPart; } /* kalGetNanoTick */
BOOLEAN GetUdpPortMapIn( IN USHORT mapped, OUT PUSHORT original, OUT PBOOLEAN trans ) /*++ Routine Description: Get the original UDP port for the incoming UDP packet. Arguments: mapped - Mapped UDP destination port in incoming packet original - Pointer to caller-supplied memory that holds the returned original port, cannot be NULL trans - Pointer to caller-supplied memory that holds the translate flag for this mapping, cannot be NULL Return Value: TRUE if find mapping is successful, original port is returned in 'original' pointer; FALSE if no valid mapping exists for this mapped port, 'original' and 'trans' is set to 0(FALSE) in this case. --*/ { BOOLEAN flag = FALSE; USHORT OriginalPort = 0; BOOLEAN Translated = FALSE; PUDP_MAP_CONTEXT Map = NULL; NdisAcquireSpinLock(&PortListLock); // Do NOT call RefreshUdpListEntrySafe() since we have already hold the spin lock. RefreshUdpListEntry(); if (UdpPortMapInTable[mapped].Map != NULL) { Map = UdpPortMapInTable[mapped].Map; if (Map->MappedPort == mapped) // Found existing mapping info { OriginalPort = Map->OriginalPort; Translated = Map->Translated; NdisGetCurrentSystemTime(&(Map->MapSetTime)); // refresh timer DBGPRINT(("==> GetUdpPortMapIn: Find Map %d -> %d, trans flag is %d.\n", Map->OriginalPort, Map->MappedPort, Map->Translated)); flag = TRUE; } } NdisReleaseSpinLock(&PortListLock); *original = OriginalPort; *trans = Translated; return flag; }
BOOLEAN HelperPortShouldPerformScan( _In_ PMP_HELPER_PORT HelperPort, _In_ PMP_SCAN_PARAMETERS ScanParameters ) { ULONGLONG currentSystemTime; ULONGLONG scanGapSeconds = HelperPort->RegInfo->InterScanTime; ULONGLONG acceptableScanTime; if (MP_TEST_PORT_STATUS(HELPPORT_GET_MP_PORT(HelperPort), MP_PORT_CANNOT_SCAN_MASK)) { // Cannot scan when in this state return FALSE; } if ((ScanParameters->CancelScan) || (ScanParameters->State != SCAN_QUEUED_FOR_PROCESSING)) { // Scan cancelled return FALSE; } if (MP_TEST_FLAG(ScanParameters->PortScanRequest->Dot11ScanRequest->dot11ScanType, dot11_scan_type_forced)) { // Forced scan. We will do it return TRUE; } if (MP_TEST_FLAG(ScanParameters->PortScanRequest->ScanRequestFlags, MP_SCAN_REQUEST_OS_ISSUED)) { // OS issued scan, we will do it return TRUE; } // Potentially, we should check if this scan request has a non-zero SSID // // To avoid too many scans, lets check if we have scanned recently. // NdisGetCurrentSystemTime((PLARGE_INTEGER)¤tSystemTime); acceptableScanTime = HelperPort->ScanContext.LastScanTime + scanGapSeconds * 10000000; // Convert seconds to 100nS if (acceptableScanTime > currentSystemTime) { // // Scanned recently. Dont scan again // return FALSE; } else { return TRUE; } }
// the input parameter start use the same unit as returned by rtw_get_current_time inline s32 rtw_get_passing_time_ms(u32 start) { #ifdef PLATFORM_LINUX return rtw_systime_to_ms(jiffies-start); #endif #ifdef PLATFORM_WINDOWS LARGE_INTEGER SystemTime; NdisGetCurrentSystemTime(&SystemTime); return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ; #endif }
VOID mp_wi_callback( IN NDIS_WORK_ITEM* pwk_item, IN PVOID cntx ) { _adapter* padapter =(_adapter *)cntx; struct mp_priv *pmppriv=&padapter->mppriv; struct mp_wi_cntx *pmp_wi_cntx=&pmppriv->wi_cntx; // Execute specified action. if(pmp_wi_cntx->curractfunc != NULL) { LARGE_INTEGER cur_time; ULONGLONG start_time, end_time; NdisGetCurrentSystemTime(&cur_time); // driver version start_time=cur_time.QuadPart/10; // The return value is in microsecond pmp_wi_cntx->curractfunc(padapter); NdisGetCurrentSystemTime(&cur_time); // driver version end_time=cur_time.QuadPart/10; // The return value is in microsecond DEBUG_INFO(("WorkItemActType: %d, time spent: %I64d us\n", pmp_wi_cntx->param.act_type, (end_time-start_time))); } NdisAcquireSpinLock( &(pmp_wi_cntx->mp_wi_lock) ); pmp_wi_cntx->bmp_wi_progress= _FALSE; NdisReleaseSpinLock( &(pmp_wi_cntx->mp_wi_lock) ); if(pmp_wi_cntx->bmpdrv_unload) { NdisSetEvent(&(pmp_wi_cntx->mp_wi_evt)); } }
u32 rtw_get_current_time(void) { #ifdef PLATFORM_LINUX return jiffies; #endif #ifdef PLATFORM_WINDOWS LARGE_INTEGER SystemTime; NdisGetCurrentSystemTime(&SystemTime); return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals #endif }
u32 rtw_get_current_time(void) { #ifdef PLATFORM_LINUX return jiffies; #endif #ifdef PLATFORM_FREEBSD struct timeval tvp; getmicrotime(&tvp); return tvp.tv_sec; #endif #ifdef PLATFORM_WINDOWS LARGE_INTEGER SystemTime; NdisGetCurrentSystemTime(&SystemTime); return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals #endif }
static UINT FillDataOnBugCheck() { UINT i, n = 0; NdisGetCurrentSystemTime(&BugCheckData.StaticData.Header.qCrashTime); for (i = 0; i < MAX_CONTEXTS; ++i) { tBugCheckPerNicDataContent *pSave = &BugCheckData.StaticData.PerNicData[i]; PARANDIS_ADAPTER *p = (PARANDIS_ADAPTER *)pSave->Context; if (!p) continue; pSave->nofPacketsToComplete = p->NetTxPacketsToReturn; pSave->nofReadyTxBuffers = p->nofFreeHardwareBuffers; pSave->LastInterruptTimeStamp.QuadPart = PARADNIS_GET_LAST_INTERRUPT_TIMESTAMP(p); pSave->LastTxCompletionTimeStamp = p->LastTxCompletionTimeStamp; ParaNdis_CallOnBugCheck(p); ++n; } return n; }
UINT CTXVirtQueue::ReleaseTransmitBuffers(CRawCNBList& listDone) { UINT len, i = 0; CTXDescriptor *TXDescriptor; DEBUG_ENTRY(4); while(NULL != (TXDescriptor = (CTXDescriptor *) GetBuf(&len))) { m_DescriptorsInUse.Remove(TXDescriptor); ReleaseOneBuffer(TXDescriptor, listDone); ++i; } if (i) { NdisGetCurrentSystemTime(&m_Context->LastTxCompletionTimeStamp); m_DoKickOnNoBuffer = true; } DPrintf((i ? 3 : 5), "[%s] returning i = %d\n", __FUNCTION__, i); return i; }
static UINT FillDataOnBugCheck() { UINT i, n = 0; NdisGetCurrentSystemTime(&BugCheckData.StaticData.Header.qCrashTime); for (i = 0; i < MAX_CONTEXTS; ++i) { tBugCheckPerNicDataContent *pSave = &BugCheckData.StaticData.PerNicData[i]; PARANDIS_ADAPTER *p = (PARANDIS_ADAPTER *)(UINT_PTR)pSave->Context; if (!p) continue; pSave->nofReadyTxBuffers = 0; for (UINT j = 0; j < p->nPathBundles; j++) { pSave->nofReadyTxBuffers += p->pPathBundles[j].txPath.GetFreeHWBuffers(); } pSave->LastInterruptTimeStamp.QuadPart = PARADNIS_GET_LAST_INTERRUPT_TIMESTAMP(p); pSave->LastTxCompletionTimeStamp = p->LastTxCompletionTimeStamp; ParaNdis_CallOnBugCheck(p); ++n; } return n; }
void ParaNdis_DebugHistory( PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4) { tBugCheckHistoryDataEntry *phe; ULONG index = InterlockedIncrement(&BugCheckData.StaticData.Data.CurrentHistoryIndex); index = (index - 1) % MAX_HISTORY; phe = &BugCheckData.StaticData.History[index]; phe->Context = (UINT_PTR)pContext; phe->operation = op; phe->pParam1 = (UINT_PTR)pParam1; phe->lParam2 = lParam2; phe->lParam3 = lParam3; phe->lParam4 = lParam4; #if (PARANDIS_DEBUG_HISTORY_DATA_VERSION == 1) phe->uIRQL = KeGetCurrentIrql(); phe->uProcessor = KeGetCurrentProcessorNumber(); #endif NdisGetCurrentSystemTime(&phe->TimeStamp); }
VOID StaReceiveAssociationResponse( __in PSTATION pStation, __in PNIC_RX_FRAGMENT pNicFragment, __in ULONG TotalLength ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PUCHAR pPacketBuffer; PDOT11_MGMT_HEADER pMgmtHeader; PDOT11_ASSOC_RESPONSE_FRAME pDot11AssocFrame; USHORT StatusCode; USHORT AID = 0; PSTA_BSS_ENTRY pAPEntry = pStation->ConnectContext.ActiveAP; BOOLEAN bTimerCancelled, bSetTxDataRate = FALSE; DOT11_RATE_SET rateSet; pPacketBuffer = Hw11GetFragmentDataStart(pNicFragment); // // Ref to make sure reset/halt does not leave while we are still working // STA_INCREMENT_REF(pStation->ConnectContext.AsyncFuncCount); NdisDprAcquireSpinLock(&(pStation->ConnectContext.Lock)); if (pStation->ConnectContext.AssociateState == ASSOC_STATE_WAITING_FOR_ASSOCIATE) { if (pStation->ConnectContext.ConnectState < CONN_STATE_READY_TO_CONNECT) { MpTrace(COMP_ASSOC, DBG_LOUD, ("Reset/Disconnect before association completed\n")); // // Reset/disconnect, etc. We dont process this associate packet. Eventually, timeout // will happen and cleanup // NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock)); STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount); return; } do { if (TotalLength < (sizeof(DOT11_MGMT_HEADER) + sizeof(DOT11_ASSOC_RESPONSE_FRAME))) { ndisStatus = NDIS_STATUS_NOT_ACCEPTED; MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet too short\n")); break; } pMgmtHeader = (PDOT11_MGMT_HEADER)pPacketBuffer; // // Check that is a packet from the AP we are interested in // if (!MP_COMPARE_MAC_ADDRESS(pMgmtHeader->SA, pAPEntry->MacAddress) || !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->BSSID, pAPEntry->Dot11BSSID) || !MP_COMPARE_MAC_ADDRESS(pMgmtHeader->DA, Hw11GetMACAddress(pStation->pNic))) { ndisStatus = NDIS_STATUS_NOT_ACCEPTED; MpTrace(COMP_ASSOC, DBG_LOUD, ("Association response packet not for me\n")); break; } } while (FALSE); if (ndisStatus != NDIS_STATUS_NOT_ACCEPTED) { // // This was a valid response to our association request // Complete the association with appropriate status // pDot11AssocFrame = (PDOT11_ASSOC_RESPONSE_FRAME)(pPacketBuffer + sizeof(DOT11_MGMT_HEADER)); // // Get association status code from the packet // StatusCode = pDot11AssocFrame->usStatusCode; if (StatusCode == DOT11_FRAME_STATUS_SUCCESSFUL) { // // Association attempt succeeded // ndisStatus = NDIS_STATUS_SUCCESS; MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association response status SUCCESS\n")); // // Validate AID // AID = pDot11AssocFrame->usAID; if ((AID & 0xc000) != 0xc000) { // Invalid AID. pStation->Config.ValidAID = FALSE; // Connecting to a non-conformant AP. Continue with association instead of bailing out. MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID)); } else { pStation->Config.ValidAID = TRUE; } AID &= ~(0xc000); if (AID > 2007) { // AID too big ndisStatus = NDIS_STATUS_FAILURE; MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association response contains invalid AID %d\n", AID)); } if (ndisStatus == NDIS_STATUS_SUCCESS) { // // Get data rate // ndisStatus = StaGetRateSetFromInfoEle( Add2Ptr(pDot11AssocFrame, sizeof(DOT11_ASSOC_RESPONSE_FRAME)), TotalLength - sizeof(DOT11_MGMT_HEADER) - sizeof(DOT11_ASSOC_RESPONSE_FRAME), FALSE, &rateSet); } if (ndisStatus == NDIS_STATUS_SUCCESS) { // Association has succeeded MpTrace(COMP_ASSOC, DBG_NORMAL, ("Association ID %d\n", AID)); pStation->ConnectContext.AssociateState = ASSOC_STATE_RECEIVED_ASSOCIATE; pStation->Config.AID = AID; // // Clear non-static WEP keys. // Hw11DeleteNonPersistentKey(pStation->pNic); bSetTxDataRate = TRUE; // // Set active PhyId // pStation->Config.ActivePhyId = pAPEntry->PhyId; // // Set multicast cipher algorithm if the exact algorithm was not selected. // if (pStation->Config.MulticastCipherAlgorithmCount > 1) { Hw11SetEncryption(pStation->pNic, FALSE, pStation->Config.MulticastCipherAlgorithm); } } else { pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION; StatusCode = DOT11_FRAME_STATUS_FAILURE; // Unspecified failure } } else { // The association attempt failed MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Association failed by the access point with status %d\n", StatusCode)); pStation->ConnectContext.AssociateState = ASSOC_STATE_STARTED_ASSOCIATION; } // // Copy the association response buffer into the AP Entry for completion indication // NdisDprAcquireSpinLock(&(pAPEntry->Lock)); pAPEntry->AssocResponseLength = (USHORT)TotalLength; MP_ALLOCATE_MEMORY(pStation->MiniportAdapterHandle, &(pAPEntry->pAssocResponse), TotalLength, STA11_MEMORY_TAG); if (pAPEntry->pAssocResponse == NULL) { MpTrace(COMP_ASSOC, DBG_SERIOUS, ("Unable to save association request packet\n")); // // We still maintain the association // pAPEntry->AssocResponseLength = 0; } else { // // Copy the association response into the packet // NdisMoveMemory(pAPEntry->pAssocResponse, pPacketBuffer, TotalLength); } // Save association ID, time, etc pAPEntry->AssocID = AID; NdisGetCurrentSystemTime(&(pAPEntry->AssociationUpTime)); pAPEntry->AssocState = dot11_assoc_state_auth_assoc; NdisDprReleaseSpinLock(&(pAPEntry->Lock)); NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock)); if (bSetTxDataRate == TRUE) { // // Set data TX rate // Hw11SetTXDataRate(pStation->pNic, &rateSet, Hw11GetCalibratedRSSI(pStation->pNic, pNicFragment) ); } // // Attempt to cancel the timer // /*NdisMCancelTimer(&(pStation->ConnectContext.Timer_AssociateTimeout), &bTimerCancelled); */ bTimerCancelled = WdfTimerStop(pStation->ConnectContext.Timer_AssociateTimeout, FALSE); if (bTimerCancelled) { STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount); } if (StatusCode) { StaAssociateComplete(pStation, StatusCode | DOT11_ASSOC_STATUS_ASSOCIATION_RESPONSE_START); } else { StaAssociateComplete(pStation, DOT11_ASSOC_STATUS_SUCCESS); } } else { NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock)); } } else { NdisDprReleaseSpinLock(&(pStation->ConnectContext.Lock)); MpTrace(COMP_ASSOC, DBG_LOUD, ("Association already timed out\n")); } STA_DECREMENT_REF(pStation->ConnectContext.AsyncFuncCount); }
BOOLEAN GetUdpPortMapOut( IN USHORT original, IN BOOLEAN trans, OUT PUSHORT mapped ) /*++ Routine Description: Get the mapped id for the outflow UDP packet. Arguments: original - Original UDP source port in outflow packet. trans - TRUE for 4to6 mapping; FLASE for 6to6 mapping. mapped - Pointer to caller-supplied memory that holds the returned mapping port. Return Value: TRUE if find mapping is successful, mapped port is returned in 'mapped' pointer; FALSE if failed to find or create a mapping info, 'mapped' is set to 0 in this case. --*/ { USHORT ret = 0; SHORT remaining; LONG MaxPorts = 65536 / LocalPrefixInfo.Ratio; // Total port number is determined by ratio USHORT rover_j; USHORT rover_k; USHORT low; // lower bound of j USHORT high; // higher bound of j PUDP_MAP_CONTEXT Map = NULL; NDIS_STATUS Status; NdisAcquireSpinLock(&PortListLock); // Do NOT call RefreshUdpListEntrySafe() since we have already hold the spin lock. RefreshUdpListEntry(); if (UdpPortMapOutTable[original].Map != NULL) { Map = UdpPortMapOutTable[original].Map; if (Map->OriginalPort == original && Map->Translated == trans) // Found existing mapping info { ret = Map->MappedPort; NdisGetCurrentSystemTime(&(Map->MapSetTime)); // refresh timer DBGPRINT(("==> GetUdpPortMapOut: Find Map %d -> %d\n", Map->OriginalPort, Map->MappedPort)); } } if (ret == 0) // no existing map, generate new map { if (PortListLength >= MaxPorts) { NdisReleaseSpinLock(&PortListLock); DBGPRINT(("==> GetUdpPortMapOut: list full. Map id is used up.\n")); *mapped = 0; return FALSE; } if (LocalPrefixInfo.XlateMode == 1) // 1:N id mapping { low = (USHORT)(1024 / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent) + 1; high = (USHORT)(65536 / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent) - 1; remaining = (high - low) + 1; if (PortListLength != 0) { rover_j = (USHORT)(LastAllocatedUdpPort / LocalPrefixInfo.Ratio / LocalPrefixInfo.Adjacent); rover_k = (USHORT)(LastAllocatedUdpPort % LocalPrefixInfo.Adjacent) + 1; if (rover_k == LocalPrefixInfo.Adjacent) { rover_j++; rover_k = 0; } } else { // No port allocated before rover_j = low; rover_k = 0; } do { ret = (rover_j * LocalPrefixInfo.Ratio + LocalPrefixInfo.Offset) * LocalPrefixInfo.Adjacent + rover_k; if (UdpPortMapInTable[ret].Map == NULL) { // find idle ivi port break; } rover_k++; if (rover_k == LocalPrefixInfo.Adjacent) { rover_j++; remaining--; rover_k = 0; if (rover_j > high) { rover_j = low; } } } while (remaining > 0); if (remaining <= 0) { NdisReleaseSpinLock(&PortListLock); *mapped = 0; return FALSE; } } else { // 1:1 id mapping ret = original; } // Allocate map info memory Status = NdisAllocateMemoryWithTag((PVOID)&Map, sizeof(UDP_MAP_CONTEXT), TAG); if (Status != NDIS_STATUS_SUCCESS) { NdisReleaseSpinLock(&PortListLock); // No memory for map info. Fail this map. DBGPRINT(("==> GetUdpPortMapOut: NdisAllocateMemoryWithTag failed for port %d\n", original)); *mapped = 0; return FALSE; } NdisZeroMemory(Map, sizeof(UDP_MAP_CONTEXT)); // Routine to add new map-info Map->OriginalPort = original; Map->MappedPort = ret; Map->Translated = trans; NdisGetCurrentSystemTime(&(Map->MapSetTime)); // set timer for newly added mapping // Set hash table pointer UdpPortMapOutTable[Map->OriginalPort].Map = Map; UdpPortMapInTable[Map->MappedPort].Map = Map; // Linked list need not be sorted. Just insert new entry at tail. InsertTailList(&PortListHead, &(Map->ListEntry)); PortListLength++; LastAllocatedUdpPort = ret; DBGPRINT(("==> GetUdpPortMapOut: New map %d -> %d added, xlate=%d.\n", Map->OriginalPort, Map->MappedPort, Map->Translated)); } NdisReleaseSpinLock(&PortListLock); *mapped = ret; return TRUE; }
NDIS_STATUS HelperPortInsertBSSEntry( __in PMP_HELPER_PORT HelperPort, __in PMP_RX_MPDU pFragment, __in PDOT11_BEACON_FRAME pDot11BeaconFrame, __in ULONG BeaconDataLength ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; ULONGLONG ullHostTimeStamp; MP_RW_LOCK_STATE LockState; PMP_BSS_ENTRY pBSSEntry = NULL; PDOT11_MGMT_HEADER pMgmtPktHeader; BOOLEAN bNewAp = FALSE; PMP_BSS_LIST pDiscoveredBSSList = &(HelperPort->BSSList); pMgmtPktHeader = (PDOT11_MGMT_HEADER)MP_RX_MPDU_DATA(pFragment); NdisGetCurrentSystemTime((PLARGE_INTEGER)&ullHostTimeStamp); // // We acquire the write lock as we are adding entries to the list // MP_ACQUIRE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState); do { // // Check again if this entry already exists in the list. This is to handle // if the AP was added since we first checked (possible if the // flush routine was running) // pBSSEntry = HelperPortFindBSSEntry( pDiscoveredBSSList, pMgmtPktHeader->SA ); if (pBSSEntry == NULL) { bNewAp = TRUE; // New AP // // We havent found this AP yet, we would add it to the list // if (pDiscoveredBSSList->NumOfBSSEntries >= pDiscoveredBSSList->MaxNumOfBSSEntries) { // // We need to replace an entry thats in the list // pBSSEntry = HelperPortExpireBSSEntry( pDiscoveredBSSList, HelperPort->RegInfo->BSSEntryExpireTime, ullHostTimeStamp ); if (pBSSEntry != NULL) { // // Add initial in-use refcount // pBSSEntry->RefCount = 1; } // // Dont zero out the AP entry so that we can // reuse the info element blob // } else { // // Create a new entry for this AP // MP_ALLOCATE_MEMORY(HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, &pBSSEntry, sizeof(MP_BSS_ENTRY), PORT_MEMORY_TAG ); if (pBSSEntry != NULL) { // // Initialize the new entry // NdisZeroMemory(pBSSEntry, sizeof(MP_BSS_ENTRY)); pBSSEntry->RefCount = 1; // Add initial in-use refcount NdisAllocateSpinLock(&(pBSSEntry->Lock)); } } if (pBSSEntry == NULL) { MpTrace(COMP_SCAN, DBG_SERIOUS, ("Not enough space to add AP: %02X-%02X-%02X-%02X-%02X-%02X\n", pMgmtPktHeader->SA[0], pMgmtPktHeader->SA[1], pMgmtPktHeader->SA[2], pMgmtPktHeader->SA[3], pMgmtPktHeader->SA[4], pMgmtPktHeader->SA[5])); ndisStatus = NDIS_STATUS_RESOURCES; break; } // // This Entry is not yet in the list // // We will be updating the beacon & probe response frames pBSSEntry->BeaconFrameSize = 0; pBSSEntry->ProbeFrameSize = 0; pBSSEntry->AssocCost = 0; NdisMoveMemory( pBSSEntry->Dot11BSSID, pMgmtPktHeader->BSSID, sizeof(DOT11_MAC_ADDRESS) ); NdisMoveMemory( pBSSEntry->MacAddress, pMgmtPktHeader->SA, sizeof(DOT11_MAC_ADDRESS) ); } // Update the information in this BSS entry (either new or reused entry) ndisStatus = HelperPortUpdateBSSEntry( HelperPort, pBSSEntry, pFragment, pDot11BeaconFrame, BeaconDataLength ); if (ndisStatus != NDIS_STATUS_SUCCESS) { break; } // // Add the new BSS to our list // if (bNewAp) { MpTrace(COMP_SCAN, DBG_LOUD, ("AP %02X-%02X-%02X-%02X-%02X-%02X at channel: %d (%d)\n", pBSSEntry->Dot11BSSID[0], pBSSEntry->Dot11BSSID[1], pBSSEntry->Dot11BSSID[2], pBSSEntry->Dot11BSSID[3], pBSSEntry->Dot11BSSID[4], pBSSEntry->Dot11BSSID[5], pBSSEntry->Channel, pFragment->Msdu->Channel)); HelperPortAddBSSEntry(pDiscoveredBSSList, pBSSEntry); } // // Note: If any code is added below here, remember to remove entry // from the list // } while (FALSE); MP_RELEASE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState); if (ndisStatus != NDIS_STATUS_SUCCESS) { // Free the new entry we may have created if ((bNewAp) && (pBSSEntry != NULL)) { if (pBSSEntry->pDot11BeaconFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11BeaconFrame); pBSSEntry->pDot11BeaconFrame = NULL; pBSSEntry->BeaconFrameSize = 0; pBSSEntry->MaxBeaconFrameSize= 0; } if (pBSSEntry->pDot11ProbeFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11ProbeFrame); pBSSEntry->pDot11ProbeFrame = NULL; pBSSEntry->ProbeFrameSize = 0; pBSSEntry->MaxProbeFrameSize= 0; } pBSSEntry->pDot11InfoElemBlob = NULL; pBSSEntry->InfoElemBlobSize = 0; MP_FREE_MEMORY(pBSSEntry); } } return ndisStatus;
u8 set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _TRUE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _queue *queue = &pmlmepriv->scanned_queue; #ifdef PLATFORM_WINDOWS LARGE_INTEGER sys_time; u32 diff_time, cur_time; #endif _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+set_802_11_ssid: ssid=[%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv))); if (padapter->hw_init_completed == _FALSE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); return _FALSE; } _enter_critical(&pmlmepriv->lock, &irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is not allowed under surveying || adhoc master || under linking\n")); status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_SSID; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); if (is_same_ibss(padapter, pnetwork) == _FALSE) { //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) indicate_disconnect(padapter); free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto _Abort_Set_SSID;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) indicate_disconnect(padapter); free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } #ifdef PLATFORM_WINDOWS if (padapter->securitypriv.btkip_countermeasure == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n")); NdisGetCurrentSystemTime(&sys_time); cur_time=(u32)(sys_time.QuadPart/10); // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid:cur_time=0x%x\n",cur_time)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time)); diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid:diff_time=0x%x\n",diff_time)); if (diff_time > 60000000) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid(): countermeasure time >60s.\n")); padapter->securitypriv.btkip_countermeasure = _FALSE; // Update MIC error time. padapter->securitypriv.btkip_countermeasure_time = 0; } else { // can't join in 60 seconds. status = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_ssid(): countermeasure time <60s.\n")); goto _Abort_Set_SSID; } } #endif #ifdef PLATFORM_LINUX if (padapter->securitypriv.btkip_countermeasure == _TRUE) { status = _FALSE; goto _Abort_Set_SSID; } #endif if (validate_ssid(ssid) == _FALSE) { status = _FALSE; goto _Abort_Set_SSID; } _memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid = _FALSE; status = do_join(padapter); goto done; _Abort_Set_SSID: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-set_802_11_ssid: _Abort_Set_SSID: status=%d\n", status)); done: _exit_critical(&pmlmepriv->lock, &irqL); _func_exit_; return status; }
u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _SUCCESS; u32 cur_time = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _func_enter_; DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv)); if(padapter->hw_init_completed==_FALSE){ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); status = _FAIL; goto exit; } _enter_critical_bh(&pmlmepriv->lock, &irqL); DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE) { //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } #ifdef CONFIG_LPS else { rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); } #endif } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: #ifdef PLATFORM_WINDOWS if (padapter->securitypriv.btkip_countermeasure==_TRUE) { LARGE_INTEGER sys_time; u32 diff_time,cur_time ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n")); NdisGetCurrentSystemTime(&sys_time); cur_time=(u32)(sys_time.QuadPart/10); // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:cur_time=0x%x\n",cur_time)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time)); diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:diff_time=0x%x\n",diff_time)); if (diff_time > 60000000) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time >60s.\n")); padapter->securitypriv.btkip_countermeasure=_FALSE; // Update MIC error time. padapter->securitypriv.btkip_countermeasure_time=0; } else { // can't join in 60 seconds. status = _FAIL; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n")); goto release_mlme_lock; } } #endif #ifdef PLATFORM_LINUX if (padapter->securitypriv.btkip_countermeasure == _TRUE) { cur_time = rtw_get_current_time(); if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ ) { padapter->securitypriv.btkip_countermeasure = _FALSE; padapter->securitypriv.btkip_countermeasure_time = 0; } else { status = _FAIL; goto release_mlme_lock; } } #endif #ifdef CONFIG_VALIDATE_SSID if (rtw_validate_ssid(ssid) == _FALSE) { status = _FAIL; goto release_mlme_lock; } #endif _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=_FALSE; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { pmlmepriv->to_join = _TRUE; } else { status = rtw_do_join(padapter); } release_mlme_lock: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-rtw_set_802_11_ssid: status=%d\n", status)); _func_exit_; return status; }
// BSS list lock acquired & called at Dispatch NDIS_STATUS HelperPortUpdateBSSEntry( __in PMP_HELPER_PORT HelperPort, __in PMP_BSS_ENTRY pBSSEntry, __in PMP_RX_MPDU pFragment, __in PDOT11_BEACON_FRAME pDot11BeaconPRFrame, __in ULONG BeaconPRDataLength ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; PDOT11_MGMT_HEADER pMgmtPktHeader; ULONGLONG ullHostTimeStamp; PVOID pSavedBeaconPRBuffer = NULL; ULONG uOffsetOfInfoElemBlob = FIELD_OFFSET(DOT11_BEACON_FRAME, InfoElements); UCHAR channel; DOT11_PHY_TYPE PhyType; pMgmtPktHeader = (PDOT11_MGMT_HEADER)MP_RX_MPDU_DATA(pFragment); NdisGetCurrentSystemTime((PLARGE_INTEGER)&ullHostTimeStamp); do { // // Modifying data in the AP entry // NdisDprAcquireSpinLock(&(pBSSEntry->Lock)); if (pDot11BeaconPRFrame->Capability.IBSS) { pBSSEntry->Dot11BSSType = dot11_BSS_type_independent; } else { pBSSEntry->Dot11BSSType = dot11_BSS_type_infrastructure; } // // Adhoc station can leave adhoc cell and create a new cell. SoftAPs // can move. This means the BSSID can change // NdisMoveMemory( pBSSEntry->Dot11BSSID, pMgmtPktHeader->BSSID, sizeof(DOT11_MAC_ADDRESS) ); pBSSEntry->HostTimestamp = ullHostTimeStamp; pBSSEntry->BeaconTimestamp = pDot11BeaconPRFrame->Timestamp; pBSSEntry->BeaconInterval = pDot11BeaconPRFrame->BeaconInterval; pBSSEntry->Dot11Capability = pDot11BeaconPRFrame->Capability; pBSSEntry->RSSI = pFragment->Msdu->RecvContext.lRSSI; pBSSEntry->LinkQuality = pFragment->Msdu->LinkQuality; pBSSEntry->ChannelCenterFrequency = pFragment->Msdu->RecvContext.uChCenterFrequency; // // If signal strength was below our threshold, catch that // if (pBSSEntry->LinkQuality < HelperPort->RegInfo->RSSILinkQualityThreshold) { pBSSEntry->LowQualityCount++; } else { pBSSEntry->LowQualityCount = 0; } #if 0 if (pBSSEntry->AssocState == dot11_assoc_state_auth_assoc) { MpTrace(COMP_ASSOC, DBG_LOUD, ("Received beacon from associated AP: %02X-%02X-%02X-%02X-%02X-%02X\n", pMgmtPktHeader->SA[0], pMgmtPktHeader->SA[1], pMgmtPktHeader->SA[2], pMgmtPktHeader->SA[3], pMgmtPktHeader->SA[4], pMgmtPktHeader->SA[5])); } #endif // // Get channel number at which the frame was received. // if (Dot11GetChannelForDSPhy(Add2Ptr(pDot11BeaconPRFrame, uOffsetOfInfoElemBlob), BeaconPRDataLength - uOffsetOfInfoElemBlob, &channel) != NDIS_STATUS_SUCCESS) { channel = pFragment->Msdu->Channel; } if (channel != 0) { pBSSEntry->Channel = channel; } // // Get PhyType and PhyId // PhyType = VNic11DeterminePHYType(HELPPORT_GET_VNIC(HelperPort), pBSSEntry->Dot11Capability, pBSSEntry->Channel); if (pBSSEntry->Dot11PhyType != PhyType) { pBSSEntry->Dot11PhyType = PhyType; pBSSEntry->PhyId = BasePortGetPhyIdFromType(HELPPORT_GET_MP_PORT(HelperPort), PhyType); } if (pMgmtPktHeader->FrameControl.Subtype == DOT11_MGMT_SUBTYPE_BEACON) { // // Increase the beacon frame size if necessary // if (pBSSEntry->MaxBeaconFrameSize < BeaconPRDataLength) { MP_ALLOCATE_MEMORY(HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, &pSavedBeaconPRBuffer, BeaconPRDataLength, PORT_MEMORY_TAG ); if (pSavedBeaconPRBuffer == NULL) { // // Unable to allocate memory for information elements. // If this is a new AP entry, we wont be adding it to the list. // For existing entries, we end up ignoring the new IE blob // ndisStatus = NDIS_STATUS_RESOURCES; NdisDprReleaseSpinLock(&(pBSSEntry->Lock)); break; } // // Delete any old blob buffer // if (pBSSEntry->pDot11BeaconFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11BeaconFrame); } pBSSEntry->pDot11BeaconFrame = pSavedBeaconPRBuffer; pBSSEntry->MaxBeaconFrameSize = BeaconPRDataLength; } // Update the beacon pBSSEntry->BeaconFrameSize = BeaconPRDataLength; // Also save this as the IE blob pointer pBSSEntry->InfoElemBlobSize = BeaconPRDataLength - uOffsetOfInfoElemBlob; pBSSEntry->pDot11InfoElemBlob = (PUCHAR)pBSSEntry->pDot11BeaconFrame + uOffsetOfInfoElemBlob; // // Update/Save the beacon information element block // NdisMoveMemory( pBSSEntry->pDot11BeaconFrame, pDot11BeaconPRFrame, BeaconPRDataLength ); } if (pMgmtPktHeader->FrameControl.Subtype == DOT11_MGMT_SUBTYPE_PROBE_RESPONSE) { // // Increase the probe response frame size if necessary // if (pBSSEntry->MaxProbeFrameSize < BeaconPRDataLength) { MP_ALLOCATE_MEMORY(HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, &pSavedBeaconPRBuffer, BeaconPRDataLength, PORT_MEMORY_TAG ); if (pSavedBeaconPRBuffer == NULL) { // // Unable to allocate memory for information elements. // If this is a new AP entry, we wont be adding it to the list. // For existing entries, we end up ignoring the new IE blob // ndisStatus = NDIS_STATUS_RESOURCES; NdisDprReleaseSpinLock(&(pBSSEntry->Lock)); break; } // // Delete any old blob buffer // if (pBSSEntry->pDot11ProbeFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11ProbeFrame); } pBSSEntry->pDot11ProbeFrame = pSavedBeaconPRBuffer; pBSSEntry->MaxProbeFrameSize = BeaconPRDataLength; } pBSSEntry->ProbeFrameSize = BeaconPRDataLength; // Also save this as the IE blob pointer pBSSEntry->InfoElemBlobSize = BeaconPRDataLength - uOffsetOfInfoElemBlob; pBSSEntry->pDot11InfoElemBlob = (PUCHAR)pBSSEntry->pDot11ProbeFrame + uOffsetOfInfoElemBlob; // // Update/Save the beacon information element block // NdisMoveMemory( pBSSEntry->pDot11ProbeFrame, pDot11BeaconPRFrame, BeaconPRDataLength ); } #if 0 if (pBSSEntry->AssocState == dot11_assoc_state_auth_assoc) { MpTrace(COMP_SCAN, DBG_LOUD, ("Received %d for AP %02X-%02X-%02X-%02X-%02X-%02X \n", pMgmtPktHeader->FrameControl.Subtype, pBSSEntry->Dot11BSSID[0], pBSSEntry->Dot11BSSID[1], pBSSEntry->Dot11BSSID[2], pBSSEntry->Dot11BSSID[3], pBSSEntry->Dot11BSSID[4], pBSSEntry->Dot11BSSID[5])); } #endif // // Done with our modification of the AP entry // NdisDprReleaseSpinLock(&(pBSSEntry->Lock)); } while (FALSE); return ndisStatus;
VOID HelperPortStartScanProcess( _In_ PMP_HELPER_PORT HelperPort, _In_ PMP_SCAN_PARAMETERS ScanParameters ) { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; ULONG scanChannelCount = 0; ULONG i; do { MpTrace(COMP_SCAN, DBG_NORMAL, ("Starting the scan process of %p for port %p\n", ScanParameters, ScanParameters->RequestingPort)); // // For optimal scanning, we specify the list of channels // that the HW should use if the port hasnt specified any. // Note that for ExtSTA the channels in the PhyTypeInfo // structures of the DOT11_SCAN_REQUEST are invalid. So we dont // need to consider those // if (ScanParameters->PortScanRequest->ChannelCount != 0) { // Use the list of channels specified by the port scanChannelCount = ScanParameters->PortScanRequest->ChannelCount; } else { if (HelperPort->ScanContext.MediaConnectedCount > 0) { // A port is connected (STA associated/AP started/Adhoc running) // We dont scan all channels in one shot. We do multiple partial // scans // The scan type determines the number of channels we scan at a time if (ScanParameters->PortScanRequest->Dot11ScanRequest->dot11ScanType & dot11_scan_type_active) scanChannelCount = HelperPort->RegInfo->ActiveScanChannelCount; else scanChannelCount = HelperPort->RegInfo->PassiveScanChannelCount; MpTrace(COMP_SCAN, DBG_NORMAL, ("Link Up scan will scan atmost %d channels at a time\n", scanChannelCount)); } else { // We can scan each phy in one scan. Find the maximum number of // channels in a phy & use that as our scan channels limit scanChannelCount = 0; for (i = 0; i < HW11_MAX_PHY_COUNT; i++) { if (HelperPort->ScanContext.ScanChannels[i].ChannelCount > scanChannelCount) { scanChannelCount = HelperPort->ScanContext.ScanChannels[i].ChannelCount; } } MpTrace(COMP_SCAN, DBG_NORMAL, ("Link Down scan will scan upto %d channels at a time\n", scanChannelCount)); } } ScanParameters->MaxChannelCount = scanChannelCount; // // Create a channel buffer that we would give to the lower layer // MP_ALLOCATE_MEMORY( HELPPORT_GET_MP_PORT(HelperPort)->MiniportAdapterHandle, &ScanParameters->VNicScanRequest.ChannelList, scanChannelCount * sizeof(ULONG), PORT_MEMORY_TAG ); if (ScanParameters->VNicScanRequest.ChannelList == NULL) { ndisStatus = NDIS_STATUS_RESOURCES; break; } // // Save scan start time // NdisGetCurrentSystemTime((PLARGE_INTEGER)&HelperPort->ScanContext.LastScanTime); ScanParameters->VNicScanRequest.Dot11ScanRequest = ScanParameters->PortScanRequest->Dot11ScanRequest; ScanParameters->VNicScanRequest.ScanRequestBufferLength = ScanParameters->PortScanRequest->ScanRequestBufferLength; MP_ACQUIRE_PORT_LOCK(HELPPORT_GET_MP_PORT(HelperPort), FALSE); if (ScanParameters->CancelScan) { MpTrace(COMP_SCAN, DBG_NORMAL, ("Aborting scan start for a cancelled scan request\n")); ndisStatus = NDIS_STATUS_REQUEST_ABORTED; } else { // We will queue an exclusive access request ScanParameters->State = SCAN_EXCLUSIVE_ACCESS_QUEUED; } MP_RELEASE_PORT_LOCK(HELPPORT_GET_MP_PORT(HelperPort), FALSE); if (ndisStatus != NDIS_STATUS_SUCCESS) { break; } // // Queue an exclusive access. The scan would be done in there // ndisStatus = HelperPortRequestExclusiveAccess(HelperPort, HelperPortScanExAccessCallback, ScanParameters, FALSE ); if (NDIS_STATUS_SUCCESS == ndisStatus) { // the function completed synchronously, call the callback ourselves HelperPortScanExAccessCallback(HELPPORT_GET_MP_PORT(HelperPort), ScanParameters); } else if (ndisStatus == NDIS_STATUS_PENDING) { // Pending is same as success if (ndisStatus == NDIS_STATUS_PENDING) { ndisStatus = NDIS_STATUS_SUCCESS; } } else { // The exclusive access request failed MpTrace(COMP_SCAN, DBG_SERIOUS, ("Exclusive access request for scan start failed. Status = 0x%08x\n", ndisStatus)); } }while (FALSE); if (ndisStatus != NDIS_STATUS_SUCCESS) { HelperPortCompleteScanProcess( HelperPort, ScanParameters, &ndisStatus ); } }
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_MINIPORT_DRIVER_CHARACTERISTICS chars; #ifdef DEBUG_TIMING LARGE_INTEGER TickCount; LARGE_INTEGER SysTime; #endif DEBUG_TIMING ParaNdis_DebugInitialize(); DEBUG_ENTRY(0); DPrintf(0, (__DATE__ " " __TIME__ "built %d.%d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION)); #ifdef DEBUG_TIMING KeQueryTickCount(&TickCount); NdisGetCurrentSystemTime(&SysTime); DPrintf(0, ("\n%s>> CPU #%d, perf-counter %I64d, tick count %I64d, NDIS_sys_time %I64d\n", __FUNCTION__, KeGetCurrentProcessorNumber(), KeQueryPerformanceCounter(NULL).QuadPart,TickCount.QuadPart, SysTime.QuadPart)); #endif NdisZeroMemory(&chars, sizeof(chars)); chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; /* stupid thing, they are at least short */ chars.MajorDriverVersion = (UCHAR)(PARANDIS_MAJOR_DRIVER_VERSION & 0xFF); chars.MinorDriverVersion = (UCHAR)(PARANDIS_MINOR_DRIVER_VERSION & 0xFF); // possible value for regular miniport NDIS_WDM_DRIVER - for USB or 1394 // chars.Flags = 0; chars.InitializeHandlerEx = ParaNdis6_Initialize; chars.HaltHandlerEx = ParaNdis6_Halt; chars.UnloadHandler = ParaNdis6_Unload; chars.PauseHandler = ParaNdis6_Pause; chars.RestartHandler = ParaNdis6_Restart; chars.OidRequestHandler = ParaNdis6_OidRequest; chars.CancelOidRequestHandler = ParaNdis6_OidCancelRequest; chars.SendNetBufferListsHandler = ParaNdis6_SendNetBufferLists; chars.CancelSendHandler = ParaNdis6_CancelSendNetBufferLists; chars.ReturnNetBufferListsHandler = ParaNdis6_ReturnNetBufferLists; chars.CheckForHangHandlerEx = ParaNdis6_CheckForHang; chars.ResetHandlerEx = ParaNdis6_Reset; chars.ShutdownHandlerEx = ParaNdis6_AdapterShutdown; chars.DevicePnPEventNotifyHandler = ParaNdis6_DevicePnPEvent; chars.SetOptionsHandler = ParaNdis6_SetOptions; #if NDIS_SUPPORT_NDIS61 chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; chars.DirectOidRequestHandler = ParaNdis6x_DirectOidRequest; chars.CancelDirectOidRequestHandler = ParaNdis6x_CancelDirectOidRequest; #endif status = NdisMRegisterMiniportDriver( pDriverObject, pRegistryPath, NULL, &chars, &DriverHandle); if (status == NDIS_STATUS_SUCCESS) { RetrieveDriverConfiguration(); } DEBUG_EXIT_STATUS(status ? 0 : 4, status); return status; }