Sample Code

Windows Driver Samples/ Native Wi-Fi Miniport Sample Driver/ C++/ hw/ hw_recv.h/

/*++

Copyright (c) Microsoft Corporation. All rights reserved.

Module Name:
    hw_recv.h

Abstract:
    Contains defines used for receive functionality 
    in the HW layer
    
Revision History:
      When        What
    ----------    ----------------------------------------------
    09-04-2007    Created

Notes:

--*/
#pragma once

/*
 * The number of Reassembly Rx MSDUs that are currently in use before
 * we start expiring old receive Rx MSDUs if they have exceeded the
 * RxLifeTime set by the OS.
 */ 
#define HW_REASSEMBLY_LINE_LOW_RESOURCES_THRESHOLD   30

/*
 * Countdown before which the Reassembly Cleanup algorithm to kick in. The unit
 * is the number of times receive interrupt handling routine has run and indicated
 * something up to the OS.
 */
#define HW_REASSEMBLY_CLEANUP_COUNTDOWN_VALUE         250


/*
 * When the number of Rx MSDU available to the miniport falls below this
 * value, the miniport starts indicating low resources with packets indicated
 * to port. At this point, the upper layer driver will copy the data
 * indicated and return it immediately so that the next received packets can
 * be indicated using this Rx MSDU. This helps avoid packet loss due to lack of
 * resources to indicate packets up in.
 */
#define HW_RX_MSDU_LOW_RESOURCE_THRESHOLD        4

#define HW_RX_MSDU_GROW_POOL_SIZE                1


#define HW_INCREMENT_AVAILABLE_RX_MPDU(_Hw)          NdisInterlockedIncrement((PLONG)&_Hw->RxInfo.NumMPDUAvailable)
#define HW_DECREMENT_AVAILABLE_RX_MPDU(_Hw)          NdisInterlockedDecrement((PLONG)&_Hw->RxInfo.NumMPDUAvailable)
#define HW_ADD_TO_AVAILABLE_RX_MPDU(_Hw, NumToAdd)   InterlockedExchangeAdd((PLONG)&_Hw->RxInfo.NumMPDUAvailable, NumToAdd);

#define HW_INCREMENT_UNUSED_RX_MPDU(_Hw)            NdisInterlockedIncrement((PLONG)&_Hw->RxInfo.NumMPDUUnused)
#define HW_DECREMENT_UNUSED_RX_MPDU(_Hw)            NdisInterlockedDecrement((PLONG)&_Hw->RxInfo.NumMPDUUnused)

#define HW_INCREMENT_TOTAL_RX_MPDU_ALLOCATED(_Hw)    NdisInterlockedIncrement((PLONG)&_Hw->RxInfo.NumMPDUAllocated)
#define HW_DECREMENT_TOTAL_RX_MPDU_ALLOCATED(_Hw)    NdisInterlockedDecrement((PLONG)&_Hw->RxInfo.NumMPDUAllocated)
#define HW_ADD_TO_TOTAL_RX_MPDU_ALLOCATED(_Hw, NumToAdd)      InterlockedExchangeAdd((PLONG)&_Hw->RxInfo.NumMPDUAllocated, NumToAdd);

/*
 * \internal
 * Matches an Rx MSDUs in Reassembly with the provided sequence number and MAC
 * address. If both the values match, the macro returns true, else returns
 * false
 */
#define HW_REASSEMBLY_RX_MSDU_MATCH(_ReassemblyRxMSDU, _SequenceNumber, _MacAddress)    \
    ((_ReassemblyRxMSDU->SequenceNumber == _SequenceNumber) &&                 \
      (MP_COMPARE_MAC_ADDRESS(                                              \
            _ReassemblyRxMSDU->PeerAddress,                                 \
            _MacAddress)))


/** Access the timestamp field of the MSDU */
#define HW_GET_RX_EXPIRATION_TIME(_Msdu)   _Msdu->ExpirationTime

/** Placed the time when MSDU will expire */
#define HW_SET_RX_EXPIRATION_TIME(_Msdu, _LifeTime)         \
{                                                                   \
    KeQueryTickCount((PLARGE_INTEGER)&(_Msdu->ExpirationTime));     \
    _Msdu->ExpirationTime += _LifeTime;          \
}


/**
 * Initializes a newly allocate HW_RX_MPDU
 */
#define HW_INITIALIZE_RX_MPDU(_Mpdu, _Hw)    \
{                                                           \
    NdisZeroMemory(_Mpdu, sizeof(HW_RX_MPDU));              \
                                                            \
    /* Set the appropriate pointers in the HW & MP MPDU */  \
    _Mpdu->MpMpdu = &_Mpdu->PrivateMpMpdu;                  \
    _Mpdu->Hw = _Hw;                                        \
    _Mpdu->MpMpdu->HwMpdu = _Mpdu;                          \
}

/**
 * Reinitialize a returned HW_RX_MPDU
 */
#define HW_REINITIALIZE_RX_MPDU(_Mpdu)    \
{                                                           \
    _Mpdu->DataLength = 0;                                  \
    _Mpdu->PhyId = DOT11_PHY_ID_ANY;                        \
    _Mpdu->Channel = 0;                                     \
    _Mpdu->RawPacket = FALSE;                               \
    _Mpdu->Encrypted = FALSE;                               \
    _Mpdu->MulticastDestination = FALSE;                    \
    _Mpdu->MacContext = NULL;                               \
    _Mpdu->Key = NULL;                                      \
}


/** We can have a special receive lock, but we currently dont use them */
#define HW_RX_ACQUIRE_LOCK(_Hw, _Dispatch)  \
    HW_ACQUIRE_HARDWARE_LOCK(_Hw, _Dispatch)
#define HW_RX_RELEASE_LOCK(_Hw, _Dispatch)  \
    HW_RELEASE_HARDWARE_LOCK(_Hw, _Dispatch)

// If this is a broadcast packet, the counters get updated on the default MAC
#define HW_MAC_CONTEXT_FOR_RX_STATISTICS(_Hw, _Mpdu)    \
    ((_Mpdu->MacContext != NULL) ? _Mpdu->MacContext : &_Hw->MacContext[0])


__inline PHW_RX_MSDU
HwAllocateRxMSDU(
    _In_  PHW                     Hw
    );

__inline VOID
HwFreeRxMSDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu
    );
    
BOOLEAN
HwCheckPhyParameters(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

// Returns TRUE if this fragment is duplicate and should be dropped. FALSE otherwise
// Also if AddToTable is true, this entry is added to the duplicates table, else its not
BOOLEAN
HwMPDUIsDuplicate(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu,
    _In_  BOOLEAN                 IsGoodPacket
    );



// Called for Data and Management packets on 
BOOLEAN
HwCheckForDuplicateMPDU(
    _In_  PHW                     Hw,
    _In_reads_bytes_(sizeof(DOT11_MGMT_DATA_MAC_HEADER))  PUCHAR                  PacketBuffer,
    _In_  BOOLEAN                 IsGoodPacket
    );

BOOLEAN
HwCheckMacParameters(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

// Lock held
BOOLEAN
HwIsReceiveAvailable(
    _In_  PHW                     Hw,
    _In_  BOOLEAN                 DispatchLevel
    );

PHW_RX_MPDU
HwGetReceivedMPDU(
    _In_  PHW                     Hw
    );


// Called at Dispatch
NDIS_STATUS
HwProcessReceivedMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );


// Returns TRUE if we do software decryption (Even if decryption gave ICV errors, etc)
BOOLEAN
HwRxDecrypt(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

// Failure only for catastrophic issues
NDIS_STATUS
HwProcessRxCipher(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

PHW_KEY_ENTRY
HwFindDecryptionKey(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

NDIS_STATUS
HwIdentifyReceiveMac(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

NDIS_STATUS
HwFilterMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

NDIS_STATUS
HwPrepareReceivedMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

NDIS_STATUS
HwSecurityCheck(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu
    );

NDIS_STATUS
HwPrepareReceivedMSDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu
    );


// Lock held (or called from Initialize)
// Used to return a RxMPDU to the HAL for filling
__inline VOID
HwSubmitRxMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

VOID
HwReturnRxMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu,
    _In_  BOOLEAN                 DispatchLevel
    );

NDIS_STATUS
HwGrowMPDUPool(
    _In_  PHW                     Hw,
    _In_  ULONG                   NumToAllocate
    );

VOID
HwReturnRxMSDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu,
    _In_  BOOLEAN                 DispatchLevel
    );

VOID
HwIndicateReceivedMSDUs(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             MsduList,
    _In_  ULONG                   ReceiveFlags
    );

PMP_RX_MSDU
HwMapHwRxMSDUToMpRxMSDU(
    _In_  PHW_RX_MSDU             Msdu
    );

VOID
HwIndicateMSDUOnMACContext(
    _In_  PHW_MAC_CONTEXT         MacContext,
    _In_  PHW_RX_MSDU             Msdu,
    _In_  ULONG                   ReceiveFlags
    );



/**
 * Internal helper function to help with reassembly. For each fragment received
 * belonging to an Rx MSDU, this function will add it to the appropriate position.
 * If the fragment cannot be added for any reason, this function will return
 * the appropriate error code.
 * 
 * \param pMpRxd            The Rx MSDU in which the fragments are to be assembled
 * \param pNicFragment      The fragment we just received
 * \param pFragmentHdr      The 802.11 header of the received fragment
 * \param usFragmentSize    The size, in bytes, of the received fragment
 * \param ucFragNumber      The 802.11 fragment number of this frag
 * \return NDIS_STATUS_SUCCESS if frag added successfully and the reassembly
 * operation got completed when the frag was added. Will return NDIS_STATUS_PENDING
 * if frag was added successfully but we have still not received all MPDUs for
 * this MSDU. Else, a failure code is returned.
 * 
 * \sa MpHandleReceiveInterrupt, MpPrepareRxMSDUForIndication
 */
__inline NDIS_STATUS
HwAddRxMPDUToMSDU(
    _In_  PHW_RX_MSDU                 Msdu,
    _In_  PHW_RX_MPDU                 Mpdu,
    _In_  PDOT11_MGMT_DATA_MAC_HEADER FragmentHeader,
    _In_  UCHAR                       FragNumber
    );




/**
 * Called when the miniport determines that a received fragment (MPDU) is part of
 * a bigger MSDU and we have to wait till all MPDU's have been received for this
 * miniport.
 * 
 * \param pAdapter      The adapter context for this miniport
 * \param pMpRxd        The Rx MSDU in which all the fragments will be assembled for this MSDU
 * \param DispatchLevel TRUE if current IRQL is DISPATCH
 * \return NDIS_STATUS_SUCCESS if added successfully, else failure
 * \sa MpRemoveMSDUFromReassemblyLine
 */
NDIS_STATUS
HwAddPartialMSDUToReassemblyLine(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu,
    _In_  BOOLEAN                 DispatchLevel
    );




/**
 * This function searches for an Rx MSDU in the reassembly line given the
 * sequence number and the Fragment Hdr (to match MAC address) of an 802.11 packet
 * 
 * \param pAdapter          The adapter context for this miniport
 * \param pFragmentHdr      802.11 header of a received fragment for which we need a match
 * \param usSequenceNumber  The Sequence Number we will use to match the RX_MSDU
 * \param 
 * \return 
 * \sa 
 */
__inline PHW_RX_MSDU
HwFindPartialMSDUInReassemblyLine(
    _In_  PHW                     Hw,
    _In_  PDOT11_MGMT_DATA_MAC_HEADER FragmentHdr, 
    _In_  USHORT                  SequenceNumber
    );



/**
 * Called when an Rx MSDU previously added to Reassembly line has to be removed. The MSDU
 * may have been assembled successfully or an unrecoverable error may have caused us
 * to drop all fragments in this MSDU
 * 
 * \param pAdapter      The adapter context for this miniport
 * \param pMpRxd        The Rx MSDU to be dropped
 * \sa MpAddPartialMSDUToReassemblyLine
 */
VOID
HwRemoveMSDUFromReassemblyLine(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MSDU             Msdu
    );

/**
 * This function goes through the Reassembly line and drops all Rx MSDUs that
 * have we were not able to assemble in the RX_LIFETIME of the packet. This
 * function needs to be run periodically to help get rid of any orphan Rx MSDUs in
 * the reassembly line that can never be completed.
 * 
 * \param pAdapter          The adapter context for this miniport
 * \param DispatchLevel     TRUE if IRQL is DISPATCH
 * \sa MpAddPartialMSDUToReassemblyLine
 */
__inline VOID
HwExpireReassemblingMSDUs(
    _In_  PHW                     Hw,
    _In_  BOOLEAN                 DispatchLevel
    );

VOID
HwFlushMSDUReassemblyLine(
    _In_  PHW                     Hw
    );

PHW_RX_MSDU
HwBuildMSDUForMPDU(
    _In_  PHW                     Hw,
    _In_  PHW_RX_MPDU             Mpdu
    );

VOID
HwHandleReceiveInterrupt(
    _In_  PHW                     Hw,
    _In_  ULONG                   MaxNblsToIndicate
    );

VOID
HwResetReceiveEngine(
    _In_  PHW                     Hw,
    _In_  BOOLEAN                 DispatchLevel
    );

VOID
HwWaitForPendingReceives(
    _In_  PHW                     Hw,
    _In_opt_ PHW_MAC_CONTEXT      MacContext
    );

Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS