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;
}
Пример #2
0
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 */
Пример #4
0
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;
}
Пример #5
0
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)&currentSystemTime);
    acceptableScanTime = HelperPort->ScanContext.LastScanTime +             
         scanGapSeconds * 10000000; // Convert seconds to 100nS

    if (acceptableScanTime > currentSystemTime)
    {
        //
        // Scanned recently. Dont scan again
        //
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
Пример #6
0
// 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
}
Пример #7
0
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));
	}

	

}
Пример #8
0
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
}
Пример #9
0
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);
}
Пример #14
0
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);    
}
Пример #15
0
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;
}
Пример #16
0
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;
Пример #17
0
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;

}
Пример #18
0
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;
	
}
Пример #19
0
// 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;
Пример #20
0
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;
}